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(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; }
static DBusCredentials* make_credentials(dbus_uid_t unix_uid, dbus_pid_t pid, const char *windows_sid) { DBusCredentials *credentials; credentials = _dbus_credentials_new (); if (unix_uid != DBUS_UID_UNSET) { if (!_dbus_credentials_add_unix_uid (credentials, unix_uid)) { _dbus_credentials_unref (credentials); return NULL; } } if (pid != DBUS_PID_UNSET) { if (!_dbus_credentials_add_pid (credentials, pid)) { _dbus_credentials_unref (credentials); return NULL; } } if (windows_sid != NULL) { if (!_dbus_credentials_add_windows_sid (credentials, windows_sid)) { _dbus_credentials_unref (credentials); return NULL; } } return credentials; }
/** * Creates a new object with credentials (user ID and process ID) from the current process. * @returns the new object or #NULL if no memory */ DBusCredentials* _dbus_credentials_new_from_current_process (void) { DBusCredentials *creds; creds = _dbus_credentials_new (); if (creds == NULL) return NULL; if (!_dbus_credentials_add_from_current_process (creds)) { _dbus_credentials_unref (creds); return NULL; } return creds; }
/** * Copy a credentials object. * * @param credentials the object * @returns the copy or #NULL */ DBusCredentials* _dbus_credentials_copy (DBusCredentials *credentials) { DBusCredentials *copy; copy = _dbus_credentials_new (); if (copy == NULL) return NULL; if (!_dbus_credentials_add_credentials (copy, credentials)) { _dbus_credentials_unref (copy); return NULL; } return copy; }
static void auth_set_unix_credentials(DBusAuth *auth, dbus_uid_t uid, dbus_pid_t pid) { DBusCredentials *credentials; credentials = _dbus_credentials_new (); if (credentials == NULL) _dbus_assert_not_reached ("no memory"); if (uid != DBUS_UID_UNSET) _dbus_credentials_add_unix_uid (credentials, uid); if (pid != DBUS_PID_UNSET) _dbus_credentials_add_pid (credentials, pid); _dbus_auth_set_credentials (auth, credentials); _dbus_credentials_unref (credentials); }
/** * Finalizes base class members of DBusTransport. * Chained up to from subclass finalizers. * * @param transport the transport. */ void _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); _dbus_counter_set_notify (transport->live_messages_size, 0, NULL, NULL); _dbus_counter_unref (transport->live_messages_size); dbus_free (transport->address); dbus_free (transport->expected_guid); if (transport->credentials) _dbus_credentials_unref (transport->credentials); }
/* This code only gets executed the first time the * config files are parsed. It is not executed * when config files are reloaded. */ static dbus_bool_t process_config_first_time_only (BusContext *context, BusConfigParser *parser, const DBusString *address, BusContextFlags flags, DBusError *error) { DBusString log_prefix; DBusList *link; DBusList **addresses; const char *user, *pidfile; char **auth_mechanisms; DBusList **auth_mechanisms_list; int len; dbus_bool_t retval; _DBUS_ASSERT_ERROR_IS_CLEAR (error); retval = FALSE; auth_mechanisms = NULL; pidfile = NULL; _dbus_init_system_log (TRUE); if (flags & BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION) context->systemd_activation = TRUE; else context->systemd_activation = FALSE; /* Check for an existing pid file. Of course this is a race; * we'd have to use fcntl() locks on the pid file to * avoid that. But we want to check for the pid file * before overwriting any existing sockets, etc. */ if (flags & BUS_CONTEXT_FLAG_WRITE_PID_FILE) pidfile = bus_config_parser_get_pidfile (parser); if (pidfile != NULL) { DBusString u; DBusStat stbuf; _dbus_string_init_const (&u, pidfile); if (_dbus_stat (&u, &stbuf, NULL)) { #ifdef DBUS_CYGWIN DBusString p; long /* int */ pid; _dbus_string_init (&p); _dbus_file_get_contents(&p, &u, NULL); _dbus_string_parse_int(&p, 0, &pid, NULL); _dbus_string_free(&p); if ((kill((int)pid, 0))) { dbus_set_error(NULL, DBUS_ERROR_FILE_EXISTS, "pid %ld not running, removing stale pid file\n", pid); _dbus_delete_file(&u, NULL); } else { #endif dbus_set_error (error, DBUS_ERROR_FAILED, "The pid file \"%s\" exists, if the message bus is not running, remove this file", pidfile); goto failed; #ifdef DBUS_CYGWIN } #endif } } /* keep around the pid filename so we can delete it later */ context->pidfile = _dbus_strdup (pidfile); /* note that type may be NULL */ context->type = _dbus_strdup (bus_config_parser_get_type (parser)); if (bus_config_parser_get_type (parser) != NULL && context->type == NULL) goto oom; user = bus_config_parser_get_user (parser); if (user != NULL) { context->user = _dbus_strdup (user); if (context->user == NULL) goto oom; } /* Set up the prefix for syslog messages */ if (!_dbus_string_init (&log_prefix)) goto oom; if (context->type && !strcmp (context->type, "system")) { if (!_dbus_string_append (&log_prefix, "[system] ")) goto oom; } else if (context->type && !strcmp (context->type, "session")) { DBusCredentials *credentials; credentials = _dbus_credentials_new_from_current_process (); if (!credentials) goto oom; if (!_dbus_string_append (&log_prefix, "[session ")) { _dbus_credentials_unref (credentials); goto oom; } if (!_dbus_credentials_to_string_append (credentials, &log_prefix)) { _dbus_credentials_unref (credentials); goto oom; } if (!_dbus_string_append (&log_prefix, "] ")) { _dbus_credentials_unref (credentials); goto oom; } _dbus_credentials_unref (credentials); } if (!_dbus_string_steal_data (&log_prefix, &context->log_prefix)) goto oom; _dbus_string_free (&log_prefix); /* Build an array of auth mechanisms */ auth_mechanisms_list = bus_config_parser_get_mechanisms (parser); len = _dbus_list_get_length (auth_mechanisms_list); if (len > 0) { int i; auth_mechanisms = dbus_new0 (char*, len + 1); if (auth_mechanisms == NULL) goto oom; i = 0; link = _dbus_list_get_first_link (auth_mechanisms_list); while (link != NULL) { auth_mechanisms[i] = _dbus_strdup (link->data); if (auth_mechanisms[i] == NULL) goto oom; link = _dbus_list_get_next_link (auth_mechanisms_list, link); i += 1; } }
/** * Initializes the base class members of DBusTransport. Chained up to * by subclasses in their constructor. The server GUID is the * globally unique ID for the server creating this connection * and will be #NULL for the client side of a connection. The GUID * is in hex format. * * @param transport the transport being created. * @param vtable the subclass vtable. * @param server_guid non-#NULL if this transport is on the server side of a connection * @param address the address of the transport * @returns #TRUE on success. */ dbus_bool_t _dbus_transport_init_base (DBusTransport *transport, const DBusTransportVTable *vtable, const DBusString *server_guid, const DBusString *address) { DBusMessageLoader *loader; DBusAuth *auth; DBusCounter *counter; char *address_copy; DBusCredentials *creds; loader = _dbus_message_loader_new (); if (loader == NULL) return FALSE; if (server_guid) auth = _dbus_auth_server_new (server_guid); else auth = _dbus_auth_client_new (); if (auth == NULL) { _dbus_message_loader_unref (loader); return FALSE; } counter = _dbus_counter_new (); if (counter == NULL) { _dbus_auth_unref (auth); _dbus_message_loader_unref (loader); return FALSE; } creds = _dbus_credentials_new (); if (creds == NULL) { _dbus_counter_unref (counter); _dbus_auth_unref (auth); _dbus_message_loader_unref (loader); return FALSE; } 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); _dbus_message_loader_unref (loader); return FALSE; } } transport->refcount = 1; transport->vtable = vtable; transport->loader = loader; transport->auth = auth; transport->live_messages_size = counter; transport->authenticated = FALSE; transport->disconnected = FALSE; transport->is_server = (server_guid != NULL); 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, * but doesn't impose too much of a limitation. */ transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63; /* credentials read from socket if any */ transport->credentials = creds; _dbus_counter_set_notify (transport->live_messages_size, transport->max_live_messages_size, live_messages_size_notify, transport); if (transport->address) _dbus_verbose ("Initialized transport on address %s\n", transport->address); return TRUE; }
dbus_bool_t _dbus_credentials_test (const char *test_data_dir) { DBusCredentials *creds; DBusCredentials *creds2; if (test_data_dir == NULL) return TRUE; creds = make_credentials (12, 511, SAMPLE_SID); if (creds == NULL) _dbus_assert_not_reached ("oom"); /* test refcounting */ _dbus_credentials_ref (creds); _dbus_credentials_unref (creds); _dbus_assert (_dbus_credentials_include (creds, DBUS_CREDENTIAL_UNIX_USER_ID)); _dbus_assert (_dbus_credentials_include (creds, DBUS_CREDENTIAL_UNIX_PROCESS_ID)); _dbus_assert (_dbus_credentials_include (creds, DBUS_CREDENTIAL_WINDOWS_SID)); _dbus_assert (_dbus_credentials_get_unix_uid (creds) == 12); _dbus_assert (_dbus_credentials_get_pid (creds) == 511); _dbus_assert (strcmp (_dbus_credentials_get_windows_sid (creds), SAMPLE_SID) == 0); _dbus_assert (!_dbus_credentials_are_empty (creds)); _dbus_assert (!_dbus_credentials_are_anonymous (creds)); /* Test copy */ creds2 = _dbus_credentials_copy (creds); if (creds2 == NULL) _dbus_assert_not_reached ("oom"); _dbus_assert (_dbus_credentials_include (creds2, DBUS_CREDENTIAL_UNIX_USER_ID)); _dbus_assert (_dbus_credentials_include (creds2, DBUS_CREDENTIAL_UNIX_PROCESS_ID)); _dbus_assert (_dbus_credentials_include (creds2, DBUS_CREDENTIAL_WINDOWS_SID)); _dbus_assert (_dbus_credentials_get_unix_uid (creds2) == 12); _dbus_assert (_dbus_credentials_get_pid (creds2) == 511); _dbus_assert (strcmp (_dbus_credentials_get_windows_sid (creds2), SAMPLE_SID) == 0); _dbus_assert (_dbus_credentials_are_superset (creds, creds2)); _dbus_credentials_unref (creds2); /* Same user if both unix and windows are the same */ creds2 = make_credentials (12, DBUS_PID_UNSET, SAMPLE_SID); if (creds2 == NULL) _dbus_assert_not_reached ("oom"); _dbus_assert (_dbus_credentials_same_user (creds, creds2)); _dbus_credentials_unref (creds2); /* Not the same user if Windows is missing */ creds2 = make_credentials (12, DBUS_PID_UNSET, NULL); if (creds2 == NULL) _dbus_assert_not_reached ("oom"); _dbus_assert (!_dbus_credentials_same_user (creds, creds2)); _dbus_assert (_dbus_credentials_are_superset (creds, creds2)); _dbus_credentials_unref (creds2); /* Not the same user if Windows is different */ creds2 = make_credentials (12, DBUS_PID_UNSET, OTHER_SAMPLE_SID); if (creds2 == NULL) _dbus_assert_not_reached ("oom"); _dbus_assert (!_dbus_credentials_same_user (creds, creds2)); _dbus_assert (!_dbus_credentials_are_superset (creds, creds2)); _dbus_credentials_unref (creds2); /* Not the same user if Unix is missing */ creds2 = make_credentials (DBUS_UID_UNSET, DBUS_PID_UNSET, SAMPLE_SID); if (creds2 == NULL) _dbus_assert_not_reached ("oom"); _dbus_assert (!_dbus_credentials_same_user (creds, creds2)); _dbus_assert (_dbus_credentials_are_superset (creds, creds2)); _dbus_credentials_unref (creds2); /* Not the same user if Unix is different */ creds2 = make_credentials (15, DBUS_PID_UNSET, SAMPLE_SID); if (creds2 == NULL) _dbus_assert_not_reached ("oom"); _dbus_assert (!_dbus_credentials_same_user (creds, creds2)); _dbus_assert (!_dbus_credentials_are_superset (creds, creds2)); _dbus_credentials_unref (creds2); /* Not the same user if both are missing */ creds2 = make_credentials (DBUS_UID_UNSET, DBUS_PID_UNSET, NULL); if (creds2 == NULL) _dbus_assert_not_reached ("oom"); _dbus_assert (!_dbus_credentials_same_user (creds, creds2)); _dbus_assert (_dbus_credentials_are_superset (creds, creds2)); _dbus_credentials_unref (creds2); /* Clearing credentials works */ _dbus_credentials_clear (creds); _dbus_assert (!_dbus_credentials_include (creds, DBUS_CREDENTIAL_UNIX_USER_ID)); _dbus_assert (!_dbus_credentials_include (creds, DBUS_CREDENTIAL_UNIX_PROCESS_ID)); _dbus_assert (!_dbus_credentials_include (creds, DBUS_CREDENTIAL_WINDOWS_SID)); _dbus_assert (_dbus_credentials_get_unix_uid (creds) == DBUS_UID_UNSET); _dbus_assert (_dbus_credentials_get_pid (creds) == DBUS_PID_UNSET); _dbus_assert (_dbus_credentials_get_windows_sid (creds) == NULL); _dbus_assert (_dbus_credentials_are_empty (creds)); _dbus_assert (_dbus_credentials_are_anonymous (creds)); _dbus_credentials_unref (creds); return TRUE; }
/** * Runs an "auth script" which is a script for testing the * authentication protocol. Scripts send and receive data, and then * include assertions about the state of both ends of the connection * after processing the data. A script succeeds if these assertions * hold. * * @param filename the file containing the script to run * @returns #TRUE if the script succeeds, #FALSE otherwise */ dbus_bool_t _dbus_auth_script_run (const DBusString *filename) { DBusString file; DBusError error = DBUS_ERROR_INIT; DBusString line; dbus_bool_t retval; int line_no; DBusAuth *auth; DBusString from_auth; DBusAuthState state; DBusString context; DBusString guid; retval = FALSE; auth = NULL; _dbus_string_init_const (&guid, "5fa01f4202cd837709a3274ca0df9d00"); _dbus_string_init_const (&context, "org_freedesktop_test"); if (!_dbus_string_init (&file)) return FALSE; if (!_dbus_string_init (&line)) { _dbus_string_free (&file); return FALSE; } if (!_dbus_string_init (&from_auth)) { _dbus_string_free (&file); _dbus_string_free (&line); return FALSE; } if (!_dbus_file_get_contents (&file, filename, &error)) { _dbus_warn ("Getting contents of %s failed: %s\n", _dbus_string_get_const_data (filename), error.message); dbus_error_free (&error); goto out; } 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) { while ((state = _dbus_auth_do_work (auth)) == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND) { const DBusString *tmp; if (_dbus_auth_get_bytes_to_send (auth, &tmp)) { int count = _dbus_string_get_length (tmp); if (_dbus_string_copy (tmp, 0, &from_auth, _dbus_string_get_length (&from_auth))) _dbus_auth_bytes_sent (auth, count); } } } if (_dbus_string_get_length (&line) == 0) { /* empty line */ goto next_iteration; } else if (_dbus_string_starts_with_c_str (&line, "#")) { /* Ignore this comment */ goto next_iteration; } #ifdef DBUS_WIN else if (_dbus_string_starts_with_c_str (&line, "WIN_ONLY")) { /* Ignore this line */ goto next_iteration; } else if (_dbus_string_starts_with_c_str (&line, "UNIX_ONLY")) { /* skip this file */ _dbus_warn ("skipping unix only auth script\n"); retval = TRUE; goto out; } #endif #ifdef DBUS_UNIX else if (_dbus_string_starts_with_c_str (&line, "UNIX_ONLY")) { /* Ignore this line */ goto next_iteration; } else if (_dbus_string_starts_with_c_str (&line, "WIN_ONLY")) { /* skip this file */ _dbus_warn ("skipping windows only auth script\n"); retval = TRUE; goto out; } #endif 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"); goto out; } auth = _dbus_auth_client_new (); if (auth == NULL) { _dbus_warn ("no memory to create DBusAuth\n"); goto out; } /* test ref/unref */ _dbus_auth_ref (auth); _dbus_auth_unref (auth); creds = _dbus_credentials_new_from_current_process (); if (creds == NULL) { _dbus_warn ("no memory for credentials\n"); _dbus_auth_unref (auth); auth = NULL; goto out; } if (!_dbus_auth_set_credentials (auth, creds)) { _dbus_warn ("no memory for setting credentials\n"); _dbus_auth_unref (auth); auth = NULL; _dbus_credentials_unref (creds); goto out; } _dbus_credentials_unref (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"); goto out; } auth = _dbus_auth_server_new (&guid); if (auth == NULL) { _dbus_warn ("no memory to create DBusAuth\n"); goto out; } /* test ref/unref */ _dbus_auth_ref (auth); _dbus_auth_unref (auth); creds = _dbus_credentials_new_from_current_process (); if (creds == NULL) { _dbus_warn ("no memory for credentials\n"); _dbus_auth_unref (auth); auth = NULL; goto out; } if (!_dbus_auth_set_credentials (auth, creds)) { _dbus_warn ("no memory for setting credentials\n"); _dbus_auth_unref (auth); auth = NULL; _dbus_credentials_unref (creds); goto out; } _dbus_credentials_unref (creds); _dbus_auth_set_context (auth, &context); } else if (auth == NULL) { _dbus_warn ("must specify CLIENT or SERVER\n"); goto out; } else if (_dbus_string_starts_with_c_str (&line, "NO_CREDENTIALS")) { auth_set_unix_credentials (auth, DBUS_UID_UNSET, DBUS_PID_UNSET); } else if (_dbus_string_starts_with_c_str (&line, "ROOT_CREDENTIALS")) { auth_set_unix_credentials (auth, 0, DBUS_PID_UNSET); } else if (_dbus_string_starts_with_c_str (&line, "SILLY_CREDENTIALS")) { auth_set_unix_credentials (auth, 4312, DBUS_PID_UNSET); } else if (_dbus_string_starts_with_c_str (&line, "ALLOWED_MECHS")) { char **mechs; _dbus_string_delete_first_word (&line); mechs = split_string (&line); _dbus_auth_set_mechanisms (auth, (const char **) mechs); dbus_free_string_array (mechs); } else if (_dbus_string_starts_with_c_str (&line, "SEND")) { DBusString to_send; _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&to_send)) { _dbus_warn ("no memory to allocate string\n"); goto out; } if (!append_quoted_string (&to_send, &line)) { _dbus_warn ("failed to append quoted string line %d\n", line_no); _dbus_string_free (&to_send); goto out; } _dbus_verbose ("Sending '%s'\n", _dbus_string_get_const_data (&to_send)); if (!_dbus_string_append (&to_send, "\r\n")) { _dbus_warn ("failed to append \r\n from line %d\n", line_no); _dbus_string_free (&to_send); goto out; } /* Replace USERID_HEX with our username in hex */ { int where; if (_dbus_string_find (&to_send, 0, "USERID_HEX", &where)) { DBusString username; if (!_dbus_string_init (&username)) { _dbus_warn ("no memory for userid\n"); _dbus_string_free (&to_send); goto out; } if (!_dbus_append_user_from_current_process (&username)) { _dbus_warn ("no memory for userid\n"); _dbus_string_free (&username); _dbus_string_free (&to_send); goto out; } _dbus_string_delete (&to_send, where, (int) strlen ("USERID_HEX")); if (!_dbus_string_hex_encode (&username, 0, &to_send, where)) { _dbus_warn ("no memory to subst USERID_HEX\n"); _dbus_string_free (&username); _dbus_string_free (&to_send); goto out; } _dbus_string_free (&username); } else if (_dbus_string_find (&to_send, 0, "USERNAME_HEX", &where)) { DBusString username; if (!_dbus_string_init (&username)) { _dbus_warn ("no memory for username\n"); _dbus_string_free (&to_send); goto out; } if (!_dbus_append_user_from_current_process (&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, (int) strlen ("USERNAME_HEX")); if (!_dbus_string_hex_encode (&username, 0, &to_send, where)) { _dbus_warn ("no memory to subst USERNAME_HEX\n"); _dbus_string_free (&username); _dbus_string_free (&to_send); goto out; } _dbus_string_free (&username); } } { DBusString *buffer; _dbus_auth_get_buffer (auth, &buffer); if (!_dbus_string_copy (&to_send, 0, buffer, _dbus_string_get_length (buffer))) { _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); _dbus_auth_return_buffer (auth, buffer); goto out; } _dbus_auth_return_buffer (auth, buffer); } _dbus_string_free (&to_send); } else if (_dbus_string_starts_with_c_str (&line, "EXPECT_STATE")) { DBusAuthState expected; _dbus_string_delete_first_word (&line); expected = auth_state_from_string (&line); if (expected < 0) { _dbus_warn ("bad auth state given to EXPECT_STATE\n"); goto parse_failed; } if (expected != state) { _dbus_warn ("expected auth state %s but got %s on line %d\n", auth_state_to_string (expected), auth_state_to_string (state), line_no); goto out; } } else if (_dbus_string_starts_with_c_str (&line, "EXPECT_COMMAND")) { DBusString received; _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&received)) { _dbus_warn ("no mem to allocate string received\n"); goto out; } if (!_dbus_string_pop_line (&from_auth, &received)) { _dbus_warn ("no line popped from the DBusAuth being tested, expected command %s on line %d\n", _dbus_string_get_const_data (&line), line_no); _dbus_string_free (&received); goto out; } if (!same_first_word (&received, &line)) { _dbus_warn ("line %d expected command '%s' and got '%s'\n", line_no, _dbus_string_get_const_data (&line), _dbus_string_get_const_data (&received)); _dbus_string_free (&received); goto out; } _dbus_string_free (&received); } else if (_dbus_string_starts_with_c_str (&line, "EXPECT_UNUSED")) { DBusString expected; const DBusString *unused; _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&expected)) { _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; } _dbus_auth_get_unused_bytes (auth, &unused); if (_dbus_string_equal (&expected, unused)) { _dbus_auth_delete_unused_bytes (auth); _dbus_string_free (&expected); } else { _dbus_warn ("Expected unused bytes '%s' and have '%s'\n", _dbus_string_get_const_data (&expected), _dbus_string_get_const_data (unused)); _dbus_string_free (&expected); goto out; } } 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_anonymous (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_anonymous (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; _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&expected)) { _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 { _dbus_warn ("Expected exact string '%s' and have '%s'\n", _dbus_string_get_const_data (&expected), _dbus_string_get_const_data (&from_auth)); _dbus_string_free (&expected); goto out; } } else goto parse_failed; goto next_iteration; /* skip parse_failed */ parse_failed: { _dbus_warn ("couldn't process line %d \"%s\"\n", line_no, _dbus_string_get_const_data (&line)); goto out; } } 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; _dbus_auth_get_unused_bytes (auth, &unused); if (_dbus_string_get_length (unused) > 0) { _dbus_warn ("did not expect unused bytes (scripts must specify explicitly if they are expected)\n"); goto out; } } if (_dbus_string_get_length (&from_auth) > 0) { _dbus_warn ("script did not have EXPECT_ statements for all the data received from the DBusAuth\n"); _dbus_warn ("Leftover data: %s\n", _dbus_string_get_const_data (&from_auth)); goto out; } retval = TRUE; out: if (auth) _dbus_auth_unref (auth); _dbus_string_free (&file); _dbus_string_free (&line); _dbus_string_free (&from_auth); return retval; }
/* This code only gets executed the first time the * config files are parsed. It is not executed * when config files are reloaded. */ static dbus_bool_t process_config_first_time_only (BusContext *context, BusConfigParser *parser, DBusError *error) { DBusString log_prefix; DBusList *link; DBusList **addresses; const char *user, *pidfile; char **auth_mechanisms; DBusList **auth_mechanisms_list; int len; dbus_bool_t retval; _DBUS_ASSERT_ERROR_IS_CLEAR (error); retval = FALSE; auth_mechanisms = NULL; /* Check for an existing pid file. Of course this is a race; * we'd have to use fcntl() locks on the pid file to * avoid that. But we want to check for the pid file * before overwriting any existing sockets, etc. */ pidfile = bus_config_parser_get_pidfile (parser); if (pidfile != NULL) { DBusString u; DBusStat stbuf; _dbus_string_init_const (&u, pidfile); if (_dbus_stat (&u, &stbuf, NULL)) { dbus_set_error (error, DBUS_ERROR_FAILED, "The pid file \"%s\" exists, if the message bus is not running, remove this file", pidfile); goto failed; } } /* keep around the pid filename so we can delete it later */ context->pidfile = _dbus_strdup (pidfile); /* note that type may be NULL */ context->type = _dbus_strdup (bus_config_parser_get_type (parser)); if (bus_config_parser_get_type (parser) != NULL && context->type == NULL) goto oom; user = bus_config_parser_get_user (parser); if (user != NULL) { context->user = _dbus_strdup (user); if (context->user == NULL) goto oom; } /* Set up the prefix for syslog messages */ if (!_dbus_string_init (&log_prefix)) goto oom; if (context->type && !strcmp (context->type, "system")) { if (!_dbus_string_append (&log_prefix, "[system] ")) goto oom; } else if (context->type && !strcmp (context->type, "session")) { DBusCredentials *credentials; credentials = _dbus_credentials_new_from_current_process (); if (!credentials) goto oom; if (!_dbus_string_append (&log_prefix, "[session ")) goto oom; if (!_dbus_credentials_to_string_append (credentials, &log_prefix)) goto oom; if (!_dbus_string_append (&log_prefix, "] ")) goto oom; _dbus_credentials_unref (credentials); } if (!_dbus_string_steal_data (&log_prefix, &context->log_prefix)) goto oom; _dbus_string_free (&log_prefix); /* Build an array of auth mechanisms */ auth_mechanisms_list = bus_config_parser_get_mechanisms (parser); len = _dbus_list_get_length (auth_mechanisms_list); if (len > 0) { int i; auth_mechanisms = dbus_new0 (char*, len + 1); if (auth_mechanisms == NULL) goto oom; i = 0; link = _dbus_list_get_first_link (auth_mechanisms_list); while (link != NULL) { auth_mechanisms[i] = _dbus_strdup (link->data); if (auth_mechanisms[i] == NULL) goto oom; link = _dbus_list_get_next_link (auth_mechanisms_list, link); } }