From 1e6b28eb960ac181b2c2cf5693b0877fac06d9e7 Mon Sep 17 00:00:00 2001 From: Cosimo Alfarano Date: Mon, 3 Oct 2011 17:16:17 +0100 Subject: [PATCH 2/8] Actually use DBusAuthorization in DBusAuth EXTERNAL mech Also update the authentication script so that DBusAuthorization default rules are used during testing --- dbus/dbus-auth-script.c | 13 +++++++++- dbus/dbus-auth.c | 59 ++++++++++++++++++++++++++++++++++++++-------- dbus/dbus-auth.h | 4 ++- dbus/dbus-connection.c | 2 +- dbus/dbus-transport.c | 9 ++++--- 5 files changed, 69 insertions(+), 18 deletions(-) diff --git a/dbus/dbus-auth-script.c b/dbus/dbus-auth-script.c index 6285e3b..06df299 100644 --- a/dbus/dbus-auth-script.c +++ b/dbus/dbus-auth-script.c @@ -30,6 +30,7 @@ #include "dbus-hash.h" #include "dbus-credentials.h" #include "dbus-internals.h" +#include "dbus-authorization.h" /** * @defgroup DBusAuthScript code for running unit test scripts for DBusAuth @@ -401,6 +402,7 @@ _dbus_auth_script_run (const DBusString *filename) "SERVER")) { DBusCredentials *creds; + DBusAuthorization *authorization; if (auth != NULL) { @@ -408,7 +410,16 @@ _dbus_auth_script_run (const DBusString *filename) goto out; } - auth = _dbus_auth_server_new (&guid); + /* empty authorization, it will use default rules */ + authorization = _dbus_authorization_new (); + if (authorization == NULL) + { + _dbus_warn ("no memory to create DBusAuthorization\n"); + goto out; + } + auth = _dbus_auth_server_new (&guid, authorization); + /* DBusAuth owns it, or finalized on OOM */ + _dbus_authorization_unref (authorization); if (auth == NULL) { _dbus_warn ("no memory to create DBusAuth\n"); diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index d2c37a7..74ec91a 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -30,6 +30,7 @@ #include "dbus-sha.h" #include "dbus-protocol.h" #include "dbus-credentials.h" +#include "dbus-authorization.h" /** * @defgroup DBusAuth Authentication @@ -213,6 +214,8 @@ typedef struct { DBusAuth base; /**< Parent class */ + DBusAuthorization *authorization; /* DBus Authorization callbacks */ + int failures; /**< Number of times client has been rejected */ int max_failures; /**< Number of times we reject before disconnect */ @@ -752,6 +755,16 @@ sha1_handle_second_client_response (DBusAuth *auth, DBUS_CREDENTIAL_UNIX_PROCESS_ID, auth->credentials)) goto out_3; + + /* Do a authorization of the transport, in order to REJECT immediately the + * connection if needed (FDO#39720) */ + if (!_dbus_authorization_do_authorization (DBUS_AUTH_SERVER (auth)->authorization, + auth->authenticated_identity)) + { + if (send_rejected (auth)) + retval = TRUE; + goto out_3; + } if (!send_ok (auth)) goto out_3; @@ -1115,12 +1128,24 @@ handle_server_data_external_mech (DBusAuth *auth, DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID, auth->credentials)) return FALSE; - - if (!send_ok (auth)) - return FALSE; - _dbus_verbose ("%s: authenticated client based on socket credentials\n", - DBUS_AUTH_NAME (auth)); + /* Do a authorization of the transport, in order to REJECT immediately + * the connection if needed (FDO#39720) */ + if (_dbus_authorization_do_authorization (DBUS_AUTH_SERVER (auth)->authorization, + auth->authorized_identity)) + { + if (!send_ok (auth)) + return FALSE; + } + else + { + _dbus_verbose ("%s: desired identity does not match server identity: " + "not authorized\n", DBUS_AUTH_NAME (auth)); + return send_rejected (auth); + } + + _dbus_verbose ("%s: authenticated and authorized client based on " + "socket credentials\n", DBUS_AUTH_NAME (auth)); return TRUE; } @@ -1219,10 +1244,19 @@ handle_server_data_anonymous_mech (DBusAuth *auth, DBUS_CREDENTIAL_UNIX_PROCESS_ID, auth->credentials)) return FALSE; - - /* Anonymous is always allowed */ - if (!send_ok (auth)) - return FALSE; + + /* Do a authorization of the transport, in order to REJECT immediately the + * connection if needed (FDO#39720) */ + if (!_dbus_authorization_do_authorization (DBUS_AUTH_SERVER (auth)->authorization, + auth->authenticated_identity)) + { + if (!send_rejected (auth)) + return FALSE; /* OOM */ + } + else if (!send_ok (auth)) + { + return FALSE; /* OOM */ + } _dbus_verbose ("%s: authenticated client as anonymous\n", DBUS_AUTH_NAME (auth)); @@ -2244,7 +2278,8 @@ process_command (DBusAuth *auth) * @returns the new object or #NULL if no memory */ DBusAuth* -_dbus_auth_server_new (const DBusString *guid) +_dbus_auth_server_new (const DBusString *guid, + DBusAuthorization *authorization) { DBusAuth *auth; DBusAuthServer *server_auth; @@ -2272,7 +2307,8 @@ _dbus_auth_server_new (const DBusString *guid) server_auth = DBUS_AUTH_SERVER (auth); server_auth->guid = guid_copy; - + server_auth->authorization = _dbus_authorization_ref (authorization); + /* perhaps this should be per-mechanism with a lower * max */ @@ -2363,6 +2399,7 @@ _dbus_auth_unref (DBusAuth *auth) _dbus_assert (DBUS_AUTH_IS_SERVER (auth)); _dbus_string_free (& DBUS_AUTH_SERVER (auth)->guid); + _dbus_authorization_unref (DBUS_AUTH_SERVER (auth)->authorization); } if (auth->keyring) diff --git a/dbus/dbus-auth.h b/dbus/dbus-auth.h index ae3f364..a6577f9 100644 --- a/dbus/dbus-auth.h +++ b/dbus/dbus-auth.h @@ -27,6 +27,7 @@ #include #include #include +#include DBUS_BEGIN_DECLS @@ -41,7 +42,8 @@ typedef enum DBUS_AUTH_STATE_AUTHENTICATED } DBusAuthState; -DBusAuth* _dbus_auth_server_new (const DBusString *guid); +DBusAuth* _dbus_auth_server_new (const DBusString *guid, + DBusAuthorization *authorization); DBusAuth* _dbus_auth_client_new (void); DBusAuth* _dbus_auth_ref (DBusAuth *auth); void _dbus_auth_unref (DBusAuth *auth); diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 9128ffc..3e74ca1 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -5309,7 +5309,7 @@ dbus_connection_get_windows_user (DBusConnection *connection, * is allowed to connect. When an incoming connection has * authenticated with a particular user ID, this function is called; * if it returns #TRUE, the connection is allowed to proceed, - * otherwise the connection is disconnected. + * otherwise the connection is REJECTED. * * If the function is set to #NULL (as it is by default), then * only the same user owning the server process will be allowed to diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index 1ef189e..328479f 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -126,7 +126,7 @@ _dbus_transport_init_base (DBusTransport *transport, return FALSE; /* OOM */ } - auth = _dbus_auth_server_new (server_guid); + auth = _dbus_auth_server_new (server_guid, authorization); } else { @@ -615,7 +615,8 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport) /* If we have an authenticated user, delegate deciding whether auth * credentials are good enough to the app */ - if (!_dbus_authorization_do_authorization (transport->authorization, auth_identity)) + if (!_dbus_authorization_do_authorization (transport->authorization, + auth_identity)) { _dbus_transport_disconnect (transport); maybe_authenticated = FALSE; @@ -1233,7 +1234,7 @@ _dbus_transport_get_adt_audit_session_data (DBusTransport *transport, * @param old_data the old user data to be freed * @param old_free_data_function old free data function to free it with */ -inline void +void _dbus_transport_set_unix_user_function (DBusTransport *transport, DBusAllowUnixUserFunction function, void *data, @@ -1355,7 +1356,7 @@ _dbus_transport_set_auth_mechanisms (DBusTransport *transport, * @param transport the transport * @param value #TRUE to allow anonymous connection */ -inline void +void _dbus_transport_set_allow_anonymous (DBusTransport *transport, dbus_bool_t value) { -- 1.7.6.3