X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-transport.c;h=6b503721aaa8c1407c08645b3471fb45e32d99c5;hb=04c58b9e5fbdf3acc7565f989e5fcd11f0c23c57;hp=661b54ff406d6142b736fc624878943697bec110;hpb=600621dbc8073527a958091316eddfbb490c1032;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index 661b54f..6b50372 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -2,6 +2,7 @@ /* dbus-transport.c DBusTransport object (internal to D-Bus implementation) * * Copyright (C) 2002, 2003 Red Hat Inc. + * Copyright (C) 2013 Samsung Electronics * * Licensed under the Academic Free License version 2.1 * @@ -21,18 +22,21 @@ * */ -#include + +#include <../config.h> #include "dbus-transport-protected.h" #include "dbus-transport-unix.h" #include "dbus-transport-socket.h" #include "dbus-connection-internal.h" #include "dbus-watch.h" #include "dbus-auth.h" -#include "dbus-authorization.h" #include "dbus-address.h" #include "dbus-credentials.h" #include "dbus-mainloop.h" #include "dbus-message.h" +#ifdef ENABLE_KDBUS_TRANSPORT +#include "dbus-transport-kdbus.h" +#endif #ifdef DBUS_ENABLE_EMBEDDED_TESTS #include "dbus-server-debug-pipe.h" #endif @@ -107,7 +111,6 @@ _dbus_transport_init_base (DBusTransport *transport, { DBusMessageLoader *loader; DBusAuth *auth; - DBusAuthorization *authorization = NULL; /* non-NULL only if is_server=TRUE */ DBusCounter *counter; char *address_copy; DBusCredentials *creds; @@ -115,26 +118,27 @@ _dbus_transport_init_base (DBusTransport *transport, loader = _dbus_message_loader_new (); if (loader == NULL) return FALSE; - - if (server_guid != NULL) - { - authorization = _dbus_authorization_new (); - if (authorization == NULL) + + if (server_guid) + auth = _dbus_auth_server_new (server_guid); + else + { + _dbus_assert (address != NULL); + if (!_dbus_string_copy_data (address, &address_copy)) { _dbus_message_loader_unref (loader); - return FALSE; /* OOM */ + return FALSE; } +#ifdef ENABLE_KDBUS_TRANSPORT + if(address_copy == strstr(address_copy, "kdbus:path=")) + auth = _dbus_auth_client_new_kdbus(); + else +#endif + auth = _dbus_auth_client_new (); + } - auth = _dbus_auth_server_new (server_guid); - } - else - { - auth = _dbus_auth_client_new (); - } if (auth == NULL) { - if (authorization != NULL) - _dbus_authorization_unref (authorization); _dbus_message_loader_unref (loader); return FALSE; } @@ -143,8 +147,6 @@ _dbus_transport_init_base (DBusTransport *transport, if (counter == NULL) { _dbus_auth_unref (auth); - if (authorization != NULL) - _dbus_authorization_unref (authorization); _dbus_message_loader_unref (loader); return FALSE; } @@ -154,37 +156,19 @@ _dbus_transport_init_base (DBusTransport *transport, { _dbus_counter_unref (counter); _dbus_auth_unref (auth); - if (authorization != NULL) - _dbus_authorization_unref (authorization); _dbus_message_loader_unref (loader); return FALSE; } - if (server_guid != NULL) + if (server_guid) { _dbus_assert (address == NULL); address_copy = NULL; } - else - { - _dbus_assert (address != NULL); - - if (!_dbus_string_copy_data (address, &address_copy)) - { - _dbus_credentials_unref (creds); - _dbus_counter_unref (counter); - _dbus_auth_unref (auth); - if (authorization != NULL) - _dbus_authorization_unref (authorization); - _dbus_message_loader_unref (loader); - return FALSE; - } - } transport->refcount = 1; transport->vtable = vtable; transport->loader = loader; - transport->authorization = authorization; transport->auth = auth; transport->live_messages = counter; transport->authenticated = FALSE; @@ -193,7 +177,15 @@ _dbus_transport_init_base (DBusTransport *transport, transport->send_credentials_pending = !transport->is_server; transport->receive_credentials_pending = transport->is_server; transport->address = address_copy; + + transport->unix_user_function = NULL; + transport->unix_user_data = NULL; + transport->free_unix_user_data = NULL; + transport->windows_user_function = NULL; + transport->windows_user_data = NULL; + transport->free_windows_user_data = NULL; + transport->expected_guid = NULL; /* Try to default to something that won't totally hose the system, @@ -217,10 +209,6 @@ _dbus_transport_init_base (DBusTransport *transport, if (transport->address) _dbus_verbose ("Initialized transport on address %s\n", transport->address); - /* we can have authorization data set only in server mode */ - _dbus_assert ((transport->is_server && transport->authorization != NULL) || - (!transport->is_server && transport->authorization == NULL)); - return TRUE; } @@ -236,10 +224,14 @@ _dbus_transport_finalize_base (DBusTransport *transport) if (!transport->disconnected) _dbus_transport_disconnect (transport); + if (transport->free_unix_user_data != NULL) + (* transport->free_unix_user_data) (transport->unix_user_data); + + if (transport->free_windows_user_data != NULL) + (* transport->free_windows_user_data) (transport->windows_user_data); + _dbus_message_loader_unref (transport->loader); _dbus_auth_unref (transport->auth); - if (transport->authorization) - _dbus_authorization_unref (transport->authorization); _dbus_counter_set_notify (transport->live_messages, 0, 0, NULL, NULL); _dbus_counter_unref (transport->live_messages); @@ -361,6 +353,9 @@ static const struct { DBusTransport **transport_p, DBusError *error); } open_funcs[] = { +#ifdef ENABLE_KDBUS_TRANSPORT + { _dbus_transport_open_kdbus }, +#endif { _dbus_transport_open_socket }, { _dbus_transport_open_platform_specific }, { _dbus_transport_open_autolaunch } @@ -543,6 +538,163 @@ _dbus_transport_get_is_connected (DBusTransport *transport) return !transport->disconnected; } +static dbus_bool_t +auth_via_unix_user_function (DBusTransport *transport) +{ + DBusCredentials *auth_identity; + dbus_bool_t allow; + DBusConnection *connection; + DBusAllowUnixUserFunction unix_user_function; + void *unix_user_data; + dbus_uid_t uid; + + /* Dropping the lock here probably isn't that safe. */ + + auth_identity = _dbus_auth_get_identity (transport->auth); + _dbus_assert (auth_identity != NULL); + + connection = transport->connection; + unix_user_function = transport->unix_user_function; + unix_user_data = transport->unix_user_data; + uid = _dbus_credentials_get_unix_uid (auth_identity); + + _dbus_verbose ("unlock\n"); + _dbus_connection_unlock (connection); + + allow = (* unix_user_function) (connection, + uid, + unix_user_data); + + _dbus_verbose ("lock post unix user function\n"); + _dbus_connection_lock (connection); + + if (allow) + { + _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid); + } + else + { + _dbus_verbose ("Client UID "DBUS_UID_FORMAT + " was rejected, disconnecting\n", + _dbus_credentials_get_unix_uid (auth_identity)); + _dbus_transport_disconnect (transport); + } + + return allow; +} + +static dbus_bool_t +auth_via_windows_user_function (DBusTransport *transport) +{ + DBusCredentials *auth_identity; + dbus_bool_t allow; + DBusConnection *connection; + DBusAllowWindowsUserFunction windows_user_function; + void *windows_user_data; + char *windows_sid; + + /* Dropping the lock here probably isn't that safe. */ + + auth_identity = _dbus_auth_get_identity (transport->auth); + _dbus_assert (auth_identity != NULL); + + connection = transport->connection; + windows_user_function = transport->windows_user_function; + windows_user_data = transport->unix_user_data; + windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity)); + + if (windows_sid == NULL) + { + /* OOM */ + return FALSE; + } + + _dbus_verbose ("unlock\n"); + _dbus_connection_unlock (connection); + + allow = (* windows_user_function) (connection, + windows_sid, + windows_user_data); + + _dbus_verbose ("lock post windows user function\n"); + _dbus_connection_lock (connection); + + if (allow) + { + _dbus_verbose ("Client SID '%s' authorized\n", windows_sid); + } + else + { + _dbus_verbose ("Client SID '%s' was rejected, disconnecting\n", + _dbus_credentials_get_windows_sid (auth_identity)); + _dbus_transport_disconnect (transport); + } + + return allow; +} + +static dbus_bool_t +auth_via_default_rules (DBusTransport *transport) +{ + DBusCredentials *auth_identity; + DBusCredentials *our_identity; + dbus_bool_t allow; + + 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 or 3) anonymous is allowed. + */ + + our_identity = _dbus_credentials_new_from_current_process (); + if (our_identity == NULL) + { + /* OOM */ + return FALSE; + } + + if (transport->allow_anonymous || + _dbus_credentials_get_unix_uid (auth_identity) == 0 || + _dbus_credentials_same_user (our_identity, + auth_identity)) + { + if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID)) + _dbus_verbose ("Client authorized as SID '%s'" + "matching our SID '%s'\n", + _dbus_credentials_get_windows_sid(auth_identity), + _dbus_credentials_get_windows_sid(our_identity)); + else + _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT + " matching our UID "DBUS_UID_FORMAT"\n", + _dbus_credentials_get_unix_uid(auth_identity), + _dbus_credentials_get_unix_uid(our_identity)); + /* We have authenticated! */ + allow = TRUE; + } + else + { + if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID)) + _dbus_verbose ("Client authorized as SID '%s'" + " but our SID is '%s', disconnecting\n", + (_dbus_credentials_get_windows_sid(auth_identity) ? + _dbus_credentials_get_windows_sid(auth_identity) : ""), + (_dbus_credentials_get_windows_sid(our_identity) ? + _dbus_credentials_get_windows_sid(our_identity) : "")); + else + _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT + " but our UID is "DBUS_UID_FORMAT", disconnecting\n", + _dbus_credentials_get_unix_uid(auth_identity), + _dbus_credentials_get_unix_uid(our_identity)); + _dbus_transport_disconnect (transport); + allow = FALSE; + } + + _dbus_credentials_unref (our_identity); + + return allow; +} + /** * Returns #TRUE if we have been authenticated. It will return #TRUE even if * the transport is now disconnected, but was ever authenticated before @@ -632,18 +784,33 @@ _dbus_transport_try_to_authenticate (DBusTransport *transport) */ if (maybe_authenticated && transport->is_server) { + dbus_bool_t allow; DBusCredentials *auth_identity; - + auth_identity = _dbus_auth_get_identity (transport->auth); _dbus_assert (auth_identity != NULL); - /* 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 we have an auth'd user and a user function, delegate + * deciding whether auth credentials are good enough to the + * app; otherwise, use our default decision process. + */ + if (transport->unix_user_function != NULL && + _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID)) { - _dbus_transport_disconnect (transport); - maybe_authenticated = FALSE; + allow = auth_via_unix_user_function (transport); + } + else if (transport->windows_user_function != NULL && + _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID)) + { + allow = auth_via_windows_user_function (transport); + } + else + { + allow = auth_via_default_rules (transport); } + + if (!allow) + maybe_authenticated = FALSE; } transport->authenticated = maybe_authenticated; @@ -773,8 +940,6 @@ _dbus_transport_set_connection (DBusTransport *transport, _dbus_assert (transport->connection == NULL); transport->connection = connection; - if (transport->is_server) - _dbus_authorization_set_connection (transport->authorization, connection); _dbus_transport_ref (transport); if (!(* transport->vtable->connection_set) (transport)) @@ -858,7 +1023,7 @@ recover_unused_bytes (DBusTransport *transport) const DBusString *encoded; DBusString *buffer; int orig_len; - + if (!_dbus_string_init (&plaintext)) goto nomem; @@ -871,12 +1036,12 @@ recover_unused_bytes (DBusTransport *transport) _dbus_string_free (&plaintext); goto nomem; } - + _dbus_message_loader_get_buffer (transport->loader, &buffer); orig_len = _dbus_string_get_length (buffer); - + if (!_dbus_string_move (&plaintext, 0, buffer, orig_len)) { @@ -908,7 +1073,7 @@ recover_unused_bytes (DBusTransport *transport) &buffer); orig_len = _dbus_string_get_length (buffer); - + _dbus_auth_get_unused_bytes (transport->auth, &bytes); @@ -1257,17 +1422,20 @@ _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, DBusFreeFunction free_data_function, void **old_data, DBusFreeFunction *old_free_data_function) -{ - if (transport->is_server) - _dbus_authorization_set_unix_authorization_callback (transport->authorization, function, - data, free_data_function, old_data, old_free_data_function); +{ + *old_data = transport->unix_user_data; + *old_free_data_function = transport->free_unix_user_data; + + transport->unix_user_function = function; + transport->unix_user_data = data; + transport->free_unix_user_data = free_data_function; } /** @@ -1313,7 +1481,7 @@ _dbus_transport_get_windows_user (DBusTransport *transport, * @param old_free_data_function old free data function to free it with */ -inline void +void _dbus_transport_set_windows_user_function (DBusTransport *transport, DBusAllowWindowsUserFunction function, void *data, @@ -1321,9 +1489,12 @@ _dbus_transport_set_windows_user_function (DBusTransport *transport void **old_data, DBusFreeFunction *old_free_data_function) { - if (transport->is_server) - _dbus_authorization_set_windows_authorization_callback (transport->authorization, function, - data, free_data_function, old_data, old_free_data_function); + *old_data = transport->windows_user_data; + *old_free_data_function = transport->free_windows_user_data; + + transport->windows_user_function = function; + transport->windows_user_data = data; + transport->free_windows_user_data = free_data_function; } /** @@ -1347,12 +1518,11 @@ _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) { - if (transport->is_server) - _dbus_authorization_set_allow_anonymous (transport->authorization, value); + transport->allow_anonymous = value != FALSE; } #ifdef DBUS_ENABLE_STATS