[apparmor] [PATCH 2/2] tests: Add regression tests for dbus

Seth Arnold seth.arnold at canonical.com
Fri Aug 9 19:56:32 UTC 2013


On Thu, Aug 01, 2013 at 02:01:39AM -0700, Tyler Hicks wrote:
> 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.

Very few comments inline.. I very heavily skimmed the borrowed source
under the assumption that if it worked well enough for the original
authors and worked well enough for the tests to pass, your changes won't
be so substantial. (And the change I did spot looked fine. Very nearly
seamless. :)

Thanks

> 
> Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
> ---
>  tests/regression/apparmor/Makefile        |  15 +-
>  tests/regression/apparmor/dbus.conf       |  27 +++
>  tests/regression/apparmor/dbus.inc        |  96 ++++++++
>  tests/regression/apparmor/dbus_common.c   | 267 ++++++++++++++++++++++
>  tests/regression/apparmor/dbus_common.h   |  28 +++
>  tests/regression/apparmor/dbus_message.c  | 364 ++++++++++++++++++++++++++++++
>  tests/regression/apparmor/dbus_message.sh | 125 ++++++++++
>  tests/regression/apparmor/dbus_service.c  | 316 ++++++++++++++++++++++++++
>  tests/regression/apparmor/dbus_service.sh | 136 +++++++++++
>  9 files changed, 1373 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 2021f51..0a05655 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 \
> @@ -118,6 +120,8 @@ TESTS=access \
>        chdir \
>        clone \
>        coredump \
> +      dbus_message \
> +      dbus_service \
>        deleted \
>        environ \
>        exec \
> @@ -161,6 +165,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 \
> @@ -200,6 +213,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..96b88fb
> --- /dev/null
> +++ b/tests/regression/apparmor/dbus.conf
> @@ -0,0 +1,27 @@
> +<!-- 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>
> +
> +  <!-- 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..ecf9488
> --- /dev/null
> +++ b/tests/regression/apparmor/dbus.inc
> @@ -0,0 +1,96 @@
> +# 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\n"
> +	fi
> +
> +	bus_addr=$(echo $out | cut -d\  -f 1)
> +	bus_pid=$(echo $out | cut -d\  -f 2)
> +	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 \"$1\""
> +    fi
> +  else
> +    d="--name=$3"
> +  fi

The fatalerror should probably be using $2, right?

> +  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..2bdefd0
> --- /dev/null
> +++ b/tests/regression/apparmor/dbus_common.c
> @@ -0,0 +1,267 @@
> +/* 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..b5730a0
> --- /dev/null
> +++ b/tests/regression/apparmor/dbus_common.h
> @@ -0,0 +1,28 @@
> +/* 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..6e53a4f
> --- /dev/null
> +++ b/tests/regression/apparmor/dbus_message.c
> @@ -0,0 +1,364 @@
> +/* -*- 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..3199fe9
> --- /dev/null
> +++ b/tests/regression/apparmor/dbus_message.sh
> @@ -0,0 +1,125 @@
> +#! /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
> +. $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..0b7ebee
> --- /dev/null
> +++ b/tests/regression/apparmor/dbus_service.c
> @@ -0,0 +1,316 @@
> +/* -*- 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;
> +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 (int ecode)
> +{
> +  char *prefix = ecode ? "FAIL: " : "";
> +
> +  fprintf (stderr, "%6sUsage: 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",
> +           prefix);
> +  exit (ecode);
> +}
> +
> +/**
> + * Returns -1 upon error, 0 when there are no more messages, 1 when the program
> + * should exit
> + */
> +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;
> +}
> +
> +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 (lock_fd >= 0)
> +    {
> +      rc = flock (lock_fd, LOCK_UN);
> +      if (rc < 0)
> +        {
> +          fprintf (stderr, "FAIL: Failed to unlock lock file: %m\n");
> +          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)
> +    exit (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 (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, "--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 (0);
> +      else if (arg[0] == '-')
> +	usage (1);
> +      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 (1);
> +
> +  if (session_or_system &&
> +      (address != NULL))
> +    {
> +      fprintf (stderr, "FAIL: \"--address\" may not be used with \"--system\" or \"--session\"\n");
> +      usage (1);
> +    }
> +
> +  rc = setup_signal_handling ();
> +  if (rc != 0)
> +    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_service ();
> +
> +  dbus_connection_unref (connection);
> +
> +  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..5026141
> --- /dev/null
> +++ b/tests/regression/apparmor/dbus_service.sh
> @@ -0,0 +1,136 @@
> +#! /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
> +. $bin/dbus.inc
> +
> +service="--$bus --name=$dest $path $iface"
> +unconfined_log="${tmpdir}/unconfined.log"
> +confined_log="${tmpdir}/confined.log"
> +
> +service_runchecktest()
> +{
> +	runchecktest "$1" "$2" $service
> +}
> +
> +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
> +	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),"
> +runchecktest "service (receive bind w/ wrong bus)" fail $service
> +
> +service_gendbusprofile "dbus bind bus=session name=${dest}.BAD, \
> +		dbus receive bus=session, \
> +		dbus send bus=session peer=(name=org.freedesktop.DBus),"
> +runchecktest "service (receive bind w/ wrong dest)" fail $service
> -- 

Is there a missing service_checktestbg for these last few?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20130809/a4c1a58b/attachment-0001.pgp>


More information about the AppArmor mailing list