189f05265910a271d126782f75672740e532cff4
[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 RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_SERVER);
93
94 RUNNER_TEST(tc_security_server_get_gid_normal_case_trying_to_get_gid_of_tel_gprs)
95 {
96     RUNNER_ASSERT_BT(security_server_get_gid("tel_gprs") >= 0);
97 }
98
99 RUNNER_TEST(tc_security_server_get_gid_empty_object_name)
100 {
101     RUNNER_ASSERT_BT(security_server_get_gid("") == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
102 }
103
104 RUNNER_TEST(tc_security_server_get_gid_wrong_object_name_teltel)
105 {
106     RUNNER_ASSERT_BT(security_server_get_gid("teltel") == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT);
107 }
108
109 RUNNER_CHILD_TEST_SMACK(tc01a_security_server_app_give_access)
110 {
111     const char *subject = "abc345v34sfa";
112     const char *object = "efg678x2lkjz";
113     const char *server_api = "security-server::api-data-share";
114
115     SmackAccess smack;
116     smack.add(subject, object, "-----");
117     smack.add(object,  server_api, "rw");
118     smack.apply();
119
120     smack_set_label_for_self(object);
121
122     RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
123
124     security_server_app_give_access(subject, getpid());
125
126     RUNNER_ASSERT_BT(1 == smack_have_access(subject, object, "rwxat"));
127 }
128
129 /*
130  * Currently we are NOT revoking any permissions given by
131  * security_server_app_give_access function
132  */
133 /*RUNNER_TEST(tc01b_security_server_app_give_access)
134 {
135     const char *subject = "abc345v34sfa";
136     const char *object = "efg678x2lkjz";
137
138     // After part A thread from security-server will be notified about
139     // process end and revoke permissions. We need to give him some
140     // time.
141     sleep(1);
142
143     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "r----"));
144     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "-w---"));
145     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "--x--"));
146     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "---a-"));
147     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "----t"));
148 }*/
149
150 RUNNER_CHILD_TEST_SMACK(tc01c_security_server_app_give_access_no_access)
151 {
152     RUNNER_IGNORED_MSG("Security-server sockets are not labeled.");
153     const char *subject = "xxx45v34sfa";
154     const char *object = "yyy78x2lkjz";
155
156     SmackAccess smack;
157     smack.add(subject, object, "-----");
158     smack.apply();
159
160     RUNNER_ASSERT_MSG_BT(0 == smack_set_label_for_self(object), "Error in smack_label_for_self");
161
162     RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
163
164     RUNNER_ASSERT_BT(SECURITY_SERVER_API_ERROR_ACCESS_DENIED ==
165             security_server_app_give_access(subject, getpid()));
166
167     RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "r"));
168 }
169
170 RUNNER_TEST_SMACK(tc02_check_privilege_by_pid)
171 {
172     int ret;
173     int pid;
174
175     pid = getpid();
176
177     //we checking existing rule, it should return positive
178     ret = security_server_check_privilege_by_pid(pid, "_", "rx");
179     RUNNER_ASSERT_BT(ret == SECURITY_SERVER_API_SUCCESS);
180
181     //we checking rule with label that not exist
182     ret = security_server_check_privilege_by_pid(pid, "thislabelisnotreal", "rwxat");
183     RUNNER_ASSERT_BT(ret != SECURITY_SERVER_API_SUCCESS);
184 }
185
186 RUNNER_CHILD_TEST_SMACK(tc03_check_API_passwd_allow)
187 {
188     int ret = -1;
189     unsigned int attempt, max_attempt, expire_sec;
190     char *str = (char*) malloc(256);
191
192     attempt = max_attempt = expire_sec = 0;
193
194     ret = clear_password(&str);
195     RUNNER_ASSERT_MSG_BT(ret == 0, "ret: " << str);
196
197     SecurityServer::AccessProvider provider(TEST03_SUBJECT);
198     provider.allowAPI(API_PASSWD_CHECK, API_RULE_REQUIRED);
199     provider.allowAPI(API_PASSWD_SET,   API_RULE_REQUIRED);
200     provider.allowAPI(API_PASSWD_RESET, API_RULE_REQUIRED);
201     provider.applyAndSwithToUser(APP_UID, APP_GID);
202
203     ret = security_server_set_pwd_validity(10);
204     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, "ret: " << ret);
205
206     ret = security_server_set_pwd_max_challenge(5);
207     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, "ret: " << ret);
208
209     ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
210     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, "ret: " << ret);
211
212     usleep(PASSWORD_RETRY_TIMEOUT_US);
213     ret = security_server_set_pwd(NULL, "12345", 0, 0);
214     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
215
216     ret = security_server_reset_pwd("12345",0, 0);
217     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
218
219     usleep(PASSWORD_RETRY_TIMEOUT_US);
220     ret = security_server_chk_pwd("12345", &attempt, &max_attempt, &expire_sec);
221     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
222
223     ret = security_server_set_pwd_history(10);
224     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
225 }
226
227 RUNNER_CHILD_TEST(tc04_check_API_passwd_denied)
228 {
229     RUNNER_IGNORED_MSG("Security-server sockets are not labeled.");
230     int ret = -1;
231     unsigned int attempt, max_attempt, expire_sec;
232
233     attempt = max_attempt = expire_sec = 0;
234
235     SecurityServer::AccessProvider privider(TEST04_SUBJECT);
236     privider.applyAndSwithToUser(APP_UID, APP_GID);
237
238     /*
239      * now SS should return error
240      * at the moment SS doesn't check return code from
241      * authorize_SS_API_caller_socket() so it should give access
242      * you can check in logs if it's working properly
243      * has access result = 1
244      * no access result = 0
245      * D/SECURITY_SERVER( 2510): security-server-main.c: authorize_SS_API_caller_socket(205) >
246      *                          [SECURE_LOG] SS_SMACK: caller_pid=5278, subject=subject_allow,
247      *                          object=security-server::api-password-check, access=w, result=1,
248      *                          caller_path=/usr/bin/security-server-tests-server
249      * E/SECURITY_SERVER( 2510): security-server-main.c: authorize_SS_API_caller_socket(207) >
250      *                          [SECURE_LOG] SS_SMACK: caller_pid=5278, subject=subject_allow,
251      *                          object=security-server::api-password-check, access=w, result=0,
252      *                          caller_path=/usr/bin/security-server-tests-server
253      */
254
255     ret = security_server_set_pwd_validity(10);
256     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED,
257             "security_server_set_pwd_validity should return access denied,"
258             " ret: " << ret);
259
260     ret = security_server_set_pwd_max_challenge(5);
261     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED,
262             "security_server_set_pwd_max_challenge should return access denied,"
263             " ret: " << ret);
264
265     ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
266     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED,
267             "security_server_is_pwd_valid should return access denied,"
268             " ret: " << ret);
269
270     usleep(PASSWORD_RETRY_TIMEOUT_US);
271     ret = security_server_set_pwd("12345", "12346", 0, 0);
272     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED,
273             "security_server_set_pwd should return access denied,"
274             " ret: " << ret);
275
276     ret = security_server_reset_pwd("12346",0, 0);
277     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED,
278             "security_server_reset_pwd should return access denied,"
279             " ret: " << ret);
280     usleep(PASSWORD_RETRY_TIMEOUT_US);
281     ret = security_server_chk_pwd("12346", &attempt, &max_attempt, &expire_sec);
282     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED,
283             "security_server_chk_pwd should return access denied,"
284             " ret: " << ret);
285
286     ret = security_server_set_pwd_history(10);
287     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED,
288             "security_server_set_pwd_history should return access denied,"
289             " ret: " << ret);
290 }
291
292 RUNNER_CHILD_TEST_SMACK(tc07_check_API_data_share_allow)
293 {
294     SecurityServer::AccessProvider provider(TEST07_SUBJECT);
295     provider.allowFunction("security_server_app_give_access");
296     provider.applyAndSwithToUser(APP_UID, APP_GID);
297
298     int ret = security_server_app_give_access(TEST07_SUBJECT, getpid());
299     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
300 }
301
302 RUNNER_CHILD_TEST_SMACK(tc08_check_API_data_share_denied)
303 {
304     RUNNER_IGNORED_MSG("Security-server sockets are not labeled.");
305     SecurityServer::AccessProvider provider(TEST08_SUBJECT);
306     provider.applyAndSwithToUser(APP_UID, APP_GID);
307
308     int ret = security_server_app_give_access(TEST08_SUBJECT, getpid());
309     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED,
310             "security_server_app_give_access should return access denied,"
311             " ret: " << ret);
312 }
313
314 //////////////////////////////////////////
315 /////////NOSMACK ENV TESTS////////////////
316 //////////////////////////////////////////
317
318 /**
319  * NOSMACK version of tc01a and tc01c tests.
320  *
321  * SMACK is turned off - that means for us, that we don't need any accesses added to our process
322  * in SMACK before dropping root privileges. This test drops root privileges, calls
323  * security_server_app_give_access and then checks if smack_have_access returns error (because
324  * SMACK is off).
325  *
326  * security_server_app_give_access shouldn't return anything else than success when SMACK is off,
327  * hence there is only one test that replaces tests tc01a and tc01c.
328  */
329 RUNNER_CHILD_TEST_NOSMACK(tc01_security_server_app_give_access_nosmack)
330 {
331     const char* subject = "abc345v34sfa";
332     const char* object = "efg678x2lkjz";
333     int result = 0;
334
335     result = drop_root_privileges();
336     RUNNER_ASSERT_MSG_BT(result == 0,
337             "Failed to drop root privileges. Result: " << result << "uid = " << getuid());
338
339     result = security_server_app_give_access(subject, getpid());
340     RUNNER_ASSERT_MSG_BT(result == SECURITY_SERVER_API_SUCCESS,
341             "Error in security_server_app_give_access. Result: " << result);
342
343     result = smack_have_access(subject, object, "rwxat");
344     RUNNER_ASSERT_MSG_BT(result == -1,
345             "smack_have_access should return error when SMACK is off. Result: " << result);
346 }
347
348 /**
349  * NOSMACK version of tc02 test.
350  *
351  * check_privilege_by_pid should always return success when SMACK is off, no matter if label is
352  * real or not.
353  */
354 RUNNER_TEST_NOSMACK(tc02_check_privilege_by_pid_nosmack)
355 {
356     int ret;
357     int pid;
358
359     pid = getpid();
360
361     //we checking existing rule, it should return positive
362     ret = security_server_check_privilege_by_pid(pid, "_", "rx");
363     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
364             "check_privilege_by_pid for existing label failed. Result: " << ret);
365
366     //we checking rule with label that not exist
367     ret = security_server_check_privilege_by_pid(pid, "thislabelisnotreal", "rwxat");
368     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
369             "check_privilege_by_pid for nonexisting label failed. Result: " << ret);
370 }
371
372 /**
373  * NOSMACK version of clear_password function.
374  *
375  * Compared to SMACK version of this function, this one skips adding rules and setting label.
376  */
377 int clear_password_nosmack()
378 {
379     int ret = -1;
380     unsigned int attempt, max_attempt, expire_sec;
381
382     if (getuid() == 0) {
383         reset_security_server();
384
385         attempt = max_attempt = expire_sec = UINT_MAX;
386         ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
387
388         RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD,
389                 "is_pwd_faild should return no password error. Result: " << ret);
390         RUNNER_ASSERT_MSG_BT(expire_sec == 0, "expire_sec = " << expire_sec << ", should be 0.");
391         RUNNER_ASSERT_MSG_BT(max_attempt == 0, "max_attempt = " << max_attempt << ", should be 0.");
392         RUNNER_ASSERT_MSG_BT(attempt == 0, "attempt = " << attempt << ", should be 0.");
393
394         return 0;
395     }
396     return -1;
397 }
398
399 /**
400  * NOSMACK version of tc03 test.
401  *
402  * Just as tc01a/tc01c NOSMACK replacement, we don't need to do anything with SMACK because most
403  * important functions will return errors (that is smack_accesses_apply/smack_have_access etc.).
404  * First clear password, then drop privileges and proceed to regular testing.
405  */
406
407 RUNNER_CHILD_TEST_NOSMACK(tc03_check_API_passwd_allow_nosmack)
408 {
409     int ret = -1;
410     unsigned int attempt, max_attempt, expire_sec;
411
412     attempt = max_attempt = expire_sec = 0;
413
414     clear_password_nosmack();
415
416     // drop root privileges
417     ret = drop_root_privileges();
418     RUNNER_ASSERT_MSG_BT(ret == 0,
419             "Failed to drop root privileges. Result: " << ret << "uid = " << getuid());
420
421     ret = security_server_set_pwd_validity(10);
422     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD,
423             "set_pwd_validity should return no password error. Result: " << ret);
424
425     ret = security_server_set_pwd_max_challenge(5);
426     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD,
427             "set_pwd_max_challenge should return no password error. Result: " << ret);
428
429     ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
430     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD,
431             "is_pwd_valid should return no password error. Result: " << ret);
432
433     usleep(PASSWORD_RETRY_TIMEOUT_US);
434     ret = security_server_set_pwd(NULL, "12345", 0, 0);
435     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
436             "set_pwd failed. Result: " << ret);
437
438     ret = security_server_reset_pwd("12345",0, 0);
439     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
440             "reset_pwd failed. Result: " << ret);
441
442     usleep(PASSWORD_RETRY_TIMEOUT_US);
443     ret = security_server_chk_pwd("12345", &attempt, &max_attempt, &expire_sec);
444     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
445             "chk_pwd failed. Result: " << ret);
446
447     ret = security_server_set_pwd_history(10);
448     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
449             "set_pwd_history failed. Result: " << ret);
450 }
451
452 /**
453  * NOSMACK version of tc07 test.
454  *
455  * Similarily to previous tests - no need to set self label because SMACK is off. Just as
456  * tc01a/tc01c replacement, security_server_app_give_access should return only success. Hence the
457  * NOSMACK version of tc08 test is skipped.
458  */
459 RUNNER_CHILD_TEST_NOSMACK(tc07_check_API_data_share_allow_nosmack)
460 {
461     int ret = -1;
462
463     // drop root privileges
464     ret = drop_root_privileges();
465     RUNNER_ASSERT_MSG_BT(ret == 0,
466             "Failed to drop root privileges. Result: " << ret << "uid = " << getuid());
467
468     ret = security_server_app_give_access(TEST07_SUBJECT, getpid());
469     RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS,
470             "app_give_access failed. Result: " << ret);
471 }
472
473 int main(int argc, char *argv[]) {
474     if (0 != getuid()) {
475         printf("Error: %s must be executed by root\n", argv[0]);
476         exit(1);
477     }
478     SummaryCollector::Register();
479     return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
480 }