~ubuntu-branches/ubuntu/saucy/apparmor/saucy

« back to all changes in this revision

Viewing changes to tests/regression/apparmor/dbus_common.c

  • Committer: Package Import Robot
  • Author(s): Tyler Hicks, Tyler Hicks, Jamie Strandboge
  • Date: 2013-08-26 15:32:12 UTC
  • mfrom: (49.1.6 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130826153212-5oehf9eda64lkpze
Tags: 2.8.0-0ubuntu25
[ Tyler Hicks ]
* Add support for mediation of D-Bus messages and services. AppArmor D-Bus
  rules are described in the apparmor.d(5) man page. dbus-daemon will use
  libapparmor to perform queries against the AppArmor policies to determine
  if a connection should be able to send messages to another connection, if
  a connection should be able to receive messages from another connection,
  and if a connection should be able to bind to a well-known name.
  - 0042-Fix-mount-rule-preprocessor-output.patch,
    0043-libapparmor-Safeguard-aa_getpeercon-buffer-reallocat.patch,
    0044-libapparmor-fix-return-value-of-aa_getpeercon_raw.patch,
    0045-libapparmor-Move-mode-parsing-into-separate-function.patch,
    0046-libapparmor-Parse-mode-from-confinement-string-in-ge.patch,
    0047-libapparmor-Make-aa_getpeercon_raw-similar-to-aa_get.patch,
    0048-libapparmor-Update-aa_getcon-man-page-to-reflect-get.patch:
    Backport parser and libapparmor pre-requisites for D-Bus mediation
  - 0049-parser-Update-man-page-for-DBus-rules.patch: Update apparmor.d man
    page
  - 0050-parser-Add-support-for-DBus-rules.patch,
    0051-parser-Regression-tests-for-DBus-rules.patch,
    0052-parser-Binary-profile-equality-tests-for-DBus-rules.patch: Add
    apparmor_parser support for D-Bus mediation rules
  - 0053-libapparmor-Export-a-label-based-query-interface.patch,
    debian/libapparmor1.symbols: Provide the libapparmor interface necessary
    for trusted helpers to make security decisions based upon AppArmor
    policy
  - 0054-libaalogparse-Parse-dbus-daemon-audit-messages.patch,
    0055-libaalogparse-Regression-tests-for-dbus-daemon-audit.patch: Allow
    applications to parse denials, generated by dbus-daemon, using
    libaalogparse and add a set of regression tests
  - 0056-tests-Add-an-optional-final-check-to-checktestfg.patch,
    0057-tests-Add-required-features-check.patch,
    0058-tests-Add-regression-tests-for-dbus.patch: Add regression tests
    which start their own dbus-daemon, load profiles containing D-Bus rules,
    and confine simple D-Bus service and client applications
  - 0059-dbus-rules-for-dbus-abstractions.patch: Add bus-specific, but
    otherwise permissive, D-Bus rules to the dbus and dbus-session
    abstractions. Confined applications that use D-Bus should already be
    including these abstractions in their profiles so this should be a
    seamless transition for those profiles.
* 0060-utils-make_clean_fixup.patch: Clean up the Python cache in the
  AppArmor tests directory
* 0061-profiles-dnsmasq-needs-dbus-abstraction.patch: Dnsmasq uses the
  system D-Bus when it is started with --enable-dbus, so its AppArmor
  profile needs to include the system bus abstraction
* 0062-fix-clone-test-on-arm.patch: Fix compiler error when building
  regression tests on ARM
* 0063-utils-ignore-unsupported-rules.patch: Utilities that use the
  Immunix::AppArmor perl module, such as aa-logprof and aa-genprof, error
  out when they encounter rules unsupported by the perl module. This patch
  ignores unsupported rules.

[ Jamie Strandboge ]
* debian/control: don't have easyprof Depends on apparmor-easyprof-ubuntu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* dbus_common.c
 
2
 *
 
3
 * Copyright (C) 2003 Philip Blundell <philb@gnu.org>
 
4
 * Copyright (C) 2013 Canonical, Ltd.
 
5
 *
 
6
 * Originally dbus-send.c from the dbus package. It has been heavily modified
 
7
 * to work within the regression test framework.
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License as published by
 
11
 * the Free Software Foundation; either version 2 of the License, or
 
12
 * (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
22
 *
 
23
 */
 
24
 
 
25
#define _GNU_SOURCE
 
26
#include <stdio.h>
 
27
#include <stdlib.h>
 
28
#include <string.h>
 
29
#include <unistd.h>
 
30
 
 
31
#include "dbus_common.h"
 
32
 
 
33
const char *type_to_name(int message_type)
 
34
{
 
35
        switch (message_type) {
 
36
        case DBUS_MESSAGE_TYPE_SIGNAL:
 
37
                return "signal";
 
38
        case DBUS_MESSAGE_TYPE_METHOD_CALL:
 
39
                return "method call";
 
40
        case DBUS_MESSAGE_TYPE_METHOD_RETURN:
 
41
                return "method return";
 
42
        case DBUS_MESSAGE_TYPE_ERROR:
 
43
                return "error";
 
44
        default:
 
45
                return "(unknown message type)";
 
46
        }
 
47
}
 
48
 
 
49
void log_message(int log_fd, const char *prefix, DBusMessage * message)
 
50
{
 
51
        const char *sender = NULL;
 
52
        const char *destination = NULL;
 
53
        const char *unique = "(UNIQUE)";
 
54
        int message_type;
 
55
 
 
56
        if (log_fd < 0)
 
57
                return;
 
58
 
 
59
        message_type = dbus_message_get_type(message);
 
60
        sender = dbus_message_get_sender(message);
 
61
        destination = dbus_message_get_destination(message);
 
62
 
 
63
        /* Remove unique (random) names from the logs since they make it
 
64
         * impossible to do simple log comparisons between two different test
 
65
         * runs.
 
66
         */
 
67
        if (sender && sender[0] == ':')
 
68
                sender = unique;
 
69
        if (destination && destination[0] == ':')
 
70
                destination = unique;
 
71
 
 
72
        dprintf(log_fd, "%s%s sender=%s -> dest=%s",
 
73
                prefix, type_to_name(message_type),
 
74
                sender ? sender : "(null)",
 
75
                destination ? destination : "(null)");
 
76
 
 
77
        switch (message_type) {
 
78
        case DBUS_MESSAGE_TYPE_METHOD_CALL:
 
79
        case DBUS_MESSAGE_TYPE_SIGNAL:
 
80
                dprintf(log_fd, " path=%s; interface=%s; member=%s\n",
 
81
                        dbus_message_get_path(message),
 
82
                        dbus_message_get_interface(message),
 
83
                        dbus_message_get_member(message));
 
84
                break;
 
85
 
 
86
        case DBUS_MESSAGE_TYPE_ERROR:
 
87
                dprintf(log_fd, " error_name=%s\n",
 
88
                        dbus_message_get_error_name(message));
 
89
                break;
 
90
 
 
91
        default:
 
92
                dprintf(log_fd, "\n");
 
93
                break;
 
94
        }
 
95
}
 
96
 
 
97
void append_arg(DBusMessageIter * iter, int type, const char *value)
 
98
{
 
99
        dbus_uint16_t uint16;
 
100
        dbus_int16_t int16;
 
101
        dbus_uint32_t uint32;
 
102
        dbus_int32_t int32;
 
103
        dbus_uint64_t uint64;
 
104
        dbus_int64_t int64;
 
105
        double d;
 
106
        unsigned char byte;
 
107
        dbus_bool_t v_BOOLEAN;
 
108
 
 
109
        /* FIXME - we are ignoring OOM returns on all these functions */
 
110
        switch (type) {
 
111
        case DBUS_TYPE_BYTE:
 
112
                byte = strtoul(value, NULL, 0);
 
113
                dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &byte);
 
114
                break;
 
115
 
 
116
        case DBUS_TYPE_DOUBLE:
 
117
                d = strtod(value, NULL);
 
118
                dbus_message_iter_append_basic(iter, DBUS_TYPE_DOUBLE, &d);
 
119
                break;
 
120
 
 
121
        case DBUS_TYPE_INT16:
 
122
                int16 = strtol(value, NULL, 0);
 
123
                dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &int16);
 
124
                break;
 
125
 
 
126
        case DBUS_TYPE_UINT16:
 
127
                uint16 = strtoul(value, NULL, 0);
 
128
                dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &uint16);
 
129
                break;
 
130
 
 
131
        case DBUS_TYPE_INT32:
 
132
                int32 = strtol(value, NULL, 0);
 
133
                dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int32);
 
