X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-auth.c;h=86e3223dddc194918fc23d2191584ca8dbd23f5e;hb=c1a77d2c58c78abc606f1cb7918704596ebf2bfe;hp=b23b1479370d451e29f0a3c1128e6b6d1953bc72;hpb=e7c0d217795f4e8eb618f82b9b3e52807436c8f1;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index b23b147..86e3223 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -1,7 +1,8 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-auth.c Authentication * * Copyright (C) 2002, 2003, 2004 Red Hat Inc. + * Copyright (C) 2013 Samsung Electronics * * Licensed under the Academic Free License version 2.1 * @@ -17,9 +18,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ + +#include #include "dbus-auth.h" #include "dbus-string.h" #include "dbus-list.h" @@ -122,7 +125,9 @@ typedef enum { DBUS_AUTH_COMMAND_REJECTED, DBUS_AUTH_COMMAND_OK, DBUS_AUTH_COMMAND_ERROR, - DBUS_AUTH_COMMAND_UNKNOWN + DBUS_AUTH_COMMAND_UNKNOWN, + DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD, + DBUS_AUTH_COMMAND_AGREE_UNIX_FD } DBusAuthCommand; /** @@ -184,6 +189,9 @@ struct DBusAuth unsigned int already_got_mechanisms : 1; /**< Client already got mech list */ unsigned int already_asked_for_initial_response : 1; /**< Already sent a blank challenge to get an initial response */ unsigned int buffer_outstanding : 1; /**< Buffer is "checked out" for reading data into */ + + unsigned int unix_fd_possible : 1; /**< This side could do unix fd passing */ + unsigned int unix_fd_negotiated : 1; /**< Unix fd was successfully negotiated */ }; /** @@ -223,9 +231,10 @@ static dbus_bool_t send_rejected (DBusAuth *auth); static dbus_bool_t send_error (DBusAuth *auth, const char *message); static dbus_bool_t send_ok (DBusAuth *auth); -static dbus_bool_t send_begin (DBusAuth *auth, - const DBusString *args_from_ok); +static dbus_bool_t send_begin (DBusAuth *auth); static dbus_bool_t send_cancel (DBusAuth *auth); +static dbus_bool_t send_negotiate_unix_fd (DBusAuth *auth); +static dbus_bool_t send_agree_unix_fd (DBusAuth *auth); /** * Client states @@ -264,6 +273,9 @@ static dbus_bool_t handle_client_state_waiting_for_ok (DBusAuth *aut static dbus_bool_t handle_client_state_waiting_for_reject (DBusAuth *auth, DBusAuthCommand command, const DBusString *args); +static dbus_bool_t handle_client_state_waiting_for_agree_unix_fd (DBusAuth *auth, + DBusAuthCommand command, + const DBusString *args); static const DBusAuthStateData client_state_need_send_auth = { "NeedSendAuth", NULL @@ -277,7 +289,10 @@ static const DBusAuthStateData client_state_waiting_for_ok = { static const DBusAuthStateData client_state_waiting_for_reject = { "WaitingForReject", handle_client_state_waiting_for_reject }; - +static const DBusAuthStateData client_state_waiting_for_agree_unix_fd = { + "WaitingForAgreeUnixFD", handle_client_state_waiting_for_agree_unix_fd +}; + /** * Common terminal states. Terminal states have handler == NULL. */ @@ -1039,6 +1054,7 @@ handle_server_data_external_mech (DBusAuth *auth, _dbus_verbose ("%s: sending empty challenge asking client for auth identity\n", DBUS_AUTH_NAME (auth)); auth->already_asked_for_initial_response = TRUE; + goto_state (auth, &server_state_waiting_for_data); return TRUE; } else @@ -1093,6 +1109,13 @@ handle_server_data_external_mech (DBusAuth *auth, DBUS_CREDENTIAL_UNIX_PROCESS_ID, auth->credentials)) return FALSE; + + /* also copy audit data from the socket credentials + */ + if (!_dbus_credentials_add_credential (auth->authorized_identity, + DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID, + auth->credentials)) + return FALSE; if (!send_ok (auth)) return FALSE; @@ -1180,18 +1203,6 @@ handle_server_data_anonymous_mech (DBusAuth *auth, { _dbus_verbose ("%s: Received invalid UTF-8 trace data from ANONYMOUS client\n", DBUS_AUTH_NAME (auth)); - - { - DBusString plaintext; - DBusString encoded; - _dbus_string_init_const (&plaintext, "D-Bus " VERSION); - _dbus_string_init (&encoded); - _dbus_string_hex_encode (&plaintext, 0, - &encoded, - 0); - _dbus_verbose ("%s: try '%s'\n", - DBUS_AUTH_NAME (auth), _dbus_string_get_const_data (&encoded)); - } return send_rejected (auth); } @@ -1242,7 +1253,7 @@ handle_client_initial_response_anonymous_mech (DBusAuth *auth, return FALSE; if (!_dbus_string_append (&plaintext, - "libdbus " VERSION)) + "libdbus " DBUS_VERSION_STRING)) goto failed; if (!_dbus_string_hex_encode (&plaintext, 0, @@ -1514,9 +1525,21 @@ send_ok (DBusAuth *auth) } static dbus_bool_t -send_begin (DBusAuth *auth, - const DBusString *args_from_ok) +send_begin (DBusAuth *auth) { + + if (!_dbus_string_append (&auth->outgoing, + "BEGIN\r\n")) + return FALSE; + + goto_state (auth, &common_state_authenticated); + return TRUE; +} + +static dbus_bool_t +process_ok(DBusAuth *auth, + const DBusString *args_from_ok) { + int end_of_hex; /* "args_from_ok" should be the GUID, whitespace already pulled off the front */ @@ -1541,20 +1564,19 @@ send_begin (DBusAuth *auth, return TRUE; } - if (_dbus_string_copy (args_from_ok, 0, &DBUS_AUTH_CLIENT (auth)->guid_from_server, 0) && - _dbus_string_append (&auth->outgoing, "BEGIN\r\n")) - { - _dbus_verbose ("Got GUID '%s' from the server\n", - _dbus_string_get_const_data (& DBUS_AUTH_CLIENT (auth)->guid_from_server)); - - goto_state (auth, &common_state_authenticated); - return TRUE; - } - else - { + if (!_dbus_string_copy (args_from_ok, 0, &DBUS_AUTH_CLIENT (auth)->guid_from_server, 0)) { _dbus_string_set_length (& DBUS_AUTH_CLIENT (auth)->guid_from_server, 0); return FALSE; - } + } + + _dbus_verbose ("Got GUID '%s' from the server\n", + _dbus_string_get_const_data (& DBUS_AUTH_CLIENT (auth)->guid_from_server)); + + if (auth->unix_fd_possible) + return send_negotiate_unix_fd(auth); + + _dbus_verbose("Not negotiating unix fd passing, since not possible\n"); + return send_begin (auth); } static dbus_bool_t @@ -1614,6 +1636,33 @@ process_data (DBusAuth *auth, } static dbus_bool_t +send_negotiate_unix_fd (DBusAuth *auth) +{ + if (!_dbus_string_append (&auth->outgoing, + "NEGOTIATE_UNIX_FD\r\n")) + return FALSE; + + goto_state (auth, &client_state_waiting_for_agree_unix_fd); + return TRUE; +} + +static dbus_bool_t +send_agree_unix_fd (DBusAuth *auth) +{ + _dbus_assert(auth->unix_fd_possible); + + auth->unix_fd_negotiated = TRUE; + _dbus_verbose("Agreed to UNIX FD passing\n"); + + if (!_dbus_string_append (&auth->outgoing, + "AGREE_UNIX_FD\r\n")) + return FALSE; + + goto_state (auth, &server_state_waiting_for_begin); + return TRUE; +} + +static dbus_bool_t handle_auth (DBusAuth *auth, const DBusString *args) { if (_dbus_string_get_length (args) == 0) @@ -1704,9 +1753,13 @@ handle_server_state_waiting_for_auth (DBusAuth *auth, case DBUS_AUTH_COMMAND_ERROR: return send_rejected (auth); + case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD: + return send_error (auth, "Need to authenticate first"); + case DBUS_AUTH_COMMAND_REJECTED: case DBUS_AUTH_COMMAND_OK: case DBUS_AUTH_COMMAND_UNKNOWN: + case DBUS_AUTH_COMMAND_AGREE_UNIX_FD: default: return send_error (auth, "Unknown command"); } @@ -1733,9 +1786,13 @@ handle_server_state_waiting_for_data (DBusAuth *auth, goto_state (auth, &common_state_need_disconnect); return TRUE; + case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD: + return send_error (auth, "Need to authenticate first"); + case DBUS_AUTH_COMMAND_REJECTED: case DBUS_AUTH_COMMAND_OK: case DBUS_AUTH_COMMAND_UNKNOWN: + case DBUS_AUTH_COMMAND_AGREE_UNIX_FD: default: return send_error (auth, "Unknown command"); } @@ -1758,9 +1815,16 @@ handle_server_state_waiting_for_begin (DBusAuth *auth, goto_state (auth, &common_state_authenticated); return TRUE; + case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD: + if (auth->unix_fd_possible) + return send_agree_unix_fd(auth); + else + return send_error(auth, "Unix FD passing not supported, not authenticated or otherwise not possible"); + case DBUS_AUTH_COMMAND_REJECTED: case DBUS_AUTH_COMMAND_OK: case DBUS_AUTH_COMMAND_UNKNOWN: + case DBUS_AUTH_COMMAND_AGREE_UNIX_FD: default: return send_error (auth, "Unknown command"); @@ -1925,7 +1989,7 @@ handle_client_state_waiting_for_data (DBusAuth *auth, return process_rejected (auth, args); case DBUS_AUTH_COMMAND_OK: - return send_begin (auth, args); + return process_ok(auth, args); case DBUS_AUTH_COMMAND_ERROR: return send_cancel (auth); @@ -1934,6 +1998,8 @@ handle_client_state_waiting_for_data (DBusAuth *auth, case DBUS_AUTH_COMMAND_CANCEL: case DBUS_AUTH_COMMAND_BEGIN: case DBUS_AUTH_COMMAND_UNKNOWN: + case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD: + case DBUS_AUTH_COMMAND_AGREE_UNIX_FD: default: return send_error (auth, "Unknown command"); } @@ -1950,7 +2016,7 @@ handle_client_state_waiting_for_ok (DBusAuth *auth, return process_rejected (auth, args); case DBUS_AUTH_COMMAND_OK: - return send_begin (auth, args); + return process_ok(auth, args); case DBUS_AUTH_COMMAND_DATA: case DBUS_AUTH_COMMAND_ERROR: @@ -1960,6 +2026,8 @@ handle_client_state_waiting_for_ok (DBusAuth *auth, case DBUS_AUTH_COMMAND_CANCEL: case DBUS_AUTH_COMMAND_BEGIN: case DBUS_AUTH_COMMAND_UNKNOWN: + case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD: + case DBUS_AUTH_COMMAND_AGREE_UNIX_FD: default: return send_error (auth, "Unknown command"); } @@ -1982,12 +2050,46 @@ handle_client_state_waiting_for_reject (DBusAuth *auth, case DBUS_AUTH_COMMAND_OK: case DBUS_AUTH_COMMAND_ERROR: case DBUS_AUTH_COMMAND_UNKNOWN: + case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD: + case DBUS_AUTH_COMMAND_AGREE_UNIX_FD: default: goto_state (auth, &common_state_need_disconnect); return TRUE; } } +static dbus_bool_t +handle_client_state_waiting_for_agree_unix_fd(DBusAuth *auth, + DBusAuthCommand command, + const DBusString *args) +{ + switch (command) + { + case DBUS_AUTH_COMMAND_AGREE_UNIX_FD: + _dbus_assert(auth->unix_fd_possible); + auth->unix_fd_negotiated = TRUE; + _dbus_verbose("Successfully negotiated UNIX FD passing\n"); + return send_begin (auth); + + case DBUS_AUTH_COMMAND_ERROR: + _dbus_assert(auth->unix_fd_possible); + auth->unix_fd_negotiated = FALSE; + _dbus_verbose("Failed to negotiate UNIX FD passing\n"); + return send_begin (auth); + + case DBUS_AUTH_COMMAND_OK: + case DBUS_AUTH_COMMAND_DATA: + case DBUS_AUTH_COMMAND_REJECTED: + case DBUS_AUTH_COMMAND_AUTH: + case DBUS_AUTH_COMMAND_CANCEL: + case DBUS_AUTH_COMMAND_BEGIN: + case DBUS_AUTH_COMMAND_UNKNOWN: + case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD: + default: + return send_error (auth, "Unknown command"); + } +} + /** * Mapping from command name to enum */ @@ -1997,13 +2099,15 @@ typedef struct { } DBusAuthCommandName; static const DBusAuthCommandName auth_command_names[] = { - { "AUTH", DBUS_AUTH_COMMAND_AUTH }, - { "CANCEL", DBUS_AUTH_COMMAND_CANCEL }, - { "DATA", DBUS_AUTH_COMMAND_DATA }, - { "BEGIN", DBUS_AUTH_COMMAND_BEGIN }, - { "REJECTED", DBUS_AUTH_COMMAND_REJECTED }, - { "OK", DBUS_AUTH_COMMAND_OK }, - { "ERROR", DBUS_AUTH_COMMAND_ERROR } + { "AUTH", DBUS_AUTH_COMMAND_AUTH }, + { "CANCEL", DBUS_AUTH_COMMAND_CANCEL }, + { "DATA", DBUS_AUTH_COMMAND_DATA }, + { "BEGIN", DBUS_AUTH_COMMAND_BEGIN }, + { "REJECTED", DBUS_AUTH_COMMAND_REJECTED }, + { "OK", DBUS_AUTH_COMMAND_OK }, + { "ERROR", DBUS_AUTH_COMMAND_ERROR }, + { "NEGOTIATE_UNIX_FD", DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD }, + { "AGREE_UNIX_FD", DBUS_AUTH_COMMAND_AGREE_UNIX_FD } }; static DBusAuthCommand @@ -2135,8 +2239,8 @@ process_command (DBusAuth *auth) /** * Creates a new auth conversation object for the server side. - * See doc/dbus-sasl-profile.txt for full details on what - * this object does. + * See http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol + * for full details on what this object does. * * @returns the new object or #NULL if no memory */ @@ -2181,8 +2285,8 @@ _dbus_auth_server_new (const DBusString *guid) /** * Creates a new auth conversation object for the client side. - * See doc/dbus-sasl-profile.txt for full details on what - * this object does. + * See http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol + * for full details on what this object does. * * @returns the new object or #NULL if no memory */ @@ -2218,6 +2322,49 @@ _dbus_auth_client_new (void) return auth; } +#ifdef ENABLE_KDBUS_TRANSPORT +/** + * Creates a new auth conversation object for the client side of kdbus. + * In fact it only initialize structures and sets authenticated state + * because of different authentication-like mechanism in kdbus - policies + * TODO Probably to be checked and modified when kdbus will be documented + * + * @returns the new object or #NULL if no memory + */ +DBusAuth* +_dbus_auth_client_new_kdbus (void) +{ + DBusAuth *auth; + DBusString guid_str; + + if (!_dbus_string_init (&guid_str)) + return NULL; + + auth = _dbus_auth_new (sizeof (DBusAuthClient)); + if (auth == NULL) + { + _dbus_string_free (&guid_str); + return NULL; + } + + DBUS_AUTH_CLIENT (auth)->guid_from_server = guid_str; + + auth->side = auth_side_client; + auth->state = &common_state_authenticated; + auth->unix_fd_negotiated = TRUE; + + /* Start the auth conversation by sending AUTH for our default + * mechanism */ +/* if (!send_auth (auth, &all_mechanisms[0])) + { + _dbus_auth_unref (auth); + return NULL; + }*/ + + return auth; +} +#endif + /** * Increments the refcount of an auth object. * @@ -2677,6 +2824,31 @@ _dbus_auth_set_context (DBusAuth *auth, &auth->context, 0, _dbus_string_get_length (context)); } +/** + * Sets whether unix fd passing is potentially on the transport and + * hence shall be negotiated. + * + * @param auth the auth conversation + * @param b TRUE when unix fd passing shall be negotiated, otherwise FALSE + */ +void +_dbus_auth_set_unix_fd_possible(DBusAuth *auth, dbus_bool_t b) +{ + auth->unix_fd_possible = b; +} + +/** + * Queries whether unix fd passing was successfully negotiated. + * + * @param auth the auth conversion + * @returns #TRUE when unix fd passing was negotiated. + */ +dbus_bool_t +_dbus_auth_get_unix_fd_negotiated(DBusAuth *auth) +{ + return auth->unix_fd_negotiated; +} + /** @} */ /* tests in dbus-auth-util.c */