? config.cache ? test/data/valid-config-files/session.d ? test/name-test/run-with-tmp-session-bus.conf Index: ChangeLog =================================================================== RCS file: /cvs/dbus/dbus/ChangeLog,v retrieving revision 1.1308 diff -u -p -r1.1308 ChangeLog --- ChangeLog 9 Jun 2007 23:41:32 -0000 1.1308 +++ ChangeLog 10 Jun 2007 04:53:54 -0000 @@ -1,5 +1,23 @@ 2007-06-09 Havoc Pennington + * dbus/dbus-string.c (_dbus_string_pop_line): fix this not to + think an empty line is the end of the file. + Also, fix some whitespace. + + * dbus/dbus-string-util.c: add more tests for + _dbus_string_pop_line() revealing that it thinks an empty line is + the end of the file, which broke dbus-auth-script.c so + it didn't really run the scripts + + * dbus/dbus-auth.c: add ANONYMOUS mechanism + + * dbus/dbus-auth-script.c (_dbus_auth_script_run): fix to detect + an empty/no-op auth script; add commands to check that we have or + don't have the expected credentials + + +2007-06-09 Havoc Pennington + * bus/policy.c (bus_policy_create_client_policy): gracefully continue if the connection has no unix user - just don't apply any unix user dependent rules. Index: dbus/dbus-auth-script.c =================================================================== RCS file: /cvs/dbus/dbus/dbus/dbus-auth-script.c,v retrieving revision 1.19 diff -u -p -r1.19 dbus-auth-script.c --- dbus/dbus-auth-script.c 9 Jun 2007 21:53:18 -0000 1.19 +++ dbus/dbus-auth-script.c 10 Jun 2007 04:53:55 -0000 @@ -218,10 +218,8 @@ auth_set_unix_credentials(DBusAuth *aut credentials = _dbus_credentials_new (); if (credentials == NULL) - { - _dbus_warn ("no memory\n"); - return; - } + _dbus_assert_not_reached ("no memory"); + if (uid != DBUS_UID_UNSET) _dbus_credentials_add_unix_uid (credentials, uid); if (pid != DBUS_PID_UNSET) @@ -288,11 +286,14 @@ _dbus_auth_script_run (const DBusString state = DBUS_AUTH_STATE_NEED_DISCONNECT; line_no = 0; + next_iteration: while (_dbus_string_pop_line (&file, &line)) { line_no += 1; + /* _dbus_warn ("%s\n", _dbus_string_get_const_data (&line)); */ + _dbus_string_delete_leading_blanks (&line); if (auth != NULL) @@ -659,6 +660,30 @@ _dbus_auth_script_run (const DBusString } } else if (_dbus_string_starts_with_c_str (&line, + "EXPECT_HAVE_NO_CREDENTIALS")) + { + DBusCredentials *authorized_identity; + + authorized_identity = _dbus_auth_get_identity (auth); + if (!_dbus_credentials_are_empty (authorized_identity)) + { + _dbus_warn ("Expected anonymous login or failed login, but some credentials were authorized\n"); + goto out; + } + } + else if (_dbus_string_starts_with_c_str (&line, + "EXPECT_HAVE_SOME_CREDENTIALS")) + { + DBusCredentials *authorized_identity; + + authorized_identity = _dbus_auth_get_identity (auth); + if (_dbus_credentials_are_empty (authorized_identity)) + { + _dbus_warn ("Expected to have some credentials, but we don't\n"); + goto out; + } + } + else if (_dbus_string_starts_with_c_str (&line, "EXPECT")) { DBusString expected; @@ -708,8 +733,12 @@ _dbus_auth_script_run (const DBusString } } - if (auth != NULL && - state == DBUS_AUTH_STATE_AUTHENTICATED) + if (auth == NULL) + { + _dbus_warn ("Auth script is bogus, did not even have CLIENT or SERVER\n"); + goto out; + } + else if (state == DBUS_AUTH_STATE_AUTHENTICATED) { const DBusString *unused; Index: dbus/dbus-auth.c =================================================================== RCS file: /cvs/dbus/dbus/dbus/dbus-auth.c,v retrieving revision 1.49 diff -u -p -r1.49 dbus-auth.c --- dbus/dbus-auth.c 9 Jun 2007 21:53:18 -0000 1.49 +++ dbus/dbus-auth.c 10 Jun 2007 04:53:56 -0000 @@ -424,6 +424,10 @@ shutdown_mech (DBusAuth *auth) } } +/* + * DBUS_COOKIE_SHA1 mechanism + */ + /* Returns TRUE but with an empty string hash if the * cookie_id isn't known. As with all this code * TRUE just means we had enough memory. @@ -982,6 +986,10 @@ handle_client_shutdown_cookie_sha1_mech _dbus_string_set_length (&auth->challenge, 0); } +/* + * EXTERNAL mechanism + */ + static dbus_bool_t handle_server_data_external_mech (DBusAuth *auth, const DBusString *data) @@ -1051,7 +1059,7 @@ handle_server_data_external_mech (DBusAu } } - if (_dbus_credentials_are_empty(auth->desired_identity)) + if (_dbus_credentials_are_empty (auth->desired_identity)) { _dbus_verbose ("%s: desired user %s is no good\n", DBUS_AUTH_NAME (auth), @@ -1142,13 +1150,120 @@ handle_client_shutdown_external_mech (DB } +/* + * ANONYMOUS mechanism + */ + +static dbus_bool_t +handle_server_data_anonymous_mech (DBusAuth *auth, + const DBusString *data) +{ + if (_dbus_string_get_length (data) > 0) + { + /* Client is allowed to send "trace" data, the only defined + * meaning is that if it contains '@' it is an email address, + * and otherwise it is anything else, and it's supposed to be + * UTF-8 + */ + if (!_dbus_string_validate_utf8 (data, 0, _dbus_string_get_length (data))) + { + _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); + } + + _dbus_verbose ("%s: ANONYMOUS client sent trace string: '%s'\n", + DBUS_AUTH_NAME (auth), + _dbus_string_get_const_data (data)); + } + + /* We want to be anonymous (clear in case some other protocol got midway through I guess) */ + _dbus_credentials_clear (auth->desired_identity); + + /* Anonymous is always allowed */ + if (!send_ok (auth)) + return FALSE; + + _dbus_verbose ("%s: authenticated client as anonymous\n", + DBUS_AUTH_NAME (auth)); + + return TRUE; +} + +static void +handle_server_shutdown_anonymous_mech (DBusAuth *auth) +{ + +} + +static dbus_bool_t +handle_client_initial_response_anonymous_mech (DBusAuth *auth, + DBusString *response) +{ + /* Our initial response is a "trace" string which must be valid UTF-8 + * and must be an email address if it contains '@'. + * We just send the dbus implementation info, like a user-agent or + * something, because... why not. There's nothing guaranteed here + * though, we could change it later. + */ + DBusString plaintext; + + if (!_dbus_string_init (&plaintext)) + return FALSE; + + if (!_dbus_string_append (&plaintext, + "libdbus " VERSION)) + goto failed; + + if (!_dbus_string_hex_encode (&plaintext, 0, + response, + _dbus_string_get_length (response))) + goto failed; + + _dbus_string_free (&plaintext); + + return TRUE; + + failed: + _dbus_string_free (&plaintext); + return FALSE; +} + +static dbus_bool_t +handle_client_data_anonymous_mech (DBusAuth *auth, + const DBusString *data) +{ + + return TRUE; +} + +static void +handle_client_shutdown_anonymous_mech (DBusAuth *auth) +{ + +} + /* Put mechanisms here in order of preference. - * What I eventually want to have is: + * Right now we have: + * + * - EXTERNAL checks socket credentials (or in the future, other info from the OS) + * - DBUS_COOKIE_SHA1 uses a cookie in the home directory, like xauth or ICE + * - ANONYMOUS checks nothing but doesn't auth the person as a user * - * - a mechanism that checks UNIX domain socket credentials - * - a simple magic cookie mechanism like X11 or ICE - * - mechanisms that chain to Cyrus SASL, so we can use anything it - * offers such as Kerberos, X509, whatever. + * We might ideally add a mechanism to chain to Cyrus SASL so we can + * use its mechanisms as well. * */ static const DBusAuthMechanismHandler @@ -1169,6 +1284,14 @@ all_mechanisms[] = { handle_client_data_cookie_sha1_mech, NULL, NULL, handle_client_shutdown_cookie_sha1_mech }, + { "ANONYMOUS", + handle_server_data_anonymous_mech, + NULL, NULL, + handle_server_shutdown_anonymous_mech, + handle_client_initial_response_anonymous_mech, + handle_client_data_anonymous_mech, + NULL, NULL, + handle_client_shutdown_anonymous_mech }, { NULL, NULL } }; @@ -1881,7 +2004,8 @@ lookup_command_from_name (DBusString *co } static void -goto_state (DBusAuth *auth, const DBusAuthStateData *state) +goto_state (DBusAuth *auth, + const DBusAuthStateData *state) { _dbus_verbose ("%s: going from state %s to state %s\n", DBUS_AUTH_NAME (auth), Index: dbus/dbus-string-util.c =================================================================== RCS file: /cvs/dbus/dbus/dbus/dbus-string-util.c,v retrieving revision 1.5 diff -u -p -r1.5 dbus-string-util.c --- dbus/dbus-string-util.c 12 Dec 2006 23:46:27 -0000 1.5 +++ dbus/dbus-string-util.c 10 Jun 2007 04:53:57 -0000 @@ -705,43 +705,93 @@ _dbus_string_test (void) _dbus_string_free (&str); { - int found,found_len; - _dbus_string_init_const (&str, "012\r\n567\n90"); - - if (!_dbus_string_find_eol(&str, 0, &found, &found_len) || found != 3 || found_len != 2) - _dbus_assert_not_reached ("Did not find '\\r\\n'"); - if (found != 3 || found_len != 2) - _dbus_assert_not_reached ("invalid return values"); - - if (!_dbus_string_find_eol(&str, 5, &found, &found_len)) - _dbus_assert_not_reached ("Did not find '\\n'"); - if (found != 8 || found_len != 1) - _dbus_assert_not_reached ("invalid return values"); - - if (_dbus_string_find_eol(&str, 9, &found, &found_len)) - _dbus_assert_not_reached ("Found not expected '\\n'"); - else if (found != 11 || found_len != 0) - _dbus_assert_not_reached ("invalid return values '\\n'"); - - _dbus_string_free (&str); - } + int found, found_len; + + _dbus_string_init_const (&str, "012\r\n567\n90"); + + if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2) + _dbus_assert_not_reached ("Did not find '\\r\\n'"); + if (found != 3 || found_len != 2) + _dbus_assert_not_reached ("invalid return values"); + + if (!_dbus_string_find_eol (&str, 5, &found, &found_len)) + _dbus_assert_not_reached ("Did not find '\\n'"); + if (found != 8 || found_len != 1) + _dbus_assert_not_reached ("invalid return values"); + + if (_dbus_string_find_eol (&str, 9, &found, &found_len)) + _dbus_assert_not_reached ("Found not expected '\\n'"); + else if (found != 11 || found_len != 0) + _dbus_assert_not_reached ("invalid return values '\\n'"); + + found = -1; + found_len = -1; + _dbus_string_init_const (&str, ""); + if (_dbus_string_find_eol (&str, 0, &found, &found_len)) + _dbus_assert_not_reached ("found an eol in an empty string"); + _dbus_assert (found == 0); + _dbus_assert (found_len == 0); + + found = -1; + found_len = -1; + _dbus_string_init_const (&str, "foobar"); + if (_dbus_string_find_eol (&str, 0, &found, &found_len)) + _dbus_assert_not_reached ("found eol in string that lacks one"); + _dbus_assert (found == 6); + _dbus_assert (found_len == 0); + + found = -1; + found_len = -1; + _dbus_string_init_const (&str, "foobar\n"); + if (!_dbus_string_find_eol (&str, 0, &found, &found_len)) + _dbus_assert_not_reached ("did not find eol in string that has one at end"); + _dbus_assert (found == 6); + _dbus_assert (found_len == 1); + } + + { + DBusString line; + +#define FIRST_LINE "this is a line" +#define SECOND_LINE "this is a second line" + /* third line is empty */ +#define THIRD_LINE "" +#define FOURTH_LINE "this is a fourth line" + + if (!_dbus_string_init (&str)) + _dbus_assert_not_reached ("no memory"); + + if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE)) + _dbus_assert_not_reached ("no memory"); + + if (!_dbus_string_init (&line)) + _dbus_assert_not_reached ("no memory"); + + if (!_dbus_string_pop_line (&str, &line)) + _dbus_assert_not_reached ("failed to pop first line"); + + _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE)); + + if (!_dbus_string_pop_line (&str, &line)) + _dbus_assert_not_reached ("failed to pop second line"); + + _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE)); + + if (!_dbus_string_pop_line (&str, &line)) + _dbus_assert_not_reached ("failed to pop third line"); + + _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE)); + + if (!_dbus_string_pop_line (&str, &line)) + _dbus_assert_not_reached ("failed to pop fourth line"); + + _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE)); + + _dbus_string_free (&str); + _dbus_string_free (&line); + } return TRUE; } #endif /* DBUS_BUILD_TESTS */ - - - - - - - - - - - - - - - Index: dbus/dbus-string.c =================================================================== RCS file: /cvs/dbus/dbus/dbus/dbus-string.c,v retrieving revision 1.77 diff -u -p -r1.77 dbus-string.c --- dbus/dbus-string.c 12 Dec 2006 23:58:32 -0000 1.77 +++ dbus/dbus-string.c 10 Jun 2007 04:53:58 -0000 @@ -1804,9 +1804,9 @@ _dbus_string_find (const DBusString *str */ dbus_bool_t _dbus_string_find_eol (const DBusString *str, - int start, - int *found, - int *found_len) + int start, + int *found, + int *found_len) { int i; @@ -1843,7 +1843,7 @@ _dbus_string_find_eol (const DBusString if (found_len) *found_len = 1; return TRUE; - } + } ++i; } @@ -2093,17 +2093,33 @@ _dbus_string_pop_line (DBusString *sourc _dbus_string_set_length (dest, 0); eol = 0; + eol_len = 0; if (!_dbus_string_find_eol (source, 0, &eol, &eol_len)) - eol = _dbus_string_get_length (source); + { + _dbus_assert (eol == _dbus_string_get_length (source)); + if (eol == 0) + { + /* If there's no newline and source has zero length, we're done */ + return FALSE; + } + /* otherwise, the last line of the file has no eol characters */ + } - if (eol == 0) - return FALSE; /* eof */ + /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also + * since find_eol returned TRUE + */ if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0)) - return FALSE; - + return FALSE; + /* remove line ending */ - return _dbus_string_set_length(dest, eol); + if (!_dbus_string_set_length (dest, eol)) + { + _dbus_assert_not_reached ("out of memory when shortening a string"); + return FALSE; + } + + return TRUE; } #ifdef DBUS_BUILD_TESTS Index: test/data/auth/anonymous-client-successful.auth-script =================================================================== RCS file: test/data/auth/anonymous-client-successful.auth-script diff -N test/data/auth/anonymous-client-successful.auth-script --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ test/data/auth/anonymous-client-successful.auth-script 10 Jun 2007 04:53:59 -0000 @@ -0,0 +1,16 @@ +## this tests that a client can login anonymously + +CLIENT + +## Reject whatever mechanism the client picks first +EXPECT_COMMAND AUTH +SEND 'REJECTED DBUS_TEST_NONEXISTENT_MECH1 ANONYMOUS DBUS_TEST_NONEXISTENT_MECH2' + +## And this time we get ANONYMOUS + +EXPECT_COMMAND AUTH +## of course real DBUS_COOKIE_SHA1 would not send this here... +SEND 'OK 1234deadbeef' + +EXPECT_COMMAND BEGIN +EXPECT_STATE AUTHENTICATED Index: test/data/auth/anonymous-server-successful.auth-script =================================================================== RCS file: test/data/auth/anonymous-server-successful.auth-script diff -N test/data/auth/anonymous-server-successful.auth-script --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ test/data/auth/anonymous-server-successful.auth-script 10 Jun 2007 04:53:59 -0000 @@ -0,0 +1,13 @@ +## this tests the server side in a successful auth of type ANONYMOUS + +SERVER +## verify that prior to doing anything, we haven't authed as anyone +EXPECT_HAVE_NO_CREDENTIALS +SEND 'AUTH ANONYMOUS 442d42757320312e312e31' +EXPECT_COMMAND OK +EXPECT_STATE WAITING_FOR_INPUT +SEND 'BEGIN' +EXPECT_STATE AUTHENTICATED +## verify that we are still anonymous +EXPECT_HAVE_NO_CREDENTIALS + Index: test/data/auth/external-failed.auth-script =================================================================== RCS file: /cvs/dbus/dbus/test/data/auth/external-failed.auth-script,v retrieving revision 1.3 diff -u -p -r1.3 external-failed.auth-script --- test/data/auth/external-failed.auth-script 17 May 2004 22:19:04 -0000 1.3 +++ test/data/auth/external-failed.auth-script 10 Jun 2007 04:53:59 -0000 @@ -2,7 +2,10 @@ SERVER NO_CREDENTIALS +## verify that prior to doing anything, we haven't authed as anyone +EXPECT_HAVE_NO_CREDENTIALS SEND 'AUTH EXTERNAL USERID_HEX' EXPECT_COMMAND REJECTED EXPECT_STATE WAITING_FOR_INPUT - +## verify that we still haven't authed as anyone +EXPECT_HAVE_NO_CREDENTIALS Index: test/data/auth/external-root.auth-script =================================================================== RCS file: /cvs/dbus/dbus/test/data/auth/external-root.auth-script,v retrieving revision 1.3 diff -u -p -r1.3 external-root.auth-script --- test/data/auth/external-root.auth-script 17 May 2004 22:19:04 -0000 1.3 +++ test/data/auth/external-root.auth-script 10 Jun 2007 04:53:59 -0000 @@ -2,7 +2,8 @@ SERVER ROOT_CREDENTIALS -SEND 'AUTH EXTERNAL USERID_HEX' +## 30 is ASCII '0' in hex +SEND 'AUTH EXTERNAL 30' EXPECT_COMMAND OK EXPECT_STATE WAITING_FOR_INPUT SEND 'BEGIN' Index: test/data/auth/external-silly.auth-script =================================================================== RCS file: /cvs/dbus/dbus/test/data/auth/external-silly.auth-script,v retrieving revision 1.3 diff -u -p -r1.3 external-silly.auth-script --- test/data/auth/external-silly.auth-script 17 May 2004 22:19:04 -0000 1.3 +++ test/data/auth/external-silly.auth-script 10 Jun 2007 04:53:59 -0000 @@ -1,8 +1,12 @@ -## this tests we can't auth with silly credentials +## this tests we can't auth if socket reports silly credentials but we ask for our own uid SERVER +## verify that prior to doing anything, we haven't authed as anyone +EXPECT_HAVE_NO_CREDENTIALS SILLY_CREDENTIALS SEND 'AUTH EXTERNAL USERID_HEX' EXPECT_COMMAND REJECTED EXPECT_STATE WAITING_FOR_INPUT +## verify that we still haven't authed as anyone +EXPECT_HAVE_NO_CREDENTIALS Index: test/data/auth/external-successful.auth-script =================================================================== RCS file: /cvs/dbus/dbus/test/data/auth/external-successful.auth-script,v retrieving revision 1.3 diff -u -p -r1.3 external-successful.auth-script --- test/data/auth/external-successful.auth-script 17 May 2004 22:19:04 -0000 1.3 +++ test/data/auth/external-successful.auth-script 10 Jun 2007 04:53:59 -0000 @@ -1,9 +1,12 @@ ## this tests a successful auth of type EXTERNAL SERVER +## verify that prior to doing anything, we haven't authed as anyone +EXPECT_HAVE_NO_CREDENTIALS SEND 'AUTH EXTERNAL USERID_HEX' EXPECT_COMMAND OK EXPECT_STATE WAITING_FOR_INPUT SEND 'BEGIN' EXPECT_STATE AUTHENTICATED - +## verify that we now have some credentials +EXPECT_HAVE_SOME_CREDENTIALS