[apparmor] [PATCH 2/2 v3] tests: Add regression tests for dbus
Tyler Hicks
tyhicks at canonical.com
Wed Aug 14 05:13:55 UTC 2013
Integrate dbus tests into the regression testing framework.
This started out as dbus-send.c, from the dbus source, and then grew
from there.
dbus_message is an example "client" program that only sends out
messages. dbus_service binds to a well-known name and then listens and
responds to incoming messages. They share some code in dbus_common.c.
The test scripts, dbus_message.sh and dbus_service.sh, share some
functionality in dbus.inc.
Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
* Changes in v3:
- Add <apparmor mode="required"/> to dbus.conf to ensure that dbus-daemon
will either enforce AppArmor mediation or fail to run if AppArmor D-Bus
mediation is not available
- Do a best effort attempt to detect if dbus-daemon initialization was
successful in dbus.inc:start_bus(). A sleep and kill -0 isn't ideal, but
dbus-daemon forks before initialization is complete.
- Fix fatalerror message in dbus.inc:send() so that it correctly prints the
message type (thanks for pointing this out, Seth!)
- Unify error paths in dbus_service.c:main()
- Introduce an unlock_fd() function that is called from
dbus_service.c:main()'s error path. This makes sure that the fd that was
pre-locked by dbus_service.sh is always unlocked.
- Set up signal handling a earlier in dbus_service.c:main()
- Stop using runchecktest() in dbus_service.sh. Instead, wrap
service_runtestbg() and service_checktestbg() with service_runchecktest()
and use that in the two remaining runchecktest() call sites. This, along
with the unlock_fd() change and <apparmor mode="required"/> changes above,
fixes a hang that Jamie was seeing.
- Run dbus_{message,service,common}.c through the kernel's scripts/Lindent
script to make the coding style less like D-Bus and more like AppArmor.
Those source files only vaguely resemble D-Bus' dbus_send.c now, so there's
little value in sticking with the D-Bus coding style.
That last bullet point obviously makes it difficult to diff v2 and v3. If it
would be helpful to see an incremental diff between v2 and v3, before I ran the
.c files through Lindent, I can easily send it out. Just let me know.
Seth gave v2 an ack, but v3 changes enough that I didn't feel comfortable
carrying that ack over. John gave v1 a tentative ack and I plan on waiting for
a solid ack from him on v3 before committing it to trunk.
Tyler
tests/regression/apparmor/Makefile | 15 +-
tests/regression/apparmor/dbus.conf | 30 +++
tests/regression/apparmor/dbus.inc | 107 ++++++++++
tests/regression/apparmor/dbus_common.c | 254 +++++++++++++++++++++++
tests/regression/apparmor/dbus_common.h | 29 +++
tests/regression/apparmor/dbus_message.c | 325 ++++++++++++++++++++++++++++++
tests/regression/apparmor/dbus_message.sh | 126 ++++++++++++
tests/regression/apparmor/dbus_service.c | 313 ++++++++++++++++++++++++++++
tests/regression/apparmor/dbus_service.sh | 138 +++++++++++++
9 files changed, 1336 insertions(+), 1 deletion(-)
create mode 100644 tests/regression/apparmor/dbus.conf
create mode 100644 tests/regression/apparmor/dbus.inc
create mode 100644 tests/regression/apparmor/dbus_common.c
create mode 100644 tests/regression/apparmor/dbus_common.h
create mode 100644 tests/regression/apparmor/dbus_message.c
create mode 100755 tests/regression/apparmor/dbus_message.sh
create mode 100644 tests/regression/apparmor/dbus_service.c
create mode 100755 tests/regression/apparmor/dbus_service.sh
diff --git a/tests/regression/apparmor/Makefile b/tests/regression/apparmor/Makefile
index e686ddc..bf0c0b1 100644
--- a/tests/regression/apparmor/Makefile
+++ b/tests/regression/apparmor/Makefile
@@ -23,6 +23,8 @@ SRC=access.c \
chown.c \
clone.c \
coredump.c \
+ dbus_message.c \
+ dbus_service.c \
deleted.c \
environ.c \
env_check.c \
@@ -120,6 +122,8 @@ TESTS=access \
chdir \
clone \
coredump \
+ dbus_message \
+ dbus_service \
deleted \
environ \
exec \
@@ -164,6 +168,15 @@ all: $(EXEC) changehat.h
changehat_pthread: changehat_pthread.c changehat.h
${CC} ${CFLAGS} ${LDFLAGS} $< -o $@ ${LDLIBS} -pthread
+dbus_common.o: dbus_common.c dbus_common.h
+ ${CC} ${CFLAGS} ${LDFLAGS} $^ -c ${LDLIBS} $(shell pkg-config --cflags --libs dbus-1)
+
+dbus_message: dbus_message.c dbus_common.o
+ ${CC} ${CFLAGS} ${LDFLAGS} $^ -o dbus_message ${LDLIBS} $(shell pkg-config --cflags --libs dbus-1)
+
+dbus_service: dbus_message dbus_service.c dbus_common.o
+ ${CC} ${CFLAGS} ${LDFLAGS} $(filter-out dbus_message, $^) -o dbus_service ${LDLIBS} $(shell pkg-config --cflags --libs dbus-1)
+
tests: all
@if [ `whoami` = "root" ] ;\
then \
@@ -203,6 +216,6 @@ alltests: all
fi
clean:
- rm -f $(EXEC)
+ rm -f $(EXEC) dbus_common.o
regex.sh: open exec
diff --git a/tests/regression/apparmor/dbus.conf b/tests/regression/apparmor/dbus.conf
new file mode 100644
index 0000000..39997c5
--- /dev/null
+++ b/tests/regression/apparmor/dbus.conf
@@ -0,0 +1,30 @@
+<!-- This configuration file controls the per-user-login-session message bus.
+ Add a session-local.conf and edit that rather than changing this
+ file directly. -->
+
+<!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>
+
+ <!-- Force AppArmor mediation to be enabled -->
+ <apparmor mode="required"/>
+
+ <!-- If we fork, keep the user's original umask to avoid affecting
+ the behavior of child processes. -->
+ <keep_umask/>
+
+ <listen>unix:tmpdir=/tmp</listen>
+
+ <standard_session_servicedirs />
+
+ <policy context="default">
+ <!-- Allow everything to be sent -->
+ <allow send_destination="*" eavesdrop="true"/>
+ <!-- Allow everything to be received -->
+ <allow eavesdrop="true"/>
+ <!-- Allow anyone to own anything -->
+ <allow own="*"/>
+ </policy>
+</busconfig>
diff --git a/tests/regression/apparmor/dbus.inc b/tests/regression/apparmor/dbus.inc
new file mode 100644
index 0000000..787ee95
--- /dev/null
+++ b/tests/regression/apparmor/dbus.inc
@@ -0,0 +1,107 @@
+# vim:syntax=sh
+#
+# Copyright (C) 2013 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, version 2 of the
+# License.
+
+gendbusprofile()
+{
+ genprofile --stdin <<EOF
+$test {
+ @{gen $test}
+ $@
+}
+EOF
+}
+
+start_bus()
+{
+ out=$(dbus-daemon --fork --print-pid --print-address --config-file=dbus.conf)
+ if [ $? -ne 0 ]
+ then
+ fatalerror "Failed to start DBus daemon"
+ fi
+
+ bus_addr=$(echo $out | cut -d\ -f 1)
+ bus_pid=$(echo $out | cut -d\ -f 2)
+
+ # The daemon may error out during initialization. Unfortunately,
+ # there's no good way to detect that, but this will work under normal
+ # conditions.
+ sleep 1
+ kill -0 $bus_pid 2>/dev/null
+ if [ $? -ne 0 ]
+ then
+ fatalerror "DBus daemon unexpectedly stopped"
+ fi
+
+ do_onexit="kill $bus_pid"
+ export DBUS_SESSION_BUS_ADDRESS=$bus_addr
+}
+
+bus="session"
+dest=com.apparmor.Test
+path=/com/apparmor/Test
+iface=com.apparmor.Test
+
+# parameters: bus message_type destination path interface.member
+#
+# destination must be a connection name or "broadcast" for a broadcast signal
+send()
+{
+ d=""
+
+ if [ "$3" == "broadcast" ]
+ then
+ if [ "$2" != "signal" ]
+ then
+ fatalerror "Cannot send broadcast for message type \"$2\""
+ fi
+ else
+ d="--name=$3"
+ fi
+
+ out=$(./dbus_message --$1 --type=$2 $d $4 $5 2>&1)
+ if [ $? -ne 0 ]
+ then
+ fatalerror "$out"
+ fi
+}
+
+sendsignal()
+{
+ send "$bus" "signal" "$dest" "$path" "${iface}.Signal"
+}
+
+sendbroadcastsignal()
+{
+ send "$bus" "signal" "broadcast" "$path" "${iface}.Signal"
+}
+
+sendmethod()
+{
+ send "$bus" "method_call" "$dest" "$path" "${iface}.Method"
+}
+
+compare_logs()
+{
+ local msg
+ local rc=0
+
+ cmp -s "$1" "$3" || rc=$?
+ if [ $rc -ne 0 ] && [ "$2" == "eq" ]
+ then
+ msg="Log files \"$1\" and \"$3\" are different, but should be equal."
+ elif [ $rc -eq 0 ] && [ "$2" == "ne" ]
+ then
+ msg="Log files \"$1\" and \"$3\" are the same, but should be different."
+ else
+ return
+ fi
+
+ echo "Error: ${testname} failed. Test '${_testdesc}' produced unexpected log contents. ${msg}"
+ testfailed
+}
diff --git a/tests/regression/apparmor/dbus_common.c b/tests/regression/apparmor/dbus_common.c
new file mode 100644
index 0000000..751a4a5
--- /dev/null
+++ b/tests/regression/apparmor/dbus_common.c
@@ -0,0 +1,254 @@
+/* dbus_common.c
+ *
+ * Copyright (C) 2003 Philip Blundell <philb at gnu.org>
+ * Copyright (C) 2013 Canonical, Ltd.
+ *
+ * Originally dbus-send.c from the dbus package. It has been heavily modified
+ * to work within the regression test framework.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "dbus_common.h"
+
+const char *type_to_name(int message_type)
+{
+ switch (message_type) {
+ case DBUS_MESSAGE_TYPE_SIGNAL:
+ return "signal";
+ case DBUS_MESSAGE_TYPE_METHOD_CALL:
+ return "method call";
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ return "method return";
+ case DBUS_MESSAGE_TYPE_ERROR:
+ return "error";
+ default:
+ return "(unknown message type)";
+ }
+}
+
+void log_message(int log_fd, const char *prefix, DBusMessage * message)
+{
+ const char *sender = NULL;
+ const char *destination = NULL;
+ const char *unique = "(UNIQUE)";
+ int message_type;
+
+ if (log_fd < 0)
+ return;
+
+ message_type = dbus_message_get_type(message);
+ sender = dbus_message_get_sender(message);
+ destination = dbus_message_get_destination(message);
+
+ /* Remove unique (random) names from the logs since they make it
+ * impossible to do simple log comparisons between two different test
+ * runs.
+ */
+ if (sender && sender[0] == ':')
+ sender = unique;
+ if (destination && destination[0] == ':')
+ destination = unique;
+
+ dprintf(log_fd, "%s%s sender=%s -> dest=%s",
+ prefix, type_to_name(message_type),
+ sender ? sender : "(null)",
+ destination ? destination : "(null)");
+
+ switch (message_type) {
+ case DBUS_MESSAGE_TYPE_METHOD_CALL:
+ case DBUS_MESSAGE_TYPE_SIGNAL:
+ dprintf(log_fd, " path=%s; interface=%s; member=%s\n",
+ dbus_message_get_path(message),
+ dbus_message_get_interface(message),
+ dbus_message_get_member(message));
+ break;
+
+ case DBUS_MESSAGE_TYPE_ERROR:
+ dprintf(log_fd, " error_name=%s\n",
+ dbus_message_get_error_name(message));
+ break;
+
+ default:
+ dprintf(log_fd, "\n");
+ break;
+ }
+}
+
+void append_arg(DBusMessageIter * iter, int type, const char *value)
+{
+ dbus_uint16_t uint16;
+ dbus_int16_t int16;
+ dbus_uint32_t uint32;
+ dbus_int32_t int32;
+ dbus_uint64_t uint64;
+ dbus_int64_t int64;
+ double d;
+ unsigned char byte;
+ dbus_bool_t v_BOOLEAN;
+
+ /* FIXME - we are ignoring OOM returns on all these functions */
+ switch (type) {
+ case DBUS_TYPE_BYTE:
+ byte = strtoul(value, NULL, 0);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &byte);
+ break;
+
+ case DBUS_TYPE_DOUBLE:
+ d = strtod(value, NULL);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_DOUBLE, &d);
+ break;
+
+ case DBUS_TYPE_INT16:
+ int16 = strtol(value, NULL, 0);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &int16);
+ break;
+
+ case DBUS_TYPE_UINT16:
+ uint16 = strtoul(value, NULL, 0);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &uint16);
+ break;
+
+ case DBUS_TYPE_INT32:
+ int32 = strtol(value, NULL, 0);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int32);
+ break;
+
+ case DBUS_TYPE_UINT32:
+ uint32 = strtoul(value, NULL, 0);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &uint32);
+ break;
+
+ case DBUS_TYPE_INT64:
+ int64 = strtoll(value, NULL, 0);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT64, &int64);
+ break;
+
+ case DBUS_TYPE_UINT64:
+ uint64 = strtoull(value, NULL, 0);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &uint64);
+ break;
+
+ case DBUS_TYPE_STRING:
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &value);
+ break;
+
+ case DBUS_TYPE_OBJECT_PATH:
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
+ &value);
+ break;
+
+ case DBUS_TYPE_BOOLEAN:
+ if (strcmp(value, "true") == 0) {
+ v_BOOLEAN = TRUE;
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
+ &v_BOOLEAN);
+ } else if (strcmp(value, "false") == 0) {
+ v_BOOLEAN = FALSE;
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
+ &v_BOOLEAN);
+ } else {
+ fprintf(stderr,
+ "FAIL: Expected \"true\" or \"false\" instead of \"%s\"\n",
+ value);
+ exit(1);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "FAIL: Unsupported data type %c\n", (char)type);
+ exit(1);
+ }
+}
+
+void append_array(DBusMessageIter * iter, int type, const char *value)
+{
+ const char *val;
+ char *dupval = strdup(value);
+
+ val = strtok(dupval, ",");
+ while (val != NULL) {
+ append_arg(iter, type, val);
+ val = strtok(NULL, ",");
+ }
+ free(dupval);
+}
+
+void
+append_dict(DBusMessageIter * iter, int keytype, int valtype, const char *value)
+{
+ const char *val;
+ char *dupval = strdup(value);
+
+ val = strtok(dupval, ",");
+ while (val != NULL) {
+ DBusMessageIter subiter;
+
+ dbus_message_iter_open_container(iter,
+ DBUS_TYPE_DICT_ENTRY,
+ NULL, &subiter);
+
+ append_arg(&subiter, keytype, val);
+ val = strtok(NULL, ",");
+ if (val == NULL) {
+ fprintf(stderr, "FAIL: Malformed dictionary\n");
+ exit(1);
+ }
+ append_arg(&subiter, valtype, val);
+
+ dbus_message_iter_close_container(iter, &subiter);
+ val = strtok(NULL, ",");
+ }
+ free(dupval);
+}
+
+int type_from_name(const char *arg)
+{
+ int type;
+ if (!strcmp(arg, "string"))
+ type = DBUS_TYPE_STRING;
+ else if (!strcmp(arg, "int16"))
+ type = DBUS_TYPE_INT16;
+ else if (!strcmp(arg, "uint16"))
+ type = DBUS_TYPE_UINT16;
+ else if (!strcmp(arg, "int32"))
+ type = DBUS_TYPE_INT32;
+ else if (!strcmp(arg, "uint32"))
+ type = DBUS_TYPE_UINT32;
+ else if (!strcmp(arg, "int64"))
+ type = DBUS_TYPE_INT64;
+ else if (!strcmp(arg, "uint64"))
+ type = DBUS_TYPE_UINT64;
+ else if (!strcmp(arg, "double"))
+ type = DBUS_TYPE_DOUBLE;
+ else if (!strcmp(arg, "byte"))
+ type = DBUS_TYPE_BYTE;
+ else if (!strcmp(arg, "boolean"))
+ type = DBUS_TYPE_BOOLEAN;
+ else if (!strcmp(arg, "objpath"))
+ type = DBUS_TYPE_OBJECT_PATH;
+ else {
+ fprintf(stderr, "FAIL: Unknown type \"%s\"\n", arg);
+ exit(1);
+ }
+ return type;
+}
diff --git a/tests/regression/apparmor/dbus_common.h b/tests/regression/apparmor/dbus_common.h
new file mode 100644
index 0000000..1f376e6
--- /dev/null
+++ b/tests/regression/apparmor/dbus_common.h
@@ -0,0 +1,29 @@
+/* dbus_common.h
+ *
+ * Copyright (C) 2013 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <dbus/dbus.h>
+
+const char *type_to_name(int message_type);
+void log_message(int log_fd, const char *prefix, DBusMessage * message);
+void append_arg(DBusMessageIter * iter, int type, const char *value);
+void append_array(DBusMessageIter * iter, int type, const char *value);
+void append_dict(DBusMessageIter * iter, int keytype, int valtype,
+ const char *value);
+int type_from_name(const char *arg);
diff --git a/tests/regression/apparmor/dbus_message.c b/tests/regression/apparmor/dbus_message.c
new file mode 100644
index 0000000..8a8d4eb
--- /dev/null
+++ b/tests/regression/apparmor/dbus_message.c
@@ -0,0 +1,325 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus_message.c Utility program to send messages from the command line
+ *
+ * Copyright (C) 2003 Philip Blundell <philb at gnu.org>
+ * Copyright (C) 2013 Canonical, Ltd.
+ *
+ * Originally dbus-send.c from the dbus package. It has been heavily modified
+ * to work within the regression test framework.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "dbus_common.h"
+
+DBusConnection *connection;
+DBusError error;
+DBusBusType type = DBUS_BUS_SESSION;
+const char *type_str = NULL;
+const char *name = NULL;
+const char *interface = NULL;
+const char *member = NULL;
+const char *path = NULL;
+int message_type = DBUS_MESSAGE_TYPE_SIGNAL;
+const char *address = NULL;
+int session_or_system = FALSE;
+int log_fd = -1;
+
+static void usage(int ecode)
+{
+ char *prefix = ecode ? "FAIL: " : "";
+
+ fprintf(stderr,
+ "%6sUsage: dbus_message [ADDRESS] [--name=NAME] [--type=TYPE] <path> <interface.member> [contents ...]\n"
+ " ADDRESS\t\t--system, --session (default), or --address=ADDR\n"
+ " NAME\t\tthe message destination\n"
+ " TYPE\t\tsignal (default) or method_call\n"
+ " path\t\tpath to object (such as /org/freedesktop/DBus)\n"
+ " interface\t\tinterface to use (such as org.freedesktop.DBus)\n"
+ " member\t\tname of the method or signal (such as ListNames)\n",
+ prefix);
+ exit(ecode);
+}
+
+static int do_message(int argc, char *argv[])
+{
+ DBusMessage *message;
+ DBusMessageIter iter;
+ int i = 0;
+
+ if (message_type == DBUS_MESSAGE_TYPE_METHOD_CALL) {
+ message = dbus_message_new_method_call(NULL,
+ path, interface, member);
+ dbus_message_set_auto_start(message, TRUE);
+ } else if (message_type == DBUS_MESSAGE_TYPE_SIGNAL) {
+ message = dbus_message_new_signal(path, interface, member);
+ } else {
+ fprintf(stderr, "FAIL: Internal error, unknown message type\n");
+ return 1;
+ }
+
+ if (message == NULL) {
+ fprintf(stderr, "FAIL: Couldn't allocate D-Bus message\n");
+ return 1;
+ }
+
+ if (name && !dbus_message_set_destination(message, name)) {
+ fprintf(stderr, "FAIL: Not enough memory\n");
+ return 1;
+ }
+
+ dbus_message_iter_init_append(message, &iter);
+
+ while (i < argc) {
+ char *arg;
+ char *c;
+ int type;
+ int secondary_type;
+ int container_type;
+ DBusMessageIter *target_iter;
+ DBusMessageIter container_iter;
+
+ type = DBUS_TYPE_INVALID;
+ arg = argv[i++];
+ c = strchr(arg, ':');
+
+ if (c == NULL) {
+ fprintf(stderr,
+ "FAIL: %s: Data item \"%s\" is badly formed\n",
+ argv[0], arg);
+ return 1;
+ }
+
+ *(c++) = 0;
+
+ container_type = DBUS_TYPE_INVALID;
+
+ if (strcmp(arg, "variant") == 0)
+ container_type = DBUS_TYPE_VARIANT;
+ else if (strcmp(arg, "array") == 0)
+ container_type = DBUS_TYPE_ARRAY;
+ else if (strcmp(arg, "dict") == 0)
+ container_type = DBUS_TYPE_DICT_ENTRY;
+
+ if (container_type != DBUS_TYPE_INVALID) {
+ arg = c;
+ c = strchr(arg, ':');
+ if (c == NULL) {
+ fprintf(stderr,
+ "FAIL: %s: Data item \"%s\" is badly formed\n",
+ argv[0], arg);
+ return 1;
+ }
+ *(c++) = 0;
+ }
+
+ if (arg[0] == 0)
+ type = DBUS_TYPE_STRING;
+ else
+ type = type_from_name(arg);
+
+ if (container_type == DBUS_TYPE_DICT_ENTRY) {
+ char sig[5];
+ arg = c;
+ c = strchr(c, ':');
+ if (c == NULL) {
+ fprintf(stderr,
+ "FAIL: %s: Data item \"%s\" is badly formed\n",
+ argv[0], arg);
+ return 1;
+ }
+ *(c++) = 0;
+ secondary_type = type_from_name(arg);
+ sig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
+ sig[1] = type;
+ sig[2] = secondary_type;
+ sig[3] = DBUS_DICT_ENTRY_END_CHAR;
+ sig[4] = '\0';
+ dbus_message_iter_open_container(&iter,
+ DBUS_TYPE_ARRAY,
+ sig, &container_iter);
+ target_iter = &container_iter;
+ } else if (container_type != DBUS_TYPE_INVALID) {
+ char sig[2];
+ sig[0] = type;
+ sig[1] = '\0';
+ dbus_message_iter_open_container(&iter,
+ container_type,
+ sig, &container_iter);
+ target_iter = &container_iter;
+ } else
+ target_iter = &iter;
+
+ if (container_type == DBUS_TYPE_ARRAY) {
+ append_array(target_iter, type, c);
+ } else if (container_type == DBUS_TYPE_DICT_ENTRY) {
+ append_dict(target_iter, type, secondary_type, c);
+ } else
+ append_arg(target_iter, type, c);
+
+ if (container_type != DBUS_TYPE_INVALID) {
+ dbus_message_iter_close_container(&iter,
+ &container_iter);
+ }
+ }
+
+ if (message_type == DBUS_MESSAGE_TYPE_METHOD_CALL) {
+ DBusMessage *reply;
+
+ log_message(log_fd, "sent ", message);
+ dbus_error_init(&error);
+ reply = dbus_connection_send_with_reply_and_block(connection,
+ message, -1,
+ &error);
+ if (dbus_error_is_set(&error)) {
+ fprintf(stderr, "FAIL: %s: %s\n",
+ error.name, error.message);
+ return 1;
+ }
+
+ if (reply) {
+ dbus_message_unref(reply);
+ }
+ } else {
+ log_message(log_fd, "sent ", message);
+ dbus_connection_send(connection, message, NULL);
+ dbus_connection_flush(connection);
+ }
+
+ dbus_message_unref(message);
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int i, rc;
+
+ if (argc < 3)
+ usage(1);
+
+ for (i = 1; i < argc && interface == NULL; i++) {
+ char *arg = argv[i];
+
+ if (strcmp(arg, "--system") == 0) {
+ type = DBUS_BUS_SYSTEM;
+ session_or_system = TRUE;
+ } else if (strcmp(arg, "--session") == 0) {
+ type = DBUS_BUS_SESSION;
+ session_or_system = TRUE;
+ } else if (strstr(arg, "--address") == arg) {
+ address = strchr(arg, '=');
+
+ if (address == NULL) {
+ fprintf(stderr,
+ "FAIL: \"--address=\" requires an ADDRESS\n");
+ usage(1);
+ } else {
+ address = address + 1;
+ }
+ } else if (strstr(arg, "--name=") == arg)
+ name = strchr(arg, '=') + 1;
+ else if (strstr(arg, "--type=") == arg)
+ type_str = strchr(arg, '=') + 1;
+ else if (strstr(arg, "--log=") == arg) {
+ char *path = strchr(arg, '=') + 1;
+
+ log_fd = open(path, O_CREAT | O_TRUNC | O_WRONLY,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
+ S_IROTH | S_IWOTH);
+ if (log_fd < 0) {
+ fprintf(stderr,
+ "FAIL: Couldn't open log file \"%s\": %m\n",
+ path);
+ exit(1);
+ }
+ } else if (!strcmp(arg, "--help"))
+ usage(0);
+ else if (arg[0] == '-')
+ usage(1);
+ else if (path == NULL)
+ path = arg;
+ else /* interface == NULL guaranteed by the 'while' loop */
+ interface = arg;
+ }
+
+ if (interface == NULL)
+ usage(1);
+ else {
+ char *last_dot = strrchr(interface, '.');
+
+ if (last_dot == NULL) {
+ fprintf(stderr,
+ "FAIL: Must use org.mydomain.Interface.Member notation, no dot in \"%s\"\n",
+ interface);
+ exit(1);
+ }
+ *last_dot = '\0';
+ member = last_dot + 1;
+ }
+
+ if (session_or_system && address != NULL) {
+ fprintf(stderr,
+ "FAIL: \"--address\" may not be used with \"--system\" or \"--session\"\n");
+ usage(1);
+ }
+
+ if (type_str != NULL) {
+ message_type = dbus_message_type_from_string(type_str);
+ if (!(message_type == DBUS_MESSAGE_TYPE_METHOD_CALL ||
+ message_type == DBUS_MESSAGE_TYPE_SIGNAL)) {
+ fprintf(stderr,
+ "FAIL: Message type \"%s\" is not supported\n",
+ type_str);
+ exit(1);
+ }
+ }
+
+ dbus_error_init(&error);
+
+ if (address != NULL)
+ connection = dbus_connection_open(address, &error);
+ else
+ connection = dbus_bus_get(type, &error);
+
+ if (connection == NULL) {
+ fprintf(stderr,
+ "FAIL: Failed to open connection to \"%s\" message bus: %s\n",
+ (address !=
+ NULL) ? address : ((type ==
+ DBUS_BUS_SYSTEM) ? "system" :
+ "session"), error.message);
+ dbus_error_free(&error);
+ exit(1);
+ } else if (address != NULL)
+ dbus_bus_register(connection, &error);
+
+ rc = do_message(argc - i, argv + i);
+ dbus_connection_unref(connection);
+ if (rc == 0)
+ printf("PASS\n");
+
+ exit(rc);
+}
diff --git a/tests/regression/apparmor/dbus_message.sh b/tests/regression/apparmor/dbus_message.sh
new file mode 100755
index 0000000..9780e13
--- /dev/null
+++ b/tests/regression/apparmor/dbus_message.sh
@@ -0,0 +1,126 @@
+#! /bin/bash
+# Copyright (C) 2013 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, version 2 of the
+# License.
+
+#=NAME dbus_message
+#=DESCRIPTION
+# This test verifies that the dbus message sending is indeed restricted for
+# confined processes.
+#=END
+
+pwd=`dirname $0`
+pwd=`cd $pwd ; /bin/pwd`
+
+bin=$pwd
+
+. $bin/prologue.inc
+required_features dbus
+. $bin/dbus.inc
+
+listnames="--type=method_call --session --name=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames"
+
+unconfined_log="${tmpdir}/unconfined.log"
+unconfined_args="--log=$unconfined_log $listnames"
+
+confined_log="${tmpdir}/confined.log"
+confined_args="--log=$confined_log $listnames"
+
+message_gendbusprofile()
+{
+ gendbusprofile "${confined_log} w,
+ $@"
+}
+
+start_bus
+
+settest dbus_message
+
+# Make sure can send unconfined
+
+runchecktest "message (unconfined)" pass $unconfined_args
+
+# Make sure send is denied when confined but not allowed
+
+message_gendbusprofile
+runchecktest "message (confined w/o dbus allowed)" fail $confined_args
+
+message_gendbusprofile "dbus receive,"
+runchecktest "message (receive allowed)" fail $confined_args
+
+message_gendbusprofile "dbus bind,"
+runchecktest "message (bind allowed)" fail $confined_args
+
+message_gendbusprofile "dbus (receive, bind),"
+runchecktest "message (receive bind allowed)" fail $confined_args
+
+# Make sure send is allowed when confined with appropriate permissions
+
+message_gendbusprofile "dbus,"
+runtestfg "message (dbus allowed)" pass $confined_args
+checktestfg "compare_logs $unconfined_log eq $confined_log"
+
+message_gendbusprofile "dbus send,"
+runtestfg "message (send allowed)" pass $confined_args
+checktestfg "compare_logs $unconfined_log eq $confined_log"
+
+message_gendbusprofile "dbus (send, receive),"
+runtestfg "message (send receive allowed)" pass $confined_args
+checktestfg "compare_logs $unconfined_log eq $confined_log"
+
+message_gendbusprofile "dbus (send, bind),"
+runtestfg "message (send bind allowed)" pass $confined_args
+checktestfg "compare_logs $unconfined_log eq $confined_log"
+
+message_gendbusprofile "dbus (send, receive, bind),"
+runtestfg "message (send receive bind allowed)" pass $confined_args
+checktestfg "compare_logs $unconfined_log eq $confined_log"
+
+# Make sure send is allowed when confined with appropriate permissions along
+# with conditionals
+
+message_gendbusprofile "dbus send bus=session,"
+runtestfg "message (send allowed w/ bus)" pass $confined_args
+checktestfg "compare_logs $unconfined_log eq $confined_log"
+
+message_gendbusprofile "dbus send bus=session peer=(name=org.freedesktop.DBus),"
+runtestfg "message (send allowed w/ bus, dest)" pass $confined_args
+checktestfg "compare_logs $unconfined_log eq $confined_log"
+
+message_gendbusprofile "dbus send bus=session path=/org/freedesktop/DBus peer=(name=org.freedesktop.DBus),"
+runchecktest "message (send allowed w/ bus, dest, path)" pass $confined_args
+checktestfg "compare_logs $unconfined_log eq $confined_log"
+
+message_gendbusprofile "dbus send bus=session path=/org/freedesktop/DBus interface=org.freedesktop.DBus peer=(name=org.freedesktop.DBus),"
+runtestfg "message (send allowed w/ bus, dest, path, interface)" pass $confined_args
+checktestfg "compare_logs $unconfined_log eq $confined_log"
+
+message_gendbusprofile "dbus send bus=session path=/org/freedesktop/DBus interface=org.freedesktop.DBus member={Hello,ListNames} peer=(name=org.freedesktop.DBus),"
+runtestfg "message (send allowed w/ bus, dest, path, interface, method)" pass $confined_args
+checktestfg "compare_logs $unconfined_log eq $confined_log"
+
+# Make sure send is denied when confined with appropriate permissions along
+# with incorrect conditionals
+
+message_gendbusprofile "dbus send bus=system,"
+runtestfg "message (send allowed w/ wrong bus)" fail $confined_args
+checktestfg "compare_logs $unconfined_log ne $confined_log"
+
+message_gendbusprofile "dbus send bus=session peer=(name=com.freedesktop.DBus),"
+runtestfg "message (send allowed w/ wrong dest)" fail $confined_args
+checktestfg "compare_logs $unconfined_log ne $confined_log"
+
+message_gendbusprofile "dbus send bus=session path=/bad/freedesktop/DBus peer=(name=bad.freedesktop.DBus),"
+runtestfg "message (send allowed w/ wrong path)" fail $confined_args
+checktestfg "compare_logs $unconfined_log ne $confined_log"
+
+message_gendbusprofile "dbus send bus=session path=/org/freedesktop/DBus interface=bad.freedesktop.DBus peer=(name=bad.freedesktop.DBus),"
+runtestfg "message (send allowed w/ wrong interface)" fail $confined_args
+checktestfg "compare_logs $unconfined_log ne $confined_log"
+
+message_gendbusprofile "dbus send bus=session path=/org/freedesktop/DBus interface=com.freedesktop.DBus member=Hello peer=(name=bad.freedesktop.DBus),"
+runtestfg "message (send allowed w/ wrong method)" fail $confined_args
+checktestfg "compare_logs $unconfined_log ne $confined_log"
diff --git a/tests/regression/apparmor/dbus_service.c b/tests/regression/apparmor/dbus_service.c
new file mode 100644
index 0000000..b4c52b1
--- /dev/null
+++ b/tests/regression/apparmor/dbus_service.c
@@ -0,0 +1,313 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus_service.c Utility program to send messages from the command line
+ *
+ * Copyright (C) 2003 Philip Blundell <philb at gnu.org>
+ * Copyright (C) 2013 Canonical, Ltd.
+ *
+ * Originally dbus-send.c from the dbus package. It has been heavily modified
+ * to work within the regression test framework.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "dbus_common.h"
+
+static int terminate = 0;
+DBusConnection *connection = NULL;
+DBusError error;
+DBusBusType type = DBUS_BUS_SESSION;
+const char *name = NULL;
+const char *path = NULL;
+const char *interface = NULL;
+const char *member = NULL;
+const char *address = NULL;
+int session_or_system = FALSE;
+int log_fd = -1;
+int lock_fd = 0;
+
+static void usage(void)
+{
+ fprintf(stderr,
+ "Usage: dbus_service [ADDRESS] --name=<NAME> <path> <interface>\n\n"
+ " ADDRESS\t\t--system, --session (default), or --address=ADDR\n"
+ " NAME\t\tthe well-known name to bind to\n"
+ " path\t\tpath to object (such as /org/freedesktop/DBus)\n"
+ " interface\t\tinterface to use (such as org.freedesktop.DBus)\n\n"
+ " The method <interface>.Method replies with an empty method_reply message.\n"
+ " The signal <interface>.Signal is accepted by the service.\n");
+}
+
+/**
+ * Returns -1 upon error, 0 when there are no more messages
+ */
+static int handle_messages(void)
+{
+ DBusMessage *message;
+
+ if (!dbus_connection_read_write(connection, 250)) {
+ fprintf(stderr, "FAIL: Connecion is closed\n");
+ return -1;
+ }
+
+ for (;;) {
+ message = dbus_connection_pop_message(connection);
+ if (message == NULL)
+ return 0;
+
+ log_message(log_fd, "received ", message);
+
+ if (dbus_message_is_signal(message, interface, "Signal")) {
+ dbus_message_unref(message);
+ continue;
+ } else
+ if (dbus_message_is_method_call
+ (message, interface, "Method")) {
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(message);
+ dbus_message_unref(message);
+
+ log_message(log_fd, "sent ", reply);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+ continue;
+ } else if (dbus_message_get_type(message) ==
+ DBUS_MESSAGE_TYPE_METHOD_CALL) {
+ DBusMessage *reply;
+
+ reply =
+ dbus_message_new_error(message,
+ DBUS_ERROR_UNKNOWN_METHOD,
+ NULL);
+ dbus_message_unref(message);
+
+ log_message(log_fd, "sent ", reply);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+ continue;
+ } else {
+ dbus_message_unref(message);
+ continue;
+ }
+ }
+
+ return 0;
+}
+
+void sigterm_handler(int signum)
+{
+ terminate = 1;
+}
+
+static int setup_signal_handling(void)
+{
+ struct sigaction sa;
+ int rc;
+
+ sa.sa_handler = sigterm_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ rc = sigaction(SIGTERM, &sa, NULL);
+ if (rc < 0) {
+ fprintf(stderr, "FAIL: Could not set up signal handling\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int unlock_fd(void)
+{
+ int rc;
+
+ if (lock_fd < 0)
+ return 0;
+
+ rc = flock(lock_fd, LOCK_UN);
+ if (rc < 0)
+ fprintf(stderr, "FAIL: Failed to unlock lock file: %m\n");
+
+ return rc;
+}
+
+static int do_service(void)
+{
+ int rc;
+
+ rc = dbus_bus_request_name(connection, name,
+ DBUS_NAME_FLAG_REPLACE_EXISTING, &error);
+ if (dbus_error_is_set(&error)) {
+ fprintf(stderr, "FAIL: %s: %s\n", error.name, error.message);
+ dbus_error_free(&error);
+ }
+ if (rc != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ return 1;
+ }
+
+ if (unlock_fd())
+ return 1;
+
+ rc = 0;
+ while (!terminate && !rc)
+ rc = handle_messages();
+
+ /* If we've received SIGTERM, try one last time to drain the incoming queue */
+ if (terminate && !rc)
+ rc = handle_messages();
+
+ if (rc < 0)
+ return 1;
+
+ rc = dbus_bus_release_name(connection, name, &error);
+ if (dbus_error_is_set(&error)) {
+ fprintf(stderr, "FAIL: %s: %s\n", error.name, error.message);
+ dbus_error_free(&error);
+ }
+ if (rc != DBUS_RELEASE_NAME_REPLY_RELEASED) {
+ return 1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int i, rc;
+
+ if (argc < 3) {
+ usage();
+ rc = 1;
+ goto out;
+ }
+
+ rc = setup_signal_handling();
+ if (rc != 0) {
+ fprintf(stderr, "FAIL: Couldn't set up signal handler\n");
+ rc = 1;
+ goto out;
+ }
+
+ for (i = 1; i < argc && interface == NULL; i++) {
+ char *arg = argv[i];
+
+ if (strcmp(arg, "--system") == 0) {
+ type = DBUS_BUS_SYSTEM;
+ session_or_system = TRUE;
+ } else if (strcmp(arg, "--session") == 0) {
+ type = DBUS_BUS_SESSION;
+ session_or_system = TRUE;
+ } else if (strstr(arg, "--address") == arg) {
+ address = strchr(arg, '=');
+
+ if (address == NULL) {
+ fprintf(stderr,
+ "FAIL: \"--address=\" requires an ADDRESS\n");
+ usage();
+ rc = 1;
+ goto out;
+ } else {
+ address = address + 1;
+ }
+ } else if (strstr(arg, "--name=") == arg)
+ name = strchr(arg, '=') + 1;
+ else if (strstr(arg, "--log=") == arg) {
+ char *path = strchr(arg, '=') + 1;
+
+ log_fd = open(path, O_CREAT | O_TRUNC | O_WRONLY,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
+ S_IROTH | S_IWOTH);
+ if (log_fd < 0) {
+ fprintf(stderr,
+ "FAIL: Couldn't open log file \"%s\"\n",
+ path);
+ exit(1);
+ }
+ } else if (strstr(arg, "--lock-fd=") == arg) {
+ char *fd = strchr(arg, '=') + 1;
+
+ lock_fd = atoi(fd);
+ } else if (!strcmp(arg, "--help")) {
+ usage();
+ rc = 0;
+ goto out;
+ } else if (arg[0] == '-') {
+ usage();
+ rc = 1;
+ goto out;
+ } else if (path == NULL)
+ path = arg;
+ else /* interface == NULL guaranteed by the 'while' loop */
+ interface = arg;
+ }
+
+ if (name == NULL || path == NULL || interface == NULL || i < argc) {
+ usage();
+ rc = 1;
+ goto out;
+ }
+
+ if (session_or_system && (address != NULL)) {
+ fprintf(stderr,
+ "FAIL: \"--address\" may not be used with \"--system\" or \"--session\"\n");
+ usage();
+ rc = 1;
+ goto out;
+ }
+
+ dbus_error_init(&error);
+
+ if (address != NULL)
+ connection = dbus_connection_open(address, &error);
+ else
+ connection = dbus_bus_get(type, &error);
+
+ if (connection == NULL) {
+ fprintf(stderr,
+ "FAIL: Failed to open connection to \"%s\" message bus: %s\n",
+ address ? address :
+ ((type == DBUS_BUS_SYSTEM) ? "system" : "session"),
+ error.message);
+ dbus_error_free(&error);
+ rc = 1;
+ goto out;
+ } else if (address != NULL)
+ dbus_bus_register(connection, &error);
+
+ rc = do_service();
+
+out:
+ if (connection)
+ dbus_connection_unref(connection);
+
+ unlock_fd();
+
+ if (rc == 0)
+ printf("PASS\n");
+
+ exit(rc);
+}
diff --git a/tests/regression/apparmor/dbus_service.sh b/tests/regression/apparmor/dbus_service.sh
new file mode 100755
index 0000000..8a44a2c
--- /dev/null
+++ b/tests/regression/apparmor/dbus_service.sh
@@ -0,0 +1,138 @@
+#! /bin/bash
+# Copyright (C) 2013 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, version 2 of the
+# License.
+
+#=NAME dbus_service
+#=DESCRIPTION
+# This test verifies that dbus services are restricted for confined processes.
+#=END
+
+pwd=`dirname $0`
+pwd=`cd $pwd ; /bin/pwd`
+
+bin=$pwd
+
+. $bin/prologue.inc
+required_features dbus
+. $bin/dbus.inc
+
+service="--$bus --name=$dest $path $iface"
+unconfined_log="${tmpdir}/unconfined.log"
+confined_log="${tmpdir}/confined.log"
+
+service_runtestbg()
+{
+ local lock=${tmpdir}/lock
+ local lockfd=-1
+ local args=$service
+
+ if [ $# -gt 2 ]
+ then
+ args="--log=$3 $args"
+ fi
+
+ exec {lockfd}>$lock
+ flock -n $lockfd
+ args="--lock-fd=$lockfd $args"
+
+ runtestbg "$1" "$2" $args
+
+ exec {lockfd}>&-
+ flock -w 30 $lock true
+ rm $lock
+}
+
+service_checktestbg()
+{
+ kill -SIGTERM $_pid 2>/dev/null
+ checktestbg "$@"
+}
+
+service_runchecktest()
+{
+ service_runtestbg "$@"
+ service_checktestbg
+}
+
+service_gendbusprofile()
+{
+ gendbusprofile "$unconfined_log w,
+ $@"
+}
+
+start_bus
+
+# Make sure we can bind a bus name and receive a message unconfined
+
+settest dbus_service
+
+service_runtestbg "service (unconfined)" pass $confined_log
+sendmethod
+sendsignal
+service_checktestbg
+
+# Make sure we get denials when confined but not allowed
+
+genprofile
+service_runchecktest "service (confined w/o dbus perms)" fail
+
+service_gendbusprofile "dbus send,"
+service_runchecktest "service (send allowed)" fail
+
+service_gendbusprofile "dbus receive,"
+service_runchecktest "service (receive allowed)" fail
+
+service_gendbusprofile "dbus bind,"
+service_runchecktest "service (bind allowed)" fail
+
+# Make sure we're okay when confined with appropriate permissions
+
+service_gendbusprofile "dbus,"
+service_runtestbg "service (dbus allowed)" pass $unconfined_log
+sendmethod
+sendsignal
+service_checktestbg "compare_logs $unconfined_log eq $confined_log"
+
+service_gendbusprofile "dbus (send, receive, bind),"
+service_runtestbg "service (send receive bind allowed)" pass $unconfined_log
+sendmethod
+sendsignal
+service_checktestbg "compare_logs $unconfined_log eq $confined_log"
+
+service_gendbusprofile "dbus (send receive bind) bus=session,"
+service_runtestbg "service (send receive bind w/ bus)" pass $unconfined_log
+sendmethod
+sendsignal
+service_checktestbg "compare_logs $unconfined_log eq $confined_log"
+
+service_gendbusprofile "dbus bind bus=session name=$dest, \
+ dbus receive bus=session, \
+ dbus send bus=session peer=(name=org.freedesktop.DBus),"
+service_runtestbg "service (receive bind w/ bus, dest)" pass $unconfined_log
+sendmethod
+sendsignal
+service_checktestbg "compare_logs $unconfined_log eq $confined_log"
+
+service_gendbusprofile "dbus bind bus=session name=$dest, \
+ dbus receive bus=session, \
+ dbus send bus=session peer=(name=org.freedesktop.DBus),"
+service_runtestbg "service (receive bind w/ bus, dest)" pass $unconfined_log
+sendmethod
+sendsignal
+service_checktestbg "compare_logs $unconfined_log eq $confined_log"
+
+# Make sure we're denied when confined without appropriate conditionals
+
+service_gendbusprofile "dbus bind bus=system name=$dest, \
+ dbus receive bus=system, \
+ dbus send bus=session peer=(name=org.freedesktop.DBus),"
+service_runchecktest "service (receive bind w/ wrong bus)" fail
+
+service_gendbusprofile "dbus bind bus=session name=${dest}.BAD, \
+ dbus receive bus=session, \
+ dbus send bus=session peer=(name=org.freedesktop.DBus),"
+service_runchecktest "service (receive bind w/ wrong dest)" fail
--
1.8.3.2
More information about the AppArmor
mailing list