bus_context_check_security_policy: factor out complain_about_message
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Tue, 15 Mar 2011 13:05:23 +0000 (13:05 +0000)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Wed, 25 May 2011 17:16:02 +0000 (18:16 +0100)
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=35358
Reviewed-by: Colin Walters <walters@verbum.org>
bus/bus.c

index 6663347..bf32724 100644 (file)
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -1307,6 +1307,76 @@ out:
   va_end (args);
 }
 
+static inline const char *
+nonnull (const char *maybe_null,
+         const char *if_null)
+{
+  return (maybe_null ? maybe_null : if_null);
+}
+
+/*
+ * Log something about a message, usually that it was rejected.
+ */
+static void
+complain_about_message (BusContext     *context,
+                        const char     *complaint,
+                        int             matched_rules,
+                        DBusMessage    *message,
+                        DBusConnection *sender,
+                        DBusConnection *proposed_recipient,
+                        dbus_bool_t     requested_reply,
+                        dbus_bool_t     log,
+                        DBusError      *error)
+{
+  DBusError stack_error = DBUS_ERROR_INIT;
+  const char *sender_name;
+  const char *sender_loginfo;
+  const char *proposed_recipient_loginfo;
+
+  if (error == NULL && !(context->syslog && log))
+    return;
+
+  if (sender != NULL)
+    {
+      sender_name = bus_connection_get_name (sender);
+      sender_loginfo = bus_connection_get_loginfo (sender);
+    }
+  else
+    {
+      sender_name = "(unset)";
+      sender_loginfo = "(bus)";
+    }
+
+  if (proposed_recipient != NULL)
+    proposed_recipient_loginfo = bus_connection_get_loginfo (proposed_recipient);
+  else
+    proposed_recipient_loginfo = "bus";
+
+  dbus_set_error (&stack_error, DBUS_ERROR_ACCESS_DENIED,
+      "%s, %d matched rules; type=\"%s\", sender=\"%s\" (%s) "
+      "interface=\"%s\" member=\"%s\" error name=\"%s\" "
+      "requested_reply=\"%d\" destination=\"%s\" (%s)",
+      complaint,
+      matched_rules,
+      dbus_message_type_to_string (dbus_message_get_type (message)),
+      sender_name,
+      sender_loginfo,
+      nonnull (dbus_message_get_interface (message), "(unset)"),
+      nonnull (dbus_message_get_member (message), "(unset)"),
+      nonnull (dbus_message_get_error_name (message), "(unset)"),
+      requested_reply,
+      nonnull (dbus_message_get_destination (message), DBUS_SERVICE_DBUS),
+      proposed_recipient_loginfo);
+
+  /* If we hit OOM while setting the error, this will syslog "out of memory"
+   * which is itself an indication that something is seriously wrong */
+  if (log)
+    bus_context_log (context, DBUS_SYSTEM_LOG_SECURITY, "%s",
+        stack_error.message);
+
+  dbus_move_error (&stack_error, error);
+}
+
 /*
  * addressed_recipient is the recipient specified in the message.
  *
@@ -1351,23 +1421,6 @@ bus_context_check_security_policy (BusContext     *context,
                 addressed_recipient != NULL ||
                 strcmp (dest, DBUS_SERVICE_DBUS) == 0);
 
-  /* Used in logging below */
-  if (sender != NULL)
-    {
-      sender_name = bus_connection_get_name (sender);
-      sender_loginfo = bus_connection_get_loginfo (sender);
-    }
-  else
-    {
-      sender_name = NULL;
-      sender_loginfo = "(bus)";
-    }
-
-  if (proposed_recipient != NULL)
-    proposed_recipient_loginfo = bus_connection_get_loginfo (proposed_recipient);
-  else
-    proposed_recipient_loginfo = "bus";
-
   switch (type)
     {
     case DBUS_MESSAGE_TYPE_METHOD_CALL:
@@ -1402,6 +1455,8 @@ bus_context_check_security_policy (BusContext     *context,
         {
           if (error != NULL && !dbus_error_is_set (error))
             {
+              sender_name = bus_connection_get_name (sender);
+
               dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
                               "An SELinux policy prevents this sender "
                               "from sending this message to this recipient "
@@ -1531,57 +1586,21 @@ bus_context_check_security_policy (BusContext     *context,
       const char *msg = "Rejected send message, %d matched rules; "
                         "type=\"%s\", sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" requested_reply=%d destination=\"%s\" (%s))";
 
-      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, msg,
-                      toggles,
-                      dbus_message_type_to_string (dbus_message_get_type (message)),
-                      sender_name ? sender_name : "(unset)",
-                      sender_loginfo,
-                      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)",
-                      requested_reply,
-                      dest ? dest : DBUS_SERVICE_DBUS,
-                      proposed_recipient_loginfo);
-      /* Needs to be duplicated to avoid calling malloc and having to handle OOM */
-      if (addressed_recipient == proposed_recipient)
-        bus_context_log (context, DBUS_SYSTEM_LOG_SECURITY, msg,
-                                  toggles,
-                                  dbus_message_type_to_string (dbus_message_get_type (message)),
-                                  sender_name ? sender_name : "(unset)",
-                                  sender_loginfo,
-                                  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)",
-                                  requested_reply,
-                                  dest ? dest : DBUS_SERVICE_DBUS,
-                                  proposed_recipient_loginfo);
+      complain_about_message (context, "Rejected send message", toggles,
+          message, sender, proposed_recipient, requested_reply,
+          (addressed_recipient == proposed_recipient), error);
       _dbus_verbose ("security policy disallowing message due to sender policy\n");
       return FALSE;
     }
 
   if (log)
-    bus_context_log (context, DBUS_SYSTEM_LOG_SECURITY,
-                              "Would reject message, %d matched rules; "
-                              "type=\"%s\", sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" requested_reply=%d destination=\"%s\" (%s))",
-                              toggles,
-                              dbus_message_type_to_string (dbus_message_get_type (message)),
-                              sender_name ? sender_name : "(unset)",
-                              sender_loginfo,
-                              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)",
-                              requested_reply,
-                              dest ? dest : DBUS_SERVICE_DBUS,
-                              proposed_recipient_loginfo);
+    {
+      /* We want to drop this message, and are only not doing so for backwards
+       * compatibility. */
+      complain_about_message (context, "Would reject message", toggles,
+          message, sender, proposed_recipient, requested_reply,
+          TRUE, NULL);
+    }
 
   if (recipient_policy &&
       !bus_client_policy_check_can_receive (recipient_policy,
@@ -1591,41 +1610,9 @@ bus_context_check_security_policy (BusContext     *context,
                                             addressed_recipient, proposed_recipient,
                                             message, &toggles))
     {
-      const char *msg = "Rejected receive message, %d matched rules; "
-                        "type=\"%s\" sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" reply serial=%u requested_reply=%d destination=\"%s\" (%s))";
-
-      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, msg,
-                      toggles,
-                      dbus_message_type_to_string (dbus_message_get_type (message)),
-                      sender_name ? sender_name : "(unset)",
-                      sender_loginfo,
-                      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)",
-                      dbus_message_get_reply_serial (message),
-                      requested_reply,
-                      dest ? dest : DBUS_SERVICE_DBUS,
-                      proposed_recipient_loginfo);
-      /* Needs to be duplicated to avoid calling malloc and having to handle OOM */
-      if (addressed_recipient == proposed_recipient)
-        bus_context_log (context, DBUS_SYSTEM_LOG_SECURITY, msg,
-                                  toggles,
-                                  dbus_message_type_to_string (dbus_message_get_type (message)),
-                                  sender_name ? sender_name : "(unset)",
-                                  sender_loginfo,
-                                  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)",
-                                  dbus_message_get_reply_serial (message),
-                                  requested_reply,
-                                  dest ? dest : DBUS_SERVICE_DBUS,
-                                  proposed_recipient_loginfo);
+      complain_about_message (context, "Rejected receive message", toggles,
+          message, sender, proposed_recipient, requested_reply,
+          (addressed_recipient == proposed_recipient), NULL);
       _dbus_verbose ("security policy disallowing message due to recipient policy\n");
       return FALSE;
     }