summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorSimon McVittie <smcv@debian.org>2015-02-09 13:32:57 +0000
committerSimon McVittie <smcv@debian.org>2015-02-09 13:32:57 +0000
commit8fd2c8098849695fce037fa3731a916ac5354e91 (patch)
tree71ee233983f8d60f96a34ef602b8e85a51301462 /test
parentdf40668f10c30c52a3f8bd50868ba31108a2eee2 (diff)
downloaddbus-8fd2c8098849695fce037fa3731a916ac5354e91.tar.gz
Imported Upstream version 1.9.10upstream/1.9.10
Diffstat (limited to 'test')
-rw-r--r--test/Makefile.am33
-rw-r--r--test/Makefile.in144
-rw-r--r--test/corrupt.c4
-rw-r--r--test/data/valid-config-files/forbidding.conf.in18
-rw-r--r--test/dbus-daemon-eavesdrop.c3
-rw-r--r--test/dbus-daemon.c3
-rw-r--r--test/fdpass.c852
-rw-r--r--test/internals/refs.c5
-rw-r--r--test/internals/syslog.c5
-rw-r--r--test/loopback.c5
-rw-r--r--test/marshal.c4
-rw-r--r--test/monitor.c1496
-rw-r--r--test/relay.c5
-rw-r--r--test/sd-activation.c34
-rw-r--r--test/syntax.c4
-rw-r--r--test/test-utils-glib.c26
-rw-r--r--test/test-utils-glib.h2
-rw-r--r--test/uid-permissions.c3
18 files changed, 2607 insertions, 39 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index 8b84c7d2..c2a55c9e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -156,6 +156,8 @@ installable_tests += \
test-corrupt \
test-dbus-daemon \
test-dbus-daemon-eavesdrop \
+ test-fdpass \
+ test-monitor \
test-loopback \
test-marshal \
test-refs \
@@ -240,14 +242,25 @@ test_sd_activation_LDADD = \
$(NULL)
test_marshal_SOURCES = marshal.c
+test_marshal_CPPFLAGS = $(testutils_shared_if_possible_cppflags)
test_marshal_LDADD = \
- $(top_builddir)/dbus/libdbus-1.la \
+ $(testutils_shared_if_possible_libs) \
+ $(GLIB_LIBS) \
+ $(NULL)
+
+test_monitor_SOURCES = \
+ monitor.c \
+ $(NULL)
+test_monitor_CPPFLAGS = $(testutils_shared_if_possible_cppflags)
+test_monitor_LDADD = \
+ $(testutils_shared_if_possible_libs) \
$(GLIB_LIBS) \
$(NULL)
test_syntax_SOURCES = syntax.c
+test_syntax_CPPFLAGS = $(testutils_shared_if_possible_cppflags)
test_syntax_LDADD = \
- $(top_builddir)/dbus/libdbus-1.la \
+ $(testutils_shared_if_possible_libs) \
$(GLIB_LIBS) \
$(NULL)
@@ -260,6 +273,17 @@ test_uid_permissions_LDADD = \
$(GLIB_LIBS) \
$(NULL)
+test_fdpass_SOURCES = \
+ fdpass.c \
+ $(NULL)
+test_fdpass_CPPFLAGS = \
+ $(static_cppflags) \
+ $(NULL)
+test_fdpass_LDADD = \
+ libdbus-testutils-internal.la \
+ $(GLIB_LIBS) \
+ $(NULL)
+
if DBUS_ENABLE_MODULAR_TESTS
TESTS += $(installable_tests)
installcheck_tests += $(installable_tests)
@@ -295,6 +319,7 @@ in_data = \
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 \
+ data/valid-config-files/forbidding.conf.in \
data/valid-config-files/incoming-limit.conf.in \
data/valid-config-files/multi-user.conf.in \
data/valid-config-files/systemd-activation.conf.in \
@@ -492,14 +517,14 @@ $(imported_data): data/valid-config-files/%.conf: $(top_builddir)/bus/%.conf
$(AM_V_at)$(MKDIR_P) data/valid-config-files
$(AM_V_GEN)cp $< $@
-$(installable_test_meta): %.test: % Makefile
+$(installable_test_meta): %.test: %$(EXEEXT) Makefile
$(AM_V_GEN) ( \
echo '[Test]'; \
echo 'Type=session'; \
echo 'Exec=env DBUS_TEST_HOME=$$(pwd)/home.tmp $(testexecdir)/$*'; \
) > $@.tmp && mv $@.tmp $@
-$(installable_test_meta_with_config): %_with_config.test: % Makefile
+$(installable_test_meta_with_config): %_with_config.test: %$(EXEEXT) Makefile
$(AM_V_GEN) ( \
echo '[Test]'; \
echo 'Type=session'; \
diff --git a/test/Makefile.in b/test/Makefile.in
index 9231159b..01a0879e 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -103,6 +103,8 @@ testexec_PROGRAMS = $(am__EXEEXT_7)
@DBUS_WITH_GLIB_TRUE@ test-corrupt \
@DBUS_WITH_GLIB_TRUE@ test-dbus-daemon \
@DBUS_WITH_GLIB_TRUE@ test-dbus-daemon-eavesdrop \
+@DBUS_WITH_GLIB_TRUE@ test-fdpass \
+@DBUS_WITH_GLIB_TRUE@ test-monitor \
@DBUS_WITH_GLIB_TRUE@ test-loopback \
@DBUS_WITH_GLIB_TRUE@ test-marshal \
@DBUS_WITH_GLIB_TRUE@ test-refs \
@@ -176,6 +178,8 @@ libdbus_testutils_la_OBJECTS = $(am_libdbus_testutils_la_OBJECTS)
@DBUS_WITH_GLIB_TRUE@am__EXEEXT_2 = test-corrupt$(EXEEXT) \
@DBUS_WITH_GLIB_TRUE@ test-dbus-daemon$(EXEEXT) \
@DBUS_WITH_GLIB_TRUE@ test-dbus-daemon-eavesdrop$(EXEEXT) \
+@DBUS_WITH_GLIB_TRUE@ test-fdpass$(EXEEXT) \
+@DBUS_WITH_GLIB_TRUE@ test-monitor$(EXEEXT) \
@DBUS_WITH_GLIB_TRUE@ test-loopback$(EXEEXT) \
@DBUS_WITH_GLIB_TRUE@ test-marshal$(EXEEXT) test-refs$(EXEEXT) \
@DBUS_WITH_GLIB_TRUE@ test-relay$(EXEEXT) \
@@ -223,13 +227,21 @@ test_dbus_daemon_eavesdrop_DEPENDENCIES = \
test_exit_SOURCES = test-exit.c
test_exit_OBJECTS = test-exit.$(OBJEXT)
test_exit_LDADD = $(LDADD)
+am_test_fdpass_OBJECTS = test_fdpass-fdpass.$(OBJEXT)
+test_fdpass_OBJECTS = $(am_test_fdpass_OBJECTS)
+test_fdpass_DEPENDENCIES = libdbus-testutils-internal.la \
+ $(am__DEPENDENCIES_1)
am_test_loopback_OBJECTS = test_loopback-loopback.$(OBJEXT)
test_loopback_OBJECTS = $(am_test_loopback_OBJECTS)
test_loopback_DEPENDENCIES = $(testutils_shared_if_possible_libs) \
$(am__DEPENDENCIES_1)
-am_test_marshal_OBJECTS = marshal.$(OBJEXT)
+am_test_marshal_OBJECTS = test_marshal-marshal.$(OBJEXT)
test_marshal_OBJECTS = $(am_test_marshal_OBJECTS)
-test_marshal_DEPENDENCIES = $(top_builddir)/dbus/libdbus-1.la \
+test_marshal_DEPENDENCIES = $(testutils_shared_if_possible_libs) \
+ $(am__DEPENDENCIES_1)
+am_test_monitor_OBJECTS = test_monitor-monitor.$(OBJEXT)
+test_monitor_OBJECTS = $(am_test_monitor_OBJECTS)
+test_monitor_DEPENDENCIES = $(testutils_shared_if_possible_libs) \
$(am__DEPENDENCIES_1)
test_names_SOURCES = test-names.c
test_names_OBJECTS = test_names-test-names.$(OBJEXT)
@@ -270,9 +282,9 @@ test_sleep_forever_LDADD = $(LDADD)
am_test_spawn_OBJECTS = test_spawn-spawn-test.$(OBJEXT)
test_spawn_OBJECTS = $(am_test_spawn_OBJECTS)
test_spawn_DEPENDENCIES = $(top_builddir)/dbus/libdbus-internal.la
-am_test_syntax_OBJECTS = syntax.$(OBJEXT)
+am_test_syntax_OBJECTS = test_syntax-syntax.$(OBJEXT)
test_syntax_OBJECTS = $(am_test_syntax_OBJECTS)
-test_syntax_DEPENDENCIES = $(top_builddir)/dbus/libdbus-1.la \
+test_syntax_DEPENDENCIES = $(testutils_shared_if_possible_libs) \
$(am__DEPENDENCIES_1)
am_test_syslog_OBJECTS = internals/test_syslog-syslog.$(OBJEXT)
test_syslog_OBJECTS = $(am_test_syslog_OBJECTS)
@@ -322,7 +334,8 @@ SOURCES = $(libdbus_testutils_internal_la_SOURCES) \
$(manual_dir_iter_SOURCES) $(manual_tcp_SOURCES) \
$(test_corrupt_SOURCES) $(test_dbus_daemon_SOURCES) \
$(test_dbus_daemon_eavesdrop_SOURCES) test-exit.c \
- $(test_loopback_SOURCES) $(test_marshal_SOURCES) test-names.c \
+ $(test_fdpass_SOURCES) $(test_loopback_SOURCES) \
+ $(test_marshal_SOURCES) $(test_monitor_SOURCES) test-names.c \
$(test_printf_SOURCES) $(test_refs_SOURCES) \
$(test_relay_SOURCES) $(test_sd_activation_SOURCES) \
test-segfault.c test-service.c $(test_shell_SOURCES) \
@@ -335,7 +348,8 @@ DIST_SOURCES = $(am__libdbus_testutils_internal_la_SOURCES_DIST) \
$(manual_tcp_SOURCES) $(test_corrupt_SOURCES) \
$(test_dbus_daemon_SOURCES) \
$(test_dbus_daemon_eavesdrop_SOURCES) test-exit.c \
- $(test_loopback_SOURCES) $(test_marshal_SOURCES) test-names.c \
+ $(test_fdpass_SOURCES) $(test_loopback_SOURCES) \
+ $(test_marshal_SOURCES) $(test_monitor_SOURCES) test-names.c \
$(test_printf_SOURCES) $(test_refs_SOURCES) \
$(test_relay_SOURCES) $(test_sd_activation_SOURCES) \
test-segfault.c test-service.c $(test_shell_SOURCES) \
@@ -982,14 +996,26 @@ test_sd_activation_LDADD = \
$(NULL)
test_marshal_SOURCES = marshal.c
+test_marshal_CPPFLAGS = $(testutils_shared_if_possible_cppflags)
test_marshal_LDADD = \
- $(top_builddir)/dbus/libdbus-1.la \
+ $(testutils_shared_if_possible_libs) \
+ $(GLIB_LIBS) \
+ $(NULL)
+
+test_monitor_SOURCES = \
+ monitor.c \
+ $(NULL)
+
+test_monitor_CPPFLAGS = $(testutils_shared_if_possible_cppflags)
+test_monitor_LDADD = \
+ $(testutils_shared_if_possible_libs) \
$(GLIB_LIBS) \
$(NULL)
test_syntax_SOURCES = syntax.c
+test_syntax_CPPFLAGS = $(testutils_shared_if_possible_cppflags)
test_syntax_LDADD = \
- $(top_builddir)/dbus/libdbus-1.la \
+ $(testutils_shared_if_possible_libs) \
$(GLIB_LIBS) \
$(NULL)
@@ -1003,12 +1029,26 @@ test_uid_permissions_LDADD = \
$(GLIB_LIBS) \
$(NULL)
+test_fdpass_SOURCES = \
+ fdpass.c \
+ $(NULL)
+
+test_fdpass_CPPFLAGS = \
+ $(static_cppflags) \
+ $(NULL)
+
+test_fdpass_LDADD = \
+ libdbus-testutils-internal.la \
+ $(GLIB_LIBS) \
+ $(NULL)
+
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-all-sha1.conf.in \
data/valid-config-files/debug-allow-all.conf.in \
data/valid-config-files/finite-timeout.conf.in \
+ data/valid-config-files/forbidding.conf.in \
data/valid-config-files/incoming-limit.conf.in \
data/valid-config-files/multi-user.conf.in \
data/valid-config-files/systemd-activation.conf.in \
@@ -1254,6 +1294,10 @@ test-exit$(EXEEXT): $(test_exit_OBJECTS) $(test_exit_DEPENDENCIES) $(EXTRA_test_
@rm -f test-exit$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_exit_OBJECTS) $(test_exit_LDADD) $(LIBS)
+test-fdpass$(EXEEXT): $(test_fdpass_OBJECTS) $(test_fdpass_DEPENDENCIES) $(EXTRA_test_fdpass_DEPENDENCIES)
+ @rm -f test-fdpass$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fdpass_OBJECTS) $(test_fdpass_LDADD) $(LIBS)
+
test-loopback$(EXEEXT): $(test_loopback_OBJECTS) $(test_loopback_DEPENDENCIES) $(EXTRA_test_loopback_DEPENDENCIES)
@rm -f test-loopback$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_loopback_OBJECTS) $(test_loopback_LDADD) $(LIBS)
@@ -1262,6 +1306,10 @@ test-marshal$(EXEEXT): $(test_marshal_OBJECTS) $(test_marshal_DEPENDENCIES) $(EX
@rm -f test-marshal$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_marshal_OBJECTS) $(test_marshal_LDADD) $(LIBS)
+test-monitor$(EXEEXT): $(test_monitor_OBJECTS) $(test_monitor_DEPENDENCIES) $(EXTRA_test_monitor_DEPENDENCIES)
+ @rm -f test-monitor$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_monitor_OBJECTS) $(test_monitor_LDADD) $(LIBS)
+
test-names$(EXEEXT): $(test_names_OBJECTS) $(test_names_DEPENDENCIES) $(EXTRA_test_names_DEPENDENCIES)
@rm -f test-names$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_names_OBJECTS) $(test_names_LDADD) $(LIBS)
@@ -1342,8 +1390,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manual_authz-manual-authz.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manual_dir_iter-manual-dir-iter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manual_tcp-manual-tcp.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/marshal.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syntax.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-exit.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-segfault.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-sleep-forever.Po@am__quote@
@@ -1352,7 +1398,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_corrupt-corrupt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dbus_daemon-dbus-daemon.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dbus_daemon_eavesdrop-dbus-daemon-eavesdrop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fdpass-fdpass.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_loopback-loopback.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_marshal-marshal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_monitor-monitor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_names-test-names.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_relay-relay.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_sd_activation-sd-activation.Po@am__quote@
@@ -1360,6 +1409,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_shell-shell-test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_shell_service-test-shell-service.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_spawn-spawn-test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_syntax-syntax.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_uid_permissions-uid-permissions.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@internals/$(DEPDIR)/test_printf-printf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@internals/$(DEPDIR)/test_refs-refs.Po@am__quote@
@@ -1487,6 +1537,20 @@ test_dbus_daemon_eavesdrop-dbus-daemon-eavesdrop.obj: dbus-daemon-eavesdrop.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dbus_daemon_eavesdrop_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_dbus_daemon_eavesdrop-dbus-daemon-eavesdrop.obj `if test -f 'dbus-daemon-eavesdrop.c'; then $(CYGPATH_W) 'dbus-daemon-eavesdrop.c'; else $(CYGPATH_W) '$(srcdir)/dbus-daemon-eavesdrop.c'; fi`
+test_fdpass-fdpass.o: fdpass.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fdpass_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_fdpass-fdpass.o -MD -MP -MF $(DEPDIR)/test_fdpass-fdpass.Tpo -c -o test_fdpass-fdpass.o `test -f 'fdpass.c' || echo '$(srcdir)/'`fdpass.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_fdpass-fdpass.Tpo $(DEPDIR)/test_fdpass-fdpass.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fdpass.c' object='test_fdpass-fdpass.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fdpass_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_fdpass-fdpass.o `test -f 'fdpass.c' || echo '$(srcdir)/'`fdpass.c
+
+test_fdpass-fdpass.obj: fdpass.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fdpass_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_fdpass-fdpass.obj -MD -MP -MF $(DEPDIR)/test_fdpass-fdpass.Tpo -c -o test_fdpass-fdpass.obj `if test -f 'fdpass.c'; then $(CYGPATH_W) 'fdpass.c'; else $(CYGPATH_W) '$(srcdir)/fdpass.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_fdpass-fdpass.Tpo $(DEPDIR)/test_fdpass-fdpass.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fdpass.c' object='test_fdpass-fdpass.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fdpass_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_fdpass-fdpass.obj `if test -f 'fdpass.c'; then $(CYGPATH_W) 'fdpass.c'; else $(CYGPATH_W) '$(srcdir)/fdpass.c'; fi`
+
test_loopback-loopback.o: loopback.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_loopback_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_loopback-loopback.o -MD -MP -MF $(DEPDIR)/test_loopback-loopback.Tpo -c -o test_loopback-loopback.o `test -f 'loopback.c' || echo '$(srcdir)/'`loopback.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_loopback-loopback.Tpo $(DEPDIR)/test_loopback-loopback.Po
@@ -1501,6 +1565,34 @@ test_loopback-loopback.obj: loopback.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_loopback_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_loopback-loopback.obj `if test -f 'loopback.c'; then $(CYGPATH_W) 'loopback.c'; else $(CYGPATH_W) '$(srcdir)/loopback.c'; fi`
+test_marshal-marshal.o: marshal.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_marshal_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_marshal-marshal.o -MD -MP -MF $(DEPDIR)/test_marshal-marshal.Tpo -c -o test_marshal-marshal.o `test -f 'marshal.c' || echo '$(srcdir)/'`marshal.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_marshal-marshal.Tpo $(DEPDIR)/test_marshal-marshal.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='marshal.c' object='test_marshal-marshal.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_marshal_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_marshal-marshal.o `test -f 'marshal.c' || echo '$(srcdir)/'`marshal.c
+
+test_marshal-marshal.obj: marshal.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_marshal_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_marshal-marshal.obj -MD -MP -MF $(DEPDIR)/test_marshal-marshal.Tpo -c -o test_marshal-marshal.obj `if test -f 'marshal.c'; then $(CYGPATH_W) 'marshal.c'; else $(CYGPATH_W) '$(srcdir)/marshal.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_marshal-marshal.Tpo $(DEPDIR)/test_marshal-marshal.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='marshal.c' object='test_marshal-marshal.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_marshal_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_marshal-marshal.obj `if test -f 'marshal.c'; then $(CYGPATH_W) 'marshal.c'; else $(CYGPATH_W) '$(srcdir)/marshal.c'; fi`
+
+test_monitor-monitor.o: monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_monitor-monitor.o -MD -MP -MF $(DEPDIR)/test_monitor-monitor.Tpo -c -o test_monitor-monitor.o `test -f 'monitor.c' || echo '$(srcdir)/'`monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_monitor-monitor.Tpo $(DEPDIR)/test_monitor-monitor.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='monitor.c' object='test_monitor-monitor.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_monitor-monitor.o `test -f 'monitor.c' || echo '$(srcdir)/'`monitor.c
+
+test_monitor-monitor.obj: monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_monitor-monitor.obj -MD -MP -MF $(DEPDIR)/test_monitor-monitor.Tpo -c -o test_monitor-monitor.obj `if test -f 'monitor.c'; then $(CYGPATH_W) 'monitor.c'; else $(CYGPATH_W) '$(srcdir)/monitor.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_monitor-monitor.Tpo $(DEPDIR)/test_monitor-monitor.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='monitor.c' object='test_monitor-monitor.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_monitor_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_monitor-monitor.obj `if test -f 'monitor.c'; then $(CYGPATH_W) 'monitor.c'; else $(CYGPATH_W) '$(srcdir)/monitor.c'; fi`
+
test_names-test-names.o: test-names.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_names_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_names-test-names.o -MD -MP -MF $(DEPDIR)/test_names-test-names.Tpo -c -o test_names-test-names.o `test -f 'test-names.c' || echo '$(srcdir)/'`test-names.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_names-test-names.Tpo $(DEPDIR)/test_names-test-names.Po
@@ -1627,6 +1719,20 @@ test_spawn-spawn-test.obj: spawn-test.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_spawn_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_spawn-spawn-test.obj `if test -f 'spawn-test.c'; then $(CYGPATH_W) 'spawn-test.c'; else $(CYGPATH_W) '$(srcdir)/spawn-test.c'; fi`
+test_syntax-syntax.o: syntax.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_syntax_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_syntax-syntax.o -MD -MP -MF $(DEPDIR)/test_syntax-syntax.Tpo -c -o test_syntax-syntax.o `test -f 'syntax.c' || echo '$(srcdir)/'`syntax.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_syntax-syntax.Tpo $(DEPDIR)/test_syntax-syntax.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='syntax.c' object='test_syntax-syntax.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_syntax_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_syntax-syntax.o `test -f 'syntax.c' || echo '$(srcdir)/'`syntax.c
+
+test_syntax-syntax.obj: syntax.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_syntax_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_syntax-syntax.obj -MD -MP -MF $(DEPDIR)/test_syntax-syntax.Tpo -c -o test_syntax-syntax.obj `if test -f 'syntax.c'; then $(CYGPATH_W) 'syntax.c'; else $(CYGPATH_W) '$(srcdir)/syntax.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_syntax-syntax.Tpo $(DEPDIR)/test_syntax-syntax.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='syntax.c' object='test_syntax-syntax.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_syntax_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_syntax-syntax.obj `if test -f 'syntax.c'; then $(CYGPATH_W) 'syntax.c'; else $(CYGPATH_W) '$(srcdir)/syntax.c'; fi`
+
internals/test_syslog-syslog.o: internals/syslog.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_syslog_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT internals/test_syslog-syslog.o -MD -MP -MF internals/$(DEPDIR)/test_syslog-syslog.Tpo -c -o internals/test_syslog-syslog.o `test -f 'internals/syslog.c' || echo '$(srcdir)/'`internals/syslog.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) internals/$(DEPDIR)/test_syslog-syslog.Tpo internals/$(DEPDIR)/test_syslog-syslog.Po
@@ -1957,6 +2063,20 @@ test-dbus-daemon-eavesdrop.log: test-dbus-daemon-eavesdrop$(EXEEXT)
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+test-fdpass.log: test-fdpass$(EXEEXT)
+ @p='test-fdpass$(EXEEXT)'; \
+ b='test-fdpass'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-monitor.log: test-monitor$(EXEEXT)
+ @p='test-monitor$(EXEEXT)'; \
+ b='test-monitor'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
test-loopback.log: test-loopback$(EXEEXT)
@p='test-loopback$(EXEEXT)'; \
b='test-loopback'; \
@@ -2337,14 +2457,14 @@ $(imported_data): data/valid-config-files/%.conf: $(top_builddir)/bus/%.conf
$(AM_V_at)$(MKDIR_P) data/valid-config-files
$(AM_V_GEN)cp $< $@
-$(installable_test_meta): %.test: % Makefile
+$(installable_test_meta): %.test: %$(EXEEXT) Makefile
$(AM_V_GEN) ( \
echo '[Test]'; \
echo 'Type=session'; \
echo 'Exec=env DBUS_TEST_HOME=$$(pwd)/home.tmp $(testexecdir)/$*'; \
) > $@.tmp && mv $@.tmp $@
-$(installable_test_meta_with_config): %_with_config.test: % Makefile
+$(installable_test_meta_with_config): %_with_config.test: %$(EXEEXT) Makefile
$(AM_V_GEN) ( \
echo '[Test]'; \
echo 'Type=session'; \
diff --git a/test/corrupt.c b/test/corrupt.c
index b0084fd3..500cbeb7 100644
--- a/test/corrupt.c
+++ b/test/corrupt.c
@@ -31,7 +31,7 @@
#include <dbus/dbus.h>
-#include "test-utils.h"
+#include "test-utils-glib.h"
typedef struct {
DBusError e;
@@ -379,7 +379,7 @@ int
main (int argc,
char **argv)
{
- g_test_init (&argc, &argv, NULL);
+ test_init (&argc, &argv);
g_test_add ("/corrupt/tcp", Fixture, "tcp:host=127.0.0.1", setup,
test_corrupt, teardown);
diff --git a/test/data/valid-config-files/forbidding.conf.in b/test/data/valid-config-files/forbidding.conf.in
new file mode 100644
index 00000000..6a674f88
--- /dev/null
+++ b/test/data/valid-config-files/forbidding.conf.in
@@ -0,0 +1,18 @@
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <!-- Our well-known bus type, don't change this -->
+ <type>session</type>
+ <listen>@TEST_LISTEN@</listen>
+
+ <policy context="default">
+ <!-- Allow everything -->
+ <allow send_destination="*"/>
+ <allow receive_sender="*"/>
+ <allow own="*"/>
+
+ <!-- Exception: some messages are forbidden -->
+ <deny send_interface="com.example.CannotSend"/>
+ <deny receive_interface="com.example.CannotReceive"/>
+ </policy>
+</busconfig>
diff --git a/test/dbus-daemon-eavesdrop.c b/test/dbus-daemon-eavesdrop.c
index 686ccb35..41985787 100644
--- a/test/dbus-daemon-eavesdrop.c
+++ b/test/dbus-daemon-eavesdrop.c
@@ -413,8 +413,7 @@ int
main (int argc,
char **argv)
{
- g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id=");
+ test_init (&argc, &argv);
g_test_add ("/eavedrop/match_keyword/broadcast", Fixture, NULL,
setup, test_eavesdrop_broadcast, teardown);
diff --git a/test/dbus-daemon.c b/test/dbus-daemon.c
index 02590904..6b0e9b8a 100644
--- a/test/dbus-daemon.c
+++ b/test/dbus-daemon.c
@@ -608,8 +608,7 @@ int
main (int argc,
char **argv)
{
- g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id=");
+ test_init (&argc, &argv);
g_test_add ("/echo/session", Fixture, NULL, setup, test_echo, teardown);
g_test_add ("/echo/limited", Fixture, &limited_config,
diff --git a/test/fdpass.c b/test/fdpass.c
new file mode 100644
index 00000000..fa958da8
--- /dev/null
+++ b/test/fdpass.c
@@ -0,0 +1,852 @@
+/*
+ * Copyright © 2010-2012 Nokia Corporation
+ * Copyright © 2014 Collabora Ltd.
+ *
+ * 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 <dbus/dbus.h>
+#include <dbus/dbus-internals.h>
+#include <dbus/dbus-sysdeps.h>
+
+#include <glib.h>
+
+#include <string.h>
+
+#ifdef G_OS_UNIX
+# include <dbus/dbus-sysdeps-unix.h>
+
+# include <errno.h>
+# include <fcntl.h>
+# ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+# endif
+# include <sys/stat.h>
+# include <sys/time.h>
+# include <sys/types.h>
+# include <unistd.h>
+#endif
+
+#include "test-utils-glib.h"
+
+/* Arbitrary; included here to avoid relying on the default */
+#define MAX_MESSAGE_UNIX_FDS 20
+/* This test won't work on Linux unless this is true. */
+_DBUS_STATIC_ASSERT (MAX_MESSAGE_UNIX_FDS <= 253);
+
+/* Arbitrary; included here to avoid relying on the default. */
+#define MAX_INCOMING_UNIX_FDS (MAX_MESSAGE_UNIX_FDS * 4)
+
+/* Arbitrary, except that MAX_MESSAGE_UNIX_FDS * SOME_MESSAGES must be
+ * less than the process's file descriptor limit. */
+#define SOME_MESSAGES 50
+
+/* Linux won't allow more than 253 fds per sendmsg(). */
+#define TOO_MANY_FDS 255
+_DBUS_STATIC_ASSERT (MAX_MESSAGE_UNIX_FDS < TOO_MANY_FDS);
+
+/* As in test/relay.c, this is a miniature dbus-daemon: we relay messages
+ * from the client on the left to the client on the right.
+ *
+ * left socket left dispatch right socket right
+ * client ===========> server --------------> server ===========> client
+ * conn conn conn conn
+ */
+
+typedef struct {
+ TestMainContext *ctx;
+ DBusError e;
+
+ DBusServer *server;
+
+ DBusConnection *left_client_conn;
+ DBusConnection *left_server_conn;
+
+ DBusConnection *right_server_conn;
+ DBusConnection *right_client_conn;
+ /* queue of DBusMessage received by right_client_conn */
+ GQueue messages;
+
+ int fd_before;
+} Fixture;
+
+#if !GLIB_CHECK_VERSION (2, 38, 0)
+#define g_test_skip(s) my_test_skip (s)
+static inline void my_test_skip (const gchar *s)
+{
+ g_message ("SKIP: %s", s);
+}
+#endif
+
+#ifdef HAVE_UNIX_FD_PASSING
+
+static void oom (const gchar *doing) G_GNUC_NORETURN;
+
+static void
+oom (const gchar *doing)
+{
+ g_error ("out of memory (%s)", doing);
+}
+
+static void
+assert_no_error (const DBusError *e)
+{
+ if (G_UNLIKELY (dbus_error_is_set (e)))
+ g_error ("expected success but got error: %s: %s", e->name, e->message);
+}
+
+static DBusHandlerResult
+left_server_message_cb (DBusConnection *server_conn,
+ DBusMessage *message,
+ void *data)
+{
+ Fixture *f = data;
+
+ g_assert (server_conn == f->left_server_conn);
+ g_assert (f->right_server_conn != NULL);
+
+ dbus_connection_send (f->right_server_conn, message, NULL);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+right_client_message_cb (DBusConnection *client_conn,
+ DBusMessage *message,
+ void *data)
+{
+ Fixture *f = data;
+
+ g_assert (client_conn == f->right_client_conn);
+ g_queue_push_tail (&f->messages, dbus_message_ref (message));
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void
+new_conn_cb (DBusServer *server,
+ DBusConnection *server_conn,
+ void *data)
+{
+ Fixture *f = data;
+
+ dbus_connection_set_max_message_unix_fds (server_conn,
+ MAX_MESSAGE_UNIX_FDS);
+ dbus_connection_set_max_received_unix_fds (server_conn,
+ MAX_INCOMING_UNIX_FDS);
+
+ if (f->left_server_conn == NULL)
+ {
+ f->left_server_conn = dbus_connection_ref (server_conn);
+
+ if (!dbus_connection_add_filter (server_conn,
+ left_server_message_cb, f, NULL))
+ oom ("adding filter");
+ }
+ else
+ {
+ g_assert (f->right_server_conn == NULL);
+ f->right_server_conn = dbus_connection_ref (server_conn);
+ }
+
+ test_connection_setup (f->ctx, server_conn);
+}
+
+static void
+test_connect (Fixture *f,
+ gconstpointer data G_GNUC_UNUSED)
+{
+ char *address;
+
+ g_assert (f->left_server_conn == NULL);
+ g_assert (f->right_server_conn == NULL);
+
+ address = dbus_server_get_address (f->server);
+ g_assert (address != NULL);
+
+ f->left_client_conn = dbus_connection_open_private (address, &f->e);
+ assert_no_error (&f->e);
+ g_assert (f->left_client_conn != NULL);
+ test_connection_setup (f->ctx, f->left_client_conn);
+
+ /* The left client connection is allowed to behave abusively. */
+ dbus_connection_set_max_message_unix_fds (f->left_client_conn, 1000);
+ dbus_connection_set_max_received_unix_fds (f->left_client_conn, 1000000);
+
+ while (f->left_server_conn == NULL)
+ {
+ g_print (".");
+ test_main_context_iterate (f->ctx, TRUE);
+ }
+
+ f->right_client_conn = dbus_connection_open_private (address, &f->e);
+ assert_no_error (&f->e);
+ g_assert (f->right_client_conn != NULL);
+ test_connection_setup (f->ctx, f->right_client_conn);
+
+ dbus_free (address);
+
+ while (f->right_server_conn == NULL)
+ {
+ g_print (".");
+ test_main_context_iterate (f->ctx, TRUE);
+ }
+
+ if (!dbus_connection_add_filter (f->right_client_conn,
+ right_client_message_cb, f, NULL))
+ oom ("adding filter");
+
+ /* The right client connection is allowed to queue all the messages. */
+ dbus_connection_set_max_message_unix_fds (f->right_client_conn, 1000);
+ dbus_connection_set_max_received_unix_fds (f->right_client_conn, 1000000);
+
+ while (!dbus_connection_get_is_authenticated (f->left_client_conn) ||
+ !dbus_connection_get_is_authenticated (f->right_client_conn) ||
+ !dbus_connection_get_is_authenticated (f->left_server_conn) ||
+ !dbus_connection_get_is_authenticated (f->right_server_conn))
+ {
+ g_printerr ("*");
+ test_main_context_iterate (f->ctx, TRUE);
+ }
+
+ if (!dbus_connection_can_send_type (f->left_client_conn,
+ DBUS_TYPE_UNIX_FD))
+ g_error ("left client connection cannot send Unix fds");
+
+ if (!dbus_connection_can_send_type (f->left_server_conn,
+ DBUS_TYPE_UNIX_FD))
+ g_error ("left server connection cannot send Unix fds");
+
+ if (!dbus_connection_can_send_type (f->right_client_conn,
+ DBUS_TYPE_UNIX_FD))
+ g_error ("right client connection cannot send Unix fds");
+
+ if (!dbus_connection_can_send_type (f->right_server_conn,
+ DBUS_TYPE_UNIX_FD))
+ g_error ("right server connection cannot send Unix fds");
+}
+#endif
+
+static void
+setup (Fixture *f,
+ gconstpointer data G_GNUC_UNUSED)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+ /* We assume that anything with fd-passing supports the unix: transport */
+
+ f->ctx = test_main_context_get ();
+ dbus_error_init (&f->e);
+ g_queue_init (&f->messages);
+
+ f->server = dbus_server_listen ("unix:tmpdir=/tmp", &f->e);
+ assert_no_error (&f->e);
+ g_assert (f->server != NULL);
+
+ dbus_server_set_new_connection_function (f->server,
+ new_conn_cb, f, NULL);
+ test_server_setup (f->ctx, f->server);
+
+ f->fd_before = open ("/dev/null", O_RDONLY);
+
+ /* this should succeed on any reasonable Unix */
+ if (f->fd_before < 0)
+ g_error ("cannot open /dev/null for reading: %s", g_strerror (errno));
+
+ _dbus_fd_set_close_on_exec (f->fd_before);
+#endif
+}
+
+static void
+test_relay (Fixture *f,
+ gconstpointer data)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+ /* We assume that any platform with working fd-passing is POSIX,
+ * and therefore has open() and fstat() */
+ dbus_uint32_t serial;
+ DBusMessage *outgoing, *incoming;
+ int fd_after;
+ struct stat stat_before;
+ struct stat stat_after;
+
+ test_connect (f, data);
+
+ outgoing = dbus_message_new_signal ("/com/example/Hello",
+ "com.example.Hello", "Greeting");
+ g_assert (outgoing != NULL);
+
+ if (!dbus_message_append_args (outgoing,
+ DBUS_TYPE_UNIX_FD, &f->fd_before,
+ DBUS_TYPE_INVALID))
+ oom ("appending fd");
+
+ if (!dbus_connection_send (f->left_client_conn, outgoing, &serial))
+ oom ("sending message");
+
+ dbus_message_unref (outgoing);
+
+ while (g_queue_get_length (&f->messages) < 1)
+ {
+ g_print (".");
+ test_main_context_iterate (f->ctx, TRUE);
+ }
+
+ g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
+
+ incoming = g_queue_pop_head (&f->messages);
+
+ g_assert (dbus_message_contains_unix_fds (incoming));
+ g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
+ "com.example.Hello");
+ g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
+ g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_signature (incoming), ==,
+ DBUS_TYPE_UNIX_FD_AS_STRING);
+ g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
+ g_assert_cmpuint (dbus_message_get_serial (incoming), ==, serial);
+
+ if (!dbus_message_get_args (incoming,
+ &f->e,
+ DBUS_TYPE_UNIX_FD, &fd_after,
+ DBUS_TYPE_INVALID))
+ g_error ("%s: %s", f->e.name, f->e.message);
+
+ assert_no_error (&f->e);
+
+ if (fstat (f->fd_before, &stat_before) < 0)
+ g_error ("%s", g_strerror (errno));
+
+ if (fstat (fd_after, &stat_after) < 0)
+ g_error ("%s", g_strerror (errno));
+
+ /* this seems like enough to say "it's the same file" */
+ g_assert_cmpint (stat_before.st_dev, ==, stat_after.st_dev);
+ g_assert_cmpint (stat_before.st_ino, ==, stat_after.st_ino);
+ g_assert_cmpint (stat_before.st_rdev, ==, stat_after.st_rdev);
+
+ dbus_message_unref (incoming);
+
+ if (close (fd_after) < 0)
+ g_error ("%s", g_strerror (errno));
+
+ g_assert (dbus_connection_get_is_connected (f->right_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->right_server_conn));
+ g_assert (dbus_connection_get_is_connected (f->left_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->left_server_conn));
+#else
+ g_test_skip ("fd-passing not supported on this platform");
+#endif
+}
+
+static void
+test_limit (Fixture *f,
+ gconstpointer data)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+ dbus_uint32_t serial;
+ DBusMessage *outgoing, *incoming;
+ int i;
+
+ test_connect (f, data);
+
+ outgoing = dbus_message_new_signal ("/com/example/Hello",
+ "com.example.Hello", "Greeting");
+ g_assert (outgoing != NULL);
+
+ for (i = 0; i < MAX_MESSAGE_UNIX_FDS; i++)
+ {
+ if (!dbus_message_append_args (outgoing,
+ DBUS_TYPE_UNIX_FD, &f->fd_before,
+ DBUS_TYPE_INVALID))
+ oom ("appending fd");
+ }
+
+ if (!dbus_connection_send (f->left_client_conn, outgoing, &serial))
+ oom ("sending message");
+
+ dbus_message_unref (outgoing);
+
+ while (g_queue_get_length (&f->messages) < 1)
+ {
+ g_print (".");
+ test_main_context_iterate (f->ctx, TRUE);
+ }
+
+ g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
+
+ incoming = g_queue_pop_head (&f->messages);
+
+ g_assert (dbus_message_contains_unix_fds (incoming));
+ g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
+ "com.example.Hello");
+ g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
+ g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
+ g_assert_cmpuint (dbus_message_get_serial (incoming), ==, serial);
+
+ dbus_message_unref (incoming);
+
+ g_assert (dbus_connection_get_is_connected (f->right_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->right_server_conn));
+ g_assert (dbus_connection_get_is_connected (f->left_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->left_server_conn));
+#else
+ g_test_skip ("fd-passing not supported on this platform");
+#endif
+}
+
+static void
+test_too_many (Fixture *f,
+ gconstpointer data)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+ DBusMessage *outgoing;
+ int i;
+
+ test_connect (f, data);
+
+ outgoing = dbus_message_new_signal ("/com/example/Hello",
+ "com.example.Hello", "Greeting");
+ g_assert (outgoing != NULL);
+
+ for (i = 0; i < MAX_MESSAGE_UNIX_FDS + GPOINTER_TO_UINT (data); i++)
+ {
+ if (!dbus_message_append_args (outgoing,
+ DBUS_TYPE_UNIX_FD, &f->fd_before,
+ DBUS_TYPE_INVALID))
+ oom ("appending fd");
+ }
+
+ if (!dbus_connection_send (f->left_client_conn, outgoing, NULL))
+ oom ("sending message");
+
+ dbus_message_unref (outgoing);
+
+ /* The sender is unceremoniously disconnected. */
+ while (dbus_connection_get_is_connected (f->left_client_conn) ||
+ dbus_connection_get_is_connected (f->left_server_conn))
+ {
+ g_print (".");
+ test_main_context_iterate (f->ctx, TRUE);
+ }
+
+ /* The message didn't get through without its fds. */
+ g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
+
+ /* The intended victim is unaffected by the left connection's
+ * misbehaviour. */
+ g_assert (dbus_connection_get_is_connected (f->right_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->right_server_conn));
+#else
+ g_test_skip ("fd-passing not supported on this platform");
+#endif
+}
+
+static void
+test_too_many_split (Fixture *f,
+ gconstpointer data)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+ DBusMessage *outgoing;
+ int i;
+ int left_client_socket;
+ char *payload;
+ int payload_len;
+ DBusString buffer;
+ int fds[TOO_MANY_FDS];
+ int done;
+
+ /* This test deliberately pushes up against OS limits, so skip it
+ * if we don't have enough fds. 4 times the maximum per message
+ * ought to be enough: that will cover the message, the dup'd fds
+ * we actually send, the copy that we potentially receive, and some
+ * spare capacity for everything else. */
+#ifdef HAVE_GETRLIMIT
+ struct rlimit lim;
+
+ if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
+ {
+ if (lim.rlim_cur != RLIM_INFINITY &&
+ lim.rlim_cur < 4 * TOO_MANY_FDS)
+ {
+ g_test_skip ("not enough RLIMIT_NOFILE");
+ return;
+ }
+ }
+#endif
+
+ test_connect (f, data);
+
+ outgoing = dbus_message_new_signal ("/com/example/Hello",
+ "com.example.Hello", "Greeting");
+ g_assert (outgoing != NULL);
+
+ /* TOO_MANY_FDS fds are far too many: in particular, Linux doesn't allow
+ * sending this many in a single sendmsg(). libdbus never splits
+ * a message between two sendmsg() calls if it can help it, and
+ * in particular it always sends all the fds with the first sendmsg(),
+ * but malicious senders might not be so considerate. */
+ for (i = 0; i < TOO_MANY_FDS; i++)
+ {
+ if (!dbus_message_append_args (outgoing,
+ DBUS_TYPE_UNIX_FD, &f->fd_before,
+ DBUS_TYPE_INVALID))
+ oom ("appending fd");
+ }
+
+ /* This probably shouldn't work for messages with fds, but it does,
+ * which is convenient for this sort of trickery. */
+ if (!dbus_message_marshal (outgoing, &payload, &payload_len))
+ oom ("marshalling message");
+
+ _dbus_string_init_const_len (&buffer, payload, payload_len);
+
+ for (i = 0; i < TOO_MANY_FDS; i++)
+ {
+ fds[i] = dup (f->fd_before);
+
+ if (fds[i] < 0)
+ g_error ("could not dup fd: %s", g_strerror (errno));
+ }
+
+ /* This is blatant cheating, and the API documentation specifically
+ * tells you not use this function in this way. Never do this
+ * in application code. */
+ if (!dbus_connection_get_socket (f->left_client_conn, &left_client_socket))
+ g_error ("'unix:' DBusConnection should have had a socket");
+
+ /* Just to be sure that we're at a message boundary. */
+ dbus_connection_flush (f->left_client_conn);
+
+ /* We have too many fds for one sendmsg(), so send the first half
+ * (rounding down if odd) with the first byte... */
+ done = _dbus_write_socket_with_unix_fds (left_client_socket, &buffer, 0, 1,
+ &fds[0], TOO_MANY_FDS / 2);
+
+ if (done < 0)
+ g_error ("could not send first byte and first batch of fds: %s",
+ g_strerror (errno));
+
+ /* ... and the second half (rounding up if odd) with the rest of
+ * the message */
+ done = _dbus_write_socket_with_unix_fds (left_client_socket, &buffer, 1,
+ payload_len - 1, &fds[TOO_MANY_FDS / 2],
+ TOO_MANY_FDS - (TOO_MANY_FDS / 2));
+
+ if (done < 0)
+ {
+ g_error ("could not send rest of message and rest of fds: %s",
+ g_strerror (errno));
+ }
+ else if (done < payload_len - 1)
+ {
+ /* For simplicity, assume the socket buffer is big enough for the
+ * whole message, which should be < 2 KiB. If this fails on some
+ * OS, redo this test code to use a proper loop like the real
+ * libdbus does. */
+ g_error ("short write in sendmsg(), fix this test: %d/%d",
+ done, payload_len - 1);
+ }
+
+ dbus_free (payload);
+
+ for (i = 0; i < TOO_MANY_FDS; i++)
+ close (fds[i]);
+
+ dbus_message_unref (outgoing);
+
+ /* The sender is unceremoniously disconnected. */
+ while (dbus_connection_get_is_connected (f->left_client_conn) ||
+ dbus_connection_get_is_connected (f->left_server_conn))
+ {
+ g_print (".");
+ test_main_context_iterate (f->ctx, TRUE);
+ }
+
+ /* The message didn't get through without its fds. */
+ g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
+
+ /* The intended victim is unaffected by the left connection's
+ * misbehaviour. */
+ g_assert (dbus_connection_get_is_connected (f->right_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->right_server_conn));
+#else
+ g_test_skip ("fd-passing not supported on this platform");
+#endif
+}
+
+static void
+test_flood (Fixture *f,
+ gconstpointer data)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+ int i, j;
+ DBusMessage *outgoing[SOME_MESSAGES];
+ dbus_uint32_t serial;
+
+ test_connect (f, data);
+
+ for (j = 0; j < SOME_MESSAGES; j++)
+ {
+ outgoing[j] = dbus_message_new_signal ("/com/example/Hello",
+ "com.example.Hello", "Greeting");
+ g_assert (outgoing[j] != NULL);
+
+ for (i = 0; i < GPOINTER_TO_UINT (data); i++)
+ {
+ if (!dbus_message_append_args (outgoing[j],
+ DBUS_TYPE_UNIX_FD, &f->fd_before,
+ DBUS_TYPE_INVALID))
+ oom ("appending fd");
+ }
+ }
+
+ /* This is in its own loop so we do it as fast as possible */
+ for (j = 0; j < SOME_MESSAGES; j++)
+ {
+ if (!dbus_connection_send (f->left_client_conn, outgoing[j], &serial))
+ oom ("sending message");
+ }
+
+ for (j = 0; j < SOME_MESSAGES; j++)
+ {
+ dbus_message_unref (outgoing[j]);
+ }
+
+ while (g_queue_get_length (&f->messages) < SOME_MESSAGES)
+ {
+ g_print (".");
+ test_main_context_iterate (f->ctx, TRUE);
+ }
+
+ g_assert_cmpuint (g_queue_get_length (&f->messages), ==, SOME_MESSAGES);
+
+ for (j = 0; j < SOME_MESSAGES; j++)
+ {
+ DBusMessage *incoming;
+
+ incoming = g_queue_pop_head (&f->messages);
+
+ g_assert (dbus_message_contains_unix_fds (incoming));
+ g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
+ "com.example.Hello");
+ g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
+ g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
+
+ dbus_message_unref (incoming);
+ }
+
+ g_assert (dbus_connection_get_is_connected (f->right_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->right_server_conn));
+ g_assert (dbus_connection_get_is_connected (f->left_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->left_server_conn));
+#else
+ g_test_skip ("fd-passing not supported on this platform");
+#endif
+}
+
+static void
+test_odd_limit (Fixture *f,
+ gconstpointer data)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+ DBusMessage *outgoing;
+ int i;
+
+ test_connect (f, data);
+ dbus_connection_set_max_message_unix_fds (f->left_server_conn, 7);
+ dbus_connection_set_max_message_unix_fds (f->right_server_conn, 7);
+
+ outgoing = dbus_message_new_signal ("/com/example/Hello",
+ "com.example.Hello", "Greeting");
+ g_assert (outgoing != NULL);
+
+ for (i = 0; i < 7 + GPOINTER_TO_INT (data); i++)
+ {
+ if (!dbus_message_append_args (outgoing,
+ DBUS_TYPE_UNIX_FD, &f->fd_before,
+ DBUS_TYPE_INVALID))
+ oom ("appending fd");
+ }
+
+ if (!dbus_connection_send (f->left_client_conn, outgoing, NULL))
+ oom ("sending message");
+
+ dbus_message_unref (outgoing);
+
+ if (GPOINTER_TO_INT (data) > 0)
+ {
+ /* The sender is unceremoniously disconnected. */
+ while (dbus_connection_get_is_connected (f->left_client_conn) ||
+ dbus_connection_get_is_connected (f->left_server_conn))
+ {
+ g_print (".");
+ test_main_context_iterate (f->ctx, TRUE);
+ }
+
+ /* The message didn't get through without its fds. */
+ g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
+
+ /* The intended victim is unaffected by the left connection's
+ * misbehaviour. */
+ g_assert (dbus_connection_get_is_connected (f->right_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->right_server_conn));
+ }
+ else
+ {
+ DBusMessage *incoming;
+
+ /* We're at or under the limit. The message gets through intact. */
+ while (g_queue_get_length (&f->messages) < 1)
+ {
+ g_print (".");
+ test_main_context_iterate (f->ctx, TRUE);
+ }
+
+ g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
+
+ incoming = g_queue_pop_head (&f->messages);
+
+ g_assert (dbus_message_contains_unix_fds (incoming));
+ g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
+ "com.example.Hello");
+ g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
+ g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
+ g_assert_cmpstr (dbus_message_get_path (incoming), ==,
+ "/com/example/Hello");
+
+ dbus_message_unref (incoming);
+
+ g_assert (dbus_connection_get_is_connected (f->right_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->right_server_conn));
+ g_assert (dbus_connection_get_is_connected (f->left_client_conn));
+ g_assert (dbus_connection_get_is_connected (f->left_server_conn));
+ }
+#else
+ g_test_skip ("fd-passing not supported on this platform");
+#endif
+}
+
+static void
+teardown (Fixture *f,
+ gconstpointer data G_GNUC_UNUSED)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+ if (f->left_client_conn != NULL)
+ {
+ dbus_connection_close (f->left_client_conn);
+ dbus_connection_unref (f->left_client_conn);
+ f->left_client_conn = NULL;
+ }
+
+ if (f->right_client_conn != NULL)
+ {
+ dbus_connection_close (f->right_client_conn);
+ dbus_connection_unref (f->right_client_conn);
+ f->right_client_conn = NULL;
+ }
+
+ if (f->left_server_conn != NULL)
+ {
+ dbus_connection_close (f->left_server_conn);
+ dbus_connection_unref (f->left_server_conn);
+ f->left_server_conn = NULL;
+ }
+
+ if (f->right_server_conn != NULL)
+ {
+ dbus_connection_close (f->right_server_conn);
+ dbus_connection_unref (f->right_server_conn);
+ f->right_server_conn = NULL;
+ }
+
+ if (f->server != NULL)
+ {
+ dbus_server_disconnect (f->server);
+ dbus_server_unref (f->server);
+ f->server = NULL;
+ }
+
+ test_main_context_unref (f->ctx);
+
+ if (f->fd_before >= 0 && close (f->fd_before) < 0)
+ g_error ("%s", g_strerror (errno));
+#endif
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ test_init (&argc, &argv);
+
+ g_test_add ("/relay", Fixture, NULL, setup,
+ test_relay, teardown);
+ g_test_add ("/limit", Fixture, NULL, setup,
+ test_limit, teardown);
+
+ g_test_add ("/too-many/plus1", Fixture, GUINT_TO_POINTER (1), setup,
+ test_too_many, teardown);
+ g_test_add ("/too-many/plus2", Fixture, GUINT_TO_POINTER (2), setup,
+ test_too_many, teardown);
+ g_test_add ("/too-many/plus17", Fixture, GUINT_TO_POINTER (17), setup,
+ test_too_many, teardown);
+
+ g_test_add ("/too-many/split", Fixture, NULL, setup,
+ test_too_many_split, teardown);
+
+ g_test_add ("/flood/1", Fixture, GUINT_TO_POINTER (1),
+ setup, test_flood, teardown);
+#if MAX_MESSAGE_UNIX_FDS >= 2
+ g_test_add ("/flood/half-limit", Fixture,
+ GUINT_TO_POINTER (MAX_MESSAGE_UNIX_FDS / 2),
+ setup, test_flood, teardown);
+#endif
+#if MAX_MESSAGE_UNIX_FDS >= 4
+ g_test_add ("/flood/over-half-limit", Fixture,
+ GUINT_TO_POINTER (3 * MAX_MESSAGE_UNIX_FDS / 4),
+ setup, test_flood, teardown);
+#endif
+ g_test_add ("/flood/limit", Fixture,
+ GUINT_TO_POINTER (MAX_MESSAGE_UNIX_FDS), setup, test_flood, teardown);
+
+ g_test_add ("/odd-limit/minus1", Fixture, GINT_TO_POINTER (-1), setup,
+ test_odd_limit, teardown);
+ g_test_add ("/odd-limit/at", Fixture, GINT_TO_POINTER (0), setup,
+ test_odd_limit, teardown);
+ g_test_add ("/odd-limit/plus1", Fixture, GINT_TO_POINTER (+1), setup,
+ test_odd_limit, teardown);
+ g_test_add ("/odd-limit/plus2", Fixture, GINT_TO_POINTER (+2), setup,
+ test_odd_limit, teardown);
+
+ return g_test_run ();
+}
diff --git a/test/internals/refs.c b/test/internals/refs.c
index 85cb3bc0..7eae44e1 100644
--- a/test/internals/refs.c
+++ b/test/internals/refs.c
@@ -35,7 +35,7 @@
#include <dbus/dbus-message-internal.h>
#include <dbus/dbus-pending-call-internal.h>
#include <dbus/dbus-server-protected.h>
-#include "test-utils.h"
+#include "test-utils-glib.h"
static void
assert_no_error (const DBusError *e)
@@ -585,8 +585,7 @@ int
main (int argc,
char **argv)
{
- g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id=");
+ test_init (&argc, &argv);
g_test_add ("/refs/connection", Fixture, NULL, setup_connection,
test_connection, teardown);
diff --git a/test/internals/syslog.c b/test/internals/syslog.c
index 80a0cebb..805c5784 100644
--- a/test/internals/syslog.c
+++ b/test/internals/syslog.c
@@ -33,6 +33,8 @@
#include <dbus/dbus.h>
#include <dbus/dbus-sysdeps.h>
+#include "test-utils-glib.h"
+
typedef struct {
int dummy;
} Fixture;
@@ -93,8 +95,7 @@ int
main (int argc,
char **argv)
{
- g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id=");
+ test_init (&argc, &argv);
g_test_add ("/syslog", Fixture, NULL, setup, test_syslog, teardown);
diff --git a/test/loopback.c b/test/loopback.c
index 7526d8d2..eeb0d65d 100644
--- a/test/loopback.c
+++ b/test/loopback.c
@@ -32,7 +32,7 @@
#include <string.h>
-#include "test-utils.h"
+#include "test-utils-glib.h"
typedef struct {
TestMainContext *ctx;
@@ -255,8 +255,7 @@ int
main (int argc,
char **argv)
{
- g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id=");
+ test_init (&argc, &argv);
g_test_add ("/connect/tcp", Fixture, "tcp:host=127.0.0.1", setup,
test_connect, teardown);
diff --git a/test/marshal.c b/test/marshal.c
index d74e7671..3353ec00 100644
--- a/test/marshal.c
+++ b/test/marshal.c
@@ -31,6 +31,8 @@
#include <dbus/dbus.h>
+#include "test-utils-glib.h"
+
typedef struct {
DBusError e;
} Fixture;
@@ -248,7 +250,7 @@ main (int argc,
char *aligned_le_blob;
char *aligned_be_blob;
- g_test_init (&argc, &argv, NULL);
+ test_init (&argc, &argv);
/* We have to pass in a buffer that's at least "default aligned",
* i.e. on GNU systems to 8 or 16. The linker may have only given
diff --git a/test/monitor.c b/test/monitor.c
new file mode 100644
index 00000000..32b7b5dd
--- /dev/null
+++ b/test/monitor.c
@@ -0,0 +1,1496 @@
+/* Integration tests for monitor-mode D-Bus connections
+ *
+ * Copyright © 2010-2011 Nokia Corporation
+ * Copyright © 2015 Collabora Ltd.
+ *
+ * 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 <string.h>
+
+#include "test-utils-glib.h"
+
+typedef struct {
+ const char *config_file;
+ const char * const *match_rules;
+ gboolean care_about_our_names;
+} Config;
+
+typedef struct {
+ const Config *config;
+ TestMainContext *ctx;
+ DBusError e;
+ GError *ge;
+
+ gchar *address;
+ GPid daemon_pid;
+
+ DBusConnection *monitor;
+ DBusConnection *sender;
+ DBusConnection *recipient;
+
+ GQueue monitored;
+
+ const char *monitor_name;
+ const char *sender_name;
+ const char *recipient_name;
+
+ DBusConnection *systemd;
+ const char *systemd_name;
+ DBusMessage *systemd_message;
+ DBusConnection *activated;
+ const char *activated_name;
+ DBusMessage *activated_message;
+} Fixture;
+
+static const char * const no_match_rules[] = {
+ NULL
+};
+
+static const char * const wildcard_match_rules[] = {
+ "",
+ NULL,
+ FALSE
+};
+
+static const char * const eavesdrop_match_rules[] = {
+ "eavesdrop=true",
+ NULL,
+ FALSE
+};
+
+static const char * const no_eavesdrop_match_rules[] = {
+ "eavesdrop=false",
+ NULL,
+ FALSE
+};
+
+static const char * const selective_match_rules[] = {
+ "interface='com.example.Interesting'",
+ "interface='com.example.Fun'",
+ NULL,
+ FALSE
+};
+
+static Config forbidding_config = {
+ "valid-config-files/forbidding.conf",
+ NULL,
+ FALSE
+};
+
+static Config wildcard_config = {
+ NULL,
+ wildcard_match_rules,
+ FALSE
+};
+
+static Config selective_config = {
+ NULL,
+ selective_match_rules,
+ FALSE
+};
+
+static Config no_rules_config = {
+ NULL,
+ no_match_rules,
+ FALSE
+};
+
+static Config eavesdrop_config = {
+ NULL,
+ eavesdrop_match_rules,
+ FALSE
+};
+
+static Config no_eavesdrop_config = {
+ NULL,
+ no_eavesdrop_match_rules,
+ FALSE
+};
+
+static Config fake_systemd_config = {
+ "valid-config-files/systemd-activation.conf",
+ NULL,
+ FALSE
+};
+
+static Config side_effects_config = {
+ NULL,
+ NULL,
+ TRUE
+};
+
+static inline const char *
+not_null2 (const char *x,
+ const char *fallback)
+{
+ if (x == NULL)
+ return fallback;
+
+ return x;
+}
+
+static inline const char *
+not_null (const char *x)
+{
+ return not_null2 (x, "(null)");
+}
+
+#define log_message(m) _log_message (m, __FILE__, __LINE__)
+
+G_GNUC_UNUSED
+static void
+_log_message (DBusMessage *m,
+ const char *file,
+ int line)
+{
+ g_message ("%s:%d: message type %d (%s)", file, line,
+ dbus_message_get_type (m),
+ dbus_message_type_to_string (dbus_message_get_type (m)));
+ g_message ("\tfrom: %s",
+ not_null2 (dbus_message_get_sender (m), "(dbus-daemon)"));
+ g_message ("\tto: %s",
+ not_null2 (dbus_message_get_destination (m), "(broadcast)"));
+ g_message ("\tpath: %s",
+ not_null (dbus_message_get_path (m)));
+ g_message ("\tinterface: %s",
+ not_null (dbus_message_get_interface (m)));
+ g_message ("\tmember: %s",
+ not_null (dbus_message_get_member (m)));
+ g_message ("\tsignature: %s",
+ not_null (dbus_message_get_signature (m)));
+ g_message ("\terror name: %s",
+ not_null (dbus_message_get_error_name (m)));
+
+ if (strcmp ("s", dbus_message_get_signature (m)) == 0)
+ {
+ DBusError e = DBUS_ERROR_INIT;
+ const char *s;
+
+ dbus_message_get_args (m, &e,
+ DBUS_TYPE_STRING, &s,
+ DBUS_TYPE_INVALID);
+ test_assert_no_error (&e);
+ g_message ("\tstring payload: %s", s);
+ }
+}
+
+/* these are macros so they get the right line number */
+
+#define assert_hello(m) \
+do { \
+ g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
+ ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_CALL)); \
+ g_assert_cmpstr (dbus_message_get_destination (m), ==, DBUS_SERVICE_DBUS); \
+ g_assert_cmpstr (dbus_message_get_path (m), ==, DBUS_PATH_DBUS); \
+ g_assert_cmpstr (dbus_message_get_interface (m), ==, DBUS_INTERFACE_DBUS); \
+ g_assert_cmpstr (dbus_message_get_member (m), ==, "Hello"); \
+ g_assert_cmpstr (dbus_message_get_signature (m), ==, ""); \
+ g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
+ g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
+} while (0)
+
+#define assert_hello_reply(m) \
+do { \
+ DBusError _e = DBUS_ERROR_INIT; \
+ const char *_s; \
+ \
+ g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
+ ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_RETURN)); \
+ g_assert_cmpstr (dbus_message_get_sender (m), ==, DBUS_SERVICE_DBUS); \
+ g_assert_cmpstr (dbus_message_get_path (m), ==, NULL); \
+ g_assert_cmpstr (dbus_message_get_interface (m), ==, NULL); \
+ g_assert_cmpstr (dbus_message_get_member (m), ==, NULL); \
+ g_assert_cmpstr (dbus_message_get_signature (m), ==, "s"); \
+ g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
+ g_assert_cmpint (dbus_message_get_reply_serial (m), !=, 0); \
+ \
+ dbus_message_get_args (m, &_e, \
+ DBUS_TYPE_STRING, &_s, \
+ DBUS_TYPE_INVALID); \
+ test_assert_no_error (&_e); \
+ g_assert_cmpstr (dbus_message_get_destination (m), ==, _s); \
+} while (0)
+
+#define assert_name_acquired(m) \
+do { \
+ DBusError _e = DBUS_ERROR_INIT; \
+ const char *_s; \
+ \
+ g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
+ ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_SIGNAL)); \
+ g_assert_cmpstr (dbus_message_get_sender (m), ==, DBUS_SERVICE_DBUS); \
+ g_assert_cmpstr (dbus_message_get_path (m), ==, DBUS_PATH_DBUS); \
+ g_assert_cmpstr (dbus_message_get_interface (m), ==, DBUS_INTERFACE_DBUS); \
+ g_assert_cmpstr (dbus_message_get_member (m), ==, "NameAcquired"); \
+ g_assert_cmpstr (dbus_message_get_signature (m), ==, "s"); \
+ g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
+ g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
+ \
+ dbus_message_get_args (m, &_e, \
+ DBUS_TYPE_STRING, &_s, \
+ DBUS_TYPE_INVALID); \
+ test_assert_no_error (&_e); \
+ g_assert_cmpstr (dbus_message_get_destination (m), ==, _s); \
+} while (0)
+
+#define assert_method_call(m, sender, \
+ destination, path, iface, method, signature) \
+do { \
+ g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
+ ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_CALL)); \
+ g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
+ g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
+ g_assert_cmpstr (dbus_message_get_path (m), ==, path); \
+ g_assert_cmpstr (dbus_message_get_interface (m), ==, iface); \
+ g_assert_cmpstr (dbus_message_get_member (m), ==, method); \
+ g_assert_cmpstr (dbus_message_get_signature (m), ==, signature); \
+ g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
+ g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
+} while (0)
+
+#define assert_signal(m, \
+ sender, path, iface, member, signature, \
+ destination) \
+do { \
+ g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
+ ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_SIGNAL)); \
+ g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
+ g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
+ g_assert_cmpstr (dbus_message_get_path (m), ==, path); \
+ g_assert_cmpstr (dbus_message_get_interface (m), ==, iface); \
+ g_assert_cmpstr (dbus_message_get_member (m), ==, member); \
+ g_assert_cmpstr (dbus_message_get_signature (m), ==, signature); \
+ g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
+ g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
+} while (0)
+
+#define assert_method_reply(m, sender, destination, signature) \
+do { \
+ g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
+ ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_RETURN)); \
+ g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
+ g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
+ g_assert_cmpstr (dbus_message_get_path (m), ==, NULL); \
+ g_assert_cmpstr (dbus_message_get_interface (m), ==, NULL); \
+ g_assert_cmpstr (dbus_message_get_member (m), ==, NULL); \
+ g_assert_cmpstr (dbus_message_get_signature (m), ==, signature); \
+ g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
+ g_assert_cmpint (dbus_message_get_reply_serial (m), !=, 0); \
+} while (0)
+
+#define assert_error_reply(m, sender, destination, error_name) \
+do { \
+ g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
+ ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_ERROR)); \
+ g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
+ g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
+ g_assert_cmpstr (dbus_message_get_error_name (m), ==, error_name); \
+ g_assert_cmpstr (dbus_message_get_path (m), ==, NULL); \
+ g_assert_cmpstr (dbus_message_get_interface (m), ==, NULL); \
+ g_assert_cmpstr (dbus_message_get_member (m), ==, NULL); \
+ g_assert_cmpstr (dbus_message_get_signature (m), ==, "s"); \
+ g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
+ g_assert_cmpint (dbus_message_get_reply_serial (m), !=, 0); \
+} while (0)
+
+/* This is called after processing pending replies to our own method
+ * calls, but before anything else.
+ */
+static DBusHandlerResult
+monitor_filter (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ Fixture *f = user_data;
+
+ g_assert_cmpstr (dbus_message_get_interface (message), !=,
+ "com.example.Tedious");
+
+ /* we are not interested in the monitor getting NameAcquired or NameLost
+ * for most tests */
+ if (f->config == NULL || !f->config->care_about_our_names)
+ {
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
+ "NameAcquired") ||
+ dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
+ "NameLost"))
+ {
+ DBusError e = DBUS_ERROR_INIT;
+ const char *s;
+
+ dbus_message_get_args (message, &e,
+ DBUS_TYPE_STRING, &s,
+ DBUS_TYPE_INVALID);
+ test_assert_no_error (&e);
+
+ if (strcmp (s, f->monitor_name) == 0)
+ {
+ /* ignore */
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ }
+ }
+
+ g_queue_push_tail (&f->monitored, dbus_message_ref (message));
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+recipient_filter (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ g_assert_cmpstr (dbus_message_get_interface (message), !=,
+ "com.example.CannotSend");
+ g_assert_cmpstr (dbus_message_get_interface (message), !=,
+ "com.example.CannotReceive");
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusHandlerResult
+systemd_filter (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ Fixture *f = user_data;
+
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
+ "NameAcquired") ||
+ dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
+ "NameLost"))
+ {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ g_assert (f->systemd_message == NULL);
+ f->systemd_message = dbus_message_ref (message);
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusHandlerResult
+activated_filter (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ Fixture *f = user_data;
+
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
+ "NameAcquired") ||
+ dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
+ "NameLost"))
+ {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ g_assert (f->activated_message == NULL);
+ f->activated_message = dbus_message_ref (message);
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static void
+setup (Fixture *f,
+ gconstpointer context)
+{
+ f->config = context;
+
+ f->ctx = test_main_context_get ();
+
+ f->ge = NULL;
+ dbus_error_init (&f->e);
+
+ f->address = test_get_dbus_daemon (f->config ? f->config->config_file : NULL,
+ TEST_USER_ME, &f->daemon_pid);
+
+ if (f->address == NULL)
+ return;
+
+ f->monitor = test_connect_to_bus (f->ctx, f->address);
+ f->monitor_name = dbus_bus_get_unique_name (f->monitor);
+ f->sender = test_connect_to_bus (f->ctx, f->address);
+ f->sender_name = dbus_bus_get_unique_name (f->sender);
+ f->recipient = test_connect_to_bus (f->ctx, f->address);
+ f->recipient_name = dbus_bus_get_unique_name (f->recipient);
+
+ if (!dbus_connection_add_filter (f->monitor, monitor_filter, f, NULL))
+ g_error ("OOM");
+
+ if (!dbus_connection_add_filter (f->recipient, recipient_filter, f, NULL))
+ g_error ("OOM");
+}
+
+static void
+become_monitor (Fixture *f)
+{
+ DBusMessage *m;
+ DBusPendingCall *pc;
+ dbus_bool_t ok;
+ DBusMessageIter appender, array_appender;
+ const char * const *match_rules;
+ int i;
+ dbus_uint32_t zero = 0;
+
+ if (f->config != NULL && f->config->match_rules != NULL)
+ match_rules = f->config->match_rules;
+ else
+ match_rules = wildcard_match_rules;
+
+ m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor");
+
+ if (m == NULL)
+ g_error ("OOM");
+
+ dbus_message_iter_init_append (m, &appender);
+
+ if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s",
+ &array_appender))
+ g_error ("OOM");
+
+ for (i = 0; match_rules[i] != NULL; i++)
+ {
+ if (!dbus_message_iter_append_basic (&array_appender, DBUS_TYPE_STRING,
+ &match_rules[i]))
+ g_error ("OOM");
+ }
+
+ if (!dbus_message_iter_close_container (&appender, &array_appender) ||
+ !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32, &zero))
+ g_error ("OOM");
+
+ if (!dbus_connection_send_with_reply (f->monitor, m, &pc,
+ DBUS_TIMEOUT_USE_DEFAULT) ||
+ pc == NULL)
+ g_error ("OOM");
+
+ dbus_message_unref (m);
+ m = NULL;
+
+ if (dbus_pending_call_get_completed (pc))
+ test_pending_call_store_reply (pc, &m);
+ else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
+ &m, NULL))
+ g_error ("OOM");
+
+ while (m == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ ok = dbus_message_get_args (m, &f->e,
+ DBUS_TYPE_INVALID);
+ test_assert_no_error (&f->e);
+ g_assert (ok);
+
+ dbus_pending_call_unref (pc);
+ dbus_message_unref (m);
+ m = NULL;
+}
+
+/*
+ * Test the side-effects of becoming a monitor.
+ */
+static void
+test_become_monitor (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+ int ret;
+ dbus_bool_t got_unique = FALSE, got_a = FALSE, got_b = FALSE, got_c = FALSE;
+ dbus_bool_t lost_unique = FALSE, lost_a = FALSE, lost_b = FALSE, lost_c = FALSE;
+
+ if (f->address == NULL)
+ return;
+
+ ret = dbus_bus_request_name (f->monitor, "com.example.A",
+ DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
+ test_assert_no_error (&f->e);
+ g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+
+ ret = dbus_bus_request_name (f->monitor, "com.example.B",
+ DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
+ test_assert_no_error (&f->e);
+ g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+
+ ret = dbus_bus_request_name (f->monitor, "com.example.C",
+ DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
+ test_assert_no_error (&f->e);
+ g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+
+ while (!got_unique || !got_a || !got_b || !got_c)
+ {
+ test_main_context_iterate (f->ctx, TRUE);
+
+ while ((m = g_queue_pop_head (&f->monitored)) != NULL)
+ {
+ if (dbus_message_is_signal (m, DBUS_INTERFACE_DBUS,
+ "NameAcquired"))
+ {
+ const char *name;
+ dbus_bool_t ok = dbus_message_get_args (m, &f->e,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID);
+
+ g_assert_cmpstr (dbus_message_get_path (m), ==,
+ DBUS_PATH_DBUS);
+
+ test_assert_no_error (&f->e);
+ g_assert (ok);
+
+ if (g_str_equal (name, f->monitor_name))
+ {
+ g_assert (!got_unique);
+ got_unique = TRUE;
+ }
+ else if (g_str_equal (name, "com.example.A"))
+ {
+ g_assert (!got_a);
+ got_a = TRUE;
+ }
+ else if (g_str_equal (name, "com.example.B"))
+ {
+ g_assert (!got_b);
+ got_b = TRUE;
+ }
+ else
+ {
+ g_assert_cmpstr (name, ==, "com.example.C");
+ g_assert (!got_c);
+ got_c = TRUE;
+ }
+ }
+ else
+ {
+ g_error ("unexpected message %s.%s",
+ dbus_message_get_interface (m),
+ dbus_message_get_member (m));
+ }
+
+ dbus_message_unref (m);
+ }
+ }
+
+ become_monitor (f);
+
+ while (!lost_unique || !lost_a || !lost_b || !lost_c)
+ {
+ test_main_context_iterate (f->ctx, TRUE);
+
+ while ((m = g_queue_pop_head (&f->monitored)) != NULL)
+ {
+ if (dbus_message_is_signal (m, DBUS_INTERFACE_DBUS,
+ "NameLost"))
+ {
+ const char *name;
+ dbus_bool_t ok = dbus_message_get_args (m, &f->e,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID);
+
+ test_assert_no_error (&f->e);
+ g_assert (ok);
+
+ if (g_str_equal (name, f->monitor_name))
+ {
+ g_assert (!lost_unique);
+ lost_unique = TRUE;
+ }
+ else if (g_str_equal (name, "com.example.A"))
+ {
+ g_assert (!lost_a);
+ lost_a = TRUE;
+ }
+ else if (g_str_equal (name, "com.example.B"))
+ {
+ g_assert (!lost_b);
+ lost_b = TRUE;
+ }
+ else
+ {
+ g_assert_cmpstr (name, ==, "com.example.C");
+ g_assert (!lost_c);
+ lost_c = TRUE;
+ }
+ }
+ else
+ {
+ g_error ("unexpected message %s.%s",
+ dbus_message_get_interface (m),
+ dbus_message_get_member (m));
+ }
+
+ dbus_message_unref (m);
+ }
+ }
+
+ /* Calling methods is forbidden; we get disconnected. */
+ dbus_bus_add_match (f->monitor, "", &f->e);
+ g_assert_cmpstr (f->e.name, ==, DBUS_ERROR_NO_REPLY);
+ g_assert (!dbus_connection_get_is_connected (f->monitor));
+
+ while (TRUE)
+ {
+ test_main_context_iterate (f->ctx, TRUE);
+
+ /* When we iterate all the connection's messages, we see ourselves
+ * losing all our names, then we're disconnected. */
+ while ((m = g_queue_pop_head (&f->monitored)) != NULL)
+ {
+ if (dbus_message_is_signal (m, DBUS_INTERFACE_LOCAL, "Disconnected"))
+ {
+ dbus_message_unref (m);
+ goto disconnected;
+ }
+ else
+ {
+ g_error ("unexpected message %s.%s",
+ dbus_message_get_interface (m),
+ dbus_message_get_member (m));
+ }
+
+ dbus_message_unref (m);
+ }
+ }
+
+disconnected:
+
+ g_assert (lost_a);
+ g_assert (lost_b);
+ g_assert (lost_c);
+}
+
+static void
+test_broadcast (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ dbus_bus_add_match (f->recipient, "type='signal'", &f->e);
+ test_assert_no_error (&f->e);
+
+ become_monitor (f);
+
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "BroadcastSignal1");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "BroadcastSignal2");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "BroadcastSignal3");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 3)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.bar",
+ "BroadcastSignal1", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.bar",
+ "BroadcastSignal2", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.bar",
+ "BroadcastSignal3", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+}
+
+static void
+test_forbidden_broadcast (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ dbus_bus_add_match (f->recipient, "type='signal'", &f->e);
+ test_assert_no_error (&f->e);
+
+ become_monitor (f);
+
+ m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
+ "BroadcastSignal1");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.CannotReceive",
+ "BroadcastSignal2");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
+ "BroadcastSignal3");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 6)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotSend",
+ "BroadcastSignal1", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotReceive",
+ "BroadcastSignal2", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotSend",
+ "BroadcastSignal3", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+}
+
+static void
+test_unicast_signal (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ become_monitor (f);
+
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal1");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal2");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal3");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 3)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.bar", "UnicastSignal1", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.bar", "UnicastSignal2", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.bar", "UnicastSignal3", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+}
+
+static void
+test_forbidden (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ become_monitor (f);
+
+ m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
+ "UnicastSignal1");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.CannotReceive",
+ "UnicastSignal2");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
+ "UnicastSignal3");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 6)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.CannotSend", "UnicastSignal1", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.CannotReceive", "UnicastSignal2", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.CannotSend", "UnicastSignal3", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+}
+
+static void
+test_method_call (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ become_monitor (f);
+
+ m = dbus_message_new_method_call (f->recipient_name, "/foo", "com.example.bar",
+ "Call1");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
+ "com.example.bar", "Call1", "");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, f->recipient_name, f->sender_name,
+ DBUS_ERROR_UNKNOWN_METHOD);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+}
+
+static void
+test_forbidden_method_call (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ become_monitor (f);
+
+ m = dbus_message_new_method_call (f->recipient_name, "/foo",
+ "com.example.CannotSend", "Call1");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
+ "com.example.CannotSend", "Call1", "");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+
+ m = dbus_message_new_method_call (f->recipient_name, "/foo",
+ "com.example.CannotReceive", "Call2");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
+ "com.example.CannotReceive", "Call2", "");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+}
+
+static void
+test_dbus_daemon (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+ int res;
+
+ if (f->address == NULL)
+ return;
+
+ become_monitor (f);
+
+ res = dbus_bus_request_name (f->sender, "com.example.Sender",
+ DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
+ test_assert_no_error (&f->e);
+ g_assert_cmpint (res, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+
+ res = dbus_bus_release_name (f->sender, "com.example.Sender", &f->e);
+ test_assert_no_error (&f->e);
+ g_assert_cmpint (res, ==, DBUS_RELEASE_NAME_REPLY_RELEASED);
+
+ while (g_queue_get_length (&f->monitored) < 8)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_call (m, f->sender_name, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS, "RequestName", "su");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
+ "NameOwnerChanged", "sss", NULL);
+ dbus_message_unref (m);
+
+ /* FIXME: should we get this? */
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
+ "NameAcquired", "s", f->sender_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_reply (m, DBUS_SERVICE_DBUS, f->sender_name, "u");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_call (m, f->sender_name, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS, "ReleaseName", "s");
+ dbus_message_unref (m);
+
+ /* FIXME: should we get this? */
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
+ "NameLost", "s", f->sender_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
+ "NameOwnerChanged", "sss", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_reply (m, DBUS_SERVICE_DBUS, f->sender_name, "u");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+}
+
+static void
+test_selective (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ /* Match rules added before becoming a monitor should be cleared:
+ * if they weren't, this test would get Interesting twice, then Tedious,
+ * and only see Fun after that. */
+ dbus_bus_add_match (f->monitor,
+ "eavesdrop='true',interface='com.example.Interesting'", &f->e);
+ test_assert_no_error (&f->e);
+ dbus_bus_add_match (f->monitor,
+ "eavesdrop='true',interface='com.example.Tedious'", &f->e);
+ test_assert_no_error (&f->e);
+
+ become_monitor (f);
+
+ m = dbus_message_new_signal ("/foo", "com.example.Interesting",
+ "UnicastSignal1");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.Tedious",
+ "UnicastSignal2");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.Fun",
+ "UnicastSignal3");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ /* We get the interesting signal and the fun signal, but not the tedious
+ * signal. */
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.Interesting", "UnicastSignal1", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.Fun", "UnicastSignal3", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+}
+
+static void
+expect_new_connection (Fixture *f)
+{
+ DBusMessage *m;
+
+ while (g_queue_get_length (&f->monitored) < 4)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_hello (m);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_hello_reply (m);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
+ "NameOwnerChanged", "sss", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_name_acquired (m);
+ dbus_message_unref (m);
+}
+
+static void
+take_well_known_name (Fixture *f,
+ DBusConnection *connection,
+ const char *name)
+{
+ int ret;
+
+ ret = dbus_bus_request_name (connection, name,
+ DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
+ test_assert_no_error (&f->e);
+ g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+}
+
+static void
+expect_take_well_known_name (Fixture *f,
+ DBusConnection *connection,
+ const char *name)
+{
+ DBusMessage *m;
+ const char *connection_name = dbus_bus_get_unique_name (connection);
+
+ while (g_queue_get_length (&f->monitored) < 4)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_call (m, connection_name, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS, "RequestName", "su");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
+ "NameOwnerChanged", "sss", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
+ "NameAcquired", "s", connection_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_reply (m, DBUS_SERVICE_DBUS, connection_name, "u");
+ dbus_message_unref (m);
+}
+
+static void
+test_activation (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ become_monitor (f);
+
+ /* The sender sends a message to an activatable service. */
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal1");
+ if (!dbus_message_set_destination (m, "com.example.SystemdActivatable1"))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ /* We observe the activation request, and the message that caused it,
+ * before systemd has even joined the bus. */
+ while (g_queue_get_length (&f->monitored) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
+ "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
+ "org.freedesktop.systemd1");
+ dbus_message_unref (m);
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.bar", "UnicastSignal1", "",
+ "com.example.SystemdActivatable1");
+ dbus_message_unref (m);
+
+ /* The fake systemd connects to the bus. */
+ f->systemd = test_connect_to_bus (f->ctx, f->address);
+ if (!dbus_connection_add_filter (f->systemd, systemd_filter, f, NULL))
+ g_error ("OOM");
+ f->systemd_name = dbus_bus_get_unique_name (f->systemd);
+
+ expect_new_connection (f);
+ take_well_known_name (f, f->systemd, "org.freedesktop.systemd1");
+ expect_take_well_known_name (f, f->systemd, "org.freedesktop.systemd1");
+
+ /* It gets its activation request. */
+ while (f->systemd_message == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = f->systemd_message;
+ f->systemd_message = NULL;
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
+ "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
+ "org.freedesktop.systemd1");
+ dbus_message_unref (m);
+
+ /* systemd starts the activatable service. */
+ f->activated = test_connect_to_bus (f->ctx, f->address);
+ if (!dbus_connection_add_filter (f->activated, activated_filter,
+ f, NULL))
+ g_error ("OOM");
+ f->activated_name = dbus_bus_get_unique_name (f->activated);
+
+ expect_new_connection (f);
+ take_well_known_name (f, f->activated, "com.example.SystemdActivatable1");
+ expect_take_well_known_name (f, f->activated,
+ "com.example.SystemdActivatable1");
+
+ /* The message is delivered to the activatable service. */
+ while (f->activated_message == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = f->activated_message;
+ f->activated_message = NULL;
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.bar", "UnicastSignal1", "",
+ "com.example.SystemdActivatable1");
+ dbus_message_unref (m);
+
+ /* The sender sends a message to a different activatable service. */
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal2");
+ if (!dbus_message_set_destination (m, "com.example.SystemdActivatable2"))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ /* This time systemd is already ready for it. */
+ while (g_queue_get_length (&f->monitored) < 2 ||
+ f->systemd_message == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = f->systemd_message;
+ f->systemd_message = NULL;
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
+ "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
+ "org.freedesktop.systemd1");
+ dbus_message_unref (m);
+
+ /* The monitor sees the activation request and the signal that
+ * prompted it.*/
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
+ "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
+ "org.freedesktop.systemd1");
+ dbus_message_unref (m);
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.bar", "UnicastSignal2", "",
+ "com.example.SystemdActivatable2");
+ dbus_message_unref (m);
+
+ /* The activatable service takes its name. Here I'm faking it by using
+ * an existing connection. */
+ take_well_known_name (f, f->activated, "com.example.SystemdActivatable2");
+
+ /* The message is delivered to the activatable service.
+ * Implementation detail: the monitor sees this happen before it even
+ * sees that the name request happened, which is pretty odd. */
+ while (f->activated_message == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = f->activated_message;
+ f->activated_message = NULL;
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.bar", "UnicastSignal2", "",
+ "com.example.SystemdActivatable2");
+ dbus_message_unref (m);
+
+ expect_take_well_known_name (f, f->activated,
+ "com.example.SystemdActivatable2");
+
+ /* A third activation. */
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal3");
+ if (!dbus_message_set_destination (m, "com.example.SystemdActivatable3"))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ /* Once again, we see the activation request and the reason. */
+ while (g_queue_get_length (&f->monitored) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
+ "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
+ "org.freedesktop.systemd1");
+ dbus_message_unref (m);
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo",
+ "com.example.bar", "UnicastSignal3", "",
+ "com.example.SystemdActivatable3");
+ dbus_message_unref (m);
+
+ /* systemd gets the request too. */
+ while (f->systemd_message == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = f->systemd_message;
+ f->systemd_message = NULL;
+ assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
+ "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
+ "org.freedesktop.systemd1");
+ dbus_message_unref (m);
+
+ /* This time activation fails */
+ m = dbus_message_new_signal ("/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Activator", "ActivationFailure");
+
+ do
+ {
+ const char *unit = "dbus-com.example.SystemdActivatable3.service";
+ const char *error_name = "com.example.Nope";
+ const char *error_message = "Computer says no";
+
+ if (!dbus_message_append_args (m,
+ DBUS_TYPE_STRING, &unit,
+ DBUS_TYPE_STRING, &error_name,
+ DBUS_TYPE_STRING, &error_message,
+ DBUS_TYPE_INVALID))
+ g_error ("OOM");
+ }
+ while (0);
+
+ if (!dbus_message_set_destination (m, "org.freedesktop.DBus"))
+ g_error ("OOM");
+ dbus_connection_send (f->systemd, m, NULL);
+ dbus_message_unref (m);
+
+ /* The monitor sees activation fail */
+
+ /* Once again, we see the activation request and the reason. */
+ while (g_queue_get_length (&f->monitored) < 1)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ "com.example.Nope");
+ dbus_message_unref (m);
+}
+
+static void
+teardown (Fixture *f,
+ gconstpointer context G_GNUC_UNUSED)
+{
+ dbus_error_free (&f->e);
+ g_clear_error (&f->ge);
+
+ if (f->monitor != NULL)
+ {
+ dbus_connection_remove_filter (f->monitor, monitor_filter, f);
+ dbus_connection_close (f->monitor);
+ dbus_connection_unref (f->monitor);
+ f->monitor = NULL;
+ }
+
+ if (f->sender != NULL)
+ {
+ dbus_connection_close (f->sender);
+ dbus_connection_unref (f->sender);
+ f->sender = NULL;
+ }
+
+ if (f->recipient != NULL)
+ {
+ dbus_connection_remove_filter (f->recipient, recipient_filter, f);
+ dbus_connection_close (f->recipient);
+ dbus_connection_unref (f->recipient);
+ f->recipient = NULL;
+ }
+
+ if (f->systemd != NULL)
+ {
+ dbus_connection_remove_filter (f->systemd, systemd_filter, f);
+ dbus_connection_close (f->systemd);
+ dbus_connection_unref (f->systemd);
+ f->systemd = NULL;
+ }
+
+ if (f->activated != NULL)
+ {
+ dbus_connection_remove_filter (f->activated, activated_filter, f);
+ dbus_connection_close (f->activated);
+ dbus_connection_unref (f->activated);
+ f->activated = NULL;
+ }
+
+ test_kill_pid (f->daemon_pid);
+ g_spawn_close_pid (f->daemon_pid);
+
+ test_main_context_unref (f->ctx);
+
+ g_queue_foreach (&f->monitored, (GFunc) dbus_message_unref, NULL);
+ g_queue_clear (&f->monitored);
+
+ g_free (f->address);
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ test_init (&argc, &argv);
+
+ g_test_add ("/monitor/become", Fixture, &side_effects_config,
+ setup, test_become_monitor, teardown);
+ g_test_add ("/monitor/broadcast", Fixture, NULL,
+ setup, test_broadcast, teardown);
+ g_test_add ("/monitor/forbidden-broadcast", Fixture, &forbidding_config,
+ setup, test_forbidden_broadcast, teardown);
+ g_test_add ("/monitor/unicast-signal", Fixture, NULL,
+ setup, test_unicast_signal, teardown);
+ g_test_add ("/monitor/forbidden", Fixture, &forbidding_config,
+ setup, test_forbidden, teardown);
+ g_test_add ("/monitor/method-call", Fixture, NULL,
+ setup, test_method_call, teardown);
+ g_test_add ("/monitor/forbidden-method", Fixture, &forbidding_config,
+ setup, test_forbidden_method_call, teardown);
+ g_test_add ("/monitor/dbus-daemon", Fixture, NULL,
+ setup, test_dbus_daemon, teardown);
+ g_test_add ("/monitor/selective", Fixture, &selective_config,
+ setup, test_selective, teardown);
+ g_test_add ("/monitor/wildcard", Fixture, &wildcard_config,
+ setup, test_unicast_signal, teardown);
+ g_test_add ("/monitor/no-rule", Fixture, &no_rules_config,
+ setup, test_unicast_signal, teardown);
+ g_test_add ("/monitor/eavesdrop", Fixture, &eavesdrop_config,
+ setup, test_unicast_signal, teardown);
+ g_test_add ("/monitor/no-eavesdrop", Fixture, &no_eavesdrop_config,
+ setup, test_unicast_signal, teardown);
+ g_test_add ("/monitor/activation", Fixture, &fake_systemd_config,
+ setup, test_activation, teardown);
+
+ return g_test_run ();
+}
diff --git a/test/relay.c b/test/relay.c
index ecfe4c82..a6ccb412 100644
--- a/test/relay.c
+++ b/test/relay.c
@@ -30,7 +30,7 @@
#include <dbus/dbus.h>
-#include "test-utils.h"
+#include "test-utils-glib.h"
/* This is basically a miniature dbus-daemon. We relay messages from the client
* on the left to the client on the right.
@@ -313,8 +313,7 @@ int
main (int argc,
char **argv)
{
- g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id=");
+ test_init (&argc, &argv);
g_test_add ("/connect", Fixture, NULL, setup,
test_connect, teardown);
diff --git a/test/sd-activation.c b/test/sd-activation.c
index 14e4ae80..2a7366df 100644
--- a/test/sd-activation.c
+++ b/test/sd-activation.c
@@ -211,6 +211,37 @@ test_activation (Fixture *f,
"org.freedesktop.systemd1");
dbus_message_unref (m);
+ /* A malicious process tries to disrupt the activation.
+ * In a more realistic scenario this would be another parallel
+ * connection. */
+ m = dbus_message_new_signal ("/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Activator", "ActivationFailure");
+ if (!dbus_message_set_destination (m, "org.freedesktop.DBus"))
+ g_error ("OOM");
+
+ do
+ {
+ const char *unit = "dbus-com.example.SystemdActivatable2.service";
+ const char *error_name = "com.example.Malice";
+ const char *error_message = "I'm on yr bus, making yr activations fail";
+
+ if (!dbus_message_append_args (m,
+ DBUS_TYPE_STRING, &unit,
+ DBUS_TYPE_STRING, &error_name,
+ DBUS_TYPE_STRING, &error_message,
+ DBUS_TYPE_INVALID))
+ g_error ("OOM");
+ }
+ while (0);
+
+ dbus_connection_send (f->caller, m, NULL);
+ dbus_message_unref (m);
+
+ /* This is just to make sure that the malicious message has arrived and
+ * been processed by the dbus-daemon, i.e. @caller won the race
+ * with @activated. */
+ take_well_known_name (f, f->caller, "com.example.Sync");
+
/* The activatable service takes its name. Here I'm faking it by using
* an existing connection; in real life it would be yet another
* connection. */
@@ -309,8 +340,7 @@ int
main (int argc,
char **argv)
{
- g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id=");
+ test_init (&argc, &argv);
g_test_add ("/sd-activation", Fixture, NULL,
setup, test_activation, teardown);
diff --git a/test/syntax.c b/test/syntax.c
index e26b3643..bf960c9e 100644
--- a/test/syntax.c
+++ b/test/syntax.c
@@ -30,6 +30,8 @@
#include <dbus/dbus.h>
+#include "test-utils-glib.h"
+
typedef struct {
DBusError e;
} Fixture;
@@ -269,7 +271,7 @@ int
main (int argc,
char **argv)
{
- g_test_init (&argc, &argv, NULL);
+ test_init (&argc, &argv);
g_test_add ("/syntax/path", Fixture, &paths, setup, test_syntax, teardown);
g_test_add ("/syntax/interface", Fixture, &interfaces,
diff --git a/test/test-utils-glib.c b/test/test-utils-glib.c
index 286e7a54..6cffcb21 100644
--- a/test/test-utils-glib.c
+++ b/test/test-utils-glib.c
@@ -385,3 +385,29 @@ test_kill_pid (GPid pid)
kill (pid, SIGTERM);
#endif
}
+
+static gboolean
+time_out (gpointer data)
+{
+ g_error ("timed out");
+ return FALSE;
+}
+
+void
+test_init (int *argcp, char ***argvp)
+{
+ g_test_init (argcp, argvp, NULL);
+ g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id=");
+
+ /* Prevent tests from hanging forever. This is intended to be long enough
+ * that any reasonable regression test on any reasonable hardware would
+ * have finished. */
+#define TIMEOUT 60
+
+ g_timeout_add_seconds (TIMEOUT, time_out, NULL);
+#ifdef G_OS_UNIX
+ /* The GLib main loop might not be running (we don't use it in every
+ * test). Die with SIGALRM shortly after if necessary. */
+ alarm (TIMEOUT + 10);
+#endif
+}
diff --git a/test/test-utils-glib.h b/test/test-utils-glib.h
index 80a7c8d4..fd14fd1f 100644
--- a/test/test-utils-glib.h
+++ b/test/test-utils-glib.h
@@ -79,4 +79,6 @@ DBusConnection *test_connect_to_bus_as_user (TestMainContext *ctx,
void test_kill_pid (GPid pid);
+void test_init (int *argcp, char ***argvp);
+
#endif
diff --git a/test/uid-permissions.c b/test/uid-permissions.c
index 407b530e..2c62185a 100644
--- a/test/uid-permissions.c
+++ b/test/uid-permissions.c
@@ -186,8 +186,7 @@ int
main (int argc,
char **argv)
{
- g_test_init (&argc, &argv, NULL);
- g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id=");
+ test_init (&argc, &argv);
g_test_add ("/uid-permissions/uae/root", Fixture, &root_ok_config,
setup, test_uae, teardown);