static dbus_bool_t handle_reload_watch (DBusWatch *watch, unsigned int flags, void *data) { DBusError error; DBusString str; _dbus_string_init (&str); if (_dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1) { _dbus_warn ("Couldn't read from reload pipe.\n"); exit (1); } _dbus_string_free (&str); dbus_error_init (&error); if (! bus_context_reload_config (context, &error)) { _dbus_warn ("Unable to reload configuration: %s\n", error.message); dbus_error_free (&error); exit (1); } return TRUE; }
static dbus_bool_t handle_reload_watch (DBusWatch *watch, unsigned int flags, void *data) { DBusError error; DBusString str; _dbus_string_init (&str); if ((reload_pipe[RELOAD_READ_END] > 0) && _dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1) { _dbus_warn ("Couldn't read from reload pipe.\n"); close_reload_pipe (); return TRUE; } _dbus_string_free (&str); /* this can only fail if we don't understand the config file * or OOM. Either way we should just stick with the currently * loaded config. */ dbus_error_init (&error); if (! bus_context_reload_config (context, &error)) { _DBUS_ASSERT_ERROR_IS_SET (&error); _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) || dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)); _dbus_warn ("Unable to reload configuration: %s\n", error.message); dbus_error_free (&error); } return TRUE; }
static dbus_bool_t do_check_nonce (int fd, const DBusString *nonce, DBusError *error) { DBusString buffer; DBusString p; size_t nleft; dbus_bool_t result; int n; _DBUS_ASSERT_ERROR_IS_CLEAR (error); nleft = 16; if ( !_dbus_string_init (&buffer) || !_dbus_string_init (&p) ) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); _dbus_string_free (&p); _dbus_string_free (&buffer); return FALSE; } while (nleft) { n = _dbus_read_socket (fd, &p, nleft); if (n == -1 && _dbus_get_is_errno_eintr()) ; else if (n == -1 && _dbus_get_is_errno_eagain_or_ewouldblock()) _dbus_sleep_milliseconds (100); else if (n==-1) { dbus_set_error (error, DBUS_ERROR_IO_ERROR, "Could not read nonce from socket (fd=%d)", fd ); _dbus_string_free (&p); _dbus_string_free (&buffer); return FALSE; } else if (!n) { _dbus_string_free (&p); _dbus_string_free (&buffer); dbus_set_error (error, DBUS_ERROR_IO_ERROR, "Could not read nonce from socket (fd=%d)", fd ); return FALSE; } else { _dbus_string_append_len(&buffer, _dbus_string_get_const_data (&p), n); nleft -= n; } } result = _dbus_string_equal_len (&buffer, nonce, 16); if (!result) dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "Nonces do not match, access denied (fd=%d)", fd ); _dbus_string_free (&p); _dbus_string_free (&buffer); return result; }
/* return value is whether we successfully read any new data. */ static dbus_bool_t read_data_into_auth (DBusTransport *transport, dbus_bool_t *oom) { DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; DBusString *buffer; int bytes_read; int saved_errno; *oom = FALSE; _dbus_auth_get_buffer (transport->auth, &buffer); bytes_read = _dbus_read_socket (socket_transport->fd, buffer, socket_transport->max_bytes_read_per_iteration); saved_errno = _dbus_save_socket_errno (); _dbus_auth_return_buffer (transport->auth, buffer); if (bytes_read > 0) { _dbus_verbose (" read %d bytes in auth phase\n", bytes_read); return TRUE; } else if (bytes_read < 0) { /* EINTR already handled for us */ if (_dbus_get_is_errno_enomem (saved_errno)) { *oom = TRUE; } else if (_dbus_get_is_errno_eagain_or_ewouldblock (saved_errno)) ; /* do nothing, just return FALSE below */ else { _dbus_verbose ("Error reading from remote app: %s\n", _dbus_strerror (saved_errno)); do_io_error (transport); } return FALSE; } else { _dbus_assert (bytes_read == 0); _dbus_verbose ("Disconnected from remote app\n"); do_io_error (transport); return FALSE; } }
static dbus_bool_t handle_reload_watch (DBusWatch *watch, unsigned int flags, void *data) { DBusError error; DBusString str; char *action_str; char action = '\0'; while (!_dbus_string_init (&str)) _dbus_wait_for_memory (); if ((reload_pipe[RELOAD_READ_END] > 0) && _dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1) { _dbus_warn ("Couldn't read from reload pipe.\n"); close_reload_pipe (&watch); return TRUE; } action_str = _dbus_string_get_data (&str); if (action_str != NULL) { action = action_str[0]; } _dbus_string_free (&str); /* this can only fail if we don't understand the config file * or OOM. Either way we should just stick with the currently * loaded config. */ dbus_error_init (&error); switch (action) { case ACTION_RELOAD: if (! bus_context_reload_config (context, &error)) { _DBUS_ASSERT_ERROR_IS_SET (&error); _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) || dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)); _dbus_warn ("Unable to reload configuration: %s\n", error.message); dbus_error_free (&error); } break; case ACTION_QUIT: { DBusLoop *loop; /* * On OSs without abstract sockets, we want to quit * gracefully rather than being killed by SIGTERM, * so that DBusServer gets a chance to clean up the * sockets from the filesystem. fd.o #38656 */ loop = bus_context_get_loop (context); if (loop != NULL) { _dbus_loop_quit (loop); } } break; default: break; } return TRUE; }
/* returns false on out-of-memory */ static dbus_bool_t do_reading (DBusTransport *transport) { DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport; DBusString *buffer; int bytes_read; int total; dbus_bool_t oom; int saved_errno; _dbus_verbose ("fd = %" DBUS_SOCKET_FORMAT "\n", _dbus_socket_printable (socket_transport->fd)); /* No messages without authentication! */ if (!_dbus_transport_try_to_authenticate (transport)) return TRUE; oom = FALSE; total = 0; again: /* See if we've exceeded max messages and need to disable reading */ check_read_watch (transport); if (total > socket_transport->max_bytes_read_per_iteration) { _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n", total, socket_transport->max_bytes_read_per_iteration); goto out; } _dbus_assert (socket_transport->read_watch != NULL || transport->disconnected); if (transport->disconnected) goto out; if (!dbus_watch_get_enabled (socket_transport->read_watch)) return TRUE; if (_dbus_auth_needs_decoding (transport->auth)) { /* Does fd passing even make sense with encoded data? */ _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)); if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0) bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming); else bytes_read = _dbus_read_socket (socket_transport->fd, &socket_transport->encoded_incoming, socket_transport->max_bytes_read_per_iteration); saved_errno = _dbus_save_socket_errno (); _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) == bytes_read); if (bytes_read > 0) { _dbus_message_loader_get_buffer (transport->loader, &buffer); if (!_dbus_auth_decode_data (transport->auth, &socket_transport->encoded_incoming, buffer)) { _dbus_verbose ("Out of memory decoding incoming data\n"); _dbus_message_loader_return_buffer (transport->loader, buffer); oom = TRUE; goto out; } _dbus_message_loader_return_buffer (transport->loader, buffer); _dbus_string_set_length (&socket_transport->encoded_incoming, 0); _dbus_string_compact (&socket_transport->encoded_incoming, 2048); } } else { _dbus_message_loader_get_buffer (transport->loader, &buffer); #ifdef HAVE_UNIX_FD_PASSING if (DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport)) { int *fds; unsigned int n_fds; if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds)) { _dbus_verbose ("Out of memory reading file descriptors\n"); _dbus_message_loader_return_buffer (transport->loader, buffer); oom = TRUE; goto out; } bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd, buffer, socket_transport->max_bytes_read_per_iteration, fds, &n_fds); saved_errno = _dbus_save_socket_errno (); if (bytes_read >= 0 && n_fds > 0) _dbus_verbose("Read %i unix fds\n", n_fds); _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds); } else #endif { bytes_read = _dbus_read_socket (socket_transport->fd, buffer, socket_transport->max_bytes_read_per_iteration); saved_errno = _dbus_save_socket_errno (); } _dbus_message_loader_return_buffer (transport->loader, buffer); } if (bytes_read < 0) { /* EINTR already handled for us */ if (_dbus_get_is_errno_enomem (saved_errno)) { _dbus_verbose ("Out of memory in read()/do_reading()\n"); oom = TRUE; goto out; } else if (_dbus_get_is_errno_eagain_or_ewouldblock (saved_errno)) goto out; else { _dbus_verbose ("Error reading from remote app: %s\n", _dbus_strerror (saved_errno)); do_io_error (transport); goto out; } } else if (bytes_read == 0) { _dbus_verbose ("Disconnected from remote app\n"); do_io_error (transport); goto out; } else { _dbus_verbose (" read %d bytes\n", bytes_read); total += bytes_read; if (!_dbus_transport_queue_messages (transport)) { oom = TRUE; _dbus_verbose (" out of memory when queueing messages we just read in the transport\n"); goto out; } /* Try reading more data until we get EAGAIN and return, or * exceed max bytes per iteration. If in blocking mode of * course we'll block instead of returning. */ goto again; } out: if (oom) return FALSE; else return TRUE; }
static dbus_bool_t do_check_nonce (DBusSocket fd, const DBusString *nonce, DBusError *error) { DBusString buffer; DBusString p; size_t nleft; dbus_bool_t result; int n; _DBUS_ASSERT_ERROR_IS_CLEAR (error); nleft = 16; /* This is a trick to make it safe to call _dbus_string_free on these * strings during error unwinding, even if allocating memory for them * fails. A constant DBusString is considered to be valid to "free", * even though there is nothing to free (of course the free operation * is trivial, because it does not own its own buffer); but * unlike a mutable DBusString, initializing a constant DBusString * cannot fail. * * We must successfully re-initialize the strings to be mutable before * writing to them, of course. */ _dbus_string_init_const (&buffer, ""); _dbus_string_init_const (&p, ""); if ( !_dbus_string_init (&buffer) || !_dbus_string_init (&p) ) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); _dbus_string_free (&p); _dbus_string_free (&buffer); return FALSE; } while (nleft) { int saved_errno; n = _dbus_read_socket (fd, &p, nleft); saved_errno = _dbus_save_socket_errno (); if (n == -1 && _dbus_get_is_errno_eintr (saved_errno)) ; else if (n == -1 && _dbus_get_is_errno_eagain_or_ewouldblock (saved_errno)) _dbus_sleep_milliseconds (100); else if (n==-1) { dbus_set_error (error, DBUS_ERROR_IO_ERROR, "Could not read nonce from socket (fd=%" DBUS_SOCKET_FORMAT ")", _dbus_socket_printable (fd)); _dbus_string_free (&p); _dbus_string_free (&buffer); return FALSE; } else if (!n) { _dbus_string_free (&p); _dbus_string_free (&buffer); dbus_set_error (error, DBUS_ERROR_IO_ERROR, "Could not read nonce from socket (fd=%" DBUS_SOCKET_FORMAT ")", _dbus_socket_printable (fd)); return FALSE; } else { if (!_dbus_string_append_len (&buffer, _dbus_string_get_const_data (&p), n)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); _dbus_string_free (&p); _dbus_string_free (&buffer); return FALSE; } nleft -= n; } } result = _dbus_string_equal_len (&buffer, nonce, 16); if (!result) dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "Nonces do not match, access denied (fd=%" DBUS_SOCKET_FORMAT ")", _dbus_socket_printable (fd)); _dbus_string_free (&p); _dbus_string_free (&buffer); return result; }