[glib] GDBus: Avoid use of libdbus-1 in authentication tests



commit 2652dc13573471a1a20070fdeef0c44eb0aa4f9a
Author: David Zeuthen <zeuthen gmail com>
Date:   Thu Jan 3 11:57:21 2013 -0500

    GDBus: Avoid use of libdbus-1 in authentication tests
    
    This greatly simplifies the test since everything is now in a single
    process and possible bugs / quirks in libdbus-1 will not interfere
    with the tests. On the other hand, we no longer test interoperability
    with libdbus-1. This is somewhat moot, however, since other tests that
    involve a message bus (e.g. GTestDBus users which include most of the
    GDBus test suite itself) will test this.
    
    Also ensure that we don't pollute existing D-Bus keyrings for the
    DBUS_COOKIE_SHA1 authentication method (e.g. files in the
    ~/.dbus-keyrings directory) by setting the environment variables
    G_DBUS_COOKIE_SHA1_KEYRING_DIR and
    G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION.
    
    All in all, this change avoids some thorny issues where the GDBus and
    libdbus-1 implementations disagree on whether an item in the D-Bus
    keyring is still valid (items have an age etc.). In reality, since the
    DBUS_COOKIE_SHA1 authentication method is never used in production,
    this is never hit in production. This bug was, however, frequently hit
    if you just ran the test suite repeatedly for 15 minutes or so.
    
    Also add TODO items to mention that we currently don't test corner
    cases involving
    
     - DBUS_COOKIE_SHA1 timeouts
     - libdbus-1 interoperability
    
    Signed-off-by: David Zeuthen <zeuthen gmail com>

 gio/tests/Makefile.am  |    2 -
 gio/tests/gdbus-auth.c |  304 ++++++++++++++++++++++++++----------------------
 2 files changed, 165 insertions(+), 141 deletions(-)
---
diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am
index df96bcc..344601b 100644
--- a/gio/tests/Makefile.am
+++ b/gio/tests/Makefile.am
@@ -194,12 +194,10 @@ gdbus_serialization_CFLAGS = $(DBUS1_CFLAGS)
 gdbus_serialization_LDADD = $(LDADD) $(DBUS1_LIBS)
 endif
 
-if HAVE_DBUS1
 TEST_PROGS += gdbus-auth
 gdbus_auth_SOURCES = gdbus-auth.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c
 gdbus_auth_CFLAGS = $(DBUS1_CFLAGS)
 gdbus_auth_LDADD = $(LDADD) $(DBUS1_LIBS)
-endif
 
 gdbus_bz627724_SOURCES = gdbus-bz627724.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c
 
diff --git a/gio/tests/gdbus-auth.c b/gio/tests/gdbus-auth.c
index cafa13f..fddd4cd 100644
--- a/gio/tests/gdbus-auth.c
+++ b/gio/tests/gdbus-auth.c
@@ -1,6 +1,6 @@
 /* GLib testing framework examples and tests
  *
- * Copyright (C) 2008-2012 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -39,68 +39,80 @@
 /* ---------------------------------------------------------------------------------------------------- */
 
 static gboolean
-on_allow_mechanism (GDBusAuthObserver *observer,
-                    const gchar       *mechanism,
-                    gpointer           user_data)
+server_on_allow_mechanism (GDBusAuthObserver *observer,
+                           const gchar       *mechanism,
+                           gpointer           user_data)
 {
-  const gchar *mechanism_to_allow = user_data;
-  if (g_strcmp0 (mechanism, mechanism_to_allow) == 0)
+  const gchar *allowed_mechanism = user_data;
+  if (allowed_mechanism == NULL || g_strcmp0 (mechanism, allowed_mechanism) == 0)
     return TRUE;
   else
     return FALSE;
 }
 
