2 * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
5 * @file security_server_tests_server.cpp
6 * @author Bumjin Im (bj.im@samsung.com)
7 * @author Mariusz Domanski (m.domanski@samsung.com)
9 * @brief Test cases for security server
15 #include <sys/types.h>
16 #include <sys/param.h>
21 #include <sys/socket.h>
23 #include <sys/smack.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>
30 #include <privilege-control.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>
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";
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";
48 int clear_password(char ** /*error*/)
51 unsigned int attempt, max_attempt, expire_sec;
52 const char *subject_allow = "subject_allow";
53 struct smack_accesses *handle = NULL;
56 reset_security_server();
58 ret = smack_accesses_new(&handle);
59 RUNNER_ASSERT_MSG_BT(ret == 0, "ret: " << ret);
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);
65 ret = smack_accesses_apply(handle);
66 RUNNER_ASSERT_MSG_BT(ret == 0, "ret: " << ret);
68 ret = smack_set_label_for_self(subject_allow);
69 RUNNER_ASSERT_MSG_BT(ret == 0, "ret: " << ret);
71 smack_accesses_free(handle);
73 attempt = max_attempt = expire_sec = UINT_MAX;
74 ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
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);
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.");
92 void check_API_passwd(bool smack) {
94 int err, err_is_pwd_valid;
95 unsigned int attempt, max_attempt, expire_sec;
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;
102 SecurityServer::AccessProvider privider(TEST04_SUBJECT);
103 privider.applyAndSwithToUser(APP_UID, APP_GID);
105 RUNNER_ASSERT_MSG_BT((ret = drop_root_privileges()) == 0,
106 "Failed to drop root privileges. Result: " << ret << "uid = " << getuid());
109 ret = security_server_set_pwd_validity(APP_UID);
110 RUNNER_ASSERT_MSG_BT(ret == err,
111 "security_server_set_pwd_validity has failed,"
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,"
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,"
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);
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);
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);
142 RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_SERVER);
144 RUNNER_TEST(tc_security_server_get_gid_normal_case_trying_to_get_gid_of_tel_gprs)
146 RUNNER_ASSERT_BT(security_server_get_gid("tel_gprs") >= 0);
149 RUNNER_TEST(tc_security_server_get_gid_empty_object_name)
151 RUNNER_ASSERT_BT(security_server_get_gid("") == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
154 RUNNER_TEST(tc_security_server_get_gid_wrong_object_name_teltel)
156 RUNNER_ASSERT_BT(security_server_get_gid("teltel") == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT);
159 RUNNER_CHILD_TEST_SMACK(tc01a_security_server_app_give_access)
161 const char *subject = "abc345v34sfa";
162 const char *object = "efg678x2lkjz";
163 const char *server_api = "security-server::api-data-share";
166 smack.add(subject, object, "-----");
167 smack.add(object, server_api, "rw");
170 smack_set_label_for_self(object);
172 RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
174 security_server_app_give_access(subject, getpid());
176 RUNNER_ASSERT_BT(1 == smack_have_access(subject, object, "rwxat"));
180 * Currently we are NOT revoking any permissions given by
181 * security_server_app_give_access function
183 /*RUNNER_TEST(tc01b_security_server_app_give_access)
185 const char *subject = "abc345v34sfa";
186 const char *object = "efg678x2lkjz";
188 // After part A thread from security-server will be notified about
189 // process end and revoke permissions. We need to give him some
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"));
200 RUNNER_CHILD_TEST_SMACK(tc01c_security_server_app_give_access_no_access)
202 RUNNER_IGNORED_MSG("Security-server sockets are not labeled.");
203 const char *subject = "xxx45v34sfa";
204 const char *object = "yyy78x2lkjz";
207 smack.add(subject, object, "-----");
210 RUNNER_ASSERT_MSG_BT(0 == smack_set_label_for_self(object), "Error in smack_label_for_self");
212 RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
214 RUNNER_ASSERT_BT(SECURITY_SERVER_API_ERROR_ACCESS_DENIED ==
215 security_server_app_give_access(subject, getpid()));
217 RUNNER_ASSERT_BT(0 == smack_have_access(subject, object, "r"));
220 RUNNER_TEST_SMACK(tc02_check_privilege_by_pid)
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);
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);
236 RUNNER_CHILD_TEST_SMACK(tc03_check_API_passwd_allow)
239 unsigned int attempt, max_attempt, expire_sec;
240 char *str = (char*) malloc(256);
242 attempt = max_attempt = expire_sec = 0;
244 ret = clear_password(&str);
245 RUNNER_ASSERT_MSG_BT(ret == 0, "ret: " << str);
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);
253 ret = security_server_set_pwd_validity(10);
254 RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, "ret: " << ret);
256 ret = security_server_set_pwd_max_challenge(5);
257 RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, "ret: " << ret);
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);
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);
266 ret = security_server_reset_pwd("12345",0, 0);
267 RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
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);
273 ret = security_server_set_pwd_history(10);
274 RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
277 RUNNER_CHILD_TEST_SMACK(tc04_check_API_passwd_denied)
279 RUNNER_IGNORED_MSG("Security-server sockets are not labeled.");
280 check_API_passwd(true);
283 RUNNER_CHILD_TEST_NOSMACK(tc04_check_API_app_user_passwd_allow_nosmack)
285 check_API_passwd(false);
288 RUNNER_CHILD_TEST_SMACK(tc07_check_API_data_share_allow)
290 SecurityServer::AccessProvider provider(TEST07_SUBJECT);
291 provider.allowFunction("security_server_app_give_access");
292 provider.applyAndSwithToUser(APP_UID, APP_GID);
294 int ret = security_server_app_give_access(TEST07_SUBJECT, getpid());
295 RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
298 RUNNER_CHILD_TEST_SMACK(tc08_check_API_data_share_denied)
300 RUNNER_IGNORED_MSG("Security-server sockets are not labeled.");
301 SecurityServer::AccessProvider provider(TEST08_SUBJECT);
302 provider.applyAndSwithToUser(APP_UID, APP_GID);
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,"
310 //////////////////////////////////////////
311 /////////NOSMACK ENV TESTS////////////////
312 //////////////////////////////////////////
315 * NOSMACK version of tc01a and tc01c tests.
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
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.
325 RUNNER_CHILD_TEST_NOSMACK(tc01_security_server_app_give_access_nosmack)
327 const char* subject = "abc345v34sfa";
328 const char* object = "efg678x2lkjz";
331 result = drop_root_privileges();
332 RUNNER_ASSERT_MSG_BT(result == 0,
333 "Failed to drop root privileges. Result: " << result << "uid = " << getuid());
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);
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);
345 * NOSMACK version of tc02 test.
347 * check_privilege_by_pid should always return success when SMACK is off, no matter if label is
350 RUNNER_TEST_NOSMACK(tc02_check_privilege_by_pid_nosmack)
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);
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);
369 * NOSMACK version of clear_password function.
371 * Compared to SMACK version of this function, this one skips adding rules and setting label.
373 int clear_password_nosmack()
376 unsigned int attempt, max_attempt, expire_sec;
379 reset_security_server();
381 attempt = max_attempt = expire_sec = UINT_MAX;
382 ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
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.");
396 * NOSMACK version of tc03 test.
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.
403 RUNNER_CHILD_TEST_NOSMACK(tc03_check_API_passwd_allow_nosmack)
406 unsigned int attempt, max_attempt, expire_sec;
408 attempt = max_attempt = expire_sec = 0;
410 clear_password_nosmack();
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());
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);
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);
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);
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);
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);
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);
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);
449 * NOSMACK version of tc07 test.
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.
455 RUNNER_CHILD_TEST_NOSMACK(tc07_check_API_data_share_allow_nosmack)
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());
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);
469 int main(int argc, char *argv[]) {
471 printf("Error: %s must be executed by root\n", argv[0]);
474 SummaryCollector::Register();
475 return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);