diff options
Diffstat (limited to 'dbus')
-rw-r--r-- | dbus/dbus-auth-script.c | 4 | ||||
-rw-r--r-- | dbus/dbus-auth.c | 21 | ||||
-rw-r--r-- | dbus/dbus-connection.c | 72 | ||||
-rw-r--r-- | dbus/dbus-connection.h | 3 | ||||
-rw-r--r-- | dbus/dbus-credentials-util.c | 2 | ||||
-rw-r--r-- | dbus/dbus-credentials.c | 14 | ||||
-rw-r--r-- | dbus/dbus-credentials.h | 1 | ||||
-rw-r--r-- | dbus/dbus-transport-protected.h | 1 | ||||
-rw-r--r-- | dbus/dbus-transport.c | 43 | ||||
-rw-r--r-- | dbus/dbus-transport.h | 5 |
10 files changed, 153 insertions, 13 deletions
diff --git a/dbus/dbus-auth-script.c b/dbus/dbus-auth-script.c index dd864ca5..eb145e49 100644 --- a/dbus/dbus-auth-script.c +++ b/dbus/dbus-auth-script.c @@ -665,7 +665,7 @@ _dbus_auth_script_run (const DBusString *filename) DBusCredentials *authorized_identity; authorized_identity = _dbus_auth_get_identity (auth); - if (!_dbus_credentials_are_empty (authorized_identity)) + if (!_dbus_credentials_are_anonymous (authorized_identity)) { _dbus_warn ("Expected anonymous login or failed login, but some credentials were authorized\n"); goto out; @@ -677,7 +677,7 @@ _dbus_auth_script_run (const DBusString *filename) DBusCredentials *authorized_identity; authorized_identity = _dbus_auth_get_identity (auth); - if (_dbus_credentials_are_empty (authorized_identity)) + if (_dbus_credentials_are_anonymous (authorized_identity)) { _dbus_warn ("Expected to have some credentials, but we don't\n"); goto out; diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index 657f8d3d..e47f6e36 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -731,6 +731,13 @@ sha1_handle_second_client_response (DBusAuth *auth, if (!_dbus_credentials_add_credentials (auth->authorized_identity, auth->desired_identity)) goto out_3; + + /* Copy process ID from the socket credentials if it's there + */ + if (!_dbus_credentials_add_credential (auth->authorized_identity, + DBUS_CREDENTIAL_UNIX_PROCESS_ID, + auth->credentials)) + goto out_3; if (!send_ok (auth)) goto out_3; @@ -994,7 +1001,7 @@ static dbus_bool_t handle_server_data_external_mech (DBusAuth *auth, const DBusString *data) { - if (_dbus_credentials_are_empty (auth->credentials)) + if (_dbus_credentials_are_anonymous (auth->credentials)) { _dbus_verbose ("%s: no credentials, mechanism EXTERNAL can't authenticate\n", DBUS_AUTH_NAME (auth)); @@ -1059,7 +1066,7 @@ handle_server_data_external_mech (DBusAuth *auth, } } - if (_dbus_credentials_are_empty (auth->desired_identity)) + if (_dbus_credentials_are_anonymous (auth->desired_identity)) { _dbus_verbose ("%s: desired user %s is no good\n", DBUS_AUTH_NAME (auth), @@ -1075,8 +1082,7 @@ handle_server_data_external_mech (DBusAuth *auth, auth->desired_identity)) return FALSE; - /* also copy process ID from the socket credentials - FIXME this - * should be done even if auth EXTERNAL not used + /* also copy process ID from the socket credentials */ if (!_dbus_credentials_add_credential (auth->authorized_identity, DBUS_CREDENTIAL_UNIX_PROCESS_ID, @@ -1192,6 +1198,13 @@ handle_server_data_anonymous_mech (DBusAuth *auth, /* We want to be anonymous (clear in case some other protocol got midway through I guess) */ _dbus_credentials_clear (auth->desired_identity); + /* Copy process ID from the socket credentials + */ + if (!_dbus_credentials_add_credential (auth->authorized_identity, + DBUS_CREDENTIAL_UNIX_PROCESS_ID, + auth->credentials)) + return FALSE; + /* Anonymous is always allowed */ if (!send_ok (auth)) return FALSE; diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 1cd3d05d..656f7502 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -2811,6 +2811,40 @@ dbus_connection_get_is_authenticated (DBusConnection *connection) } /** + * Gets whether the connection is not authenticated as a specific + * user. If the connection is not authenticated, this function + * returns #TRUE, and if it is authenticated but as an anonymous user, + * it returns #TRUE. If it is authenticated as a specific user, then + * this returns #FALSE. (Note that if the connection was authenticated + * as anonymous then disconnected, this function still returns #TRUE.) + * + * If the connection is not anonymous, you can use + * dbus_connection_get_unix_user() and + * dbus_connection_get_windows_user() to see who it's authorized as. + * + * If you want to prevent non-anonymous authorization, use + * dbus_server_set_auth_mechanisms() to remove the mechanisms that + * allow proving user identity (i.e. only allow the ANONYMOUS + * mechanism). + * + * @param connection the connection + * @returns #TRUE if not authenticated or authenticated as anonymous + */ +dbus_bool_t +dbus_connection_get_is_anonymous (DBusConnection *connection) +{ + dbus_bool_t res; + + _dbus_return_val_if_fail (connection != NULL, FALSE); + + CONNECTION_LOCK (connection); + res = _dbus_transport_get_is_anonymous (connection->transport); + CONNECTION_UNLOCK (connection); + + return res; +} + +/** * Set whether _exit() should be called when the connection receives a * disconnect signal. The call to _exit() comes after any handlers for * the disconnect signal run; handlers can cancel the exit by calling @@ -4987,6 +5021,43 @@ dbus_connection_set_windows_user_function (DBusConnection *connecti } /** + * This function must be called on the server side of a connection when the + * connection is first seen in the #DBusNewConnectionFunction. If set to + * #TRUE (the default is #FALSE), then the connection can proceed even if + * the client does not authenticate as some user identity, i.e. clients + * can connect anonymously. + * + * This setting interacts with the available authorization mechanisms + * (see dbus_server_set_auth_mechanisms()). Namely, an auth mechanism + * such as ANONYMOUS that supports anonymous auth must be included in + * the list of available mechanisms for anonymous login to work. + * + * This setting also changes the default rule for connections + * authorized as a user; normally, if a connection authorizes as + * a user identity, it is permitted if the user identity is + * root or the user identity matches the user identity of the server + * process. If anonymous connections are allowed, however, + * then any user identity is allowed. + * + * You can override the rules for connections authorized as a + * user identity with dbus_connection_set_unix_user_function() + * and dbus_connection_set_windows_user_function(). + * + * @param connection the connection + * @param value whether to allow authentication as an anonymous user + */ +void +dbus_connection_set_allow_anonymous (DBusConnection *connection, + dbus_bool_t value) +{ + _dbus_return_if_fail (connection != NULL); + + CONNECTION_LOCK (connection); + _dbus_transport_set_allow_anonymous (connection->transport, value); + CONNECTION_UNLOCK (connection); +} + +/** * * Normally #DBusConnection automatically handles all messages to the * org.freedesktop.DBus.Peer interface. However, the message bus wants @@ -4997,7 +5068,6 @@ dbus_connection_set_windows_user_function (DBusConnection *connecti * handled by the #DBusConnection and instead will be dispatched * normally to the application. * - * * If a normal application sets this flag, it can break things badly. * So don't set this unless you are the message bus. * diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h index 2b673fda..533ac98d 100644 --- a/dbus/dbus-connection.h +++ b/dbus/dbus-connection.h @@ -178,6 +178,7 @@ void dbus_connection_unref (DBusConnection void dbus_connection_close (DBusConnection *connection); dbus_bool_t dbus_connection_get_is_connected (DBusConnection *connection); dbus_bool_t dbus_connection_get_is_authenticated (DBusConnection *connection); +dbus_bool_t dbus_connection_get_is_anonymous (DBusConnection *connection); void dbus_connection_set_exit_on_disconnect (DBusConnection *connection, dbus_bool_t exit_on_disconnect); void dbus_connection_flush (DBusConnection *connection); @@ -239,6 +240,8 @@ void dbus_connection_set_windows_user_function (DBusConnection DBusAllowWindowsUserFunction function, void *data, DBusFreeFunction free_data_function); +void dbus_connection_set_allow_anonymous (DBusConnection *connection, + dbus_bool_t value); void dbus_connection_set_route_peer_messages (DBusConnection *connection, dbus_bool_t value); diff --git a/dbus/dbus-credentials-util.c b/dbus/dbus-credentials-util.c index 9b81aca4..a76ad093 100644 --- a/dbus/dbus-credentials-util.c +++ b/dbus/dbus-credentials-util.c @@ -104,6 +104,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (strcmp (_dbus_credentials_get_windows_sid (creds), SAMPLE_SID) == 0); _dbus_assert (!_dbus_credentials_are_empty (creds)); + _dbus_assert (!_dbus_credentials_are_anonymous (creds)); /* Test copy */ creds2 = _dbus_credentials_copy (creds); @@ -193,6 +194,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (_dbus_credentials_get_windows_sid (creds) == NULL); _dbus_assert (_dbus_credentials_are_empty (creds)); + _dbus_assert (_dbus_credentials_are_anonymous (creds)); _dbus_credentials_unref (creds); diff --git a/dbus/dbus-credentials.c b/dbus/dbus-credentials.c index dde69281..2023c170 100644 --- a/dbus/dbus-credentials.c +++ b/dbus/dbus-credentials.c @@ -289,6 +289,20 @@ _dbus_credentials_are_empty (DBusCredentials *credentials) } /** + * Checks whether a credentials object contains a user identity. + * + * @param credentials the object + * @returns #TRUE if there are no user identities in the object + */ +dbus_bool_t +_dbus_credentials_are_anonymous (DBusCredentials *credentials) +{ + return + credentials->unix_uid == DBUS_UID_UNSET && + credentials->windows_sid == NULL; +} + +/** * Merge all credentials found in the second object into the first object, * overwriting the first object if there are any overlaps. * diff --git a/dbus/dbus-credentials.h b/dbus/dbus-credentials.h index b47c9c47..f728b375 100644 --- a/dbus/dbus-credentials.h +++ b/dbus/dbus-credentials.h @@ -54,6 +54,7 @@ const char* _dbus_credentials_get_windows_sid (DBusCredentials dbus_bool_t _dbus_credentials_are_superset (DBusCredentials *credentials, DBusCredentials *possible_subset); dbus_bool_t _dbus_credentials_are_empty (DBusCredentials *credentials); +dbus_bool_t _dbus_credentials_are_anonymous (DBusCredentials *credentials); dbus_bool_t _dbus_credentials_add_credentials (DBusCredentials *credentials, DBusCredentials *other_credentials); /* must silently allow 'which' to not exist */ diff --git a/dbus/dbus-transport-protected.h b/dbus/dbus-transport-protected.h index 6d3f1f3c..76a17cf2 100644 --- a/dbus/dbus-transport-protected.h +++ b/dbus/dbus-transport-protected.h @@ -116,6 +116,7 @@ struct DBusTransport unsigned int receive_credentials_pending : 1; /**< #TRUE if we need to receive credentials */ unsigned int is_server : 1; /**< #TRUE if on the server side */ unsigned int unused_bytes_recovered : 1; /**< #TRUE if we've recovered unused bytes from auth */ + unsigned int allow_anonymous : 1; /**< #TRUE if an anonymous client can connect */ }; dbus_bool_t _dbus_transport_init_base (DBusTransport *transport, diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index 029cc6cf..d738cc0c 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -603,10 +603,10 @@ auth_via_default_rules (DBusTransport *transport) auth_identity = _dbus_auth_get_identity (transport->auth); _dbus_assert (auth_identity != NULL); - /* By default, connection is allowed if the client is - * 1) root or 2) has the same UID as us + /* By default, connection is allowed if the client is 1) root or 2) + * has the same UID as us or 3) anonymous is allowed. */ - + our_identity = _dbus_credentials_new_from_current_process (); if (our_identity == NULL) { @@ -614,7 +614,8 @@ auth_via_default_rules (DBusTransport *transport) return FALSE; } - if (_dbus_credentials_get_unix_uid (auth_identity) == 0 || + if (transport->allow_anonymous || + _dbus_credentials_get_unix_uid (auth_identity) == 0 || _dbus_credentials_same_user (our_identity, auth_identity)) { @@ -756,6 +757,28 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport) } /** + * See dbus_connection_get_is_anonymous(). + * + * @param transport the transport + * @returns #TRUE if not authenticated or authenticated as anonymous + */ +dbus_bool_t +_dbus_transport_get_is_anonymous (DBusTransport *transport) +{ + DBusCredentials *auth_identity; + + if (!transport->authenticated) + return TRUE; + + auth_identity = _dbus_auth_get_identity (transport->auth); + + if (_dbus_credentials_are_anonymous (auth_identity)) + return TRUE; + else + return FALSE; +} + +/** * Gets the address of a transport. It will be * #NULL for a server-side transport. * @@ -1298,5 +1321,17 @@ _dbus_transport_set_auth_mechanisms (DBusTransport *transport, return _dbus_auth_set_mechanisms (transport->auth, mechanisms); } +/** + * See dbus_connection_set_allow_anonymous() + * + * @param transport the transport + * @param value #TRUE to allow anonymous connection + */ +void +_dbus_transport_set_allow_anonymous (DBusTransport *transport, + dbus_bool_t value) +{ + transport->allow_anonymous = value != FALSE; +} /** @} */ diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h index 9e952a1e..3335c46b 100644 --- a/dbus/dbus-transport.h +++ b/dbus/dbus-transport.h @@ -39,6 +39,7 @@ void _dbus_transport_unref (DBusTransport void _dbus_transport_disconnect (DBusTransport *transport); dbus_bool_t _dbus_transport_get_is_connected (DBusTransport *transport); dbus_bool_t _dbus_transport_get_is_authenticated (DBusTransport *transport); +dbus_bool_t _dbus_transport_get_is_anonymous (DBusTransport *transport); const char* _dbus_transport_get_address (DBusTransport *transport); dbus_bool_t _dbus_transport_handle_watch (DBusTransport *transport, DBusWatch *watch, @@ -78,8 +79,8 @@ void _dbus_transport_set_windows_user_function (DBusTransport DBusFreeFunction *old_free_data_function); dbus_bool_t _dbus_transport_set_auth_mechanisms (DBusTransport *transport, const char **mechanisms); - - +void _dbus_transport_set_allow_anonymous (DBusTransport *transport, + dbus_bool_t value); DBUS_END_DECLS |