-static void
-auth_client_mechanism (const gchar *mechanism)
+/* pass NULL to allow any mechanism */
+static GDBusServer *
+server_new_for_mechanism (const gchar *allowed_mechanism)
 {
-  gchar *address = NULL;
-  GDBusConnection *c = NULL;
-  GError *error = NULL;
+  gchar *addr;
+  gchar *guid;
+  GDBusServer *server;
   GDBusAuthObserver *auth_observer;
+  GError *error;
+  GDBusServerFlags flags;
 
-  address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL, &error);
-  g_assert_no_error (error);
-  g_assert (address != NULL);
+  guid = g_dbus_generate_guid ();
+
+#ifdef G_OS_UNIX
+  if (g_unix_socket_address_abstract_names_supported ())
+    {
+      addr = g_strdup ("unix:tmpdir=/tmp/gdbus-test-");
+    }
+  else
+    {
+      gchar *tmpdir;
+      tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL);
+      addr = g_strdup_printf ("unix:tmpdir=%s", tmpdir);
+      g_free (tmpdir);
+    }
+#else
+  addr = g_strdup ("nonce-tcp:");
+#endif
 
   auth_observer = g_dbus_auth_observer_new ();
 
-  g_signal_connect (auth_observer,
-                    "allow-mechanism",
-                    G_CALLBACK (on_allow_mechanism),
-                    (gpointer) mechanism);
+  flags = G_DBUS_SERVER_FLAGS_NONE;
+  if (g_strcmp0 (allowed_mechanism, "ANONYMOUS") == 0)
+    flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
 
-  c = g_dbus_connection_new_for_address_sync (address,
-                                              G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
-                                              G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
-                                              auth_observer,
-                                              NULL,
-                                              &error);
+  error = NULL;
+  server = g_dbus_server_new_sync (addr,
+                                   flags,
+                                   guid,
+                                   auth_observer,
+                                   NULL, /* cancellable */
+                                   &error);
   g_assert_no_error (error);
-  g_assert (c != NULL);
+  g_assert (server != NULL);
 
-  g_free (address);
-  g_object_unref (c);
-  g_object_unref (auth_observer);
-}
+  g_signal_connect (auth_observer,
+                    "allow-mechanism",
+                    G_CALLBACK (server_on_allow_mechanism),
+                    (gpointer) allowed_mechanism);
 
-static void
-auth_client_external (void)
-{
-  auth_client_mechanism ("EXTERNAL");
-}
+  g_free (addr);
+  g_free (guid);
+  g_object_unref (auth_observer);
 
