diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am index df96bccde..344601b34 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 cafa13f5c..fddd4cde8 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,138 +39,28 @@ /* ---------------------------------------------------------------------------------------------------- */ 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) -{ - gchar *address = NULL; - GDBusConnection *c = NULL; - GError *error = NULL; - GDBusAuthObserver *auth_observer; - - address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL, &error); - g_assert_no_error (error); - g_assert (address != NULL); - - auth_observer = g_dbus_auth_observer_new (); - - g_signal_connect (auth_observer, - "allow-mechanism", - G_CALLBACK (on_allow_mechanism), - (gpointer) mechanism); - - 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); - g_assert_no_error (error); - g_assert (c != NULL); - - g_free (address); - g_object_unref (c); - g_object_unref (auth_observer); -} - -static void -auth_client_external (void) -{ - auth_client_mechanism ("EXTERNAL"); -} - -static void -auth_client_dbus_cookie_sha1 (void) -{ - auth_client_mechanism ("DBUS_COOKIE_SHA1"); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static gboolean -on_new_connection (GDBusServer *server, - GDBusConnection *connection, - gpointer user_data) -{ - GMainLoop *loop = user_data; - g_main_loop_quit (loop); - return FALSE; -} - -static gboolean -on_timeout (gpointer user_data) -{ - g_error ("Timeout waiting for client"); - g_assert_not_reached (); - return FALSE; -} - -static gpointer -dbus_1_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; - - // For the dbus part, just use dbus-monitor to connect(1) - command_line = g_strdup_printf ("dbus-monitor --address %s", address); - - error = NULL; - rc = g_spawn_command_line_sync (command_line, - &str_stdout, - &str_stderr, - &exit_status, - &error); - g_assert_no_error (error); - g_assert (rc); - g_free (str_stdout); - g_free (str_stderr); - g_free (command_line); - return NULL; -} - -static void -auth_server_mechanism (const gchar *mechanism) +/* pass NULL to allow any mechanism */ +static GDBusServer * +server_new_for_mechanism (const gchar *allowed_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; - } - } - guid = g_dbus_generate_guid (); #ifdef G_OS_UNIX @@ -189,12 +79,10 @@ auth_server_mechanism (const gchar *mechanism) addr = g_strdup ("nonce-tcp:"); #endif - 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) + if (g_strcmp0 (allowed_mechanism, "ANONYMOUS") == 0) flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; error = NULL; @@ -209,51 +97,184 @@ auth_server_mechanism (const gchar *mechanism) g_signal_connect (auth_observer, "allow-mechanism", - G_CALLBACK (on_allow_mechanism), - (gpointer) mechanism); + G_CALLBACK (server_on_allow_mechanism), + (gpointer) allowed_mechanism); + + g_free (addr); + g_free (guid); + g_object_unref (auth_observer); + + return server; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +test_auth_on_new_connection (GDBusServer *server, + GDBusConnection *connection, + gpointer user_data) +{ + GMainLoop *loop = user_data; + g_main_loop_quit (loop); + return FALSE; +} + +static gboolean +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 +test_auth_client_thread_func (gpointer user_data) +{ + TestAuthData *data = user_data; + GDBusConnection *c = NULL; + GError *error = NULL; + GDBusAuthObserver *auth_observer = NULL; + + auth_observer = g_dbus_auth_observer_new (); + + 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 (c != NULL); + g_clear_object (&c); + g_clear_object (&auth_observer); + return NULL; +} + +static void +test_auth_mechanism (const gchar *allowed_client_mechanism, + const gchar *allowed_server_mechanism) +{ + GDBusServer *server; + GMainLoop *loop; + GThread *client_thread; + TestAuthData data; + + server = server_new_for_mechanism (allowed_server_mechanism); + + loop = g_main_loop_new (NULL, FALSE); g_signal_connect (server, "new-connection", - G_CALLBACK (on_new_connection), + G_CALLBACK (test_auth_on_new_connection), loop); + 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); + + /* run the D-Bus client in a thread */ + client_thread = g_thread_new ("gdbus-client-thread", + test_auth_client_thread_func, + &data); + g_dbus_server_start (server); - g_timeout_add_seconds (5, on_timeout, NULL); - - /* 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_main_loop_run (loop); g_dbus_server_stop (server); 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; }