From 427ff01f9d656700b370bb905fe738e76602a842 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Tue, 16 Dec 2008 11:57:27 -0500
Subject: [PATCH] Add optional logging on allow rules

This lets us have a backwards compatibility allow rule but still easily
see when that rule is being used.
---
 bus/bus.c           |   37 +++++++++++++++++++++++--------------
 bus/config-parser.c |    5 +++++
 bus/policy.c        |    4 +++-
 bus/policy.h        |    4 +++-
 4 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/bus/bus.c b/bus/bus.c
index ab986b9..b749d30 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -1160,22 +1160,25 @@ bus_context_check_security_policy (BusContext     *context,
                                    DBusMessage    *message,
                                    DBusError      *error)
 {
+  const char *dest;
   BusClientPolicy *sender_policy;
   BusClientPolicy *recipient_policy;
   dbus_int32_t toggles;
+  dbus_bool_t log;
   int type;
   dbus_bool_t requested_reply;
   const char *sender_name;
   
   type = dbus_message_get_type (message);
+  dest = dbus_message_get_destination (message);
   
   /* dispatch.c was supposed to ensure these invariants */
-  _dbus_assert (dbus_message_get_destination (message) != NULL ||
+  _dbus_assert (dest != NULL ||
                 type == DBUS_MESSAGE_TYPE_SIGNAL ||
                 (sender == NULL && !bus_connection_is_active (proposed_recipient)));
   _dbus_assert (type == DBUS_MESSAGE_TYPE_SIGNAL ||
                 addressed_recipient != NULL ||
-                strcmp (dbus_message_get_destination (message), DBUS_SERVICE_DBUS) == 0);
+                strcmp (dest, DBUS_SERVICE_DBUS) == 0);
 
   /* Used in logging below */
   if (sender != NULL)
@@ -1205,10 +1208,6 @@ bus_context_check_security_policy (BusContext     *context,
   
   if (sender != NULL)
     {
-      const char *dest;
-
-      dest = dbus_message_get_destination (message);
-	
       /* First verify the SELinux access controls.  If allowed then
        * go on with the standard checks.
        */
@@ -1339,18 +1338,18 @@ bus_context_check_security_policy (BusContext     *context,
                 (proposed_recipient != NULL && sender == NULL && recipient_policy == NULL) ||
                 (proposed_recipient == NULL && recipient_policy == NULL));
   
+  log = FALSE;
   if (sender_policy &&
       !bus_client_policy_check_can_send (sender_policy,
                                          context->registry,
                                          requested_reply,
                                          proposed_recipient,
-                                         message, &toggles))
+                                         message, &toggles, &log))
     {
-      const char *dest;
       const char *msg = "Rejected send message, %d matched rules; "
                         "type=\"%s\", sender=\"%s\" interface=\"%s\" member=\"%s\" error name=\"%s\" destination=\"%s\")";
 
-      dest = dbus_message_get_destination (message);
+
       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, msg,
                       toggles,
                       dbus_message_type_to_string (dbus_message_get_type (message)),
@@ -1378,6 +1377,21 @@ bus_context_check_security_policy (BusContext     *context,
       return FALSE;
     }
 
+  if (log)
+    bus_context_log_security (context, 
+                              "Would reject message, %d matched rules; "
+                              "type=\"%s\", sender=\"%s\" interface=\"%s\" member=\"%s\" error name=\"%s\" destination=\"%s\")",
+                              toggles,
+                              dbus_message_type_to_string (dbus_message_get_type (message)),
+                              sender_name ? sender_name : "(unset)",
+                              dbus_message_get_interface (message) ?
+                              dbus_message_get_interface (message) : "(unset)",
+                              dbus_message_get_member (message) ?
+                              dbus_message_get_member (message) : "(unset)",
+                              dbus_message_get_error_name (message) ?
+                              dbus_message_get_error_name (message) : "(unset)",
+                              dest ? dest : DBUS_SERVICE_DBUS);
+
   if (recipient_policy &&
       !bus_client_policy_check_can_receive (recipient_policy,
                                             context->registry,
@@ -1388,9 +1402,7 @@ bus_context_check_security_policy (BusContext     *context,
     {
       const char *msg = "Rejected receive message, %d matched rules; "
                         "type=\"%s\" sender=\"%s\" interface=\"%s\" member=\"%s\" error name=\"%s\" destination=\"%s\" reply serial=%u requested_reply=%d)";
-      const char *dest;
 
-      dest = dbus_message_get_destination (message);
       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, msg,
                       toggles,
                       dbus_message_type_to_string (dbus_message_get_type (message)),
@@ -1427,9 +1439,6 @@ bus_context_check_security_policy (BusContext     *context,
       dbus_connection_get_outgoing_size (proposed_recipient) >
       context->limits.max_outgoing_bytes)
     {
-      const char *dest;
-
-      dest = dbus_message_get_destination (message);
       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
                       "The destination service \"%s\" has a full message queue",
                       dest ? dest : (proposed_recipient ?
diff --git a/bus/config-parser.c b/bus/config-parser.c
index f4d7c50..a8de3ff 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -1090,6 +1090,7 @@ append_rule_from_element (BusConfigParser   *parser,
                           dbus_bool_t        allow,
                           DBusError         *error)
 {
+  const char *log;
   const char *send_interface;
   const char *send_member;
   const char *send_error;
@@ -1133,6 +1134,7 @@ append_rule_from_element (BusConfigParser   *parser,
                           "own", &own,
                           "user", &user,
                           "group", &group,
+                          "log", &log,
                           NULL))
     return FALSE;
 
@@ -1337,6 +1339,9 @@ append_rule_from_element (BusConfigParser   *parser,
       if (eavesdrop)
         rule->d.send.eavesdrop = (strcmp (eavesdrop, "true") == 0);
 
+      if (log)
+        rule->d.send.log = (strcmp (log, "true") == 0);
+
       if (send_requested_reply)
         rule->d.send.requested_reply = (strcmp (send_requested_reply, "true") == 0);
 
diff --git a/bus/policy.c b/bus/policy.c
index 2c1a354..ef31800 100644
--- a/bus/policy.c
+++ b/bus/policy.c
@@ -867,7 +867,8 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
                                   dbus_bool_t      requested_reply,
                                   DBusConnection  *receiver,
                                   DBusMessage     *message,
-                                  dbus_int32_t    *toggles)
+                                  dbus_int32_t    *toggles,
+                                  dbus_bool_t     *log)
 {
   DBusList *link;
   dbus_bool_t allowed;
@@ -1028,6 +1029,7 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
 
       /* Use this rule */
       allowed = rule->allow;
+      *log = rule->d.send.log;
       (*toggles)++;
 
       _dbus_verbose ("  (policy) used rule, allow now = %d\n",
diff --git a/bus/policy.h b/bus/policy.h
index 91fde99..a75e0dd 100644
--- a/bus/policy.h
+++ b/bus/policy.h
@@ -65,6 +65,7 @@ struct BusPolicyRule
       char *destination;
       unsigned int eavesdrop : 1;
       unsigned int requested_reply : 1;
+      unsigned int log : 1;
     } send;
 
     struct
@@ -142,7 +143,8 @@ dbus_bool_t      bus_client_policy_check_can_send    (BusClientPolicy  *policy,
                                                       dbus_bool_t       requested_reply,
                                                       DBusConnection   *receiver,
                                                       DBusMessage      *message,
-                                                      dbus_int32_t     *toggles);
+                                                      dbus_int32_t     *toggles,
+                                                      dbus_bool_t      *log);
 dbus_bool_t      bus_client_policy_check_can_receive (BusClientPolicy  *policy,
                                                       BusRegistry      *registry,
                                                       dbus_bool_t       requested_reply,
-- 
1.5.6.5

