[PATCH 3/5] Add argument checks to policy <allow>/<deny> rules.

Pekka Pessi Pekka.Pessi at nokia.com
Fri Jun 4 09:58:44 PDT 2010


Added attributes send_signature, send_arg<n>, receive_signature, receive_arg<n>.

The type of the argument is determined with the signature. The corresponding
signature attribute is mandatory if *_arg<n> are specified. Only basic types
are supported. However, it is possible to check if an array is empty.
---
 bus/bus.h           |    1 +
 bus/config-parser.c |  370 +++++++++++++++++++++++++++++++++++++++++++++++++--
 bus/policy.c        |  125 +++++++++++++++++-
 bus/policy.h        |   20 +++
 4 files changed, 506 insertions(+), 10 deletions(-)

diff --git a/bus/bus.h b/bus/bus.h
index 7eb5fd8..b904136 100644
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -36,6 +36,7 @@ typedef struct BusContext       BusContext;
 typedef struct BusPolicy        BusPolicy;
 typedef struct BusClientPolicy  BusClientPolicy;
 typedef struct BusPolicyRule    BusPolicyRule;
+typedef struct BusPolicyArgs    BusPolicyArgs;
 typedef struct BusRegistry      BusRegistry;
 typedef struct BusSELinuxID     BusSELinuxID;
 typedef struct BusService       BusService;
