From fc597fa5f99810564c963c23cd37605d581fea89 Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Tue, 11 Jun 2019 22:35:19 -0500 Subject: [PATCH] gdbus: support unix:dir= addresses unix:dir= addresses are exactly the same as unix:tmpdir= addresses, already supported by GDBus, except they forbid use of abstract sockets. This is convenient for situations where abstract sockets are impermissible, such as when a D-Bus client inside a network namespace needs to connect to a server running in a different network namespace. An abstract socket cannot be shared between two processes in different network namespaces. Applications could use unix:path= addresses instead, so this is only a convenience, but there's no good reason not to support unix:dir=. Currently it is not supported simply because unix:dir= is a relatively recent addition to the D-Bus spec. --- gio/gdbusaddress.c | 13 ++++++++----- gio/gdbusserver.c | 13 ++++++++----- gio/tests/gdbus-addresses.c | 4 ++++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c index 1f7d19396..e88695139 100644 --- a/gio/gdbusaddress.c +++ b/gio/gdbusaddress.c @@ -127,12 +127,14 @@ is_valid_unix (const gchar *address_entry, GList *keys; GList *l; const gchar *path; + const gchar *dir; const gchar *tmpdir; const gchar *abstract; ret = FALSE; keys = NULL; path = NULL; + dir = NULL; tmpdir = NULL; abstract = NULL; @@ -142,6 +144,8 @@ is_valid_unix (const gchar *address_entry, const gchar *key = l->data; if (g_strcmp0 (key, "path") == 0) path = g_hash_table_lookup (key_value_pairs, key); + else if (g_strcmp0 (key, "dir") == 0) + dir = g_hash_table_lookup (key_value_pairs, key); else if (g_strcmp0 (key, "tmpdir") == 0) tmpdir = g_hash_table_lookup (key_value_pairs, key); else if (g_strcmp0 (key, "abstract") == 0) @@ -158,9 +162,8 @@ is_valid_unix (const gchar *address_entry, } } - if ((path != NULL && tmpdir != NULL) || - (tmpdir != NULL && abstract != NULL) || - (abstract != NULL && path != NULL)) + /* Exactly one key must be set */ + if ((path != NULL) + (dir != NULL) + (tmpdir != NULL) + (abstract != NULL) > 1) { g_set_error (error, G_IO_ERROR, @@ -169,12 +172,12 @@ is_valid_unix (const gchar *address_entry, address_entry); goto out; } - else if (path == NULL && tmpdir == NULL && abstract == NULL) + else if (path == NULL && dir == NULL && tmpdir == NULL && abstract == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, - _("Address ā€œ%sā€ is invalid (need exactly one of path, tmpdir or abstract keys)"), + _("Address ā€œ%sā€ is invalid (need exactly one of path, dir, tmpdir, or abstract keys)"), address_entry); goto out; } diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c index b3459ce47..2f137ecca 100644 --- a/gio/gdbusserver.c +++ b/gio/gdbusserver.c @@ -641,7 +641,7 @@ random_ascii (void) return ret; } -/* note that address_entry has already been validated => exactly one of path, tmpdir or abstract keys are set */ +/* note that address_entry has already been validated => exactly one of path, dir, tmpdir, or abstract keys are set */ static gboolean try_unix (GDBusServer *server, const gchar *address_entry, @@ -650,6 +650,7 @@ try_unix (GDBusServer *server, { gboolean ret; const gchar *path; + const gchar *dir; const gchar *tmpdir; const gchar *abstract; GSocketAddress *address; @@ -658,6 +659,7 @@ try_unix (GDBusServer *server, address = NULL; path = g_hash_table_lookup (key_value_pairs, "path"); + dir = g_hash_table_lookup (key_value_pairs, "dir"); tmpdir = g_hash_table_lookup (key_value_pairs, "tmpdir"); abstract = g_hash_table_lookup (key_value_pairs, "abstract"); @@ -665,20 +667,21 @@ try_unix (GDBusServer *server, { address = g_unix_socket_address_new (path); } - else if (tmpdir != NULL) + else if (dir != NULL || tmpdir != NULL) { gint n; GString *s; GError *local_error; retry: - s = g_string_new (tmpdir); + s = g_string_new (tmpdir != NULL ? tmpdir : dir); g_string_append (s, "/dbus-"); for (n = 0; n < 8; n++) g_string_append_c (s, random_ascii ()); - /* prefer abstract namespace if available */ - if (g_unix_socket_address_abstract_names_supported ()) + /* prefer abstract namespace if available for tmpdir: addresses + * abstract namespace is disallowed for dir: addresses */ + if (tmpdir != NULL && g_unix_socket_address_abstract_names_supported ()) address = g_unix_socket_address_new_with_type (s->str, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT); diff --git a/gio/tests/gdbus-addresses.c b/gio/tests/gdbus-addresses.c index d6a5c2360..b7c81fc06 100644 --- a/gio/tests/gdbus-addresses.c +++ b/gio/tests/gdbus-addresses.c @@ -113,9 +113,13 @@ test_unix_address (void) g_assert_false (g_dbus_is_address ("unix:path=/foo;abstract=/bar")); assert_is_supported_address ("unix:path=/tmp/concrete;unix:abstract=/tmp/abstract"); assert_is_supported_address ("unix:tmpdir=/tmp"); + assert_is_supported_address ("unix:dir=/tmp"); assert_not_supported_address ("unix:tmpdir=/tmp,path=/tmp"); assert_not_supported_address ("unix:tmpdir=/tmp,abstract=/tmp/foo"); + assert_not_supported_address ("unix:tmpdir=/tmp,dir=/tmp"); assert_not_supported_address ("unix:path=/tmp,abstract=/tmp/foo"); + assert_not_supported_address ("unix:path=/tmp,dir=/tmp"); + assert_not_supported_address ("unix:abstract=/tmp/foo,dir=/tmp"); assert_not_supported_address ("unix:"); #endif }