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.
This commit is contained in:
Michael Catanzaro 2019-06-11 22:35:19 -05:00
parent d2450c8124
commit fc597fa5f9
3 changed files with 20 additions and 10 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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
}