require that policy files also provide a <message> element
authorDavid Zeuthen <davidz@redhat.com>
Wed, 25 Jul 2007 21:47:45 +0000 (17:47 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Wed, 25 Jul 2007 21:47:45 +0000 (17:47 -0400)
Declaring an action now requires two textual elements (that both are
subject to translation):

 description: This is intended to be used in policy editors, for
              example "Mount internal volumes".
 message:     This is to be used in auth dialogs, for example "System
              Policy prevents mounting this internal volume".

This is actually needed for security reasons. The idea is that the
desktop environment can provide infrastructure that Callers
(e.g. applications) can use to ask the user to authenticate to gain a
privilege. One such example is PolicyKit-gnome; it's a D-Bus session
based service that applications can use to ask the user to
auth.

Before this change the caller provided the markup, e.g. gnome-mount
would do

 action = "hal-storage-mount-fixed";
 markup = _("System policy prevents mounting internal drives");
 result = org.gnome.PolicyKit.ShowDialog (action, markup);

and the problem here is that any application in the session can spoof
the dialog by providing false information and getting to use to click
through on that.

With this change, where the org.gnome.PolicyKit auth service reads the
message from a system-controlled file, this can't happen. What the
user sees really reflects the action he's asking to consider allowing
to happen.

Especially with things like XACE (previously known as SEX) this is
important as we can make the process providing the D-Bus service
org.gnome.PolicyKit run in a dedicated security context, audit it to
make sure it's secure. Then have the window manager paint trust window
decorations or other things to make the user feel fuzzy, warm and
safe.

Btw, with this change the PolicyKit-gnome API will be simplified to

 action = "hal-storage-mount-fixed";
 result = org.gnome.PolicyKit.ShowDialog (action);

which is just about as simple as it can get.

Credit goes to Ryan Lortie <desrt@desrt.ca> for pointing this out
on #gnome-hackers earlier this morning.

polkit/polkit-policy-file-entry.c
polkit/polkit-policy-file-entry.h
polkit/polkit-policy-file.c

index 988b9c2..1e10f96 100644 (file)
@@ -64,11 +64,13 @@ struct PolKitPolicyFileEntry
 
         char *group_description;
         char *policy_description;
+        char *policy_message;
 };
 
 extern void _polkit_policy_file_entry_set_descriptions (PolKitPolicyFileEntry *pfe,
                                                         const char *group_description,
-                                                        const char *policy_description);
+                                                        const char *policy_description,
+                                                        const char *policy_message);
 
 
 extern PolKitPolicyDefault *_polkit_policy_default_new (PolKitResult defaults_allow_inactive,
@@ -107,11 +109,13 @@ error:
 void 
 _polkit_policy_file_entry_set_descriptions (PolKitPolicyFileEntry *policy_file_entry,
                                             const char *group_description,
-                                            const char *policy_description)
+                                            const char *policy_description,
+                                            const char *policy_message)
 {
         g_return_if_fail (policy_file_entry != NULL);
         policy_file_entry->group_description = g_strdup (group_description);
         policy_file_entry->policy_description = g_strdup (policy_description);
+        policy_file_entry->policy_message = g_strdup (policy_message);
 }
 
 /**
@@ -137,7 +141,10 @@ polkit_policy_file_get_group_description (PolKitPolicyFileEntry *policy_file_ent
  * polkit_policy_file_get_action_description:
  * @policy_file_entry: the object
  * 
- * Get the description of the action that this policy entry describes.
+ * Get the description of the action that this policy entry describes. This
+ * is intended to be used in policy editors, for example "Mount internal
+ * volumes". Contrast with polkit_policy_file_get_action_message(). The
+ * textual string will be returned in the current locale.
  *
  * Note, if polkit_context_set_load_descriptions() on the
  * #PolKitContext object used to get this object wasn't called, this
@@ -153,6 +160,29 @@ polkit_policy_file_get_action_description (PolKitPolicyFileEntry *policy_file_en
 }
 
 /**
+ * polkit_policy_file_get_action_message:
+ * @policy_file_entry: the object
+ * 
+ * Get the message describing the action that this policy entry
+ * describes. This is to be used in dialogs, for example "System
+ * Policy prevents mounting this volume". Contrast with
+ * polkit_policy_file_get_action_description(). The textual string
+ * will be returned in the current locale.
+ *
+ * Note, if polkit_context_set_load_descriptions() on the
+ * #PolKitContext object used to get this object wasn't called, this
+ * method will return #NULL.
+ * 
+ * Returns: string or #NULL if descriptions are not loaded - caller shall not free this string
+ **/
+const char *
+polkit_policy_file_get_action_message (PolKitPolicyFileEntry *policy_file_entry)
+{
+        g_return_val_if_fail (policy_file_entry != NULL, NULL);
+        return policy_file_entry->policy_message;
+}
+
+/**
  * polkit_policy_file_entry_ref:
  * @policy_file_entry: the policy file object
  * 
index 70be923..0956507 100644 (file)
@@ -46,6 +46,7 @@ PolKitPolicyDefault   *polkit_policy_file_entry_get_default  (PolKitPolicyFileEn
 
 const char            *polkit_policy_file_get_group_description (PolKitPolicyFileEntry *policy_file_entry);
 const char            *polkit_policy_file_get_action_description (PolKitPolicyFileEntry *policy_file_entry);
+const char            *polkit_policy_file_get_action_message (PolKitPolicyFileEntry *policy_file_entry);
 
 
 #endif /* POLKIT_POLICY_FILE_ENTRY_H */
