]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
Add DBus method to return the AA context of a connection
authorTyler Hicks <tyhicks@canonical.com>
Wed, 4 Feb 2015 17:53:31 +0000 (17:53 +0000)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Wed, 18 Feb 2015 20:42:05 +0000 (20:42 +0000)
This is not intended for upstream inclusion. It implements a bus method
(GetConnectionAppArmorSecurityContext) to get a connection's AppArmor
security context but upstream D-Bus has recently added a generic way of
getting a connection's security credentials (GetConnectionCredentials).
Ubuntu should carry this patch until packages in the archive are moved
over to the new, generic method of getting a connection's credentials.

[Altered by Simon McVittie: survive non-UTF-8 contexts which
would otherwise be a local denial of service, except that Ubuntu
inherits a non-fatal warnings patch from Debian; new commit message
taken from the Ubuntu changelog; do not emit unreachable code if
AppArmor is disabled.]

bus/apparmor.c
bus/apparmor.h
bus/driver.c
dbus/dbus-protocol.h

index 072e2edf9e6e92f4e6613d66dc729c7a5cd82240..af76ca2788b8929a22102e574064ce4826a2fd77 100644 (file)
@@ -105,6 +105,21 @@ bus_apparmor_confinement_new (char       *label,
   return confinement;
 }
 
+const char*
+bus_apparmor_confinement_get_label (BusAppArmorConfinement *confinement)
+{
+#ifdef HAVE_APPARMOR
+  if (!apparmor_enabled)
+    return NULL;
+
+  _dbus_assert (confinement != NULL);
+
+  return confinement->label;
+#else
+  return NULL;
+#endif
+}
+
 void
 bus_apparmor_confinement_unref (BusAppArmorConfinement *confinement)
 {
index 4a47aecc46a49eb5c7b90faff310e5d8bbda48a1..e9fcc1b04d8c613b3e5139136a0b9ca1537f1783 100644 (file)
@@ -39,6 +39,7 @@ dbus_bool_t bus_apparmor_enabled (void);
 
 void bus_apparmor_confinement_unref (BusAppArmorConfinement *confinement);
 void bus_apparmor_confinement_ref (BusAppArmorConfinement *confinement);
+const char* bus_apparmor_confinement_get_label (BusAppArmorConfinement *confinement);
 BusAppArmorConfinement* bus_apparmor_init_connection_confinement (DBusConnection *connection,
                                                                   DBusError      *error);
 
index aab922ae739ccf7c5f6df0a494599cecca2da3a0..4dcf76c88fabbb6897ececad767e221976bc8401 100644 (file)
@@ -1759,6 +1759,91 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection,
   return FALSE;
 }
 
+static dbus_bool_t
+bus_driver_handle_get_connection_apparmor_security_context (DBusConnection *connection,
+                                                            BusTransaction *transaction,
+                                                            DBusMessage    *message,
+                                                            DBusError      *error)
+{
+  const char *service;
+  DBusString str;
+  BusRegistry *registry;
+  BusService *serv;
+  DBusConnection *primary_connection;
+  DBusMessage *reply;
+  BusAppArmorConfinement *confinement;
+  const char *label;
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+  registry = bus_connection_get_registry (connection);
+
+  service = NULL;
+  reply = NULL;
+  confinement = NULL;
+
+  if (! dbus_message_get_args (message, error, DBUS_TYPE_STRING, &service,
+                               DBUS_TYPE_INVALID))
+      goto failed;
+
+  _dbus_verbose ("asked for security context of connection %s\n", service);
+
+  _dbus_string_init_const (&str, service);
+  serv = bus_registry_lookup (registry, &str);
+  if (serv == NULL)
+    {
+      dbus_set_error (error,
+                      DBUS_ERROR_NAME_HAS_NO_OWNER,
+                      "Could not get security context of name '%s': no such name", service);
+      goto failed;
+    }
+
+  primary_connection = bus_service_get_primary_owners_connection (serv);
+
+  reply = dbus_message_new_method_return (message);
+  if (reply == NULL)
+    goto oom;
+
+  confinement = bus_connection_dup_apparmor_confinement (primary_connection);
+  label = bus_apparmor_confinement_get_label (confinement);
+
+  if (label == NULL)
+    {
+      dbus_set_error (error,
+                      DBUS_ERROR_APPARMOR_SECURITY_CONTEXT_UNKNOWN,
+                      "Could not determine security context for '%s'", service);
+      goto failed;
+    }
+
+  if (!dbus_validate_utf8 (label, error))
+    goto failed;
+
+  if (! dbus_message_append_args (reply,
+                                  DBUS_TYPE_STRING,
+                                  &label,
+                                  DBUS_TYPE_INVALID))
+    goto failed;
+
+  if (! bus_transaction_send_from_driver (transaction, connection, reply))
+    goto oom;
+
+  bus_apparmor_confinement_unref (confinement);
+  dbus_message_unref (reply);
+
+  return TRUE;
+
+ oom:
+  BUS_SET_OOM (error);
+
+ failed:
+  _DBUS_ASSERT_ERROR_IS_SET (error);
+  if (confinement)
+    bus_apparmor_confinement_unref (confinement);
+  if (reply)
+    dbus_message_unref (reply);
+  return FALSE;
+}
+
 static dbus_bool_t
 bus_driver_handle_reload_config (DBusConnection *connection,
                                 BusTransaction *transaction,
@@ -2115,6 +2200,10 @@ static const MessageHandler dbus_message_handlers[] = {
     DBUS_TYPE_STRING_AS_STRING,
     DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
     bus_driver_handle_get_connection_selinux_security_context },
+  { "GetConnectionAppArmorSecurityContext",
+    DBUS_TYPE_STRING_AS_STRING,
+    DBUS_TYPE_STRING_AS_STRING,
+    bus_driver_handle_get_connection_apparmor_security_context },
   { "ReloadConfig",
     "",
     "",
index 933c3658c366ed3a1a5ebaedc7172ee8d39228f9..2b7fd2313a0e7fada6a73a2aa0ea51a6c4238290 100644 (file)
@@ -444,6 +444,8 @@ extern "C" {
 #define DBUS_ERROR_INVALID_FILE_CONTENT       "org.freedesktop.DBus.Error.InvalidFileContent"
 /** Asked for SELinux security context and it wasn't available. */
 #define DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN    "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"
+/** Asked for AppArmor security context and it wasn't available. */
+#define DBUS_ERROR_APPARMOR_SECURITY_CONTEXT_UNKNOWN   "org.freedesktop.DBus.Error.AppArmorSecurityContextUnknown"
 /** Asked for ADT audit data and it wasn't available. */
 #define DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN     "org.freedesktop.DBus.Error.AdtAuditDataUnknown"
 /** There's already an object with the requested object path. */