tizen 2.3 release
[external/buxton.git] / test / check_smack.c
1 /*
2  * This file is part of buxton.
3  *
4  * Copyright (C) 2013 Intel Corporation
5  *
6  * buxton is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1
9  * of the License, or (at your option) any later version.
10  */
11
12 #ifdef HAVE_CONFIG_H
13         #include "config.h"
14 #endif
15
16 #include <check.h>
17 #include <limits.h>
18 #include <signal.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <unistd.h>
24
25 #include "buxton.h"
26 #include "configurator.h"
27 #include "check_utils.h"
28 #include "daemon.h"
29 #include "log.h"
30 #include "smack.h"
31 #include "util.h"
32
33 #ifdef NDEBUG
34         #error "re-run configure with --enable-debug"
35 #endif
36
37 static pid_t daemon_pid;
38
39 static void exec_daemon(void)
40 {
41         char path[PATH_MAX];
42
43         //FIXME: path is wrong for makedistcheck
44         snprintf(path, PATH_MAX, "%s/check_buxtond", get_current_dir_name());
45
46         if (execl(path, "check_buxtond", (const char*)NULL) < 0) {
47                 fail("couldn't exec: %m");
48         }
49         fail("should never reach here");
50 }
51
52 static void setup(void)
53 {
54         daemon_pid = 0;
55         sigset_t sigset;
56         pid_t pid;
57
58         unlink(buxton_socket());
59
60         sigemptyset(&sigset);
61         sigaddset(&sigset, SIGCHLD);
62         sigprocmask(SIG_BLOCK, &sigset, NULL);
63
64         pid = fork();
65         fail_if(pid < 0, "couldn't fork");
66         if (pid) {
67                 /* parent*/
68                 daemon_pid = pid;
69                 usleep(128*1000);
70         } else {
71                 /* child */
72                 exec_daemon();
73         }
74 }
75
76 static void teardown(void)
77 {
78         if (daemon_pid) {
79                 int status;
80                 pid_t pid;
81
82                 pid = waitpid(daemon_pid, &status, WNOHANG);
83                 fail_if(pid == -1, "waitpid error");
84                 if (pid) {
85                         fail("daemon crashed!");
86                 } else {
87                         /* if the daemon is still running, kill it */
88                         kill(SIGTERM, daemon_pid);
89                         usleep(64*1000);
90                         kill(SIGKILL, daemon_pid);
91                 }
92         }
93 }
94
95 START_TEST(smack_access_check)
96 {
97         bool ret;
98         BuxtonString subject;
99         BuxtonString object;
100
101         ret = buxton_cache_smack_rules();
102         fail_if(!ret, "Failed to cache Smack rules");
103
104         subject = buxton_string_pack("system");
105         object = buxton_string_pack("base/sample/key");
106         ret = buxton_check_smack_access(&subject, &object, ACCESS_READ);
107         fail_if(!ret, "Read access was denied, but should have been granted");
108         ret = buxton_check_smack_access(&subject, &object, ACCESS_WRITE);
109         fail_if(ret, "Write access was granted, but should have been denied");
110
111         subject = buxton_string_pack("system");
112         object = buxton_string_pack("system/sample/key");
113         ret = buxton_check_smack_access(&subject, &object, ACCESS_READ);
114         fail_if(!ret, "Read access was denied");
115         ret = buxton_check_smack_access(&subject, &object, ACCESS_WRITE);
116         fail_if(!ret, "Write access was denied");
117
118         subject = buxton_string_pack("*");
119         object = buxton_string_pack("foo");
120         ret = buxton_check_smack_access(&subject, &object, ACCESS_READ);
121         fail_if(ret, "Read access granted for * subject");
122         ret = buxton_check_smack_access(&subject, &object, ACCESS_WRITE);
123         fail_if(ret, "Write access granted for * subject");
124
125         subject = buxton_string_pack("foo");
126         object = buxton_string_pack("@");
127         ret = buxton_check_smack_access(&subject, &object, ACCESS_READ);
128         fail_if(!ret, "Read access denied for @ object");
129         ret = buxton_check_smack_access(&subject, &object, ACCESS_WRITE);
130         fail_if(!ret, "Write access denied for @ object");
131
132         subject = buxton_string_pack("@");
133         object = buxton_string_pack("foo");
134         ret = buxton_check_smack_access(&subject, &object, ACCESS_READ);
135         fail_if(!ret, "Read access denied for @ subject");
136         ret = buxton_check_smack_access(&subject, &object, ACCESS_WRITE);
137         fail_if(!ret, "Write access denied for @ subject");
138
139         subject = buxton_string_pack("foo");
140         object = buxton_string_pack("*");
141         ret = buxton_check_smack_access(&subject, &object, ACCESS_READ);
142         fail_if(!ret, "Read access denied for * object");
143         ret = buxton_check_smack_access(&subject, &object, ACCESS_WRITE);
144         fail_if(!ret, "Write access denied for * object");
145
146         subject = buxton_string_pack("foo");
147         object = buxton_string_pack("foo");
148         ret = buxton_check_smack_access(&subject, &object, ACCESS_READ);
149         fail_if(!ret, "Read access denied for matching subject/object");
150         ret = buxton_check_smack_access(&subject, &object, ACCESS_WRITE);
151         fail_if(!ret, "Write access denied for matching subject/object");
152
153         subject = buxton_string_pack("foo");
154         object = buxton_string_pack("_");
155         ret = buxton_check_smack_access(&subject, &object, ACCESS_READ);
156         fail_if(!ret, "Read access denied for _ object");
157
158         subject = buxton_string_pack("^");
159         object = buxton_string_pack("foo");
160         ret = buxton_check_smack_access(&subject, &object, ACCESS_READ);
161         fail_if(!ret, "Read access denied for ^ subject");
162
163         subject = buxton_string_pack("subjecttest");
164         object = buxton_string_pack("objecttest");
165         ret = buxton_check_smack_access(&subject, &object, ACCESS_READ);
166         fail_if(ret, "Read access granted for unrecognized subject/object");
167
168         subject = buxton_string_pack("subjecttest");
169         object = buxton_string_pack("objecttest");
170         ret = buxton_check_smack_access(&subject, &object, ACCESS_WRITE);
171         fail_if(ret, "Write access granted for unrecognized subject/object");
172 }
173 END_TEST
174
175 static Suite *
176 daemon_suite(void)
177 {
178         Suite *s;
179         TCase *tc;
180         bool __attribute__((unused))dummy;
181
182         s = suite_create("smack");
183
184         dummy = buxton_cache_smack_rules();
185         if (buxton_smack_enabled()) {
186                 tc = tcase_create("smack access test functions");
187                 tcase_add_checked_fixture(tc, setup, teardown);
188                 /* TODO: add tests that use actual client Smack labels */
189                 suite_add_tcase(s, tc);
190
191                 tc = tcase_create("smack libsecurity functions");
192                 tcase_add_test(tc, smack_access_check);
193                 suite_add_tcase(s, tc);
194         } else {
195                 buxton_log("Smack support not detected; skipping this test suite\n");
196         }
197
198         return s;
199 }
200
201 int main(void)
202 {
203         int number_failed;
204         Suite *s;
205         SRunner *sr;
206
207         putenv("BUXTON_CONF_FILE=" ABS_TOP_BUILDDIR "/test/test.conf");
208         s = daemon_suite();
209         sr = srunner_create(s);
210         srunner_run_all(sr, CK_VERBOSE);
211         number_failed = srunner_ntests_failed(sr);
212         srunner_free(sr);
213
214         return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
215 }
216
217 /*
218  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
219  *
220  * Local variables:
221  * c-basic-offset: 8
222  * tab-width: 8
223  * indent-tabs-mode: t
224  * End:
225  *
226  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
227  * :indentSize=8:tabSize=8:noTabs=false:
228  */