summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2015-10-16 17:33:36 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2016-11-28 12:11:32 +0000
commit5503511f91a66f0888937690e95d85100bcde4e4 (patch)
treebaa15feb3fd35993fc53fa17b310753dde631bf0
parent8de8bbbeaf03c78f9fa69d1d49ef01a1749220a7 (diff)
downloaddbus-5503511f91a66f0888937690e95d85100bcde4e4.tar.gz
Add tests for activation when message send/receive is denied
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk> Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk> Bug: https://bugs.freedesktop.org/show_bug.cgi?id=98666
-rw-r--r--test/Makefile.am2
-rw-r--r--test/data/systemd-activation/com.example.ReceiveDenied.service4
-rw-r--r--test/data/systemd-activation/com.example.SendDenied.service4
-rw-r--r--test/data/valid-config-files/systemd-activation.conf.in6
-rw-r--r--test/sd-activation.c193
5 files changed, 207 insertions, 2 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index bbd01d04..1eb086d9 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -430,6 +430,8 @@ static_data = \
data/sha-1/bit-messages.sha1 \
data/sha-1/byte-hashes.sha1 \
data/sha-1/byte-messages.sha1 \
+ data/systemd-activation/com.example.ReceiveDenied.service \
+ data/systemd-activation/com.example.SendDenied.service \
data/systemd-activation/com.example.SystemdActivatable1.service \
data/systemd-activation/com.example.SystemdActivatable2.service \
data/systemd-activation/com.example.SystemdActivatable3.service \
diff --git a/test/data/systemd-activation/com.example.ReceiveDenied.service b/test/data/systemd-activation/com.example.ReceiveDenied.service
new file mode 100644
index 00000000..a4944f70
--- /dev/null
+++ b/test/data/systemd-activation/com.example.ReceiveDenied.service
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=com.example.ReceiveDenied
+Exec=/bin/false ReceiveDenied
+SystemdService=dbus-com.example.ReceiveDenied.service
diff --git a/test/data/systemd-activation/com.example.SendDenied.service b/test/data/systemd-activation/com.example.SendDenied.service
new file mode 100644
index 00000000..aa9eb787
--- /dev/null
+++ b/test/data/systemd-activation/com.example.SendDenied.service
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=com.example.SendDenied
+Exec=/bin/false SendDenied
+SystemdService=dbus-com.example.SendDenied.service
diff --git a/test/data/valid-config-files/systemd-activation.conf.in b/test/data/valid-config-files/systemd-activation.conf.in
index bcd6416c..a3a59f05 100644
--- a/test/data/valid-config-files/systemd-activation.conf.in
+++ b/test/data/valid-config-files/systemd-activation.conf.in
@@ -3,9 +3,15 @@
<busconfig>
<listen>@TEST_LISTEN@</listen>
<servicedir>@DBUS_TEST_DATA@/systemd-activation</servicedir>
+
<policy context="default">
<allow send_destination="*"/>
<allow receive_sender="*"/>
<allow own="*"/>
</policy>
+
+ <policy context="mandatory">
+ <deny send_destination="com.example.SendDenied"/>
+ <deny receive_interface="com.example.ReceiveDenied" receive_member="Call"/>
+ </policy>
</busconfig>
diff --git a/test/sd-activation.c b/test/sd-activation.c
index f0450125..6d529870 100644
--- a/test/sd-activation.c
+++ b/test/sd-activation.c
@@ -40,12 +40,18 @@ typedef struct {
DBusConnection *caller;
const char *caller_name;
+ DBusMessage *caller_message;
+ dbus_bool_t caller_filter_added;
+
DBusConnection *systemd;
const char *systemd_name;
DBusMessage *systemd_message;
+ dbus_bool_t systemd_filter_added;
+
DBusConnection *activated;
const char *activated_name;
DBusMessage *activated_message;
+ dbus_bool_t activated_filter_added;
} Fixture;
/* this is a macro so it gets the right line number */
@@ -94,6 +100,21 @@ do { \
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)
+
static DBusHandlerResult
systemd_filter (DBusConnection *connection,
DBusMessage *message,
@@ -150,6 +171,27 @@ activated_filter (DBusConnection *connection,
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
+static DBusHandlerResult
+caller_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->caller_message == NULL);
+ f->caller_message = dbus_message_ref (message);
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
static void
setup (Fixture *f,
gconstpointer context G_GNUC_UNUSED)
@@ -203,6 +245,7 @@ test_activation (Fixture *f,
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_filter_added = TRUE;
f->systemd_name = dbus_bus_get_unique_name (f->systemd);
take_well_known_name (f, f->systemd, "org.freedesktop.systemd1");
@@ -222,6 +265,7 @@ test_activation (Fixture *f,
if (!dbus_connection_add_filter (f->activated, activated_filter,
f, NULL))
g_error ("OOM");
+ f->activated_filter_added = TRUE;
f->activated_name = dbus_bus_get_unique_name (f->activated);
take_well_known_name (f, f->activated, "com.example.SystemdActivatable1");
@@ -509,6 +553,140 @@ test_uae (Fixture *f,
}
static void
+test_deny_send (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ if (!dbus_connection_add_filter (f->caller, caller_filter, f, NULL))
+ g_error ("OOM");
+
+ f->caller_filter_added = TRUE;
+
+ /* The sender sends a message to an activatable service. */
+ m = dbus_message_new_method_call ("com.example.SendDenied", "/foo",
+ "com.example.bar", "Call");
+ if (m == NULL)
+ g_error ("OOM");
+
+ dbus_connection_send (f->caller, m, NULL);
+ 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_filter_added = TRUE;
+ f->systemd_name = dbus_bus_get_unique_name (f->systemd);
+ take_well_known_name (f, f->systemd, "org.freedesktop.systemd1");
+
+ /* It gets its activation request. */
+ while (f->caller_message == NULL && f->systemd_message == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ g_assert (f->caller_message == NULL);
+ g_assert (f->systemd_message != NULL);
+
+ 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_filter_added = TRUE;
+ f->activated_name = dbus_bus_get_unique_name (f->activated);
+ take_well_known_name (f, f->activated, "com.example.SendDenied");
+
+ /* We re-do the message matching, and now the message is
+ * forbidden by the receive policy. */
+ while (f->activated_message == NULL && f->caller_message == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ g_assert (f->activated_message == NULL);
+
+ m = f->caller_message;
+ f->caller_message = NULL;
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->caller_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+}
+
+static void
+test_deny_receive (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ if (!dbus_connection_add_filter (f->caller, caller_filter, f, NULL))
+ g_error ("OOM");
+
+ f->caller_filter_added = TRUE;
+
+ /* The sender sends a message to an activatable service. */
+ m = dbus_message_new_method_call ("com.example.ReceiveDenied", "/foo",
+ "com.example.ReceiveDenied", "Call");
+ if (m == NULL)
+ g_error ("OOM");
+
+ dbus_connection_send (f->caller, m, NULL);
+ 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_filter_added = TRUE;
+ f->systemd_name = dbus_bus_get_unique_name (f->systemd);
+ 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_filter_added = TRUE;
+ f->activated_name = dbus_bus_get_unique_name (f->activated);
+ take_well_known_name (f, f->activated, "com.example.ReceiveDenied");
+
+ /* We re-do the message matching, and now the message is
+ * forbidden by the receive policy. */
+ while (f->caller_message == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = f->caller_message;
+ f->caller_message = NULL;
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->caller_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ /* The activated service never even saw it. */
+ g_assert (f->activated_message == NULL);
+}
+
+static void
teardown (Fixture *f,
gconstpointer context G_GNUC_UNUSED)
{
@@ -517,6 +695,9 @@ teardown (Fixture *f,
if (f->caller != NULL)
{
+ if (f->caller_filter_added)
+ dbus_connection_remove_filter (f->caller, caller_filter, f);
+
dbus_connection_close (f->caller);
dbus_connection_unref (f->caller);
f->caller = NULL;
@@ -524,7 +705,9 @@ teardown (Fixture *f,
if (f->systemd != NULL)
{
- dbus_connection_remove_filter (f->systemd, systemd_filter, f);
+ if (f->systemd_filter_added)
+ dbus_connection_remove_filter (f->systemd, systemd_filter, f);
+
dbus_connection_close (f->systemd);
dbus_connection_unref (f->systemd);
f->systemd = NULL;
@@ -532,7 +715,9 @@ teardown (Fixture *f,
if (f->activated != NULL)
{
- dbus_connection_remove_filter (f->activated, activated_filter, f);
+ if (f->activated_filter_added)
+ dbus_connection_remove_filter (f->activated, activated_filter, f);
+
dbus_connection_close (f->activated);
dbus_connection_unref (f->activated);
f->activated = NULL;
@@ -554,6 +739,10 @@ main (int argc,
setup, test_activation, teardown);
g_test_add ("/sd-activation/uae", Fixture, NULL,
setup, test_uae, teardown);
+ g_test_add ("/sd-activation/deny-send", Fixture, NULL,
+ setup, test_deny_send, teardown);
+ g_test_add ("/sd-activation/deny-receive", Fixture, NULL,
+ setup, test_deny_receive, teardown);
return g_test_run ();
}