Some tests that call smack_revoke_subject should run with smack
[platform/core/test/security-tests.git] / tests / security-server-tests / server.cpp
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  */
4 /*
5  * @file    security_server_tests_server.cpp
6  * @author  Bumjin Im (bj.im@samsung.com)
7  * @author  Mariusz Domanski (m.domanski@samsung.com)
8  * @version 1.0
9  * @brief   Test cases for security server
10  */
11
12 #include <stdio.h>
13 #include <errno.h>
14 #include <stdlib.h>
15 #include <sys/types.h>
16 #include <sys/param.h>
17 #include <fcntl.h>
18 #include <sys/un.h>
19 #include <unistd.h>
20 #include <poll.h>
21 #include <sys/socket.h>
22 #include <sys/stat.h>
23 #include <sys/smack.h>
24 #include <sys/wait.h>
25 #include "security-server.h"
26 #include "security_server_clean_env.h"
27 #include <dpl/test/test_runner.h>
28 #include <dpl/test/test_runner_child.h>
29 #include <dlog.h>
30 #include <privilege-control.h>
31 #include <ftw.h>
32 #include "security_server_tests_common.h"
33 #include "tests_common.h"
34 #include <smack_access.h>
35 #include <access_provider.h>
36 #include <summary_collector.h>
37
38 const char *TEST03_SUBJECT = "subject_0f09f7cc";
39 const char *TEST04_SUBJECT = "subject_57dfbfc5";
40 const char *TEST07_SUBJECT = "subject_cd738844";
41 const char *TEST08_SUBJECT = "subject_fd84ba7f";
42
43 const char *API_PASSWD_SET    = "security-server::api-password-set";
44 const char *API_PASSWD_CHECK  = "security-server::api-password-check";
45 const char *API_PASSWD_RESET  = "security-server::api-password-reset";
46 const char *API_RULE_REQUIRED = "w";
47
48 int clear_password(char ** /*error*/)
49 {
50     int ret = -1;
51     unsigned int attempt, max_attempt, expire_sec;
52     const char *subject_allow = "subject_allow";
53     struct smack_accesses *handle = NULL;
54
55     if (getuid() == 0) {
56         reset_security_server();
57
58         ret = smack_accesses_new(&handle);
59         RUNNER_ASSERT_MSG_BT(ret == 0, "ret: " << ret);
60
61         /* our subject 'subject_allow' has access to security-server::api-password-check */
62         ret = smack_accesses_add(handle, subject_allow, API_PASSWD_CHECK, API_RULE_REQUIRED);
63         RUNNER_ASSERT_MSG_BT(ret == 0, "ret: " << ret);
64
65         ret = smack_accesses_apply(handle);
66         RUNNER_ASSERT_MSG_BT(ret == 0, "ret: " << ret);
67
68         ret = smack_set_label_for_self(subject_allow);
69         RUNNER_ASSERT_MSG_BT(ret == 0, "ret: " << ret);
70
71         smack_accesses_free(handle);
72
73         attempt = max_attempt = expire_sec = UINT_MAX;
74         ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
75
76         RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, "ret: " << ret);
77         RUNNER_ASSERT_BT(expire_sec == 0);
78         RUNNER_ASSERT_BT(max_attempt == 0);
79         RUNNER_ASSERT_BT(attempt == 0);
80
81         /* we revoke all rules for subject 'subject_allow' */
82         ret = smack_revoke_subject(subject_allow);
83         RUNNER_ASSERT_MSG_BT(ret == 0, "Revoking subject didn't work.");
84
85         sleep(1);
86
87         return 0;
88     }
89     return -1;
90 }
91
92 void check_API_passwd(bool smack) {
93     int ret = -1;
94     int err, err_is_pwd_valid;
95     unsigned int attempt, max_attempt, expire_sec;
96
97     err = smack ? SECURITY_SERVER_API_ERROR_ACCESS_DENIED : SECURITY_SERVER_API_SUCCESS;
98     err_is_pwd_valid = smack ? SECURITY_SERVER_API_ERROR_ACCESS_DENIED : SECURITY_SERVER_API_ERROR_PASSWORD_EXIST;
99     attempt = max_attempt = expire_sec = 0;
100
101     if (smack) {
102         SecurityServer::AccessProvider privider(TEST04_SUBJECT);
103         privider.applyAndSwithToUser(APP_UID, APP_GID);
104     } else {
105         RUNNER_ASSERT_MSG_BT((ret = drop_root_privileges()) == 0,
106                 "Failed to drop root privileges. Result: " << ret << "uid = " << getuid());
107     }
108
109     ret = security_server_set_pwd_validity(APP_UID);
110     RUNNER_ASSERT_MSG_BT(ret == err,
111             "security_server_set_pwd_validity has failed,"
112             " ret: " << ret);
113
114     ret = security_server_set_pwd_max_challenge(5);
115     RUNNER_ASSERT_MSG_BT(ret == err,
116             "security_server_set_pwd_max_challenge has failed,"
117             " ret: " << ret);
118
119     ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
120     RUNNER_ASSERT_MSG_BT(ret == err_is_pwd_valid,
121             "security_server_is_pwd_valid should return password exist,"
122             " ret: " << ret);
123
124     usleep(PASSWORD_RETRY_TIMEOUT_US);
125     ret = security_server_set_pwd("12345", "12346", 0, 0);
126     RUNNER_ASSERT_MSG_BT(ret == err,
127             "security_server_set_pwd has failed, ret: " << ret);
128
129     ret = security_server_reset_pwd("12346",0, 0);
130     RUNNER_ASSERT_MSG_BT(ret == err,
131             "security_server_reset_pwd has failed, ret: " << ret);
132     usleep(PASSWORD_RETRY_TIMEOUT_US);
133     ret = security_server_chk_pwd("12346", &attempt, &max_attempt, &expire_sec);
134     RUNNER_ASSERT_MSG_BT(ret == err,
135             "security_server_chk_pwd has failed, ret: " << ret);
136
137     ret = security_server_set_pwd_history(10);
138     RUNNER_ASSERT_MSG_BT(ret == err,
139             "security_server_set_pwd_history has failed, ret: " << ret);
140 }
141
142 RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_SERVER);
143
144 RUNNER_TEST(tc_security_server_get_gid_normal_case_trying_to_get_gid_of_tel_gprs)
145 {
146     RUNNER_ASSERT_BT(security_server_get_gid("tel_gprs") >= 0);
147 }
148
149 RUNNER_TEST(tc_security_server_get_gid_empty_object_name)
150 {
151     RUNNER_ASSERT_BT(security_server_get_gid("") == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
152 }
153
154 RUNNER_TEST(tc_security_server_get_gid_wrong_object_name_teltel)
155 {
156     RUNNER_ASSERT_BT(security_server_get_gid("teltel") == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT);
157 }
158
159 RUNNER_CHILD_TEST_SMACK(tc01a_security_server_app_give_access)
160 {
161     const char *subject = "abc345v34sfa";
162     const char *object = "efg678x2lkjz";
163     const char *server_api = "security-server::api-data-share";
164
165     SmackAccess smack;
166     smack.add(subject, object, "-----");
167     smack.add(object,  server_api, "rw");
168     smack.apply();
169
170     smack_set_label_for_self(object);
171
172     RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
173
174     security_server_app_give_access(subject, getpid());
175
176     RUNNER_ASSERT_BT(1 == smack_have_access(subject, object, "rwxat"));
177 }
178
179 /*
180  * Currently we are NOT revoking any permissions given by
181  * security_server_app_give_access function
182  */
183 /*RUNNER_TEST(tc01b_security_server_app_give_access)
184 {
185     const char *subject = "abc345v34sfa";
186     const char *object = "efg678x2lkjz";
187
188     // After part A thread from security-server will be notified about
189     // process end and revoke permissions. We need to give him some
190     // time.
191     sleep(1);
192
193     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "r----"));
194     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "-w---"));
195     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "--x--"));
196     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "---a-"));
197     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "----t"));
198 }*/
199
200 RUNNER_CHILD_TEST_SMACK(tc01c_security_server_app_give_access_no_access)
201 {
202     RUNNER_IGNORED_MSG("Security-server sockets are not labeled.");
203     const char *subject = "xxx45v34sfa";
204     const char *object = "yyy78x2lkjz";
205
206     SmackAccess smack;
207     smack.add(subject, object, "-----");
208     smack.apply();
209
210     RUNNER_ASSERT_MSG_BT(0 == smack_set_label_for_self(object), "Error in smack_label_for_self");
211
212     RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
213
214     RUNNER_ASSERT_BT(SECURITY_SERVER_API_ERROR_ACCESS_DENIED ==
215             security_server_app_give_access(subject, getpid()));
216
217     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "r"));
218 }
219
220 RUNNER_TEST_SMACK(tc02_check_privilege_by_pid)
221 {
222     int ret;
223     int pid;
224
225     pid = getpid();
226
227     //we checking existing rule, it should return positive
228     ret = security_server_check_privilege_by_pid(pid, "_", "rx");
229     RUNNER_ASSERT_BT(ret == SECURITY_SERVER_API_SUCCESS);
230
231     //we checking rule with label that not exist
232     ret = security_server_check_privilege_by_pid(pid, "thislabelisnotreal", "rwxat");
233     RUNNER_ASSERT_BT(ret != SECURITY_SERVER_API_SUCCESS);
234 }
235
236 RUNNER_CHILD_TEST_SMACK(tc03_check_API_passwd_allow)
237 {
238     int ret = -1;
239     unsigned int attempt, max_attempt, expire_sec;
240     char *str = (char*) malloc(256);
241
242     attempt = max_attempt = expire_sec = 0;
243
244     ret = clear_password(&str);
245     RUNNER_ASSERT_MSG_BT(ret == 0, "ret: " << str);
246
247     SecurityServer::AccessProvider provider(TEST03_SUBJECT);
248     provider.allowAPI(API_PASSWD_CHECK, API_RULE_REQUIRED);
249     provider.allowAPI(API_PASSWD_SET,   API_RULE_REQUIRED);
250     provider.allowAPI(API_PASSWD_RESET, API_RULE_REQUIRED);
251     provider.applyAndSwithToUser(APP_UID, APP_GID);
252
253     ret = security_server_set_pwd_validity(10);
254     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, "ret: " << ret);
255
256     ret = security_server_set_pwd_max_challenge(5);
257     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, "ret: " << ret);
258
259     ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
260     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, "ret: " << ret);
261
262     usleep(PASSWORD_RETRY_TIMEOUT_US);
263     ret = security_server_set_pwd(NULL, "12345", 0, 0);
264     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
265
266     ret = security_server_reset_pwd("12345",0, 0);
267     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
268
269     usleep(PASSWORD_RETRY_TIMEOUT_US);
270     ret = security_server_chk_pwd("12345", &attempt, &max_attempt, &expire_sec);
271     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
272
273     ret = security_server_set_pwd_history(10);
274     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
275 }
276
277 RUNNER_CHILD_TEST_SMACK(tc04_check_API_passwd_denied)
278 {
279     RUNNER_IGNORED_MSG("Security-server sockets are not labeled.");
280     check_API_passwd(true);
281 }
282
283 RUNNER_CHILD_TEST_NOSMACK(tc04_check_API_app_user_passwd_allow_nosmack)
284 {
285     check_API_passwd(false);
286 }
287
288 RUNNER_CHILD_TEST_SMACK(tc07_check_API_data_share_allow)
289 {
290     SecurityServer::AccessProvider provider(TEST07_SUBJECT);
291     provider.allowFunction("security_server_app_give_access");
292     provider.applyAndSwithToUser(APP_UID, APP_GID);
293
294     int ret = security_server_app_give_access(TEST07_SUBJECT, getpid());
295     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
296 }
297
298 RUNNER_CHILD_TEST_SMACK(tc08_check_API_data_share_denied)
299 {
300     RUNNER_IGNORED_MSG("Security-server sockets are not labeled.");
301     SecurityServer::AccessProvider provider(TEST08_SUBJECT);
302     provider.applyAndSwithToUser(APP_UID, APP_GID);
303
304     int ret = security_server_app_give_access(TEST08_SUBJECT, getpid());
305     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED,
306             "security_server_app_give_access should return access denied,"
307             " ret: " << ret);
308 }
309
310 //////////////////////////////////////////
311 /////////NOSMACK ENV TESTS////////////////
312 //////////////////////////////////////////
313
314 /**
315  * NOSMACK version of tc01a and tc01c tests.
316  *
317  * SMACK is turned off - that means for us, that we don't need any accesses added to our process
318  * in SMACK before dropping root privileges. This test drops root privileges, calls
319  * security_server_app_give_access and then checks if smack_have_access returns error (because
320  * SMACK is off).
321  *
322  * security_server_app_give_access shouldn't return anything else than success when SMACK is off,
323  * hence there is only one test that replaces tests tc01a and tc01c.
324  */
325 RUNNER_CHILD_TEST_NOSMACK(tc01_security_server_app_give_access_nosmack)
326 {
327     const char* subject = "abc345v34sfa";
328     const char* object = "efg678x2lkjz";
329     int result = 0;
330
331     result = drop_root_privileges();
332     RUNNER_ASSERT_MSG_BT(result == 0,
333             "Failed to drop root privileges. Result: " << result << "uid = " << getuid());
334
335     result = security_server_app_give_access(subject, getpid());
336     RUNNER_ASSERT_MSG_BT(result == SECURITY_SERVER_API_SUCCESS,
337             "Error in security_server_app_give_access. Result: " << result);
338
339     result = smack_have_access(subject, object, "rwxat");
340     RUNNER_ASSERT_MSG_BT(result == -1,
341             "smack_have_access should return error when SMACK is off. Result: " << result);
342 }
343
344 /**
345  * NOSMACK version of tc02 test.
346  *
347  * check_privilege_by_pid should always return success when SMACK is off, no matter if label is
348  * real or not.
349  */
350 RUNNER_TEST_NOSMACK(tc02_check_privilege_by_pid_nosmack)
351 {
352     int ret;
353     int pid;
354
355     pid = getpid();
356
357     //we checking existing rule, it should return positive
358     ret = security_server_check_privilege_by_pid(pid, "_", "rx");
359     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
360             "check_privilege_by_pid for existing label failed. Result: " << ret);
361
362     //we checking rule with label that not exist
363     ret = security_server_check_privilege_by_pid(pid, "thislabelisnotreal", "rwxat");
364     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
365             "check_privilege_by_pid for nonexisting label failed. Result: " << ret);
366 }
367
368 /**
369  * NOSMACK version of clear_password function.
370  *
371  * Compared to SMACK version of this function, this one skips adding rules and setting label.
372  */
373 int clear_password_nosmack()
374 {
375     int ret = -1;
376     unsigned int attempt, max_attempt, expire_sec;
377
378     if (getuid() == 0) {
379         reset_security_server();
380
381         attempt = max_attempt = expire_sec = UINT_MAX;
382         ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
383
384         RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD,
385                 "is_pwd_faild should return no password error. Result: " << ret);
386         RUNNER_ASSERT_MSG_BT(expire_sec == 0, "expire_sec = " << expire_sec << ", should be 0.");
387         RUNNER_ASSERT_MSG_BT(max_attempt == 0, "max_attempt = " << max_attempt << ", should be 0.");
388         RUNNER_ASSERT_MSG_BT(attempt == 0, "attempt = " << attempt << ", should be 0.");
389
390         return 0;
391     }
392     return -1;
393 }
394
395 /**
396  * NOSMACK version of tc03 test.
397  *
398  * Just as tc01a/tc01c NOSMACK replacement, we don't need to do anything with SMACK because most
399  * important functions will return errors (that is smack_accesses_apply/smack_have_access etc.).
400  * First clear password, then drop privileges and proceed to regular testing.
401  */
402
403 RUNNER_CHILD_TEST_NOSMACK(tc03_check_API_passwd_allow_nosmack)
404 {
405     int ret = -1;
406     unsigned int attempt, max_attempt, expire_sec;
407
408     attempt = max_attempt = expire_sec = 0;
409
410     clear_password_nosmack();
411
412     // drop root privileges
413     ret = drop_root_privileges();
414     RUNNER_ASSERT_MSG_BT(ret == 0,
415             "Failed to drop root privileges. Result: " << ret << "uid = " << getuid());
416
417     ret = security_server_set_pwd_validity(10);
418     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD,
419             "set_pwd_validity should return no password error. Result: " << ret);
420
421     ret = security_server_set_pwd_max_challenge(5);
422     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD,
423             "set_pwd_max_challenge should return no password error. Result: " << ret);
424
425     ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
426     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD,
427             "is_pwd_valid should return no password error. Result: " << ret);
428
429     usleep(PASSWORD_RETRY_TIMEOUT_US);
430     ret = security_server_set_pwd(NULL, "12345", 0, 0);
431     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
432             "set_pwd failed. Result: " << ret);
433
434     ret = security_server_reset_pwd("12345",0, 0);
435     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
436             "reset_pwd failed. Result: " << ret);
437
438     usleep(PASSWORD_RETRY_TIMEOUT_US);
439     ret = security_server_chk_pwd("12345", &attempt, &max_attempt, &expire_sec);
440     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
441             "chk_pwd failed. Result: " << ret);
442
443     ret = security_server_set_pwd_history(10);
444     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
445             "set_pwd_history failed. Result: " << ret);
446 }
447
448 /**
449  * NOSMACK version of tc07 test.
450  *
451  * Similarily to previous tests - no need to set self label because SMACK is off. Just as
452  * tc01a/tc01c replacement, security_server_app_give_access should return only success. Hence the
453  * NOSMACK version of tc08 test is skipped.
454  */
455 RUNNER_CHILD_TEST_NOSMACK(tc07_check_API_data_share_allow_nosmack)
456 {
457     int ret = -1;
458
459     // drop root privileges
460     ret = drop_root_privileges();
461     RUNNER_ASSERT_MSG_BT(ret == 0,
462             "Failed to drop root privileges. Result: " << ret << "uid = " << getuid());
463
464     ret = security_server_app_give_access(TEST07_SUBJECT, getpid());
465     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
466             "app_give_access failed. Result: " << ret);
467 }
468
469 int main(int argc, char *argv[]) {
470     if (0 != getuid()) {
471         printf("Error: %s must be executed by root\n", argv[0]);
472         exit(1);
473     }
474     SummaryCollector::Register();
475     return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
476 }