-static void
-auth_client_dbus_cookie_sha1 (void)
-{
-  auth_client_mechanism ("DBUS_COOKIE_SHA1");
+  return server;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 static gboolean
-on_new_connection (GDBusServer     *server,
-                   GDBusConnection *connection,
-                   gpointer         user_data)
+test_auth_on_new_connection (GDBusServer     *server,
+                             GDBusConnection *connection,
+                             gpointer         user_data)
 {
   GMainLoop *loop = user_data;
   g_main_loop_quit (loop);
@@ -108,123 +120,78 @@ on_new_connection (GDBusServer     *server,
 }
 
 static gboolean
-on_timeout (gpointer user_data)
+test_auth_on_timeout (gpointer user_data)
 {
   g_error ("Timeout waiting for client");
   g_assert_not_reached ();
   return FALSE;
 }
 
+
+typedef struct
+{
+  const gchar *address;
+  const gchar *allowed_client_mechanism;
+  const gchar *allowed_server_mechanism;
+} TestAuthData;
+
 static gpointer
-dbus_1_client_thread_func (gpointer user_data)
+test_auth_client_thread_func (gpointer user_data)
 {
-  const gchar *address = user_data;
-  gchar *str_stdout;
-  gchar *str_stderr;
-  gint exit_status;
-  gboolean rc;
-  gchar *command_line;
-  GError *error;
+  TestAuthData *data = user_data;
+  GDBusConnection *c = NULL;
+  GError *error = NULL;
+  GDBusAuthObserver *auth_observer = NULL;
 
-  // For the dbus part, just use dbus-monitor to connect(1)
-  command_line = g_strdup_printf ("dbus-monitor --address %s", address);
+  auth_observer = g_dbus_auth_observer_new ();
 
-  error = NULL;
-  rc = g_spawn_command_line_sync (command_line,
-                                  &str_stdout,
-                                  &str_stderr,
-                                  &exit_status,
-                                  &error);
+  g_signal_connect (auth_observer,
+                    "allow-mechanism",
+                    G_CALLBACK (server_on_allow_mechanism),
+                    (gpointer) data->allowed_client_mechanism);
+
+  c = g_dbus_connection_new_for_address_sync (data->address,
+                                              G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+                                              auth_observer,
+                                              NULL, /* GCancellable */
+                                              &error);
   g_assert_no_error (error);
-  g_assert (rc);
-  g_free (str_stdout);
-  g_free (str_stderr);
-  g_free (command_line);
+  g_assert (c != NULL);
+  g_clear_object (&c);
+  g_clear_object (&auth_observer);
   return NULL;
 }
 
 static void
-auth_server_mechanism (const gchar *mechanism)
+test_auth_mechanism (const gchar *allowed_client_mechanism,
+                     const gchar *allowed_server_mechanism)
 {
-  gchar *addr;
-  gchar *guid;
   GDBusServer *server;
-  GDBusAuthObserver *auth_observer;
   GMainLoop *loop;
-  GError *error;
   GThread *client_thread;
-  GDBusServerFlags flags;
-
-  /* Skip DBUS_COOKIE_SHA1 test unless we have a sufficiently new version of dbus-1 */
-  if (g_strcmp0 (mechanism, "DBUS_COOKIE_SHA1") == 0)
-    {
-      int dbus_major, dbus_minor, dbus_micro;
-      dbus_get_version (&dbus_major, &dbus_minor, &dbus_micro);
-      if (!((dbus_major == 1 && dbus_minor == 4 && dbus_micro >= 21) ||
-            (dbus_major == 1 && dbus_minor == 5 && dbus_micro >= 13) ||
-            (dbus_major == 1 && dbus_minor > 5) ||
-            (dbus_major > 1)))
-        {
-          g_print ("Your libdbus-1 library is too old (version %d.%d.%d) so skipping DBUS_COOKIE_SHA1 test. See https://bugs.freedesktop.org/show_bug.cgi?id=48580 for more details.\n",
-                   dbus_major, dbus_minor, dbus_micro);
-          return;
-        }
-    }
+  TestAuthData data;
 
-  guid = g_dbus_generate_guid ();
-
-#ifdef G_OS_UNIX
-  if (g_unix_socket_address_abstract_names_supported ())
-    {
-      addr = g_strdup ("unix:tmpdir=/tmp/gdbus-test-");
-    }
-  else
-    {
-      gchar *tmpdir;
-      tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL);
-      addr = g_strdup_printf ("unix:tmpdir=%s", tmpdir);
-      g_free (tmpdir);
-    }
-#else
-  addr = g_strdup ("nonce-tcp:");
-#endif
+  server = server_new_for_mechanism (allowed_server_mechanism);
 
   loop = g_main_loop_new (NULL, FALSE);
 
-  auth_observer = g_dbus_auth_observer_new ();
-
-  flags = G_DBUS_SERVER_FLAGS_NONE;
-  if (g_strcmp0 (mechanism, "ANONYMOUS") == 0)
-    flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
-
-  error = NULL;
-  server = g_dbus_server_new_sync (addr,
-                                   flags,
-                                   guid,
-                                   auth_observer,
-                                   NULL, /* cancellable */
-                                   &error);
-  g_assert_no_error (error);
-  g_assert (server != NULL);
-
-  g_signal_connect (auth_observer,
-                    "allow-mechanism",
-                    G_CALLBACK (on_allow_mechanism),
-                    (gpointer) mechanism);
-
   g_signal_connect (server,
                     "new-connection",
-                    G_CALLBACK (on_new_connection),
+                    G_CALLBACK (test_auth_on_new_connection),
                     loop);
 
-  g_dbus_server_start (server);
+  g_timeout_add_seconds (5, test_auth_on_timeout, NULL);
+
+  data.allowed_client_mechanism = allowed_client_mechanism;
+  data.allowed_server_mechanism = allowed_server_mechanism;
+  data.address = g_dbus_server_get_client_address (server);
 
-  g_timeout_add_seconds (5, on_timeout, NULL);
+  /* run the D-Bus client in a thread */
+  client_thread = g_thread_new ("gdbus-client-thread",
+                                test_auth_client_thread_func,
+                                &data);
 
-  /* run the libdbus-1 client in a thread */
-  client_thread = g_thread_new ("dbus-1-client-thread",
-                                dbus_1_client_thread_func,
-                                (gpointer) g_dbus_server_get_client_address (server));
+  g_dbus_server_start (server);
 
   g_main_loop_run (loop);
 
@@ -232,28 +199,82 @@ auth_server_mechanism (const gchar *mechanism)
 
   g_thread_join (client_thread);
 
-  g_free (addr);
-  g_free (guid);
-  g_object_unref (auth_observer);
   g_object_unref (server);
 }
 
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+auth_client_external (void)
+{
+  test_auth_mechanism ("EXTERNAL", NULL);
+}
+
+static void
+auth_client_dbus_cookie_sha1 (void)
+{
+  test_auth_mechanism ("DBUS_COOKIE_SHA1", NULL);
+}
+
 static void
 auth_server_anonymous (void)
 {
-  auth_server_mechanism ("ANONYMOUS");
+  test_auth_mechanism (NULL, "ANONYMOUS");
 }
 
 static void
 auth_server_external (void)
 {
-  auth_server_mechanism ("EXTERNAL");
+  test_auth_mechanism (NULL, "EXTERNAL");
 }
 
 static void
 auth_server_dbus_cookie_sha1 (void)
 {
-  auth_server_mechanism ("DBUS_COOKIE_SHA1");
+  test_auth_mechanism (NULL, "DBUS_COOKIE_SHA1");
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gchar *temp_dbus_keyrings_dir = NULL;
+
+static void
+temp_dbus_keyrings_setup (void)
+{
+  GError *error = NULL;
+
+  g_assert (temp_dbus_keyrings_dir == NULL);
+  temp_dbus_keyrings_dir = g_dir_make_tmp ("gdbus-test-dbus-keyrings-XXXXXX", &error);
+  g_assert_no_error (error);
+  g_assert (temp_dbus_keyrings_dir != NULL);
+  g_setenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR", temp_dbus_keyrings_dir, TRUE);
+  g_setenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION", "1", TRUE);
+}
+
+static void
+temp_dbus_keyrings_teardown (void)
+{
+  GDir *dir;
+  GError *error = NULL;
+  const gchar *name;
+
+  g_assert (temp_dbus_keyrings_dir != NULL);
+
+  dir = g_dir_open (temp_dbus_keyrings_dir, 0, &error);
+  g_assert_no_error (error);
+  g_assert (dir != NULL);
+  while ((name = g_dir_read_name (dir)) != NULL)
+    {
+      gchar *path = g_build_filename (temp_dbus_keyrings_dir, name, NULL);
+      g_assert (unlink (path) == 0);
+      g_free (path);
+    }
+  g_dir_close (dir);
+  g_assert (rmdir (temp_dbus_keyrings_dir) == 0);
+
+  temp_dbus_keyrings_dir = NULL;
+  g_setenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR", NULL, TRUE);
+  g_setenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION", NULL, TRUE);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -266,9 +287,9 @@ main (int   argc,
 
   setlocale (LC_ALL, "C");
 
-  g_test_init (&argc, &argv, NULL);
+  temp_dbus_keyrings_setup ();
 
-  session_bus_up ();
+  g_test_init (&argc, &argv, NULL);
 
   g_test_add_func ("/gdbus/auth/client/EXTERNAL",         auth_client_external);
   g_test_add_func ("/gdbus/auth/client/DBUS_COOKIE_SHA1", auth_client_dbus_cookie_sha1);
@@ -276,10 +297,15 @@ main (int   argc,
   g_test_add_func ("/gdbus/auth/server/EXTERNAL",         auth_server_external);
   g_test_add_func ("/gdbus/auth/server/DBUS_COOKIE_SHA1", auth_server_dbus_cookie_sha1);
 
+  /* TODO: we currently don't have tests for
+   *
+   *  - DBUS_COOKIE_SHA1 timeouts (and clock changes etc)
+   *  - interoperability with libdbus-1 implementations of authentication methods (both client and server)
+   */
+
   ret = g_test_run();
 
-  /* tear down bus */
-  session_bus_down ();
+  temp_dbus_keyrings_teardown ();
 
   return ret;
 }



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