index 7e67a15..1efdbee 100644 (file)
@@ -76,6 +76,7 @@ enum {
         STATE_IN_GROUP_DESCRIPTION,
         STATE_IN_POLICY,
         STATE_IN_POLICY_DESCRIPTION,
+        STATE_IN_POLICY_MESSAGE,
         STATE_IN_DEFAULTS,
         STATE_IN_DEFAULTS_ALLOW_INACTIVE,
         STATE_IN_DEFAULTS_ALLOW_ACTIVE
@@ -96,6 +97,7 @@ typedef struct {
 
         char *group_description;
         char *policy_description;
+        char *policy_message;
 } ParserData;
 
 static void
@@ -137,6 +139,7 @@ _start (void *data, const char *el, const char **attr)
                         state = STATE_IN_POLICY;
 
                         pd->policy_description = NULL;
+                        pd->policy_message = NULL;
 
                         /* initialize defaults */
                         pd->defaults_allow_inactive = POLKIT_RESULT_NO;
@@ -152,9 +155,13 @@ _start (void *data, const char *el, const char **attr)
                         state = STATE_IN_DEFAULTS;
                 else if (strcmp (el, "description") == 0)
                         state = STATE_IN_POLICY_DESCRIPTION;
+                else if (strcmp (el, "message") == 0)
+                        state = STATE_IN_POLICY_MESSAGE;
                 break;
         case STATE_IN_POLICY_DESCRIPTION:
                 break;
+        case STATE_IN_POLICY_MESSAGE:
+                break;
         case STATE_IN_DEFAULTS:
                 if (strcmp (el, "allow_inactive") == 0)
                         state = STATE_IN_DEFAULTS_ALLOW_INACTIVE;
@@ -189,13 +196,27 @@ _cdata (void *data, const char *s, int len)
         switch (pd->state) {
 
         case STATE_IN_GROUP_DESCRIPTION:
-                if (pd->load_descriptions)
+                if (pd->load_descriptions) {
+                        if (pd->group_description != NULL)
+                                g_free (pd->group_description);
                         pd->group_description = g_strdup (str);
+                }
                 break;
                 
         case STATE_IN_POLICY_DESCRIPTION:
-                if (pd->load_descriptions)
+                if (pd->load_descriptions) {
+                        if (pd->policy_description != NULL)
+                                g_free (pd->policy_description);
                         pd->policy_description = g_strdup (str);
+                }
+                break;
+
+        case STATE_IN_POLICY_MESSAGE:
+                if (pd->load_descriptions) {
+                        if (pd->policy_message != NULL)
+                                g_free (pd->policy_message);
+                        pd->policy_message = g_strdup (str);
+                }
                 break;
 
         case STATE_IN_DEFAULTS_ALLOW_INACTIVE:
@@ -219,7 +240,8 @@ error:
 
 extern void _polkit_policy_file_entry_set_descriptions (PolKitPolicyFileEntry *pfe,
                                                         const char *group_description,
-                                                        const char *policy_description);
+                                                        const char *policy_description,
+                                                        const char *policy_message);
 
 static void
 _end (void *data, const char *el)
@@ -254,7 +276,8 @@ _end (void *data, const char *el)
                 if (pd->load_descriptions)
                         _polkit_policy_file_entry_set_descriptions (pfe,
                                                                     pd->group_description,
-                                                                    pd->policy_description);
+                                                                    pd->policy_description,
+                                                                    pd->policy_message);
 
                 pd->pf->entries = g_slist_prepend (pd->pf->entries, pfe);
 
@@ -264,6 +287,9 @@ _end (void *data, const char *el)
         case STATE_IN_POLICY_DESCRIPTION:
                 state = STATE_IN_POLICY;
                 break;
+        case STATE_IN_POLICY_MESSAGE:
+                state = STATE_IN_POLICY;
+                break;
         case STATE_IN_DEFAULTS:
                 state = STATE_IN_POLICY;
                 break;
@@ -345,6 +371,7 @@ polkit_policy_file_new (const char *path, polkit_bool_t load_descriptions, PolKi
         pd.action_id = NULL;
         pd.group_description = NULL;
         pd.policy_description = NULL;
+        pd.policy_message = NULL;
         pd.pf = pf;
         pd.load_descriptions = load_descriptions;
 
@@ -354,6 +381,7 @@ polkit_policy_file_new (const char *path, polkit_bool_t load_descriptions, PolKi
         g_free (pd.action_id);
         g_free (pd.group_description);
         g_free (pd.policy_description);
+        g_free (pd.policy_message);
 
        if (xml_res == 0) {
                 polkit_error_set_error (error, POLKIT_ERROR_POLICY_FILE_INVALID,