test: enforce own_prefix policy rules
authorAlban Crequy <alban.crequy@collabora.co.uk>
Wed, 21 Mar 2012 19:05:42 +0000 (19:05 +0000)
committerAlban Crequy <alban.crequy@collabora.co.uk>
Thu, 22 Mar 2012 11:51:23 +0000 (11:51 +0000)
After parsing [allow|deny] rules with own_prefix, check they are enforced
correctly.

https://bugs.freedesktop.org/show_bug.cgi?id=46886

bus/config-parser.c
bus/policy.c
bus/policy.h
test/data/valid-config-files/check-own-rules.conf [new file with mode: 0644]

index b83c1b3..07e8fbb 100644 (file)
@@ -2746,9 +2746,60 @@ typedef enum
 } Validity;
 
 static dbus_bool_t
+do_check_own_rules (BusPolicy  *policy)
+{
+  const struct {
+    char *name;
+    dbus_bool_t allowed;
+  } checks[] = {
+    {"org.freedesktop", FALSE},
+    {"org.freedesktop.ManySystem", FALSE},
+    {"org.freedesktop.ManySystems", TRUE},
+    {"org.freedesktop.ManySystems.foo", TRUE},
+    {"org.freedesktop.ManySystems.foo.bar", TRUE},
+    {"org.freedesktop.ManySystems2", FALSE},
+    {"org.freedesktop.ManySystems2.foo", FALSE},
+    {"org.freedesktop.ManySystems2.foo.bar", FALSE},
+    {NULL, FALSE}
+  };
+  int i = 0;
+
+  while (checks[i].name)
+    {
+      DBusString service_name;
+      dbus_bool_t ret;
+
+      if (!_dbus_string_init (&service_name))
+        _dbus_assert_not_reached ("couldn't init string");
+      if (!_dbus_string_append (&service_name, checks[i].name))
+        _dbus_assert_not_reached ("couldn't append string");
+
+      ret = bus_policy_check_can_own (policy, &service_name);
+      printf ("        Check name %s: %s\n", checks[i].name,
+              ret ? "allowed" : "not allowed");
+      if (checks[i].allowed && !ret)
+        {
+          _dbus_warn ("Cannot own %s\n", checks[i].name);
+          return FALSE;
+        }
+      if (!checks[i].allowed && ret)
+        {
+          _dbus_warn ("Can own %s\n", checks[i].name);
+          return FALSE;
+        }
+      _dbus_string_free (&service_name);
+
+      i++;
+    }
+
+  return TRUE;
+}
+
+static dbus_bool_t
 do_load (const DBusString *full_path,
          Validity          validity,
-         dbus_bool_t       oom_possible)
+         dbus_bool_t       oom_possible,
+         dbus_bool_t       check_own_rules)
 {
   BusConfigParser *parser;
   DBusError error;
@@ -2785,6 +2836,11 @@ do_load (const DBusString *full_path,
     {
       _DBUS_ASSERT_ERROR_IS_CLEAR (&error);
 
+      if (check_own_rules && do_check_own_rules (parser->policy) == FALSE)
+        {
+          return FALSE;
+        }
+
       bus_config_parser_unref (parser);
 
       if (validity == INVALID)
@@ -2801,6 +2857,7 @@ typedef struct
 {
   const DBusString *full_path;
   Validity          validity;
+  dbus_bool_t       check_own_rules;
 } LoaderOomData;
 
 static dbus_bool_t
@@ -2808,7 +2865,7 @@ check_loader_oom_func (void *data)
 {
   LoaderOomData *d = data;
 
-  return do_load (d->full_path, d->validity, TRUE);
+  return do_load (d->full_path, d->validity, TRUE, d->check_own_rules);
 }
 
 static dbus_bool_t
@@ -2891,6 +2948,8 @@ process_test_valid_subdir (const DBusString *test_base_dir,
 
       d.full_path = &full_path;
       d.validity = validity;
+      d.check_own_rules = _dbus_string_ends_with_c_str (&full_path,
+          "check-own-rules.conf");
 
       /* FIXME hackaround for an expat problem, see
        * https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=124747
index e820373..379cea9 100644 (file)
@@ -1240,24 +1240,26 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
   return allowed;
 }
 
-dbus_bool_t
-bus_client_policy_check_can_own (BusClientPolicy  *policy,
-                                 const DBusString *service_name)
+
+
+static dbus_bool_t
+bus_rules_check_can_own (DBusList *rules,
+                         const DBusString *service_name)
 {
   DBusList *link;
   dbus_bool_t allowed;
   
-  /* policy->rules is in the order the rules appeared
+  /* rules is in the order the rules appeared
    * in the config file, i.e. last rule that applies wins
    */
 
   allowed = FALSE;
-  link = _dbus_list_get_first_link (&policy->rules);
+  link = _dbus_list_get_first_link (&rules);
   while (link != NULL)
     {
       BusPolicyRule *rule = link->data;
 
-      link = _dbus_list_get_next_link (&policy->rules, link);
+      link = _dbus_list_get_next_link (&rules, link);
       
       /* Rule is skipped if it specifies a different service name from
        * the desired one.
@@ -1292,3 +1294,20 @@ bus_client_policy_check_can_own (BusClientPolicy  *policy,
 
   return allowed;
 }
+
+dbus_bool_t
+bus_client_policy_check_can_own (BusClientPolicy  *policy,
+                                 const DBusString *service_name)
+{
+  return bus_rules_check_can_own (policy->rules, service_name);
+}
+
+#ifdef DBUS_BUILD_TESTS
+dbus_bool_t
+bus_policy_check_can_own (BusPolicy  *policy,
+                          const DBusString *service_name)
+{
+  return bus_rules_check_can_own (policy->default_rules, service_name);
+}
+#endif /* DBUS_BUILD_TESTS */
+
index b1e2c9f..3ff6f48 100644 (file)
@@ -161,5 +161,9 @@ dbus_bool_t      bus_client_policy_append_rule       (BusClientPolicy  *policy,
                                                       BusPolicyRule    *rule);
 void             bus_client_policy_optimize          (BusClientPolicy  *policy);
 
+#ifdef DBUS_BUILD_TESTS
+dbus_bool_t      bus_policy_check_can_own     (BusPolicy  *policy,
+                                               const DBusString *service_name);
+#endif
 
 #endif /* BUS_POLICY_H */
diff --git a/test/data/valid-config-files/check-own-rules.conf b/test/data/valid-config-files/check-own-rules.conf
new file mode 100644 (file)
index 0000000..bc2f415
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+  <user>mybususer</user>
+  <listen>unix:path=/foo/bar</listen>
+  <listen>tcp:port=1234</listen>
+  <servicedir>/usr/share/foo</servicedir>
+  <policy context="default">
+    <allow user="*"/>
+    <deny own="*"/>
+    <allow own_prefix="org.freedesktop.ManySystems"/>
+  </policy>
+
+</busconfig>