134
                break;
 
135
 
 
136
        case DBUS_TYPE_UINT32:
 
137
                uint32 = strtoul(value, NULL, 0);
 
138
                dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &uint32);
 
139
                break;
 
140
 
 
141
        case DBUS_TYPE_INT64:
 
142
                int64 = strtoll(value, NULL, 0);
 
143
                dbus_message_iter_append_basic(iter, DBUS_TYPE_INT64, &int64);
 
144
                break;
 
145
 
 
146
        case DBUS_TYPE_UINT64:
 
147
                uint64 = strtoull(value, NULL, 0);
 
148
                dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &uint64);
 
149
                break;
 
150
 
 
151
        case DBUS_TYPE_STRING:
 
152
                dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &value);
 
153
                break;
 
154
 
 
155
        case DBUS_TYPE_OBJECT_PATH:
 
156
                dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
 
157
                                               &value);
 
158
                break;
 
159
 
 
160
        case DBUS_TYPE_BOOLEAN:
 
161
                if (strcmp(value, "true") == 0) {
 
162
                        v_BOOLEAN = TRUE;
 
163
                        dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
 
164
                                                       &v_BOOLEAN);
 
165
                } else if (strcmp(value, "false") == 0) {
 
166
                        v_BOOLEAN = FALSE;
 
167
                        dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
 
168
                                                       &v_BOOLEAN);
 
