[glib/mcatanzaro/gdbus-dir-addresses: 1/6] gdbus: support unix:dir= addresses



commit 59ec18e9799b6fe46c25736b1b6bfc82f1de4d2e
Author: Michael Catanzaro <mcatanzaro igalia com>
Date:   Tue Jun 11 22:35:19 2019 -0500

    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. It's weird and unexpected that this one type of unix:
    address from the D-Bus spec is strangely unimplemented by GDBus. This
    limitation doesn't seem to be documented anywhere that I could find,
    anyway.

 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
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]