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