169
                } else {
 
170
                        fprintf(stderr,
 
171
                                "FAIL: Expected \"true\" or \"false\" instead of \"%s\"\n",
 
172
                                value);
 
173
                        exit(1);
 
174
                }
 
175
                break;
 
176
 
 
177
        default:
 
178
                fprintf(stderr, "FAIL: Unsupported data type %c\n", (char)type);
 
179
                exit(1);
 
180
        }
 
181
}
 
182
 
 
183
void append_array(DBusMessageIter * iter, int type, const char *value)
 
184
{
 
185
        const char *val;
 
186
        char *dupval = strdup(value);
 
187
 
 
188
        val = strtok(dupval, ",");
 
189
        while (val != NULL) {
 
190
                append_arg(iter, type, val);
 
191
                val = strtok(NULL, ",");
 
192
        }
 
193
        free(dupval);
 
194
}
 
195
 
 
196
void
 
197
append_dict(DBusMessageIter * iter, int keytype, int valtype, const char *value)
 
198
{
 
199
        const char *val;
 
200
        char *dupval = strdup(value);
 
201
 
 
202
        val = strtok(dupval, ",");
 
203
        while (val != NULL) {
 
204
                DBusMessageIter subiter;
 
205
 
 
206
                dbus_message_iter_open_container(iter,
 
207
                                                 DBUS_TYPE_DICT_ENTRY,
 
208
                                                 NULL, &subiter);
 
209
 
 
210
                append_arg(&subiter, keytype, val);
 
211
                val = strtok(NULL, ",");
 
212
                if (val == NULL) {
 
213
                        fprintf(stderr, "FAIL: Malformed dictionary\n");
 
214
                        exit(1);
 
215
                }
 
216
                append_arg(&subiter, valtype, val);
 
217
 
 
218
                dbus_message_iter_close_container(iter, &subiter);
 
219
                val = strtok(NULL, ",");
 
220
        }
 
221
        free(dupval);
 
222
}
 
223
 
 
224
int type_from_name(const char *arg)
 
225
{
 
226
        int type;
 
227
        if (!strcmp(arg, "string"))
 
228
                type = DBUS_TYPE_STRING;
 
229
        else if (!strcmp(arg, "int16"))
 
230
                type = DBUS_TYPE_INT16;
 
231
        else if (!strcmp(arg, "uint16"))
 
232
                type = DBUS_TYPE_UINT16;
 
233
        else if (!strcmp(arg, "int32"))
 
234
                type = DBUS_TYPE_INT32;
 
235
        else if (!strcmp(arg, "uint32"))
 
236
                type = DBUS_TYPE_UINT32;
 
237
        else if (!strcmp(arg, "int64"))
 
238
                type = DBUS_TYPE_INT64;
 
239
        else if (!strcmp(arg, "uint64"))
 
240
                type = DBUS_TYPE_UINT64;
 
241
        else if (!strcmp(arg, "double"))
 
242
                type = DBUS_TYPE_DOUBLE;
 
243
        else if (!strcmp(arg, "byte"))
 
244
                type = DBUS_TYPE_BYTE;
 
245
        else if (!strcmp(arg, "boolean"))
 
246
                type = DBUS_TYPE_BOOLEAN;
 
247
        else if (!strcmp(arg, "objpath"))
 
248
                type = DBUS_TYPE_OBJECT_PATH;
 
249
        else {
 
250
                fprintf(stderr, "FAIL: Unknown type \"%s\"\n", arg);
 
251
                exit(1);
 
252
        }
 
253
        return type;
 
254
}