From 5970d04af540af4825958272cba950c0b7dff15d Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Thu, 13 Feb 2003 04:11:57 +0000 Subject: 2003-02-13 Havoc Pennington * dbus/dbus-auth.c (handle_server_data_external_mech): args to dbus_credentials_match were backward * dbus/dbus-auth-script.c (_dbus_auth_script_run): support NO_CREDENTIALS and ROOT_CREDENTIALS * dbus/dbus-auth.c (_dbus_auth_do_work): move get_state() routine into here. Never process more commands after we've reached an end state; store further data as unused bytes. * test/data/auth/*: add more auth tests * dbus/dbus-auth-script.c (_dbus_auth_script_run): support EXPECT command to match exact string and EXPECT_UNUSED to match unused bytes * test/Makefile.am (dist-hook): fix to dist all the test stuff --- dbus/Makefile.am | 4 + dbus/dbus-auth-script.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++- dbus/dbus-auth.c | 77 ++++++++++--------- 3 files changed, 237 insertions(+), 39 deletions(-) (limited to 'dbus') diff --git a/dbus/Makefile.am b/dbus/Makefile.am index cc1294b6..ae0188cf 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -111,3 +111,7 @@ dbus_test_SOURCES= \ dbus-test-main.c dbus_test_LDADD= $(DBUS_CLIENT_LIBS) libdbus-convenience.la libdbus-1.la + +## mop up the gcov files +clean-local: + /bin/rm *.bb *.bbg *.da *.gcov || true \ No newline at end of file diff --git a/dbus/dbus-auth-script.c b/dbus/dbus-auth-script.c index 6c5009a5..21a9f996 100644 --- a/dbus/dbus-auth-script.c +++ b/dbus/dbus-auth-script.c @@ -42,11 +42,15 @@ * @{ */ +/* this is slightly different from the other append_quoted_string + * in dbus-message-builder.c + */ static dbus_bool_t append_quoted_string (DBusString *dest, const DBusString *quoted) { dbus_bool_t in_quotes = FALSE; + dbus_bool_t in_backslash = FALSE; int i; i = 0; @@ -55,8 +59,33 @@ append_quoted_string (DBusString *dest, unsigned char b; b = _dbus_string_get_byte (quoted, i); - - if (in_quotes) + + if (in_backslash) + { + unsigned char a; + + if (b == 'r') + a = '\r'; + else if (b == 'n') + a = '\n'; + else if (b == '\\') + a = '\\'; + else + { + _dbus_warn ("bad backslashed byte %c\n", b); + return FALSE; + } + + if (!_dbus_string_append_byte (dest, a)) + return FALSE; + + in_backslash = FALSE; + } + else if (b == '\\') + { + in_backslash = TRUE; + } + else if (in_quotes) { if (b == '\'') in_quotes = FALSE; @@ -222,6 +251,8 @@ _dbus_auth_script_run (const DBusString *filename) else if (_dbus_string_starts_with_c_str (&line, "CLIENT")) { + DBusCredentials creds; + if (auth != NULL) { _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n"); @@ -234,10 +265,15 @@ _dbus_auth_script_run (const DBusString *filename) _dbus_warn ("no memory to create DBusAuth\n"); goto out; } + + _dbus_credentials_from_current_process (&creds); + _dbus_auth_set_credentials (auth, &creds); } else if (_dbus_string_starts_with_c_str (&line, "SERVER")) { + DBusCredentials creds; + if (auth != NULL) { _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n"); @@ -250,6 +286,9 @@ _dbus_auth_script_run (const DBusString *filename) _dbus_warn ("no memory to create DBusAuth\n"); goto out; } + + _dbus_credentials_from_current_process (&creds); + _dbus_auth_set_credentials (auth, &creds); } else if (auth == NULL) { @@ -257,6 +296,24 @@ _dbus_auth_script_run (const DBusString *filename) goto out; } + else if (_dbus_string_starts_with_c_str (&line, + "NO_CREDENTIALS")) + { + DBusCredentials creds = { -1, -1, -1 }; + _dbus_auth_set_credentials (auth, &creds); + } + else if (_dbus_string_starts_with_c_str (&line, + "ROOT_CREDENTIALS")) + { + DBusCredentials creds = { -1, 0, 0 }; + _dbus_auth_set_credentials (auth, &creds); + } + else if (_dbus_string_starts_with_c_str (&line, + "SILLY_CREDENTIALS")) + { + DBusCredentials creds = { -1, 4312, 1232 }; + _dbus_auth_set_credentials (auth, &creds); + } else if (_dbus_string_starts_with_c_str (&line, "SEND")) { @@ -291,10 +348,49 @@ _dbus_auth_script_run (const DBusString *filename) _dbus_string_free (&to_send); goto out; } + + /* Replace USERNAME_BASE64 with our username in base64 */ + { + int where; + + if (_dbus_string_find (&to_send, 0, + "USERNAME_BASE64", &where)) + { + DBusString username; + + if (!_dbus_string_init (&username, _DBUS_INT_MAX)) + { + _dbus_warn ("no memory for username\n"); + _dbus_string_free (&to_send); + goto out; + } + + if (!_dbus_string_append_our_uid (&username)) + { + _dbus_warn ("no memory for username\n"); + _dbus_string_free (&username); + _dbus_string_free (&to_send); + goto out; + } + + _dbus_string_delete (&to_send, where, strlen ("USERNAME_BASE64")); + + if (!_dbus_string_base64_encode (&username, 0, + &to_send, where)) + { + _dbus_warn ("no memory to subst USERNAME_BASE64\n"); + _dbus_string_free (&username); + _dbus_string_free (&to_send); + goto out; + } + + _dbus_string_free (&username); + } + } if (!_dbus_auth_bytes_received (auth, &to_send)) { - _dbus_warn ("not enough memory to call bytes_received\n"); + _dbus_warn ("not enough memory to call bytes_received, or can't add bytes to auth object already in end state\n"); _dbus_string_free (&to_send); goto out; } @@ -360,6 +456,99 @@ _dbus_auth_script_run (const DBusString *filename) _dbus_string_free (&received); } + else if (_dbus_string_starts_with_c_str (&line, + "EXPECT_UNUSED")) + { + DBusString expected; + DBusString unused; + + _dbus_string_delete_first_word (&line); + + if (!_dbus_string_init (&expected, _DBUS_INT_MAX)) + { + _dbus_warn ("no mem to allocate string expected\n"); + goto out; + } + + if (!append_quoted_string (&expected, &line)) + { + _dbus_warn ("failed to append quoted string line %d\n", + line_no); + _dbus_string_free (&expected); + goto out; + } + + if (!_dbus_string_init (&unused, _DBUS_INT_MAX)) + { + _dbus_warn ("no mem to allocate string unused\n"); + _dbus_string_free (&expected); + goto out; + } + + if (!_dbus_auth_get_unused_bytes (auth, &unused)) + { + _dbus_warn ("couldn't get unused bytes\n"); + _dbus_string_free (&expected); + _dbus_string_free (&unused); + goto out; + } + + if (_dbus_string_equal (&expected, &unused)) + { + _dbus_string_free (&expected); + _dbus_string_free (&unused); + } + else + { + const char *e1, *h1; + _dbus_string_get_const_data (&expected, &e1); + _dbus_string_get_const_data (&unused, &h1); + _dbus_warn ("Expected unused bytes '%s' and have '%s'\n", + e1, h1); + _dbus_string_free (&expected); + _dbus_string_free (&unused); + goto out; + } + } + else if (_dbus_string_starts_with_c_str (&line, + "EXPECT")) + { + DBusString expected; + + _dbus_string_delete_first_word (&line); + + if (!_dbus_string_init (&expected, _DBUS_INT_MAX)) + { + _dbus_warn ("no mem to allocate string expected\n"); + goto out; + } + + if (!append_quoted_string (&expected, &line)) + { + _dbus_warn ("failed to append quoted string line %d\n", + line_no); + _dbus_string_free (&expected); + goto out; + } + + if (_dbus_string_equal_len (&expected, &from_auth, + _dbus_string_get_length (&expected))) + { + _dbus_string_delete (&from_auth, 0, + _dbus_string_get_length (&expected)); + _dbus_string_free (&expected); + } + else + { + const char *e1, *h1; + _dbus_string_get_const_data (&expected, &e1); + _dbus_string_get_const_data (&from_auth, &h1); + _dbus_warn ("Expected exact string '%s' and have '%s'\n", + e1, h1); + _dbus_string_free (&expected); + goto out; + } + } else goto parse_failed; diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index 071e3416..324391ea 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -38,6 +38,10 @@ * * The file doc/dbus-sasl-profile.txt documents the network protocol * used for authentication. + * + * @todo some SASL profiles require sending the empty string as a + * challenge/response, but we don't currently allow that in our + * protocol. */ /** @@ -283,31 +287,6 @@ _dbus_auth_new (int size) return auth; } -static DBusAuthState -get_state (DBusAuth *auth) -{ - if (DBUS_AUTH_IS_SERVER (auth) && - DBUS_AUTH_SERVER (auth)->failures >= - DBUS_AUTH_SERVER (auth)->max_failures) - auth->need_disconnect = TRUE; - - if (auth->need_disconnect) - return DBUS_AUTH_STATE_NEED_DISCONNECT; - else if (auth->authenticated) - { - if (_dbus_string_get_length (&auth->incoming) > 0) - return DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES; - else - return DBUS_AUTH_STATE_AUTHENTICATED; - } - else if (auth->needed_memory) - return DBUS_AUTH_STATE_WAITING_FOR_MEMORY; - else if (_dbus_string_get_length (&auth->outgoing) > 0) - return DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND; - else - return DBUS_AUTH_STATE_WAITING_FOR_INPUT; -} - static void shutdown_mech (DBusAuth *auth) { @@ -411,6 +390,7 @@ handle_server_data_external_mech (DBusAuth *auth, if (_dbus_string_get_length (&auth->identity) > 0) { /* Tried to send two auth identities, wtf */ + _dbus_verbose ("client tried to send auth identity, but we already have one\n"); return send_rejected (auth); } else @@ -453,7 +433,10 @@ handle_server_data_external_mech (DBusAuth *auth, { if (!_dbus_credentials_from_uid_string (&auth->identity, &desired_identity)) - return send_rejected (auth); + { + _dbus_verbose ("could not get credentials from uid string\n"); + return send_rejected (auth); + } } if (desired_identity.uid < 0) @@ -462,8 +445,8 @@ handle_server_data_external_mech (DBusAuth *auth, return send_rejected (auth); } - if (_dbus_credentials_match (&auth->credentials, - &desired_identity)) + if (_dbus_credentials_match (&desired_identity, + &auth->credentials)) { /* client has authenticated */ _dbus_verbose ("authenticated client with UID %d matching socket credentials UID %d\n", @@ -482,6 +465,9 @@ handle_server_data_external_mech (DBusAuth *auth, } else { + _dbus_verbose ("credentials uid=%d gid=%d do not allow uid=%d gid=%d\n", + auth->credentials.uid, auth->credentials.gid, + desired_identity.uid, desired_identity.gid); return send_rejected (auth); } } @@ -1061,7 +1047,7 @@ process_command (DBusAuth *auth) int i, j; dbus_bool_t retval; - _dbus_verbose (" trying process_command()\n"); + /* _dbus_verbose (" trying process_command()\n"); */ retval = FALSE; @@ -1296,10 +1282,7 @@ _dbus_auth_unref (DBusAuth *auth) */ DBusAuthState _dbus_auth_do_work (DBusAuth *auth) -{ - if (DBUS_AUTH_IN_END_STATE (auth)) - return get_state (auth); - +{ auth->needed_memory = FALSE; /* Max amount we'll buffer up before deciding someone's on crack */ @@ -1307,6 +1290,9 @@ _dbus_auth_do_work (DBusAuth *auth) do { + if (DBUS_AUTH_IN_END_STATE (auth)) + break; + if (_dbus_string_get_length (&auth->incoming) > MAX_BUFFER || _dbus_string_get_length (&auth->outgoing) > MAX_BUFFER) { @@ -1325,8 +1311,27 @@ _dbus_auth_do_work (DBusAuth *auth) } } while (process_command (auth)); - - return get_state (auth); + + if (DBUS_AUTH_IS_SERVER (auth) && + DBUS_AUTH_SERVER (auth)->failures >= + DBUS_AUTH_SERVER (auth)->max_failures) + auth->need_disconnect = TRUE; + + if (auth->need_disconnect) + return DBUS_AUTH_STATE_NEED_DISCONNECT; + else if (auth->authenticated) + { + if (_dbus_string_get_length (&auth->incoming) > 0) + return DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES; + else + return DBUS_AUTH_STATE_AUTHENTICATED; + } + else if (auth->needed_memory) + return DBUS_AUTH_STATE_WAITING_FOR_MEMORY; + else if (_dbus_string_get_length (&auth->outgoing) > 0) + return DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND; + else + return DBUS_AUTH_STATE_WAITING_FOR_INPUT; } /** @@ -1383,7 +1388,7 @@ _dbus_auth_bytes_sent (DBusAuth *auth, * * @param auth the auth conversation * @param str the received bytes. - * @returns #FALSE if not enough memory to store the bytes. + * @returns #FALSE if not enough memory to store the bytes or we were already authenticated. */ dbus_bool_t _dbus_auth_bytes_received (DBusAuth *auth, -- cgit