From 81c930ab9ebf4cd0bf9e7c8ef68d94e469bbd89b Mon Sep 17 00:00:00 2001 From: Ralf Habacker <ralf.habacker@freenet.de> Date: Fri, 27 Jan 2017 17:52:19 +0100 Subject: [PATCH] Add glib based test case for testing dbus auth configuration. This patch contains an endless loop fix in spawn_dbus_daemon() in case the spawned process exits unexpected. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=99512 --- cmake/test/CMakeLists.txt | 1 + test/Makefile.am | 12 ++ .../debug-allow-anonymous.conf.in | 14 ++ .../valid-config-files/debug-allow-any.conf.in | 12 ++ .../debug-allow-external.conf.in | 13 ++ .../valid-config-files/debug-allow-invalid.conf.in | 13 ++ .../valid-config-files/debug-allow-sha1.conf.in | 13 ++ test/test-auth.c | 181 +++++++++++++++++++++ test/test-utils-glib.c | 61 +++++-- test/test-utils-glib.h | 6 + 10 files changed, 313 insertions(+), 13 deletions(-) create mode 100644 test/data/valid-config-files/debug-allow-anonymous.conf.in create mode 100644 test/data/valid-config-files/debug-allow-any.conf.in create mode 100644 test/data/valid-config-files/debug-allow-external.conf.in create mode 100644 test/data/valid-config-files/debug-allow-invalid.conf.in create mode 100644 test/data/valid-config-files/debug-allow-sha1.conf.in create mode 100644 test/test-auth.c diff --git a/cmake/test/CMakeLists.txt b/cmake/test/CMakeLists.txt index 58eed09..4111c18 100644 --- a/cmake/test/CMakeLists.txt +++ b/cmake/test/CMakeLists.txt @@ -110,6 +110,7 @@ if(DBUS_WITH_GLIB) add_test_executable(test-syntax ${CMAKE_SOURCE_DIR}/../test/syntax.c ${TEST_LIBRARIES}) add_test_executable(test-syslog ${CMAKE_SOURCE_DIR}/../test/internals/syslog.c ${TEST_LIBRARIES}) add_helper_executable(manual-authz ${CMAKE_SOURCE_DIR}/../test/manual-authz.c ${TEST_LIBRARIES}) + add_test_executable(test-auth ${CMAKE_SOURCE_DIR}/../test/test-auth.c ${TEST_LIBRARIES}) endif() ### keep these in creation order, i.e. uppermost dirs first diff --git a/test/Makefile.am b/test/Makefile.am index eaf2df8..797fd9d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -156,6 +156,7 @@ endif if DBUS_WITH_GLIB installable_tests += \ + test-auth \ test-corrupt \ test-dbus-daemon \ test-dbus-daemon-eavesdrop \ @@ -231,6 +232,12 @@ manual_authz_LDADD = \ $(GLIB_LIBS) \ $(NULL) +test_auth_SOURCES = test-auth.c +test_auth_LDADD = \ + libdbus-testutils.la \ + $(GLIB_LIBS) \ + $(NULL) + test_corrupt_SOURCES = corrupt.c test_corrupt_LDADD = \ libdbus-testutils.la \ @@ -344,6 +351,11 @@ endif DBUS_ENABLE_INSTALLED_TESTS in_data = \ data/valid-config-files-system/debug-allow-all-fail.conf.in \ data/valid-config-files-system/debug-allow-all-pass.conf.in \ + data/valid-config-files/debug-allow-invalid.conf.in \ + data/valid-config-files/debug-allow-anonymous.conf.in \ + data/valid-config-files/debug-allow-external.conf.in \ + data/valid-config-files/debug-allow-sha1.conf.in \ + data/valid-config-files/debug-allow-any.conf.in \ data/valid-config-files/debug-allow-all-sha1.conf.in \ data/valid-config-files/debug-allow-all.conf.in \ data/valid-config-files/finite-timeout.conf.in \ diff --git a/test/data/valid-config-files/debug-allow-anonymous.conf.in b/test/data/valid-config-files/debug-allow-anonymous.conf.in new file mode 100644 index 0000000..e433391 --- /dev/null +++ b/test/data/valid-config-files/debug-allow-anonymous.conf.in @@ -0,0 +1,14 @@ +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <listen>@TEST_LISTEN@</listen> + <auth>ANONYMOUS</auth> + <allow_anonymous/> + <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir> + <policy context="default"> + <allow send_interface="*"/> + <allow receive_interface="*"/> + <allow own="*"/> + <allow user="*"/> + </policy> +</busconfig> diff --git a/test/data/valid-config-files/debug-allow-any.conf.in b/test/data/valid-config-files/debug-allow-any.conf.in new file mode 100644 index 0000000..b4bab47 --- /dev/null +++ b/test/data/valid-config-files/debug-allow-any.conf.in @@ -0,0 +1,12 @@ +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <listen>@TEST_LISTEN@</listen> + <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir> + <policy context="default"> + <allow send_interface="*"/> + <allow receive_interface="*"/> + <allow own="*"/> + <allow user="*"/> + </policy> +</busconfig> diff --git a/test/data/valid-config-files/debug-allow-external.conf.in b/test/data/valid-config-files/debug-allow-external.conf.in new file mode 100644 index 0000000..6c4e8e5 --- /dev/null +++ b/test/data/valid-config-files/debug-allow-external.conf.in @@ -0,0 +1,13 @@ +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <listen>@TEST_LISTEN@</listen> + <auth>EXTERNAL</auth> + <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir> + <policy context="default"> + <allow send_interface="*"/> + <allow receive_interface="*"/> + <allow own="*"/> + <allow user="*"/> + </policy> +</busconfig> diff --git a/test/data/valid-config-files/debug-allow-invalid.conf.in b/test/data/valid-config-files/debug-allow-invalid.conf.in new file mode 100644 index 0000000..1ca544c --- /dev/null +++ b/test/data/valid-config-files/debug-allow-invalid.conf.in @@ -0,0 +1,13 @@ +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <listen>@TEST_LISTEN@</listen> + <auth>INVALID</auth> + <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir> + <policy context="default"> + <allow send_interface="*"/> + <allow receive_interface="*"/> + <allow own="*"/> + <allow user="*"/> + </policy> +</busconfig> diff --git a/test/data/valid-config-files/debug-allow-sha1.conf.in b/test/data/valid-config-files/debug-allow-sha1.conf.in new file mode 100644 index 0000000..1dc57ed --- /dev/null +++ b/test/data/valid-config-files/debug-allow-sha1.conf.in @@ -0,0 +1,13 @@ +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <listen>@TEST_LISTEN@</listen> + <auth>DBUS_COOKIE_SHA1</auth> + <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir> + <policy context="default"> + <allow send_interface="*"/> + <allow receive_interface="*"/> + <allow own="*"/> + <allow user="*"/> + </policy> +</busconfig> diff --git a/test/test-auth.c b/test/test-auth.c new file mode 100644 index 0000000..36094a4 --- /dev/null +++ b/test/test-auth.c @@ -0,0 +1,181 @@ +/* test case for dbus daemon auth configuration + * + * Copyright © 2017 Ralf Habacker <ralf.habacker@freenet.de> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <config.h> + +#include <glib.h> + +#include <dbus/dbus.h> + +#include "test-utils-glib.h" + +typedef struct { + gboolean skip; + TestMainContext *ctx; + + GPid daemon_pid; + gchar *address; + + DBusConnection *client_conn; +} Fixture; + +typedef struct { + const char *config_file; + enum { SPECIFY_ADDRESS = 0, RELY_ON_DEFAULT } connect_mode; +} Config; + +static void +setup (Fixture *f, + gconstpointer context) +{ + const Config *config = context; + + f->ctx = test_main_context_get (); + f->skip = FALSE; + f->address = NULL; + + if (!_test_get_dbus_daemon (config ? config->config_file : NULL, + TEST_USER_ME, + &f->daemon_pid, &f->address)) + { + g_test_skip ("could not start dbus daemon"); + f->skip = TRUE; + } + f->client_conn = 0; +} + +static dbus_bool_t +_test_connect_to_bus (Fixture *f) +{ + DBusError error = DBUS_ERROR_INIT; + dbus_bool_t ok; + + f->client_conn = dbus_connection_open_private (f->address, &error); + if (dbus_error_is_set (&error)) + return FALSE; + + if (f->client_conn == NULL) + return FALSE; + + ok = dbus_bus_register (f->client_conn, &error); + if (dbus_error_is_set (&error)) + return FALSE; + + if (!ok) + return FALSE; + + if (dbus_bus_get_unique_name (f->client_conn) == NULL) + return FALSE; + + test_connection_setup (f->ctx, f->client_conn); + return TRUE; +} + +static void +test_invalid (Fixture *f, gconstpointer context) +{ + if (f->skip) + return; + if (f->address != NULL) + g_test_fail(); +} + +static void +test_valid (Fixture *f, gconstpointer context) +{ + if (f->skip) + return; + if (f->address == NULL) + { + g_test_fail(); + return; + } + if (!_test_connect_to_bus (f)) + g_test_fail(); +} + +static void +teardown (Fixture *f, + gconstpointer context G_GNUC_UNUSED) +{ + if (f->client_conn != NULL) + { + dbus_connection_close (f->client_conn); + dbus_connection_unref (f->client_conn); + f->client_conn = NULL; + } + + if (f->daemon_pid != 0) + { + test_kill_pid (f->daemon_pid); + g_spawn_close_pid (f->daemon_pid); + f->daemon_pid = 0; + } + + test_main_context_unref (f->ctx); + g_free (f->address); +} + +static Config config_invalid = { + "valid-config-files/debug-allow-invalid.conf", + SPECIFY_ADDRESS +}; + +static Config config_external = { + "valid-config-files/debug-allow-external.conf", + SPECIFY_ADDRESS +}; + +static Config config_sha1 = { + "valid-config-files/debug-allow-sha1.conf", + SPECIFY_ADDRESS +}; + +static Config config_anonymous = { + "valid-config-files/debug-allow-anonymous.conf", + SPECIFY_ADDRESS +}; + +static Config config_any = { + "valid-config-files/debug-allow-any.conf", + SPECIFY_ADDRESS +}; + +int +main (int argc, + char **argv) +{ + test_init (&argc, &argv); + + g_test_add ("/auth/invalid", Fixture, &config_invalid, setup, test_invalid, teardown); + g_test_add ("/auth/external", Fixture, &config_external, setup, test_valid, teardown); + g_test_add ("/auth/sha1", Fixture, &config_sha1, setup, test_valid, teardown); + g_test_add ("/auth/anonymous", Fixture, &config_anonymous, setup, test_valid, teardown); + g_test_add ("/auth/any", Fixture, &config_any, setup, test_valid, teardown); + + return g_test_run (); + + return 0; +} diff --git a/test/test-utils-glib.c b/test/test-utils-glib.c index 2ba4451..6609942 100644 --- a/test/test-utils-glib.c +++ b/test/test-utils-glib.c @@ -105,6 +105,7 @@ spawn_dbus_daemon (const gchar *binary, const struct passwd *pwd = NULL; #endif char *envp[2] = { "DBUS_VERBOSE=1", NULL }; + gboolean is_running = TRUE; if (!g_getenv ("DBUS_VERBOSE") || *g_getenv ("DBUS_VERBOSE") == '0') envp[0] = NULL; @@ -200,7 +201,7 @@ spawn_dbus_daemon (const gchar *binary, /* polling until the dbus-daemon writes out its address is a bit stupid, * but at least it's simple, unlike dbus-launch... in principle we could * use select() here, but life's too short */ - while (1) + while (is_running) { gssize bytes; gchar buf[4096]; @@ -222,11 +223,12 @@ spawn_dbus_daemon (const gchar *binary, } g_usleep (G_USEC_PER_SEC / 10); + is_running = test_check_pid (*daemon_pid); } g_close (address_fd, NULL); - return g_string_free (address, FALSE); + return is_running ? g_string_free (address, FALSE) : 0; } gchar * @@ -234,10 +236,23 @@ test_get_dbus_daemon (const gchar *config_file, TestUser user, GPid *daemon_pid) { - gchar *dbus_daemon; - gchar *arg; + gchar **address = 0; + if (_test_get_dbus_daemon (config_file, user, daemon_pid, address)) + return *address; + else + return NULL; +} + +dbus_bool_t +_test_get_dbus_daemon (const gchar *config_file, + TestUser user, + GPid *daemon_pid, + gchar **address) +{ + gchar *dbus_daemon = NULL; + gchar *arg = NULL; const gchar *listen_address = NULL; - gchar *address; + dbus_bool_t result = FALSE; /* we often have to override this because on Windows, the default may be * autolaunch:, which is globally-scoped and hence unsuitable for @@ -246,13 +261,12 @@ test_get_dbus_daemon (const gchar *config_file, if (config_file != NULL) { - if (g_getenv ("DBUS_TEST_DATA") == NULL) { g_test_message ("set DBUS_TEST_DATA to a directory containing %s", config_file); g_test_skip ("DBUS_TEST_DATA not set"); - return NULL; + goto fail; } arg = g_strdup_printf ( @@ -290,22 +304,27 @@ test_get_dbus_daemon (const gchar *config_file, { g_test_skip ("cannot use DBUS_TEST_DAEMON_ADDRESS for " "unusally-configured dbus-daemon"); - address = NULL; + goto fail; } else { - address = g_strdup (g_getenv ("DBUS_TEST_DAEMON_ADDRESS")); + *address = g_strdup (g_getenv ("DBUS_TEST_DAEMON_ADDRESS")); + result = TRUE; } } else { - address = spawn_dbus_daemon (dbus_daemon, arg, + *address = spawn_dbus_daemon (dbus_daemon, arg, listen_address, user, daemon_pid); + result = TRUE; } - g_free (dbus_daemon); - g_free (arg); - return address; +fail: + if (dbus_daemon) + g_free (dbus_daemon); + if (arg) + g_free (arg); + return result; } DBusConnection * @@ -425,6 +444,22 @@ test_kill_pid (GPid pid) #endif } +gboolean +test_check_pid (GPid pid) +{ +#ifdef DBUS_WIN + DWORD ret = WaitForSingleObject(pid, 0); + return ret == WAIT_TIMEOUT; +#else + int wstatus; + if (waitpid (pid, &wstatus, WNOHANG) == -1) + return FALSE; + if (WIFEXITED (wstatus)) + return FALSE; + return TRUE; +#endif +} + static gboolean time_out (gpointer data) { diff --git a/test/test-utils-glib.h b/test/test-utils-glib.h index acacee0..f892fc3 100644 --- a/test/test-utils-glib.h +++ b/test/test-utils-glib.h @@ -71,6 +71,11 @@ gchar *test_get_dbus_daemon (const gchar *config_file, TestUser user, GPid *daemon_pid); +dbus_bool_t _test_get_dbus_daemon (const gchar *config_file, + TestUser user, + GPid *daemon_pid, + gchar **address); + DBusConnection *test_connect_to_bus (TestMainContext *ctx, const gchar *address); DBusConnection *test_connect_to_bus_as_user (TestMainContext *ctx, @@ -78,6 +83,7 @@ DBusConnection *test_connect_to_bus_as_user (TestMainContext *ctx, TestUser user); void test_kill_pid (GPid pid); +gboolean test_check_pid (GPid pid); void test_init (int *argcp, char ***argvp); -- 2.6.6