4
#include <sys/apparmor.h>
6
#define OPT_EXPECT "--expect="
7
#define OPT_EXPECT_LEN strlen(OPT_EXPECT)
9
#define OPT_LABEL "--label="
10
#define OPT_LABEL_LEN strlen(OPT_LABEL)
12
#define OPT_TYPE_DBUS "--dbus="
13
#define OPT_TYPE_DBUS_LEN strlen(OPT_TYPE_DBUS)
15
static char *progname = NULL;
19
fprintf(stderr, "Usage: %s --expect=EXPECTED --label=LABEL --CLASS=PERMS QUERY...\n\n",
21
fprintf(stderr, " EXPECTED\tA comma separated list of allow, audit, and/or anything.\n");
22
fprintf(stderr, "\t\t\"anything\" is a special keyword that matches any condition\n");
23
fprintf(stderr, "\t\tand cannot be used with other keywords. Additionally,\n");
24
fprintf(stderr, "\t\tEXPECTED can be empty to indicate neither, allow or audit,\n");
25
fprintf(stderr, "\t\tin the results.\n");
26
fprintf(stderr, " LABEL\t\tThe AppArmor label to use in the query\n");
27
fprintf(stderr, " CLASS\t\tThe rule class and may consist of:\n");
28
fprintf(stderr, "\t\t dbus\n");
29
fprintf(stderr, " PERMS\t\tA comma separated list of permissions. Possibilities\n");
30
fprintf(stderr, "\t\tfor the supported rule classes are:\n");
31
fprintf(stderr, "\t\t dbus: send,receive,bind\n");
32
fprintf(stderr, "\t\tAdditionaly, PERMS can be empty to indicate an empty mask\n");
36
static int parse_expected(int *should_allow, int *should_audit, char *expected)
40
*should_allow = *should_audit = 0;
42
expect = strtok(expected, ",");
44
if (!strcmp(expect, "allow")) {
46
} else if (!strcmp(expect, "audit")) {
48
} else if (!strcmp(expect, "anything")) {
49
*should_allow = *should_audit = -1;
51
fprintf(stderr, "FAIL: unknown expect: %s\n", expect);
55
expect = strtok(NULL, ",");
61
static int parse_dbus_perms(uint32_t *mask, char *perms)
67
perm = strtok(perms, ",");
69
if (!strcmp(perm, "send"))
70
*mask |= AA_DBUS_SEND;
71
else if (!strcmp(perm, "receive"))
72
*mask |= AA_DBUS_RECEIVE;
73
else if (!strcmp(perm, "bind"))
74
*mask |= AA_DBUS_BIND;
76
fprintf(stderr, "FAIL: unknown perm: %s\n", perm);
80
perm = strtok(NULL, ",");
86
static ssize_t build_query(char **qstr, const char *label, int class,
87
int argc, char **argv)
89
int size, label_size, i;
92
label_size = strlen(label);
93
size = label_size + 1;
94
for (i = 0; i < argc; i++) {
96
size += strlen(argv[i]);
99
buffer = malloc(size + argc + 1 + AA_QUERY_CMD_LABEL_SIZE);
103
to = buffer + AA_QUERY_CMD_LABEL_SIZE;
109
for (i = 0; i < argc; to++, i++) {
114
to = stpcpy(to, arg);
118
/* don't include trailing \0 in size */
119
return size + argc + AA_QUERY_CMD_LABEL_SIZE;
122
int main(int argc, char **argv)
124
char *label, *class_str, *query;
125
int class, should_allow, allowed, should_audit, audited, rc;
134
if (!strncmp(argv[1], OPT_EXPECT, OPT_EXPECT_LEN)) {
135
rc = parse_expected(&should_allow, &should_audit,
136
argv[1] + OPT_EXPECT_LEN);
141
if (!strncmp(argv[2], OPT_LABEL, OPT_LABEL_LEN))
142
label = argv[2] + OPT_LABEL_LEN;
147
if (!strncmp(class_str, OPT_TYPE_DBUS, OPT_TYPE_DBUS_LEN)) {
148
class = AA_CLASS_DBUS;
149
rc = parse_dbus_perms(&mask, class_str + OPT_TYPE_DBUS_LEN);
153
fprintf(stderr, "FAIL: unknown rule class: %s\n", class_str);
157
query_len = build_query(&query, label, class, argc - 4, argv + 4);
159
fprintf(stderr, "FAIL: failed to allocate memory for query string\n");
163
rc = aa_query_label(mask, query, query_len, &allowed, &audited);
166
fprintf(stderr, "FAIL: failed to perform query: %m\n");
170
if ((should_allow == -1 && should_audit == -1) ||
171
(allowed == should_allow && audited == should_audit)) {
174
fprintf(stderr, "FAIL: the access should %sbe allowed and should %sbe audited\n",
175
allowed ? "" : "not ", audited ? "" : "not ");