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



commit e13f1fba20874c58d6d22b7c423f64d763513e6c
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.
    
    Epiphany would be the first consumer of this, to allow its D-Bus server
    to function in the presence of a bubblewrap web process sandbox.

 gio/gdbusaddress.c          | 15 ++++++++++-----
 gio/gdbusserver.c           | 13 ++++++++-----
 gio/tests/gdbus-addresses.c |  4 ++++
 3 files changed, 22 insertions(+), 10 deletions(-)
---
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index 1f7d19396..7052ed943 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,10 @@ 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)) ||
+      (dir != NULL && (tmpdir != NULL || abstract != NULL)) ||
+      (tmpdir != NULL && abstract != NULL))
     {
       g_set_error (error,
              G_IO_ERROR,
@@ -169,12 +174,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 026d4ee6b..d4f46daa2 100644
--- a/gio/gdbusserver.c
+++ b/gio/gdbusserver.c
@@ -632,7 +632,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,
@@ -641,6 +641,7 @@ try_unix (GDBusServer  *server,
 {
   gboolean ret;
   const gchar *path;
+  const gchar *dir;
   const gchar *tmpdir;
   const gchar *abstract;
   GSocketAddress *address;
@@ -649,6 +650,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");
 
@@ -656,20 +658,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]