diff options
author | Tyler Hicks <tyhicks@canonical.com> | 2015-02-04 17:53:31 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2015-02-18 20:42:05 +0000 |
commit | 24f1502e42b58a7c238779c023c6bfe870dc78cc (patch) | |
tree | df05ab64c7129955498554e7d02a1577ab1b2dfb | |
parent | eac45c0484edfdbf5d8d7c0b613c31dc64d2f53b (diff) | |
download | dbus-24f1502e42b58a7c238779c023c6bfe870dc78cc.tar.gz |
Add DBus method to return the AA context of a connection
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.]
-rw-r--r-- | bus/apparmor.c | 15 | ||||
-rw-r--r-- | bus/apparmor.h | 1 | ||||
-rw-r--r-- | bus/driver.c | 89 | ||||
-rw-r--r-- | dbus/dbus-protocol.h | 2 |
4 files changed, 107 insertions, 0 deletions
diff --git a/bus/apparmor.c b/bus/apparmor.c index 072e2edf..af76ca27 100644 --- a/bus/apparmor.c +++ b/bus/apparmor.c @@ -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) { diff --git a/bus/apparmor.h b/bus/apparmor.h index 4a47aecc..e9fcc1b0 100644 --- a/bus/apparmor.h +++ b/bus/apparmor.h @@ -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); diff --git a/bus/driver.c b/bus/driver.c index aab922ae..4dcf76c8 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -1760,6 +1760,91 @@ bus_driver_handle_get_connection_credentials (DBusConnection *connection, } 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, DBusMessage *message, @@ -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", "", "", diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h index 933c3658..2b7fd231 100644 --- a/dbus/dbus-protocol.h +++ b/dbus/dbus-protocol.h @@ -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. */ |