diff options
Diffstat (limited to 'dbus/dbus-auth.c')
-rw-r--r-- | dbus/dbus-auth.c | 96 |
1 files changed, 85 insertions, 11 deletions
diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index 2a1bbd4c..ced93303 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -199,6 +199,8 @@ typedef struct DBusAuth base; /**< Parent class */ DBusList *mechs_to_try; /**< Mechanisms we got from the server that we're going to try using */ + + DBusString guid_from_server; /**< GUID received from server */ } DBusAuthClient; @@ -226,7 +228,8 @@ 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); +static dbus_bool_t send_begin (DBusAuth *auth, + const DBusString *args_from_ok); static dbus_bool_t send_cancel (DBusAuth *auth); /** @@ -1329,25 +1332,69 @@ send_error (DBusAuth *auth, const char *message) static dbus_bool_t send_ok (DBusAuth *auth) { - if (_dbus_string_append (&auth->outgoing, "OK\r\n")) + int orig_len; + + orig_len = _dbus_string_get_length (&auth->outgoing); + + if (_dbus_string_append (&auth->outgoing, "OK ") && + _dbus_string_copy (& DBUS_AUTH_SERVER (auth)->guid, + 0, + &auth->outgoing, + _dbus_string_get_length (&auth->outgoing)) && + _dbus_string_append (&auth->outgoing, "\r\n")) { goto_state (auth, &server_state_waiting_for_begin); return TRUE; } else - return FALSE; + { + _dbus_string_set_length (&auth->outgoing, orig_len); + return FALSE; + } } static dbus_bool_t -send_begin (DBusAuth *auth) +send_begin (DBusAuth *auth, + const DBusString *args_from_ok) { - if (_dbus_string_append (&auth->outgoing, "BEGIN\r\n")) + int end_of_hex; + + /* "args_from_ok" should be the GUID, whitespace already pulled off the front */ + _dbus_assert (_dbus_string_get_length (& DBUS_AUTH_CLIENT (auth)->guid_from_server) == 0); + + /* We decode the hex string to binary, using guid_from_server as scratch... */ + + end_of_hex = 0; + if (!_dbus_string_hex_decode (args_from_ok, 0, &end_of_hex, + & DBUS_AUTH_CLIENT (auth)->guid_from_server, 0)) + return FALSE; + + /* now clear out the scratch */ + _dbus_string_set_length (& DBUS_AUTH_CLIENT (auth)->guid_from_server, 0); + + if (end_of_hex != _dbus_string_get_length (args_from_ok) || + end_of_hex == 0) + { + _dbus_verbose ("Bad GUID from server, parsed %d bytes and had %d bytes from server\n", + end_of_hex, _dbus_string_get_length (args_from_ok)); + goto_state (auth, &common_state_need_disconnect); + 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 - return FALSE; + { + _dbus_string_set_length (& DBUS_AUTH_CLIENT (auth)->guid_from_server, 0); + return FALSE; + } } static dbus_bool_t @@ -1364,8 +1411,8 @@ send_cancel (DBusAuth *auth) static dbus_bool_t process_data (DBusAuth *auth, - const DBusString *args, - DBusAuthDataFunction data_func) + const DBusString *args, + DBusAuthDataFunction data_func) { int end; DBusString decoded; @@ -1710,7 +1757,7 @@ handle_client_state_waiting_for_data (DBusAuth *auth, return process_rejected (auth, args); case DBUS_AUTH_COMMAND_OK: - return send_begin (auth); + return send_begin (auth, args); case DBUS_AUTH_COMMAND_ERROR: return send_cancel (auth); @@ -1735,7 +1782,7 @@ handle_client_state_waiting_for_ok (DBusAuth *auth, return process_rejected (auth, args); case DBUS_AUTH_COMMAND_OK: - return send_begin (auth); + return send_begin (auth, args); case DBUS_AUTH_COMMAND_DATA: case DBUS_AUTH_COMMAND_ERROR: @@ -1974,10 +2021,19 @@ DBusAuth* _dbus_auth_client_new (void) { DBusAuth *auth; + DBusString guid_str; + + if (!_dbus_string_init (&guid_str)) + return NULL; auth = _dbus_auth_new (sizeof (DBusAuthClient)); if (auth == NULL) - return NULL; + { + _dbus_string_free (&guid_str); + return NULL; + } + + DBUS_AUTH_CLIENT (auth)->guid_from_server = guid_str; auth->side = auth_side_client; auth->state = &client_state_need_send_auth; @@ -2027,6 +2083,7 @@ _dbus_auth_unref (DBusAuth *auth) if (DBUS_AUTH_IS_CLIENT (auth)) { + _dbus_string_free (& DBUS_AUTH_CLIENT (auth)->guid_from_server); _dbus_list_clear (& DBUS_AUTH_CLIENT (auth)->mechs_to_try); } else @@ -2402,6 +2459,23 @@ _dbus_auth_get_identity (DBusAuth *auth, } /** + * Gets the GUID from the server if we've authenticated; gets + * #NULL otherwise. + * @param auth the auth object + * @returns the GUID in ASCII hex format + */ +const char* +_dbus_auth_get_guid_from_server (DBusAuth *auth) +{ + _dbus_assert (DBUS_AUTH_IS_CLIENT (auth)); + + if (auth->state == &common_state_authenticated) + return _dbus_string_get_const_data (& DBUS_AUTH_CLIENT (auth)->guid_from_server); + else + return NULL; +} + +/** * Sets the "authentication context" which scopes cookies * with the DBUS_COOKIE_SHA1 auth mechanism for example. * |