diff options
39 files changed, 847 insertions, 244 deletions
@@ -1,3 +1,30 @@ +2003-03-31 Havoc Pennington <hp@pobox.com> + + * dbus/dbus-transport-unix.c (_dbus_transport_new_for_domain_socket) + (_dbus_transport_new_for_tcp_socket): these didn't need the "server" + argument since they are always client side + + * dbus/dbus-server.c (dbus_server_get_address): new function + + * bus/main.c (main): take the configuration file as an argument. + + * test/data/valid-config-files/debug-allow-all.conf: new file to + use with dispatch.c tests for example + + * bus/test-main.c (main): require test data dir + + * bus/bus.c (bus_context_new): change this to take a + configuration file name as argument + + * doc/config-file.txt (Elements): add <servicedir> + + * bus/system.conf, bus/session.conf: new files + + * dbus/dbus-bus.c (dbus_bus_get): look for system bus on + well-known socket if none set + + * configure.in: create system.conf and session.conf + 2003-03-30 Havoc Pennington <hp@pobox.com> * bus/config-parser.c: hacking diff --git a/bus/Makefile.am b/bus/Makefile.am index 904e0c5e..ece0aa55 100644 --- a/bus/Makefile.am +++ b/bus/Makefile.am @@ -4,6 +4,12 @@ INCLUDES=-I$(top_srcdir) $(DBUS_BUS_CFLAGS) \ EFENCE= +configdir=$(sysconfdir)/dbus-1 + +config_DATA= \ + system.conf \ + session.conf + bin_PROGRAMS=dbus-daemon-1 if DBUS_USE_LIBXML diff --git a/bus/activation.c b/bus/activation.c index 03a01937..8def99b9 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -323,10 +323,10 @@ load_directory (BusActivation *activation, } BusActivation* -bus_activation_new (BusContext *context, - const char *address, - const char **directories, - DBusError *error) +bus_activation_new (BusContext *context, + const DBusString *address, + const char **directories, + DBusError *error) { int i; BusActivation *activation; @@ -343,9 +343,7 @@ bus_activation_new (BusContext *context, activation->refcount = 1; activation->context = context; - /* FIXME: We should split up the server addresses. */ - activation->server_address = _dbus_strdup (address); - if (activation->server_address == NULL) + if (!_dbus_string_copy_data (address, &activation->server_address)) { BUS_SET_OOM (error); goto failed; diff --git a/bus/activation.h b/bus/activation.h index 1fd416ea..fd3a72c9 100644 --- a/bus/activation.h +++ b/bus/activation.h @@ -27,19 +27,20 @@ #include <dbus/dbus.h> #include "bus.h" -BusActivation* bus_activation_new (BusContext *context, - const char *address, - const char **paths, - DBusError *error); -void bus_activation_ref (BusActivation *activation); -void bus_activation_unref (BusActivation *activation); -dbus_bool_t bus_activation_activate_service (BusActivation *activation, - DBusConnection *connection, - DBusMessage *activation_message, - const char *service_name, - DBusError *error); -dbus_bool_t bus_activation_service_created (BusActivation *activation, - const char *service_name, - DBusError *error); +BusActivation* bus_activation_new (BusContext *context, + const DBusString *address, + const char **paths, + DBusError *error); +void bus_activation_ref (BusActivation *activation); +void bus_activation_unref (BusActivation *activation); +dbus_bool_t bus_activation_activate_service (BusActivation *activation, + DBusConnection *connection, + DBusMessage *activation_message, + const char *service_name, + DBusError *error); +dbus_bool_t bus_activation_service_created (BusActivation *activation, + const char *service_name, + DBusError *error); + #endif /* BUS_ACTIVATION_H */ @@ -28,6 +28,7 @@ #include "services.h" #include "utils.h" #include "policy.h" +#include "config-parser.h" #include <dbus/dbus-list.h> #include <dbus/dbus-hash.h> #include <dbus/dbus-internals.h> @@ -36,7 +37,7 @@ struct BusContext { int refcount; char *address; - DBusServer *server; + DBusList *servers; BusConnections *connections; BusActivation *activation; BusRegistry *registry; @@ -51,24 +52,24 @@ server_watch_callback (DBusWatch *watch, unsigned int condition, void *data) { - BusContext *context = data; + DBusServer *server = data; - return dbus_server_handle_watch (context->server, watch, condition); + return dbus_server_handle_watch (server, watch, condition); } static dbus_bool_t add_server_watch (DBusWatch *watch, - BusContext *context) + void *data) { - return bus_loop_add_watch (watch, server_watch_callback, context, + return bus_loop_add_watch (watch, server_watch_callback, data, NULL); } static void remove_server_watch (DBusWatch *watch, - BusContext *context) + void *data) { - bus_loop_remove_watch (watch, server_watch_callback, context); + bus_loop_remove_watch (watch, server_watch_callback, data); } @@ -82,16 +83,16 @@ server_timeout_callback (DBusTimeout *timeout, static dbus_bool_t add_server_timeout (DBusTimeout *timeout, - BusContext *context) + void *data) { - return bus_loop_add_timeout (timeout, server_timeout_callback, context, NULL); + return bus_loop_add_timeout (timeout, server_timeout_callback, data, NULL); } static void remove_server_timeout (DBusTimeout *timeout, - BusContext *context) + void *data) { - bus_loop_remove_timeout (timeout, server_timeout_callback, context); + bus_loop_remove_timeout (timeout, server_timeout_callback, data); } static void @@ -137,37 +138,136 @@ free_rule_list_func (void *data) dbus_free (list); } +static dbus_bool_t +setup_server (BusContext *context, + DBusServer *server, + DBusError *error) +{ + dbus_server_set_new_connection_function (server, + new_connection_callback, + context, NULL); + + if (!dbus_server_set_watch_functions (server, + add_server_watch, + remove_server_watch, + NULL, + server, + NULL)) + { + BUS_SET_OOM (error); + return FALSE; + } + + if (!dbus_server_set_timeout_functions (server, + add_server_timeout, + remove_server_timeout, + NULL, + server, NULL)) + { + BUS_SET_OOM (error); + return FALSE; + } + + return TRUE; +} + BusContext* -bus_context_new (const char *address, - const char **service_dirs, - DBusError *error) +bus_context_new (const DBusString *config_file, + DBusError *error) { BusContext *context; - + DBusList *link; + DBusList **addresses; + BusConfigParser *parser; + DBusString full_address; + const char *service_dirs[] = { NULL, NULL }; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + if (!_dbus_string_init (&full_address, _DBUS_INT_MAX)) + return NULL; + + parser = NULL; + context = NULL; + + parser = bus_config_load (config_file, error); + if (parser == NULL) + goto failed; context = dbus_new0 (BusContext, 1); if (context == NULL) { BUS_SET_OOM (error); - return NULL; + goto failed; } context->refcount = 1; + + addresses = bus_config_parser_get_addresses (parser); + + link = _dbus_list_get_first_link (addresses); + while (link != NULL) + { + DBusServer *server; + + server = dbus_server_listen (link->data, error); + if (server == NULL) + goto failed; + else if (!setup_server (context, server, error)) + goto failed; - context->address = _dbus_strdup (address); - if (context->address == NULL) + if (!_dbus_list_append (&context->servers, server)) + { + BUS_SET_OOM (error); + goto failed; + } + + link = _dbus_list_get_next_link (addresses, link); + } + + /* We have to build the address backward, so that + * <listen> later in the config file have priority + */ + link = _dbus_list_get_last_link (&context->servers); + while (link != NULL) + { + char *addr; + + addr = dbus_server_get_address (link->data); + if (addr == NULL) + { + BUS_SET_OOM (error); + goto failed; + } + + if (_dbus_string_get_length (&full_address) > 0) + { + if (!_dbus_string_append (&full_address, ";")) + { + BUS_SET_OOM (error); + goto failed; + } + } + + if (!_dbus_string_append (&full_address, addr)) + { + BUS_SET_OOM (error); + goto failed; + } + + dbus_free (addr); + + link = _dbus_list_get_prev_link (&context->servers, link); + } + + if (!_dbus_string_copy_data (&full_address, &context->address)) { BUS_SET_OOM (error); goto failed; } - context->server = dbus_server_listen (address, error); - if (context->server == NULL) - goto failed; - - context->activation = bus_activation_new (context, address, service_dirs, - error); + context->activation = bus_activation_new (context, &full_address, + service_dirs, error); if (context->activation == NULL) { _DBUS_ASSERT_ERROR_IS_SET (error); @@ -205,59 +305,58 @@ bus_context_new (const char *address, BUS_SET_OOM (error); goto failed; } - - dbus_server_set_new_connection_function (context->server, - new_connection_callback, - context, NULL); - - if (!dbus_server_set_watch_functions (context->server, - (DBusAddWatchFunction) add_server_watch, - (DBusRemoveWatchFunction) remove_server_watch, - NULL, - context, - NULL)) - { - BUS_SET_OOM (error); - goto failed; - } - if (!dbus_server_set_timeout_functions (context->server, - (DBusAddTimeoutFunction) add_server_timeout, - (DBusRemoveTimeoutFunction) remove_server_timeout, - NULL, - context, NULL)) - { - BUS_SET_OOM (error); - goto failed; - } + bus_config_parser_unref (parser); + _dbus_string_free (&full_address); return context; failed: - bus_context_unref (context); + if (parser != NULL) + bus_config_parser_unref (parser); + + if (context != NULL) + bus_context_unref (context); + + _dbus_string_free (&full_address); return NULL; } -void -bus_context_shutdown (BusContext *context) +static void +shutdown_server (BusContext *context, + DBusServer *server) { - if (context->server == NULL || - !dbus_server_get_is_connected (context->server)) + if (server == NULL || + !dbus_server_get_is_connected (server)) return; - if (!dbus_server_set_watch_functions (context->server, + if (!dbus_server_set_watch_functions (server, NULL, NULL, NULL, context, NULL)) _dbus_assert_not_reached ("setting watch functions to NULL failed"); - if (!dbus_server_set_timeout_functions (context->server, + if (!dbus_server_set_timeout_functions (server, NULL, NULL, NULL, context, NULL)) _dbus_assert_not_reached ("setting timeout functions to NULL failed"); - dbus_server_disconnect (context->server); + dbus_server_disconnect (server); +} + +void +bus_context_shutdown (BusContext *context) +{ + DBusList *link; + + link = _dbus_list_get_first_link (&context->servers); + while (link != NULL) + { + shutdown_server (context, link->data); + + link = _dbus_list_get_next_link (&context->servers, link); + } } void @@ -275,6 +374,8 @@ bus_context_unref (BusContext *context) if (context->refcount == 0) { + DBusList *link; + _dbus_verbose ("Finalizing bus context %p\n", context); bus_context_shutdown (context); @@ -296,12 +397,15 @@ bus_context_unref (BusContext *context) bus_activation_unref (context->activation); context->activation = NULL; } - - if (context->server) + + link = _dbus_list_get_first_link (&context->servers); + while (link != NULL) { - dbus_server_unref (context->server); - context->server = NULL; + dbus_server_unref (link->data); + + link = _dbus_list_get_next_link (&context->servers, link); } + _dbus_list_clear (&context->servers); if (context->rules_by_uid) { @@ -38,19 +38,17 @@ typedef struct BusRegistry BusRegistry; typedef struct BusService BusService; typedef struct BusTransaction BusTransaction; -BusContext* bus_context_new (const char *address, - const char **service_dirs, - DBusError *error); -void bus_context_shutdown (BusContext *context); -void bus_context_ref (BusContext *context); -void bus_context_unref (BusContext *context); -BusRegistry* bus_context_get_registry (BusContext *context); -BusConnections* bus_context_get_connections (BusContext *context); -BusActivation* bus_context_get_activation (BusContext *context); -dbus_bool_t bus_context_allow_user (BusContext *context, - unsigned long uid); -BusPolicy* bus_context_create_connection_policy (BusContext *context, - DBusConnection *connection); - +BusContext* bus_context_new (const DBusString *config_file, + DBusError *error); +void bus_context_shutdown (BusContext *context); +void bus_context_ref (BusContext *context); +void bus_context_unref (BusContext *context); +BusRegistry* bus_context_get_registry (BusContext *context); +BusConnections* bus_context_get_connections (BusContext *context); +BusActivation* bus_context_get_activation (BusContext *context); +dbus_bool_t bus_context_allow_user (BusContext *context, + unsigned long uid); +BusPolicy* bus_context_create_connection_policy (BusContext *context, + DBusConnection *connection); #endif /* BUS_BUS_H */ diff --git a/bus/config-parser.c b/bus/config-parser.c index 972c05ac..bf4f6f7b 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -828,6 +828,13 @@ bus_config_parser_finished (BusConfigParser *parser, return FALSE; } + + if (parser->listen_on == NULL) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Configuration file needs one or more <listen> elements giving addresses"); + return FALSE; + } return TRUE; } @@ -838,6 +845,12 @@ bus_config_parser_get_user (BusConfigParser *parser) return parser->user; } +DBusList** +bus_config_parser_get_addresses (BusConfigParser *parser) +{ + return &parser->listen_on; +} + #ifdef DBUS_BUILD_TESTS #include <stdio.h> diff --git a/bus/config-parser.h b/bus/config-parser.h index 2fa651a3..8c66fa63 100644 --- a/bus/config-parser.h +++ b/bus/config-parser.h @@ -28,6 +28,7 @@ #include <dbus/dbus.h> #include <dbus/dbus-string.h> +#include <dbus/dbus-list.h> /* Whatever XML library we're using just pushes data into this API */ @@ -55,7 +56,7 @@ dbus_bool_t bus_config_parser_finished (BusConfigParser *parser, /* Functions for extracting the parse results */ const char* bus_config_parser_get_user (BusConfigParser *parser); - +DBusList** bus_config_parser_get_addresses (BusConfigParser *parser); /* Loader functions (backended off one of the XML parsers). Returns a * finished ConfigParser. diff --git a/bus/dispatch.c b/bus/dispatch.c index 2b1dc782..e75d8e6d 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -958,18 +958,17 @@ dbus_bool_t bus_dispatch_test (const DBusString *test_data_dir) { BusContext *context; - DBusError error; - const char *activation_dirs[] = { NULL, NULL }; DBusConnection *foo; DBusConnection *bar; DBusConnection *baz; + DBusError error; + + context = bus_context_new_test (test_data_dir, + "valid-config-files/debug-allow-all.conf"); + if (context == NULL) + return FALSE; dbus_error_init (&error); - context = bus_context_new ("debug-pipe:name=test-server", - activation_dirs, - &error); - if (context == NULL) - _dbus_assert_not_reached ("could not alloc context"); foo = dbus_connection_open ("debug-pipe:name=test-server", &error); if (foo == NULL) @@ -29,19 +29,23 @@ main (int argc, char **argv) { BusContext *context; DBusError error; - const char *paths[] = { NULL, NULL }; + DBusString config_file; + + /* FIXME I think the arguments should be like: + * --system use standard system config file + * --session use standard session config file + * --config-file=foo.conf use some other file + */ - if (argc < 3) + if (argc != 2) { - /* FIXME obviously just for testing */ - _dbus_warn ("Give the server address as an argument and activation directory as args\n"); + _dbus_warn ("The message bus configuration file must be given as the only argument\n"); return 1; } - - paths[0] = argv[2]; dbus_error_init (&error); - context = bus_context_new (argv[1], paths, &error); + _dbus_string_init_const (&config_file, argv[1]); + context = bus_context_new (&config_file, &error); if (context == NULL) { _dbus_warn ("Failed to start message bus: %s\n", @@ -55,6 +59,6 @@ main (int argc, char **argv) bus_context_shutdown (context); bus_context_unref (context); - + return 0; } diff --git a/bus/session.conf.in b/bus/session.conf.in new file mode 100644 index 00000000..fe7aa5f0 --- /dev/null +++ b/bus/session.conf.in @@ -0,0 +1,31 @@ +<!-- This configuration file controls the per-user-login-session message bus. + Add a session-local.conf and edit that rather than changing this + file directly. --> + +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <!-- FIXME - this is fairly complicated to fix. + Propose the following: + - add "unix:tmpdir=/tmp" which means unix domain transport + creates a socket with a random secure name + - add dbus_server_get_address() that gets the actual + server address + - add command line option or env variable to the daemon + causing it to print its list of addresses to a given + file descriptor + - session manager or whatever launches the session bus + reads the address from there and sets the env variable + --> + <listen>unix:path=/tmp/foobar</listen> + <policy context="default"> + <!-- Allow everything --> + <allow send="*"/> + <allow receive="*"/> + <allow own="*"/> + </policy> + + <!-- This is included last so local configuration can override what's + in this standard file --> + <include ignore_missing="yes">session-local.conf</include> +</busconfig> diff --git a/bus/system.conf.in b/bus/system.conf.in new file mode 100644 index 00000000..fe4e049a --- /dev/null +++ b/bus/system.conf.in @@ -0,0 +1,20 @@ +<!-- This configuration file controls the systemwide message bus. + Add a system-local.conf and edit that rather than changing this + file directly. --> + +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <user>fixme</user> + <listen>unix:path=@EXPANDED_LOCALSTATEDIR@/@DBUS_SYSTEM_SOCKET@</listen> + <policy context="default"> + <!-- Deny everything --> + <deny send="*"/> + <deny receive="*"/> + <deny own="*"/> + </policy> + + <!-- This is included last so local configuration can override what's + in this standard file --> + <include ignore_missing="yes">system-local.conf</include> +</busconfig> diff --git a/bus/test-main.c b/bus/test-main.c index 862ba604..8ef6bfc4 100644 --- a/bus/test-main.c +++ b/bus/test-main.c @@ -62,7 +62,10 @@ main (int argc, char **argv) dir = _dbus_getenv ("DBUS_TEST_DATA"); if (dir == NULL) - dir = ""; + { + fprintf (stderr, "Must specify test data directory as argv[1] or in DBUS_TEST_DATA env variable\n"); + return 1; + } _dbus_string_init_const (&test_data_dir, dir); @@ -287,4 +287,57 @@ bus_test_flush_bus (BusContext *context) ; } +BusContext* +bus_context_new_test (const DBusString *test_data_dir, + const char *filename) +{ + DBusError error; + DBusString config_file; + DBusString relative; + BusContext *context; + + if (!_dbus_string_init (&config_file, _DBUS_INT_MAX)) + { + _dbus_warn ("No memory\n"); + return NULL; + } + + if (!_dbus_string_copy (test_data_dir, 0, + &config_file, 0)) + { + _dbus_warn ("No memory\n"); + _dbus_string_free (&config_file); + return NULL; + } + + _dbus_string_init_const (&relative, filename); + + if (!_dbus_concat_dir_and_file (&config_file, &relative)) + { + _dbus_warn ("No memory\n"); + _dbus_string_free (&config_file); + return NULL; + } + + dbus_error_init (&error); + context = bus_context_new (&config_file, &error); + if (context == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (&error); + + _dbus_warn ("Failed to create debug bus context from configuration file %s: %s\n", + filename, error.message); + + dbus_error_free (&error); + + _dbus_string_free (&config_file); + + return NULL; + } + + _dbus_string_free (&config_file); + + return context; +} + #endif @@ -41,6 +41,9 @@ void bus_test_clients_foreach (BusConnectionForeachFunction function, dbus_bool_t bus_test_client_listed (DBusConnection *connection); void bus_test_flush_bus (BusContext *context); +BusContext* bus_context_new_test (const DBusString *test_data_dir, + const char *filename); + #endif #endif /* BUS_TEST_H */ diff --git a/bus/utils.c b/bus/utils.c index 090e27f0..df061165 100644 --- a/bus/utils.c +++ b/bus/utils.c @@ -33,7 +33,7 @@ bus_get_oom_wait (void) { #ifdef DBUS_BUILD_TESTS /* make tests go fast */ - return 10; + return 0; #else return 500; #endif diff --git a/configure.in b/configure.in index 81b316df..3714ca16 100644 --- a/configure.in +++ b/configure.in @@ -47,6 +47,8 @@ if test x$enable_asserts = xno; then AC_DEFINE(DBUS_DISABLE_ASSERT,1,[Disable assertion checking]) fi +#### gcc warning flags + if test "x$GCC" = "xyes"; then changequote(,)dnl case " $CFLAGS " in @@ -120,6 +122,8 @@ else fi fi +#### Assorted checks + AC_CHECK_SIZEOF(char) AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(long) @@ -350,9 +354,33 @@ dnl Qt flags AC_SUBST(DBUS_QT_CXXFLAGS) AC_SUBST(DBUS_QT_LIBS) +##### Set up location for system bus socket +## name of socket relative to localstatedir +DBUS_SYSTEM_SOCKET=run/dbus/system_bus_socket +AC_SUBST(DBUS_SYSTEM_SOCKET) + +#### find the actual value for $prefix that we'll end up with +REAL_PREFIX= +if test "x$prefix" = "xNONE"; then + REAL_PREFIX=$ac_default_prefix +else + REAL_PREFIX=$prefix +fi + +#### Have to go $localstatedir->$prefix/var->/usr/local/var +#### someone please fix this a better way... +LOCALSTATEDIR_TMP="$localstatedir" +old_prefix=$prefix +prefix=$REAL_PREFIX +EXPANDED_LOCALSTATEDIR=`eval echo $LOCALSTATEDIR_TMP` +prefix=$old_prefix +AC_SUBST(EXPANDED_LOCALSTATEDIR) + AC_OUTPUT([ -Makefile Doxyfile +bus/system.conf +bus/session.conf +Makefile dbus/Makefile glib/Makefile qt/Makefile @@ -381,17 +409,18 @@ echo " Building Qt bindings: ${have_qt} Building GLib bindings: ${have_glib} Using XML parser: ${with_xml} + System bus socket: ${EXPANDED_LOCALSTATEDIR}/${DBUS_SYSTEM_SOCKET} " if test x$enable_tests = xyes; then - echo "NOTE: building with unit tests increases the size of the installed library and renders it insecure" + echo "NOTE: building with unit tests increases the size of the installed library and renders it insecure." fi if test x$enable_gcov = xyes; then - echo "NOTE: building with coverage profiling is definitely for developers only" + echo "NOTE: building with coverage profiling is definitely for developers only." fi if test x$enable_verbose_mode = xyes; then - echo "NOTE: building with verbose mode increases library size and may slightly increase security risk, but aids debugging." + echo "NOTE: building with verbose mode increases library size, may slightly increase security risk, and may cause a slight performance decrease, but aids debugging." fi if test x$enable_asserts = xyes; then - echo "NOTE: building with assertions increases library size, but is probably a good idea anyway." + echo "NOTE: building with assertions increases library size, but will help a lot when tracking down bugs in software using D-BUS." fi diff --git a/dbus/Makefile.am b/dbus/Makefile.am index 20be7919..475f0cb7 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -1,5 +1,6 @@ -INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) -DDBUS_COMPILATION +INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) -DDBUS_COMPILATION \ + -DDBUS_SYSTEM_BUS_PATH=\""$(localstatedir)/@DBUS_SYSTEM_SOCKET@"\" dbusincludedir=$(includedir)/dbus-1.0/dbus diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index c3978db2..22af3dab 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -221,10 +221,18 @@ dbus_bus_get (DBusBusType type, value = _dbus_getenv (name); - if (!value) + if (type == DBUS_BUS_SYSTEM && + (value == NULL || *value == '\0')) + { + /* Use default system bus address if none set */ + value = "unix:path=" DBUS_SYSTEM_BUS_PATH; + } + + if (value == NULL || *value == '\0') { dbus_set_error (error, DBUS_ERROR_FAILED, - "Could not get bus daemon address."); + "Environment variable %s not set, address of message bus unknown", + name); _DBUS_UNLOCK (bus); return NULL; diff --git a/dbus/dbus-server-debug-pipe.c b/dbus/dbus-server-debug-pipe.c index c6dc9f70..ed65298b 100644 --- a/dbus/dbus-server-debug-pipe.c +++ b/dbus/dbus-server-debug-pipe.c @@ -141,7 +141,8 @@ _dbus_server_debug_pipe_new (const char *server_name, DBusError *error) { DBusServerDebugPipe *debug_server; - + DBusString address; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (!pipe_hash_ref ()) @@ -155,52 +156,47 @@ _dbus_server_debug_pipe_new (const char *server_name, } debug_server = dbus_new0 (DBusServerDebugPipe, 1); - if (debug_server == NULL) - { - pipe_hash_unref (); - return NULL; - } + goto nomem_0; + + if (!_dbus_string_init (&address, _DBUS_INT_MAX)) + goto nomem_1; + if (!_dbus_string_append (&address, "debug-pipe:name=") || + !_dbus_string_append (&address, server_name)) + goto nomem_2; + debug_server->name = _dbus_strdup (server_name); if (debug_server->name == NULL) - { - dbus_free (debug_server->name); - dbus_free (debug_server); - - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - - pipe_hash_unref (); - return NULL; - } + goto nomem_2; if (!_dbus_server_init_base (&debug_server->base, - &debug_vtable)) - { - dbus_free (debug_server->name); - dbus_free (debug_server); - - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - - pipe_hash_unref (); - return NULL; - } + &debug_vtable, &address)) + goto nomem_3; if (!_dbus_hash_table_insert_string (server_pipe_hash, debug_server->name, debug_server)) - { - _dbus_server_finalize_base (&debug_server->base); - dbus_free (debug_server->name); - dbus_free (debug_server); + goto nomem_4; - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + _dbus_string_free (&address); - pipe_hash_unref (); - return NULL; - } + /* server keeps the pipe hash ref */ return (DBusServer *)debug_server; + + nomem_4: + _dbus_server_finalize_base (&debug_server->base); + nomem_3: + dbus_free (debug_server->name); + nomem_2: + _dbus_string_free (&address); + nomem_1: + dbus_free (debug_server); + nomem_0: + pipe_hash_unref (); + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; } /** @@ -221,7 +217,8 @@ _dbus_transport_debug_pipe_new (const char *server_name, DBusConnection *connection; int client_fd, server_fd; DBusServer *server; - + DBusString address; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); server = _dbus_hash_table_lookup_string (server_pipe_hash, @@ -232,12 +229,27 @@ _dbus_transport_debug_pipe_new (const char *server_name, dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, NULL); return NULL; } + + if (!_dbus_string_init (&address, _DBUS_INT_MAX)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } + + if (!_dbus_string_append (&address, "debug-pipe:name=") || + !_dbus_string_append (&address, server_name)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + _dbus_string_free (&address); + return NULL; + } if (!_dbus_full_duplex_pipe (&client_fd, &server_fd, NULL)) { _dbus_verbose ("failed to create full duplex pipe\n"); dbus_set_error (error, DBUS_ERROR_FAILED, "Could not create full-duplex pipe"); + _dbus_string_free (&address); return NULL; } @@ -245,19 +257,22 @@ _dbus_transport_debug_pipe_new (const char *server_name, _dbus_fd_set_close_on_exec (server_fd); client_transport = _dbus_transport_new_for_fd (client_fd, - FALSE); + FALSE, &address); if (client_transport == NULL) { _dbus_close (client_fd, NULL); _dbus_close (server_fd, NULL); dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + _dbus_string_free (&address); return NULL; } + _dbus_string_free (&address); + client_fd = -1; server_transport = _dbus_transport_new_for_fd (server_fd, - TRUE); + TRUE, NULL); if (server_transport == NULL) { _dbus_transport_unref (client_transport); diff --git a/dbus/dbus-server-debug.c b/dbus/dbus-server-debug.c index 7af2336b..e61f8099 100644 --- a/dbus/dbus-server-debug.c +++ b/dbus/dbus-server-debug.c @@ -117,7 +117,8 @@ _dbus_server_debug_new (const char *server_name, DBusError *error) { DBusServerDebug *debug_server; - + DBusString address; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (!server_hash) @@ -143,40 +144,43 @@ _dbus_server_debug_new (const char *server_name, if (debug_server == NULL) return NULL; + if (!_dbus_string_init (&address, _DBUS_INT_MAX)) + goto nomem_0; + + if (!_dbus_string_append (&address, "debug:name=") || + !_dbus_string_append (&address, server_name)) + goto nomem_1; + debug_server->name = _dbus_strdup (server_name); if (debug_server->name == NULL) - { - dbus_free (debug_server->name); - dbus_free (debug_server); - - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - } + goto nomem_1; if (!_dbus_server_init_base (&debug_server->base, - &debug_vtable)) - { - dbus_free (debug_server->name); - dbus_free (debug_server); - - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - - return NULL; - } + &debug_vtable, + &address)) + goto nomem_2; if (!_dbus_hash_table_insert_string (server_hash, debug_server->name, debug_server)) - { - _dbus_server_finalize_base (&debug_server->base); - dbus_free (debug_server->name); - dbus_free (debug_server); + goto nomem_3; - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); - - return NULL; - } + _dbus_string_free (&address); return (DBusServer *)debug_server; + + nomem_3: + _dbus_server_finalize_base (&debug_server->base); + nomem_2: + dbus_free (debug_server->name); + nomem_1: + _dbus_string_free (&address); + nomem_0: + dbus_free (debug_server); + + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + + return NULL; } typedef struct diff --git a/dbus/dbus-server-protected.h b/dbus/dbus-server-protected.h index d47215b7..475bf3a2 100644 --- a/dbus/dbus-server-protected.h +++ b/dbus/dbus-server-protected.h @@ -61,6 +61,8 @@ struct DBusServer * to this server */ + char *address; /**< Address this server is listening on. */ + int max_connections; /**< Max number of connections allowed at once. */ DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */ @@ -78,7 +80,8 @@ struct DBusServer }; dbus_bool_t _dbus_server_init_base (DBusServer *server, - const DBusServerVTable *vtable); + const DBusServerVTable *vtable, + const DBusString *address); void _dbus_server_finalize_base (DBusServer *server); dbus_bool_t _dbus_server_add_watch (DBusServer *server, DBusWatch *watch); diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c index 41553fe2..ee26b243 100644 --- a/dbus/dbus-server-unix.c +++ b/dbus/dbus-server-unix.c @@ -83,7 +83,7 @@ handle_new_client_fd (DBusServer *server, if (!_dbus_set_fd_nonblocking (client_fd, NULL)) return TRUE; - transport = _dbus_transport_new_for_fd (client_fd, TRUE); + transport = _dbus_transport_new_for_fd (client_fd, TRUE, NULL); if (transport == NULL) { close (client_fd); @@ -201,11 +201,13 @@ static DBusServerVTable unix_vtable = { * accept new client connections. * * @param fd the file descriptor. + * @param address the server's address * @returns the new server, or #NULL if no memory. * */ DBusServer* -_dbus_server_new_for_fd (int fd) +_dbus_server_new_for_fd (int fd, + const DBusString *address) { DBusServerUnix *unix_server; DBusWatch *watch; @@ -224,7 +226,7 @@ _dbus_server_new_for_fd (int fd) } if (!_dbus_server_init_base (&unix_server->base, - &unix_vtable)) + &unix_vtable, address)) { _dbus_watch_unref (watch); dbus_free (unix_server); @@ -259,23 +261,44 @@ _dbus_server_new_for_domain_socket (const char *path, { DBusServer *server; int listen_fd; - + DBusString address; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + if (!_dbus_string_init (&address, _DBUS_INT_MAX)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } + + if (!_dbus_string_append (&address, "unix:path=") || + !_dbus_string_append (&address, path)) + { + _dbus_string_free (&address); + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } listen_fd = _dbus_listen_unix_socket (path, error); _dbus_fd_set_close_on_exec (listen_fd); if (listen_fd < 0) - return NULL; + { + _dbus_string_free (&address); + return NULL; + } - server = _dbus_server_new_for_fd (listen_fd); + server = _dbus_server_new_for_fd (listen_fd, &address); if (server == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); close (listen_fd); + _dbus_string_free (&address); return NULL; } + _dbus_string_free (&address); + return server; } @@ -295,23 +318,46 @@ _dbus_server_new_for_tcp_socket (const char *host, { DBusServer *server; int listen_fd; - + DBusString address; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + if (!_dbus_string_init (&address, _DBUS_INT_MAX)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } + + if (!_dbus_string_append (&address, "tcp:host=") || + !_dbus_string_append (&address, host) || + !_dbus_string_append (&address, ",port=") || + !_dbus_string_append_int (&address, port)) + { + _dbus_string_free (&address); + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } listen_fd = _dbus_listen_tcp_socket (host, port, error); _dbus_fd_set_close_on_exec (listen_fd); if (listen_fd < 0) - return NULL; + { + _dbus_string_free (&address); + return NULL; + } - server = _dbus_server_new_for_fd (listen_fd); + server = _dbus_server_new_for_fd (listen_fd, &address); if (server == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); close (listen_fd); + _dbus_string_free (&address); return NULL; } + _dbus_string_free (&address); + return server; diff --git a/dbus/dbus-server-unix.h b/dbus/dbus-server-unix.h index 947425b1..1d038db0 100644 --- a/dbus/dbus-server-unix.h +++ b/dbus/dbus-server-unix.h @@ -28,12 +28,14 @@ DBUS_BEGIN_DECLS; -DBusServer* _dbus_server_new_for_fd (int fd); -DBusServer* _dbus_server_new_for_domain_socket (const char *path, - DBusError *error); -DBusServer* _dbus_server_new_for_tcp_socket (const char *host, - dbus_uint32_t port, - DBusError *error); +DBusServer* _dbus_server_new_for_fd (int fd, + const DBusString *address); +DBusServer* _dbus_server_new_for_domain_socket (const char *path, + DBusError *error); +DBusServer* _dbus_server_new_for_tcp_socket (const char *host, + dbus_uint32_t port, + DBusError *error); + DBUS_END_DECLS; diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index 6b9f17e8..9f70649b 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -57,43 +57,68 @@ * * @param server the server. * @param vtable the vtable for the subclass. + * @param address the server's address * @returns #TRUE on success. */ dbus_bool_t _dbus_server_init_base (DBusServer *server, - const DBusServerVTable *vtable) + const DBusServerVTable *vtable, + const DBusString *address) { server->vtable = vtable; server->refcount = 1; + server->address = NULL; + server->watches = NULL; + server->timeouts = NULL; + server->connection_counter = NULL; + + if (!_dbus_string_copy_data (address, &server->address)) + goto failed; + server->watches = _dbus_watch_list_new (); if (server->watches == NULL) - return FALSE; + goto failed; server->timeouts = _dbus_timeout_list_new (); if (server->timeouts == NULL) - { - _dbus_watch_list_free (server->watches); - server->watches = NULL; - return FALSE; - } + goto failed; server->connection_counter = _dbus_counter_new (); if (server->connection_counter == NULL) + goto failed; + + server->max_connections = 256; /* same as an X server, seems like a nice default */ + + _dbus_data_slot_list_init (&server->slot_list); + + _dbus_verbose ("Initialized server on address %s\n", server->address); + + return TRUE; + + failed: + if (server->watches) { _dbus_watch_list_free (server->watches); server->watches = NULL; + } + if (server->timeouts) + { _dbus_timeout_list_free (server->timeouts); server->timeouts = NULL; - - return FALSE; } - - server->max_connections = 256; /* same as an X server, seems like a nice default */ - - _dbus_data_slot_list_init (&server->slot_list); + if (server->connection_counter) + { + _dbus_counter_unref (server->connection_counter); + server->connection_counter = NULL; + } + if (server->address) + { + dbus_free (server->address); + server->address = NULL; + } - return TRUE; + return FALSE; } /** @@ -116,6 +141,8 @@ _dbus_server_finalize_base (DBusServer *server) _dbus_watch_list_free (server->watches); _dbus_timeout_list_free (server->timeouts); _dbus_counter_unref (server->connection_counter); + + dbus_free (server->address); } /** @@ -445,6 +472,19 @@ dbus_server_get_is_connected (DBusServer *server) } /** + * Returns the address of the server, as a newly-allocated + * string which must be freed by the caller. + * + * @param server the server + * @returns the address or #NULL if no memory + */ +char* +dbus_server_get_address (DBusServer *server) +{ + return _dbus_strdup (server->address); +} + +/** * Sets a function to be used for handling new connections. The given * function is passed each new connection as the connection is * created. If the new connection function increments the connection's diff --git a/dbus/dbus-server.h b/dbus/dbus-server.h index fcfc6e70..e36ed86e 100644 --- a/dbus/dbus-server.h +++ b/dbus/dbus-server.h @@ -45,6 +45,7 @@ void dbus_server_ref (DBusServer *server); void dbus_server_unref (DBusServer *server); void dbus_server_disconnect (DBusServer *server); dbus_bool_t dbus_server_get_is_connected (DBusServer *server); +char* dbus_server_get_address (DBusServer *server); void dbus_server_set_new_connection_function (DBusServer *server, DBusNewConnectionFunction function, void *data, diff --git a/dbus/dbus-transport-debug.c b/dbus/dbus-transport-debug.c index 03b40593..a1b2a64a 100644 --- a/dbus/dbus-transport-debug.c +++ b/dbus/dbus-transport-debug.c @@ -277,7 +277,7 @@ _dbus_transport_debug_server_new (DBusTransport *client) if (!_dbus_transport_init_base (&debug_transport->base, &debug_vtable, - TRUE)) + TRUE, NULL)) { dbus_free (debug_transport); return NULL; @@ -316,7 +316,8 @@ _dbus_transport_debug_client_new (const char *server_name, { DBusServer *debug_server; DBusTransportDebug *debug_transport; - + DBusString address; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); debug_server = _dbus_server_debug_lookup (server_name); @@ -327,21 +328,39 @@ _dbus_transport_debug_client_new (const char *server_name, return NULL; } + if (!_dbus_string_init (&address, _DBUS_INT_MAX)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } + + if (!_dbus_string_append (&address, "debug-pipe:name=") || + !_dbus_string_append (&address, server_name)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + _dbus_string_free (&address); + return NULL; + } + debug_transport = dbus_new0 (DBusTransportDebug, 1); if (debug_transport == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + _dbus_string_free (&address); return NULL; } if (!_dbus_transport_init_base (&debug_transport->base, &debug_vtable, - FALSE)) + FALSE, &address)) { dbus_free (debug_transport); dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + _dbus_string_free (&address); return NULL; } + + _dbus_string_free (&address); if (!create_timeout_object (debug_transport)) { diff --git a/dbus/dbus-transport-protected.h b/dbus/dbus-transport-protected.h index 31668389..052c15fa 100644 --- a/dbus/dbus-transport-protected.h +++ b/dbus/dbus-transport-protected.h @@ -88,6 +88,8 @@ struct DBusTransport DBusCounter *live_messages_size; /**< Counter for size of all live messages. */ + char *address; /**< Address of this server */ + DBusAllowUnixUserFunction unix_user_function; /**< Function for checking whether a user is authorized. */ void *unix_user_data; /**< Data for unix_user_function */ DBusFreeFunction free_unix_user_data; /**< Function to free unix_user_data */ @@ -102,7 +104,8 @@ struct DBusTransport dbus_bool_t _dbus_transport_init_base (DBusTransport *transport, const DBusTransportVTable *vtable, - dbus_bool_t server); + dbus_bool_t server, + const DBusString *address); void _dbus_transport_finalize_base (DBusTransport *transport); diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c index d34565eb..81672de5 100644 --- a/dbus/dbus-transport-unix.c +++ b/dbus/dbus-transport-unix.c @@ -963,11 +963,13 @@ static DBusTransportVTable unix_vtable = { * * @param fd the file descriptor. * @param server #TRUE if this transport is on the server side of a connection + * @param address the transport's address * @returns the new transport, or #NULL if no memory. */ DBusTransport* -_dbus_transport_new_for_fd (int fd, - dbus_bool_t server) +_dbus_transport_new_for_fd (int fd, + dbus_bool_t server, + const DBusString *address) { DBusTransportUnix *unix_transport; @@ -997,7 +999,7 @@ _dbus_transport_new_for_fd (int fd, if (!_dbus_transport_init_base (&unix_transport->base, &unix_vtable, - server)) + server, address)) goto failed_4; unix_transport->fd = fd; @@ -1024,27 +1026,41 @@ _dbus_transport_new_for_fd (int fd, /** * Creates a new transport for the given Unix domain socket - * path. + * path. This creates a client-side of a transport. * * @param path the path to the domain socket. - * @param server #TRUE if this transport is on the server side of a connection * @param error address where an error can be returned. * @returns a new transport, or #NULL on failure. */ DBusTransport* _dbus_transport_new_for_domain_socket (const char *path, - dbus_bool_t server, DBusError *error) { int fd; DBusTransport *transport; - + DBusString address; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + if (!_dbus_string_init (&address, _DBUS_INT_MAX)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } + + if (!_dbus_string_append (&address, "unix:path=") || + !_dbus_string_append (&address, path)) + { + _dbus_string_free (&address); + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } fd = _dbus_connect_unix_socket (path, error); if (fd < 0) { _DBUS_ASSERT_ERROR_IS_SET (error); + _dbus_string_free (&address); return NULL; } @@ -1052,14 +1068,17 @@ _dbus_transport_new_for_domain_socket (const char *path, _dbus_verbose ("Successfully connected to unix socket %s\n", path); - - transport = _dbus_transport_new_for_fd (fd, server); + + transport = _dbus_transport_new_for_fd (fd, FALSE, &address); if (transport == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + _dbus_string_free (&address); _dbus_close (fd, NULL); fd = -1; } + + _dbus_string_free (&address); return transport; } @@ -1069,25 +1088,41 @@ _dbus_transport_new_for_domain_socket (const char *path, * * @param host the host to connect to * @param port the port to connect to - * @param server #TRUE if this transport is on the server side of a connection * @param error location to store reason for failure. * @returns a new transport, or #NULL on failure. */ DBusTransport* _dbus_transport_new_for_tcp_socket (const char *host, dbus_int32_t port, - dbus_bool_t server, DBusError *error) { int fd; DBusTransport *transport; - + DBusString address; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + if (!_dbus_string_init (&address, _DBUS_INT_MAX)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } + + if (!_dbus_string_append (&address, "tcp:host=") || + !_dbus_string_append (&address, host) || + !_dbus_string_append (&address, ",port=") || + !_dbus_string_append_int (&address, port)) + { + _dbus_string_free (&address); + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } fd = _dbus_connect_tcp_socket (host, port, error); if (fd < 0) { _DBUS_ASSERT_ERROR_IS_SET (error); + _dbus_string_free (&address); return NULL; } @@ -1096,14 +1131,17 @@ _dbus_transport_new_for_tcp_socket (const char *host, _dbus_verbose ("Successfully connected to tcp socket %s:%d\n", host, port); - transport = _dbus_transport_new_for_fd (fd, server); + transport = _dbus_transport_new_for_fd (fd, FALSE, &address); if (transport == NULL) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); _dbus_close (fd, NULL); + _dbus_string_free (&address); fd = -1; } + _dbus_string_free (&address); + return transport; } diff --git a/dbus/dbus-transport-unix.h b/dbus/dbus-transport-unix.h index 595fbc18..ef7ac9b1 100644 --- a/dbus/dbus-transport-unix.h +++ b/dbus/dbus-transport-unix.h @@ -27,15 +27,15 @@ DBUS_BEGIN_DECLS; -DBusTransport* _dbus_transport_new_for_fd (int fd, - dbus_bool_t server); -DBusTransport* _dbus_transport_new_for_domain_socket (const char *path, - dbus_bool_t server, - DBusError *error); -DBusTransport* _dbus_transport_new_for_tcp_socket (const char *host, - dbus_int32_t port, - dbus_bool_t server, - DBusError *error); +DBusTransport* _dbus_transport_new_for_fd (int fd, + dbus_bool_t server, + const DBusString *address); +DBusTransport* _dbus_transport_new_for_domain_socket (const char *path, + DBusError *error); +DBusTransport* _dbus_transport_new_for_tcp_socket (const char *host, + dbus_int32_t port, + DBusError *error); + DBUS_END_DECLS; diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index 41466ec9..a7aecc3f 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -82,16 +82,19 @@ live_messages_size_notify (DBusCounter *counter, * @param transport the transport being created. * @param vtable the subclass vtable. * @param server #TRUE 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, - dbus_bool_t server) + dbus_bool_t server, + const DBusString *address) { DBusMessageLoader *loader; DBusAuth *auth; DBusCounter *counter; + char *address_copy; loader = _dbus_message_loader_new (); if (loader == NULL) @@ -113,6 +116,24 @@ _dbus_transport_init_base (DBusTransport *transport, _dbus_auth_unref (auth); _dbus_message_loader_unref (loader); return FALSE; + } + + if (server) + { + _dbus_assert (address == NULL); + address_copy = NULL; + } + else + { + _dbus_assert (address != NULL); + + if (!_dbus_string_copy_data (address, &address_copy)) + { + _dbus_counter_unref (counter); + _dbus_auth_unref (auth); + _dbus_message_loader_unref (loader); + return FALSE; + } } transport->refcount = 1; @@ -126,7 +147,8 @@ _dbus_transport_init_base (DBusTransport *transport, transport->send_credentials_pending = !server; transport->receive_credentials_pending = server; transport->is_server = server; - + transport->address = address_copy; + transport->unix_user_function = NULL; transport->unix_user_data = NULL; transport->free_unix_user_data = NULL; @@ -144,6 +166,9 @@ _dbus_transport_init_base (DBusTransport *transport, 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; } @@ -168,6 +193,7 @@ _dbus_transport_finalize_base (DBusTransport *transport) _dbus_counter_set_notify (transport->live_messages_size, 0, NULL, NULL); _dbus_counter_unref (transport->live_messages_size); + dbus_free (transport->address); } /** @@ -217,7 +243,7 @@ _dbus_transport_open (const char *address, goto bad_address; } - transport = _dbus_transport_new_for_domain_socket (path, FALSE, error); + transport = _dbus_transport_new_for_domain_socket (path, error); } else if (strcmp (method, "tcp") == 0) { @@ -244,7 +270,7 @@ _dbus_transport_open (const char *address, goto bad_address; } - transport = _dbus_transport_new_for_tcp_socket (host, lport, FALSE, error); + transport = _dbus_transport_new_for_tcp_socket (host, lport, error); } #ifdef DBUS_BUILD_TESTS else if (strcmp (method, "debug") == 0) @@ -461,6 +487,19 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport) } /** + * Gets the address of a transport. It will be + * #NULL for a server-side transport. + * + * @param transport the transport + * @returns transport's address + */ +const char* +_dbus_transport_get_address (DBusTransport *transport) +{ + return transport->address; +} + +/** * Handles a watch by reading data, writing data, or disconnecting * the transport, as appropriate for the given condition. * diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h index d129ccef..128f0fe3 100644 --- a/dbus/dbus-transport.h +++ b/dbus/dbus-transport.h @@ -37,6 +37,7 @@ void _dbus_transport_unref (DBusTransport void _dbus_transport_disconnect (DBusTransport *transport); dbus_bool_t _dbus_transport_get_is_connected (DBusTransport *transport); dbus_bool_t _dbus_transport_get_is_authenticated (DBusTransport *transport); +const char* _dbus_transport_get_address (DBusTransport *transport); dbus_bool_t _dbus_transport_handle_watch (DBusTransport *transport, DBusWatch *watch, unsigned int condition); diff --git a/doc/Makefile.am b/doc/Makefile.am index ff9249f6..2761155d 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,4 +1,5 @@ EXTRA_DIST= \ + config-file.txt \ dbus-specification.html \ dbus-specification.sgml \ dbus-test-plan.html \ diff --git a/doc/config-file.txt b/doc/config-file.txt index df1e43d8..5502c82b 100644 --- a/doc/config-file.txt +++ b/doc/config-file.txt @@ -62,7 +62,10 @@ Elements: Example: <listen>unix:path=/tmp/foo</listen> If there are multiple <listen> elements, then the bus listens - on multiple addresses. + on multiple addresses. The bus will pass its address to + activated services or other interested parties with + the last address given in <listen> first. That is, + apps will try to connect to the last <listen> address first. <auth> @@ -73,6 +76,13 @@ Elements: Example: <auth>EXTERNAL</auth> Example: <auth>DBUS_COOKIE_SHA1</auth> + <servicedir> + + Adds a directory to scan for .service files. Directories are + scanned starting with the last to appear in the config file + (the first .service file found that provides a particular + service will be used). + <policy> context="(default|mandatory)" one of the context/user/group attributes is mandatory diff --git a/test/Makefile.am b/test/Makefile.am index f900b021..5d67283b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -44,13 +44,24 @@ break_loader_LDADD= $(TEST_LIBS) #bus_test_LDADD=$(TEST_LIBS) $(top_builddir)/bus/libdbus-daemon.la spawn_test_LDADD=$(TEST_LIBS) +EXTRA_DIST=fix-standard-tests.sh + dist-hook: - DIRS="data data/valid-messages data/invalid-messages data/incomplete-messages data/auth data/sha-1"; \ + DIRS="data data/valid-messages data/invalid-messages data/incomplete-messages data/auth data/sha-1 data/valid-config-files"; \ for D in $$DIRS; do \ test -d $(distdir)/$$D || mkdir $(distdir)/$$D ; \ done ; \ - FILES=`find -name "*.message" -o -name "*.message-raw" -o -name "*.auth-script" -o -name "*.sha1" -o -name "*.txt"` ; \ + FILES=`find -name "*.message" -o -name "*.message-raw" -o -name "*.auth-script" -o -name "*.sha1" -o -name "*.txt" -o -name "*.conf"` ; \ for F in $$FILES; do \ echo '-- Disting file '$$F ; \ cp $$F $(distdir)/$$F ; \ done + + +### we want our standard session.conf and system.conf in the test suite, +### right now we manually sync copies of them over to the test suite +### from time to time +update-standard-tests: + cp -f $(top_builddir)/bus/system.conf.in data/valid-config-files/system.conf ; \ + cp -f $(top_builddir)/bus/session.conf.in data/valid-config-files/session.conf ; \ + $(srcdir)/fix-standard-tests.sh diff --git a/test/data/valid-config-files/debug-allow-all.conf b/test/data/valid-config-files/debug-allow-all.conf new file mode 100644 index 00000000..86900ebb --- /dev/null +++ b/test/data/valid-config-files/debug-allow-all.conf @@ -0,0 +1,12 @@ +<!-- Bus that listens on a debug pipe and doesn't create any restrictions --> + +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <listen>debug-pipe:name=test-server</listen> + <policy context="default"> + <allow send="*"/> + <allow receive="*"/> + <allow own="*"/> + </policy> +</busconfig> diff --git a/test/data/valid-config-files/session.conf b/test/data/valid-config-files/session.conf new file mode 100644 index 00000000..fe7aa5f0 --- /dev/null +++ b/test/data/valid-config-files/session.conf @@ -0,0 +1,31 @@ +<!-- This configuration file controls the per-user-login-session message bus. + Add a session-local.conf and edit that rather than changing this + file directly. --> + +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <!-- FIXME - this is fairly complicated to fix. + Propose the following: + - add "unix:tmpdir=/tmp" which means unix domain transport + creates a socket with a random secure name + - add dbus_server_get_address() that gets the actual + server address + - add command line option or env variable to the daemon + causing it to print its list of addresses to a given + file descriptor + - session manager or whatever launches the session bus + reads the address from there and sets the env variable + --> + <listen>unix:path=/tmp/foobar</listen> + <policy context="default"> + <!-- Allow everything --> + <allow send="*"/> + <allow receive="*"/> + <allow own="*"/> + </policy> + + <!-- This is included last so local configuration can override what's + in this standard file --> + <include ignore_missing="yes">session-local.conf</include> +</busconfig> diff --git a/test/data/valid-config-files/system.conf b/test/data/valid-config-files/system.conf new file mode 100644 index 00000000..e2c7ab7f --- /dev/null +++ b/test/data/valid-config-files/system.conf @@ -0,0 +1,20 @@ +<!-- This configuration file controls the systemwide message bus. + Add a system-local.conf and edit that rather than changing this + file directly. --> + +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <user>fixme</user> + <listen>unix:path=/var/run/dbus/system_bus_socket</listen> + <policy context="default"> + <!-- Deny everything --> + <deny send="*"/> + <deny receive="*"/> + <deny own="*"/> + </policy> + + <!-- This is included last so local configuration can override what's + in this standard file --> + <include ignore_missing="yes">system-local.conf</include> +</busconfig> diff --git a/test/fix-standard-tests.sh b/test/fix-standard-tests.sh new file mode 100755 index 00000000..80e6dae1 --- /dev/null +++ b/test/fix-standard-tests.sh @@ -0,0 +1,8 @@ +#! /bin/sh + +### this script is a lame hack used in the Makefile because +### I couldn't figure out how to escape @EXPANDED_LOCALSTATEDIR@ etc. +### inside the Makefile + +perl -pi -e "s%\@EXPANDED_LOCALSTATEDIR\@%/var%g" data/valid-config-files/system.conf +perl -pi -e "s%\@DBUS_SYSTEM_SOCKET\@%run/dbus/system_bus_socket%g" data/valid-config-files/system.conf |