diff --git a/bus/config-parser.c b/bus/config-parser.c
index 1a091df..398fd5a 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -31,6 +31,8 @@
 #include <dbus/dbus-list.h>
 #include <dbus/dbus-internals.h>
 #include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
 
 typedef enum
 {
@@ -549,6 +551,7 @@ typedef struct
 {
   const char  *name;
   const char **retloc;
+  const char  *template;
 } LocateAttr;
 
 static dbus_bool_t
@@ -564,6 +567,7 @@ locate_attributes (BusConfigParser  *parser,
   va_list args;
   const char *name;
   const char **retloc;
+  const char *template;
   int n_attrs;
 #define MAX_ATTRS 24
   LocateAttr attrs[MAX_ATTRS];
@@ -572,10 +576,16 @@ locate_attributes (BusConfigParser  *parser,
   _dbus_assert (first_attribute_name != NULL);
   _dbus_assert (first_attribute_retloc != NULL);
 
+  template = strchr (first_attribute_name, '%');
+  /* Template can have single %d */
+  _dbus_assert (template == NULL || template[1] == 'd');
+  _dbus_assert (template == NULL || strchr (template + 1, '%') == NULL);
+
   n_attrs = 1;
   attrs[0].name = first_attribute_name;
   attrs[0].retloc = first_attribute_retloc;
   *first_attribute_retloc = NULL;
+  attrs[0].template = template;
 
   va_start (args, first_attribute_retloc);
 
@@ -584,11 +594,16 @@ locate_attributes (BusConfigParser  *parser,
 
   while (name != NULL)
     {
+      template = strchr (name, '%');
+
       _dbus_assert (retloc != NULL);
       _dbus_assert (n_attrs < MAX_ATTRS);
+      _dbus_assert (template == NULL || template[1] == 'd');
+      _dbus_assert (template == NULL || strchr (template + 1, '%') == NULL);
 
       attrs[n_attrs].name = name;
       attrs[n_attrs].retloc = retloc;
+      attrs[n_attrs].template = template;
       n_attrs += 1;
       *retloc = NULL;
 
@@ -601,14 +616,33 @@ locate_attributes (BusConfigParser  *parser,
   i = 0;
   while (attribute_names[i])
     {
+      const char *aname = attribute_names[i];
+      const char *avalue = attribute_values[i];
+
       for (j = 0; j < n_attrs; ++j)
         {
           name = attrs[j].name;
+          template = attrs[j].template;
           retloc = attrs[j].retloc;
 
-          if (strcmp (name, attribute_names[i]) == 0)
+          if (template)
+            {
+              int offset = template - name;
+              int digits;
+
+              if (strncmp (aname, name, offset) != 0)
+                continue;
+              digits = (int) strspn (aname + offset, "0123456789");
+              if (digits > 1 && aname[offset] == '0')
+                continue;
+              if (digits == 0 || digits > 2)
+                continue;
+              if (strcmp (aname + offset + digits, template + 2) != 0)
+                continue;
+              goto found;
+            }
+          else if (strcmp (name, aname) == 0)
             {
-              *retloc = attribute_values[i];
               goto found;
             }
         }
@@ -619,12 +653,68 @@ locate_attributes (BusConfigParser  *parser,
       return FALSE;
 
     found:
+      *retloc = avalue;
       ++i;
     }
 
   return TRUE;
 }
 
+typedef struct
+{
+  int n;
+  struct {
+    const char *name;
+    const char *value;
+  } list[BUS_POLICY_MAX_ARGS];
+} ArgAttrList;
+
+static dbus_bool_t
+template_attributes (BusConfigParser  *parser,
+                     const char       *element_name,
+                     const char      **attribute_names,
+                     const char      **attribute_values,
+                     DBusError        *error,
+                     const char       *template,
+                     ArgAttrList      *retlist)
+{
+  const char *percent;
+  int i;
+
+  /* Template can have single %d */
+  _dbus_assert (template != NULL);
+  percent = strchr (template, '%');
+  _dbus_assert (percent != NULL);
+  _dbus_assert (percent[1] == 'd');
+  _dbus_assert (strchr (percent + 1, '%') == NULL);
+  _dbus_assert (retlist != NULL);
+
+  memset (retlist, 0, sizeof *retlist);
+
+  for (i = 0; attribute_names[i]; ++i)
+    {
+      int n;
+      if (strncmp (attribute_names[i], template, percent - template))
+        continue;
+      if (sscanf (attribute_names[i], template, &n) != 1)
+        continue;
+      if (n < 0 || n >= BUS_POLICY_MAX_ARGS)
+        {
+          dbus_set_error (error, DBUS_ERROR_FAILED,
+                          "Attribute \"%s\" is invalid on <%s> element in this context",
+                          attribute_names[i], element_name);
+          return FALSE;
+        }
+      if (n >= retlist->n)
+        retlist->n = n + 1;
+      /* Duplicate attributes are already detected by expat */
+      retlist->list[n].name = attribute_names[i];
+      retlist->list[n].value = attribute_values[i];
+    }
+
+  return TRUE;
+}
+
 static dbus_bool_t
 check_no_attributes (BusConfigParser  *parser,
                      const char       *element_name,
@@ -1106,6 +1196,196 @@ start_busconfig_child (BusConfigParser   *parser,
     }
 }
 
+static BusPolicyArgs *
+parse_arg_attributes (BusConfigParser  *parser,
+                      const char       *element_name,
+                      const char      **attribute_names,
+                      const char      **attribute_values,
+                      DBusError        *error,
+                      char const       *signature,
+                      char const       *template)
+{
+  ArgAttrList argv;
+  BusPolicyArgs *args;
+  DBusSignatureIter si;
+  int i;
+  int type;
+  char const *avalue;
+  char *rest;
+  union value {
+    dbus_uint16_t q;
+    dbus_int16_t n;
+    dbus_uint32_t u;
+    dbus_int32_t i;
+    dbus_uint64_t t;
+    dbus_int64_t x;
+    double d;
+    unsigned char y;
+    dbus_bool_t b;
+    char s[sizeof (double)];
+    char o[sizeof (double)];
+  } *value;
+  long l;
+  unsigned long ul;
+  long long ll;
+  unsigned long long ull;
+  size_t length;
+
+  if (!template_attributes  (parser, element_name,
+                             attribute_names,
+                             attribute_values,
+                             error,
+                             template,
+                             &argv))
+    return NULL;
+
+  args = bus_policy_args_alloc (argv.n);
+  if (args == NULL)
+    goto nomem;
+
+  dbus_signature_iter_init (&si, signature);
+
+  for (i = 0; i < argv.n; i++, dbus_signature_iter_next (&si))
+    {
+      avalue = argv.list[i].value;
+      if (avalue == NULL)
+        continue;
+
+      type = dbus_signature_iter_get_current_type (&si);
+
+      if (type == DBUS_TYPE_OBJECT_PATH
+          || type == DBUS_TYPE_STRING
+          || type == DBUS_TYPE_SIGNATURE)
+        value = (void *)_dbus_strdup (avalue);
+      else
+        value = dbus_new0 (union value, 1);
+
+      if (value == NULL)
+        goto nomem;
+
+      args->n = i + 1;
+      args->args[i].type = type;
+      args->args[i].value = value;
+
+      rest = NULL;
+
+      switch (type)
+        {
+        case DBUS_TYPE_INVALID:
+          dbus_set_error (error, DBUS_ERROR_FAILED,
+                          "On element <%s>, attribute %s is not allowed with signature=\"%s\"",
+                          element_name, argv.list[i].name, signature);
+          goto failed;
+
+        case DBUS_TYPE_BOOLEAN:
+          if (strcmp (avalue, "true") == 0)
+            value->b = TRUE;
+          else if (strcmp (avalue, "false") == 0)
+            value->b = FALSE;
+          else
+            goto value_error;
+          length = sizeof value->b;
+          break;
+
+        case DBUS_TYPE_BYTE:
+          ul = strtoul (avalue, &rest, 0);
+          if (ul >= 256)
+            goto value_error;
+          value->y = (unsigned char)ul;
+          length = sizeof value->y;
+          break;
+
+        case DBUS_TYPE_DOUBLE:
+          value->d = strtod (avalue, &rest);
+          length = sizeof value->d;
+          break;
+
+        case DBUS_TYPE_INT16:
+          l = strtol (avalue, &rest, 0);
+          if (l < _DBUS_INT16_MIN || _DBUS_INT16_MAX < l)
+            goto value_error;
+          value->n = (dbus_int16_t)l;
+          length = sizeof value->n;
+          break;
+
+        case DBUS_TYPE_UINT16:
+          ul = strtoul (avalue, &rest, 0);
+          if (_DBUS_UINT16_MAX < ul)
+            goto value_error;
+          value->q = (dbus_uint16_t)ul;
+          length = sizeof value->q;
+          break;
+
+        case DBUS_TYPE_INT32:
+          ll = strtol (avalue, &rest, 0);
+          if (ll < _DBUS_INT32_MIN || _DBUS_INT32_MAX < ll)
+            goto value_error;
+          value->i = (dbus_int32_t)ll;
+          length = sizeof value->i;
+          break;
+
+        case DBUS_TYPE_UINT32:
+          ull = strtoul (avalue, &rest, 0);
+          if (_DBUS_UINT32_MAX < ull)
+            goto value_error;
+          value->u = (dbus_uint32_t)ull;
+          length = sizeof value->u;
+          break;
+
+        case DBUS_TYPE_INT64:
+          value->x = strtoll (avalue, &rest, 0);
+          length = sizeof value->x;
+          break;
+
+        case DBUS_TYPE_UINT64:
+          value->t = strtoull (avalue, &rest, 0);
+          length = sizeof value->t;
+          break;
+
+        case DBUS_TYPE_STRING:
+        case DBUS_TYPE_SIGNATURE:
+        case DBUS_TYPE_OBJECT_PATH:
+          length = strlen (value->o) + 1;
+          break;
+
+        case DBUS_TYPE_ARRAY:
+          /* Empty string indicates empty array */
+          if (strlen (avalue))
+            goto value_error;
+          length = 0;
+          break;
+
+        default:
+          dbus_set_error (error, DBUS_ERROR_FAILED,
+                          "On element <%s>, %s in signature \"%s\" is not supported",
+                          element_name, argv.list[i].name,
+                          dbus_signature_iter_get_signature (&si));
+          goto failed;
+	}
+
+      if (rest == NULL || rest[0] == '\0')
+        {
+          args->args[i].length = length;
+          continue;
+        }
+
+    value_error:
+      dbus_set_error (error, DBUS_ERROR_FAILED,
+                      "On element <%s>, attribute %s has invalid value '%s'",
+                      element_name, argv.list[i].name, avalue);
+      goto failed;
+    }
+
+  return args;
+
+ nomem:
+  BUS_SET_OOM (error);
+ failed:
+  if (args)
+    bus_policy_args_free (args);
+  return NULL;
+}
+
 static dbus_bool_t
 append_rule_from_element (BusConfigParser   *parser,
                           const char        *element_name,
@@ -1122,12 +1402,16 @@ append_rule_from_element (BusConfigParser   *parser,
   const char *send_destination;
   const char *send_path;
   const char *send_type;
+  const char *send_signature;
+  const char *send_argv;
   const char *receive_interface;
   const char *receive_member;
   const char *receive_error;
   const char *receive_sender;
   const char *receive_path;
   const char *receive_type;
+  const char *receive_signature;
+  const char *receive_argv;
   const char *eavesdrop;
   const char *send_requested_reply;
   const char *receive_requested_reply;
@@ -1136,7 +1420,10 @@ append_rule_from_element (BusConfigParser   *parser,
   const char *group;
 
   BusPolicyRule *rule;
-  
+
+  ArgAttrList argv;
+  BusPolicyArgs *args;
+
   if (!locate_attributes (parser, element_name,
                           attribute_names,
                           attribute_values,
@@ -1147,12 +1434,16 @@ append_rule_from_element (BusConfigParser   *parser,
                           "send_destination", &send_destination,
                           "send_path", &send_path,
                           "send_type", &send_type,
+                          "send_signature", &send_signature,
+                          "send_arg%d", &send_argv,
                           "receive_interface", &receive_interface,
                           "receive_member", &receive_member,
                           "receive_error", &receive_error,
                           "receive_sender", &receive_sender,
                           "receive_path", &receive_path,
                           "receive_type", &receive_type,
+                          "receive_signature", &receive_signature,
+                          "receive_arg%d", &receive_argv,
                           "eavesdrop", &eavesdrop,
                           "send_requested_reply", &send_requested_reply,
                           "receive_requested_reply", &receive_requested_reply,
@@ -1164,9 +1455,11 @@ append_rule_from_element (BusConfigParser   *parser,
     return FALSE;
 
   send_attr = send_interface || send_member || send_error || send_destination ||
+    send_signature || send_argv ||
     send_type || send_path || send_requested_reply;
 
   receive_attr = receive_interface || receive_member || receive_error || receive_sender ||
+    receive_signature || receive_argv ||
     receive_type || receive_path || receive_requested_reply;
 
   if (!(send_attr || receive_attr || eavesdrop || own || user || group))
@@ -1186,6 +1479,15 @@ append_rule_from_element (BusConfigParser   *parser,
       return FALSE;
     }
 
+  if ((send_argv && send_signature == NULL) ||
+      (receive_argv && receive_signature == NULL))
+    {
+      dbus_set_error (error, DBUS_ERROR_FAILED,
+                      "On element <%s>, if you specify arguments you must specify a signature.",
+                      element_name);
+      return FALSE;
+    }
+
   /* Allowed combinations of elements are:
    *
    *   base attributes, must be all send or all receive:
@@ -1216,8 +1518,9 @@ append_rule_from_element (BusConfigParser   *parser,
                       element_name);
       return FALSE;
     }
-  
+
   rule = NULL;
+  args = NULL;
 
   /* In BusPolicyRule, NULL represents wildcard.
    * In the config file, '*' represents it.
@@ -1270,14 +1573,35 @@ append_rule_from_element (BusConfigParser   *parser,
         {
           dbus_set_error (error, DBUS_ERROR_FAILED,
                           "Bad value \"%s\" for %s attribute, must be true or false",
-                          "send_requested_reply", send_requested_reply);
+                          send_requested_reply, "send_requested_reply");
           return FALSE;
         }
-      
-      rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow); 
+
+      if (send_signature && !dbus_signature_validate (send_signature, NULL))
+        {
+          dbus_set_error (error, DBUS_ERROR_FAILED,
+                          "Bad value \"%s\" for %s attribute",
+                          send_signature, "send_signature");
+          return FALSE;
+        }
+
+      rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow);
       if (rule == NULL)
         goto nomem;
-      
+
+      if (send_argv)
+        {
+          args = parse_arg_attributes (parser, element_name,
+                                       attribute_names,
+                                       attribute_values,
+                                       error,
+                                       send_signature,
+                                       "send_arg%d");
+          if (args == NULL)
+            goto failed;
+          rule->d.send.args = args;
+        }
+
       if (eavesdrop)
         rule->d.send.eavesdrop = (strcmp (eavesdrop, "true") == 0);
 
@@ -1291,6 +1615,7 @@ append_rule_from_element (BusConfigParser   *parser,
       rule->d.send.path = _dbus_strdup (send_path);
       rule->d.send.interface = _dbus_strdup (send_interface);
       rule->d.send.member = _dbus_strdup (send_member);
+      rule->d.send.signature = _dbus_strdup (send_signature);
       rule->d.send.error = _dbus_strdup (send_error);
       rule->d.send.destination = _dbus_strdup (send_destination);
       if (send_path && rule->d.send.path == NULL)
@@ -1299,6 +1624,8 @@ append_rule_from_element (BusConfigParser   *parser,
         goto nomem;
       if (send_member && rule->d.send.member == NULL)
         goto nomem;
+      if (send_signature && rule->d.send.signature == NULL)
+        goto nomem;
       if (send_error && rule->d.send.error == NULL)
         goto nomem;
       if (send_destination && rule->d.send.destination == NULL)
@@ -1354,11 +1681,32 @@ append_rule_from_element (BusConfigParser   *parser,
                           "receive_requested_reply", receive_requested_reply);
           return FALSE;
         }
-      
+
+      if (receive_signature && !dbus_signature_validate (receive_signature, NULL))
+        {
+          dbus_set_error (error, DBUS_ERROR_FAILED,
+                          "Bad value \"%s\" for %s attribute",
+                          receive_signature, "receive_signature");
+          return FALSE;
+        }
+
       rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow); 
       if (rule == NULL)
         goto nomem;
 
+      if (receive_argv)
+        {
+          args = parse_arg_attributes (parser, element_name,
+                                       attribute_names,
+                                       attribute_values,
+                                       error,
+                                       receive_signature,
+                                       "receive_arg%d");
+          if (args == NULL)
+            goto failed;
+          rule->d.receive.args = args;
+        }
+
       if (eavesdrop)
         rule->d.receive.eavesdrop = (strcmp (eavesdrop, "true") == 0);
 
@@ -1369,6 +1717,7 @@ append_rule_from_element (BusConfigParser   *parser,
       rule->d.receive.path = _dbus_strdup (receive_path);
       rule->d.receive.interface = _dbus_strdup (receive_interface);
       rule->d.receive.member = _dbus_strdup (receive_member);
+      rule->d.receive.signature = _dbus_strdup (receive_signature);
       rule->d.receive.error = _dbus_strdup (receive_error);
       rule->d.receive.origin = _dbus_strdup (receive_sender);
 
@@ -1378,6 +1727,8 @@ append_rule_from_element (BusConfigParser   *parser,
         goto nomem;
       if (receive_member && rule->d.receive.member == NULL)
         goto nomem;
+      if (receive_signature && rule->d.receive.signature == NULL)
+        goto nomem;
       if (receive_error && rule->d.receive.error == NULL)
         goto nomem;
       if (receive_sender && rule->d.receive.origin == NULL)
@@ -1531,6 +1882,7 @@ append_rule_from_element (BusConfigParser   *parser,
  failed:
   if (rule)
     bus_policy_rule_unref (rule);
+
   return FALSE;
 }
 
diff --git a/bus/policy.c b/bus/policy.c
index a1fff86..43ebdc5 100644
--- a/bus/policy.c
+++ b/bus/policy.c
@@ -101,6 +101,8 @@ bus_policy_rule_unref (BusPolicyRule *rule)
           dbus_free (rule->d.send.member);
           dbus_free (rule->d.send.error);
           dbus_free (rule->d.send.destination);
+          dbus_free (rule->d.send.signature);
+          bus_policy_args_free (rule->d.send.args);
           break;
         case BUS_POLICY_RULE_RECEIVE:
           dbus_free (rule->d.receive.path);
@@ -108,6 +110,8 @@ bus_policy_rule_unref (BusPolicyRule *rule)
           dbus_free (rule->d.receive.member);
           dbus_free (rule->d.receive.error);
           dbus_free (rule->d.receive.origin);
+          dbus_free (rule->d.receive.signature);
+          bus_policy_args_free (rule->d.receive.args);
           break;
         case BUS_POLICY_RULE_OWN:
           dbus_free (rule->d.own.service_name);
@@ -117,11 +121,39 @@ bus_policy_rule_unref (BusPolicyRule *rule)
         case BUS_POLICY_RULE_GROUP:
           break;
         }
-      
+
       dbus_free (rule);
     }
 }
 
+BusPolicyArgs *
+bus_policy_args_alloc (int n)
+{
+  BusPolicyArgs *args = dbus_new0 (BusPolicyArgs, 1);
+
+  if (args)
+    args->n = n;
+
+  return args;
+}
+
+void
+bus_policy_args_free (BusPolicyArgs *args)
+{
+  if (args)
+    {
+      int i;
+
+      for (i = 0; i < args->n; i++)
+        {
+          if (args->args[i].value)
+            dbus_free (args->args[i].value);
+        }
+
+      dbus_free (args);
+    }
+}
+
 struct BusPolicy
 {
   int refcount;
@@ -862,6 +894,65 @@ bus_client_policy_append_rule (BusClientPolicy *policy,
   return TRUE;
 }
 
+static dbus_bool_t
+check_policy_message_args (DBusMessage *message,
+                           BusPolicyArgs *args)
+{
+  int i, type;
+  DBusMessageIter iter, subiter;
+  union {
+    void *pointer;
+    dbus_uint64_t data;
+    double d;
+  } basic;
+  void *value;
+
+  dbus_message_iter_init (message, &iter);
+
+  for (i = 0; i < args->n; dbus_message_iter_next (&iter), i++)
+    {
+      if (args->args[i].type == DBUS_TYPE_INVALID)
+        continue;
+
+      type = dbus_message_iter_get_arg_type (&iter);
+
+      if (args->args[i].type != type)
+        {
+          _dbus_verbose ("  (policy) skipping rule for inconsistent signature\n");
+          return FALSE;
+        };
+
+      if (type == DBUS_TYPE_ARRAY)
+        {
+          dbus_message_iter_recurse (&iter, &subiter);
+          type = dbus_message_iter_get_arg_type (&subiter);
+          if (type != DBUS_TYPE_INVALID)
+            {
+              _dbus_verbose ("  (policy) skipping rule because array is not empty\n");
+              return FALSE;
+            };
+          continue;
+        }
+
+      dbus_message_iter_get_basic (&iter, &basic);
+
+      if (type == DBUS_TYPE_OBJECT_PATH
+          || type == DBUS_TYPE_STRING
+          || type == DBUS_TYPE_SIGNATURE)
+        value = basic.pointer;
+      else
+        value = &basic.data;
+
+      if (memcmp (value, args->args[i].value, args->args[i].length))
+        {
+          _dbus_verbose ("  (policy) skipping rule because value does not match\n");
+          return FALSE;
+        }
+    }
+
+  return TRUE;
+}
+
 dbus_bool_t
 bus_client_policy_check_can_send (BusClientPolicy *policy,
                                   BusRegistry     *registry,
@@ -976,6 +1067,22 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
             }
         }
 
+      if (rule->d.send.signature != NULL)
+        {
+          if (!dbus_message_has_signature (message,
+                                           rule->d.send.signature))
+            {
+              _dbus_verbose ("  (policy) skipping rule for different signature\n");
+              continue;
+            }
+        }
+
+      if (rule->d.send.args != NULL)
+        {
+          if (!check_policy_message_args (message, rule->d.send.args))
+            continue;
+        }
+
       if (rule->d.send.error != NULL)
         {
           if (dbus_message_get_error_name (message) != NULL &&
@@ -1176,6 +1283,22 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
             }
         }
 
+      if (rule->d.receive.signature != NULL)
+        {
+          if (!dbus_message_has_signature (message,
+                                           rule->d.receive.signature))
+            {
+              _dbus_verbose ("  (policy) skipping rule for different signature\n");
+              continue;
+            }
+        }
+
+      if (rule->d.receive.args != NULL)
+        {
+          if (!check_policy_message_args (message, rule->d.receive.args))
+            continue;
+        }
+
       if (rule->d.receive.error != NULL)
         {
           if (dbus_message_get_error_name (message) != NULL &&
diff --git a/bus/policy.h b/bus/policy.h
index 1782dbf..487e429 100644
--- a/bus/policy.h
+++ b/bus/policy.h
@@ -61,8 +61,10 @@ struct BusPolicyRule
       char *path;
       char *interface;
       char *member;
+      char *signature;
       char *error;
       char *destination;
+      BusPolicyArgs *args;
       unsigned int eavesdrop : 1;
       unsigned int requested_reply : 1;
       unsigned int log : 1;
@@ -76,8 +78,10 @@ struct BusPolicyRule
       char *path;
       char *interface;
       char *member;
+      char *signature;
       char *error;
       char *origin;
+      BusPolicyArgs *args;
       unsigned int eavesdrop : 1;
       unsigned int requested_reply : 1;
     } receive;
@@ -103,11 +107,27 @@ struct BusPolicyRule
   } d;
 };
 
+#define BUS_POLICY_MAX_ARGS (30)
+
+struct BusPolicyArgs
+{
+  int n;
+  struct
+  {
+    int   type;
+    size_t length;
+    void *value;
+  } args[BUS_POLICY_MAX_ARGS];
+};
+
 BusPolicyRule* bus_policy_rule_new   (BusPolicyRuleType type,
                                       dbus_bool_t       allow);
 BusPolicyRule* bus_policy_rule_ref   (BusPolicyRule    *rule);
 void           bus_policy_rule_unref (BusPolicyRule    *rule);
 
+BusPolicyArgs* bus_policy_args_alloc (int n);
+void           bus_policy_args_free (BusPolicyArgs *args);
+
 BusPolicy*       bus_policy_new                   (void);
 BusPolicy*       bus_policy_ref                   (BusPolicy        *policy);
 void             bus_policy_unref                 (BusPolicy        *policy);
-- 
1.6.3.3



More information about the dbus mailing list