2 * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
5 * @file security_server_tests_client_smack.cpp
6 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
8 * @brief Test cases for security-server-client-smack.
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <sys/smack.h>
25 #include <dpl/log/log.h>
26 #include <dpl/test/test_runner.h>
27 #include <dpl/test/test_runner_child.h>
28 #include <dpl/test/test_runner_multiprocess.h>
29 #include "security_server_mockup.h"
31 #include <security-server.h>
32 #include <access_provider.h>
33 #include "tests_common.h"
34 #include <summary_collector.h>
37 #define PROPER_COOKIE_SIZE 20
40 RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_CLIENT_SMACK)
43 * test: tc04_security_server_get_gid
44 * description: Checking for security_server_get_gid
45 * with nonexisting gid and existing one
46 * expected: security_server_get_gid should return
47 * SECURITY_SERVER_ERROR_NO_SUCH_OBJECT with first call
48 * and group id with second call
50 RUNNER_CHILD_TEST_SMACK(tc04_security_server_get_gid)
52 SecurityServer::AccessProvider provider("tc04mylabel");
54 provider.applyAndSwithToUser(APP_UID, APP_GID);
56 int ret = security_server_get_gid("abc123xyz_pysiaczek");
57 LogDebug("ret = " << ret);
58 RUNNER_ASSERT_MSG_BT(SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT == ret, "Ret: " << ret);
59 ret = security_server_get_gid("root");
60 LogDebug("ret = " << ret);
61 RUNNER_ASSERT_MSG_BT(0 == ret, "Ret: " << ret);
65 * test: tc05_check_privilege_by_cookie
66 * description: Function security_server_check_privilege_by_cookie should
67 * return status of access rights of cookie owner. In this case cookie owner
68 * is the same process that ask for the rights.
69 * expected: Function call with access rights set to "r" should return SUCCESS,
70 * with "rw" should return ACCESS DENIED.
72 RUNNER_CHILD_TEST_SMACK(tc05_check_privilege_by_cookie)
74 RUNNER_IGNORED_MSG("security_server_check_privilege_by_cookie is temporarily disabled: always returns success");
76 const char *object_label = "tc05objectlabel";
77 const char *access_rights = "r";
78 const char *access_rights_ext = "rw";
79 const char *subject_label = "tc05subjectlabel";
81 SecurityServer::AccessProvider provider(subject_label);
83 provider.addObjectRule(object_label, access_rights);
84 provider.applyAndSwithToUser(APP_UID, APP_GID);
86 RUNNER_ASSERT_BT(SECURITY_SERVER_API_SUCCESS ==
87 security_server_request_cookie(cookie,20));
89 RUNNER_ASSERT_BT(SECURITY_SERVER_API_SUCCESS ==
90 security_server_check_privilege_by_cookie(
95 RUNNER_ASSERT_BT(SECURITY_SERVER_API_ERROR_ACCESS_DENIED ==
96 security_server_check_privilege_by_cookie(
103 * test: security_server_check_privilege_by_sockfd
104 * description: This test will create dummy server that will accept connection
105 * and die. The client will try to check access rights using connection descriptor.
106 * expected: Function call with access rights set to "r" should return SUCCESS,
107 * with "rw" should return ACCESS DENIED.
109 RUNNER_MULTIPROCESS_TEST_SMACK(tc06_check_privilege_by_sockfd)
111 RUNNER_IGNORED_MSG("security_server_check_privilege_by_sockfd is temporarily disabled: always returns success");
112 const char *object_label = "tc06objectlabel";
113 const char *access_rights = "r";
114 const char *access_rights_ext = "rw";
115 const char *subject_label = "tc06subjectlabel";
120 smack_accesses *handle;
121 RUNNER_ASSERT_BT(0 == smack_accesses_new(&handle));
122 RUNNER_ASSERT_BT(0 == smack_accesses_add(handle,
126 RUNNER_ASSERT_BT(0 == smack_accesses_apply(handle));
127 smack_accesses_free(handle);
131 RUNNER_ASSERT_BT(-1 != pid);
135 RUNNER_ASSERT_MSG_BT(0 == smack_set_label_for_self(subject_label), "child label " << subject_label << " not set");
137 int sockfd = create_new_socket();
138 RUNNER_ASSERT_MSG_BT(sockfd >= 0, "create_new_socket() failed");
140 SockUniquePtr sockfd_ptr(&sockfd);
142 label = security_server_get_smacklabel_sockfd(sockfd);
143 RUNNER_ASSERT_MSG_BT(label != NULL, "security_server_get_smacklabel_sockfd failed");
144 RUNNER_ASSERT_MSG_BT(strcmp(label,"") == 0, "label is \"" << label << "\"");
147 RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
149 RUNNER_ASSERT_MSG_BT(listen(sockfd, 5) >= 0, "child listen failed");
151 label = security_server_get_smacklabel_sockfd(sockfd);
152 RUNNER_ASSERT_MSG_BT(label != NULL, "security_server_get_smacklabel_sockfd failed");
153 RUNNER_ASSERT_MSG_BT(strcmp(label,"") == 0, "label is \"" << label << "\"");
156 struct sockaddr_un client_addr;
157 socklen_t client_len = sizeof(client_addr);
159 RUNNER_ASSERT_MSG_BT((csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len)) > 0, "child accept failed");
168 int sockfd = connect_to_testserver();
169 RUNNER_ASSERT_MSG_BT(sockfd >= 0, "connect_to_testserver() failed");
171 SockUniquePtr sockfd_ptr(&sockfd);
173 label = security_server_get_smacklabel_sockfd(sockfd);
174 RUNNER_ASSERT_MSG_BT(label != NULL, "security_server_get_smacklabel_sockfd failed");
175 RUNNER_ASSERT_MSG_BT(strcmp(label,subject_label) == 0, "label is \"" << label << "\"" << ", subject_label is \"" << subject_label << "\"" );
178 result1 = security_server_check_privilege_by_sockfd(
182 result2 = security_server_check_privilege_by_sockfd(
188 RUNNER_ASSERT_MSG_BT(SECURITY_SERVER_API_SUCCESS == result1, "result = " << result1);
189 RUNNER_ASSERT_MSG_BT(SECURITY_SERVER_API_ERROR_ACCESS_DENIED == result2, "result = " << result2);
193 * test: security_server_check_privilege_by_sockfd
194 * description: This test will create dummy server that will accept connection
195 * and die. The client will try to check access rights using connection descriptor.
196 * Because we read a smack label not from socket directly, but from from pid of process
197 * on the other end of socket - that's why smack label will be updated.
198 * In this test client is running under root and server is not - to test the extreme case.
199 * expected: Function call with access rights set to "r" should return SUCCESS,
200 * with "rw" should return ACCESS DENIED.
202 RUNNER_MULTIPROCESS_TEST_SMACK(tc07_check_privilege_by_sockfd)
204 RUNNER_IGNORED_MSG("security_server_check_privilege_by_sockfd is temporarily disabled: always returns success");
205 const char *object_label = "tc07objectlabel";
206 const char *access_rights = "r";
207 const char *access_rights_ext = "rw";
208 const char *subject_label = "tc07subjectlabel";
214 access.add(subject_label, object_label, access_rights);
218 RUNNER_ASSERT_BT(-1 != pid);
223 RUNNER_ASSERT_BT(-1 != pid);
227 int sockfd = create_new_socket();
228 RUNNER_ASSERT_MSG_BT(sockfd >= 0, "create_new_socket() failed");
230 SockUniquePtr sockfd_ptr(&sockfd);
232 RUNNER_ASSERT_MSG_BT(0 == smack_set_label_for_self(subject_label), "child label " << subject_label << " not set");
234 RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
236 RUNNER_ASSERT_MSG_BT(listen(sockfd, 5) >= 0, "child listen failed");
238 struct sockaddr_un client_addr;
239 socklen_t client_len = sizeof(client_addr);
240 int csockfd = TEMP_FAILURE_RETRY(accept(sockfd,(struct sockaddr*)&client_addr, &client_len));
248 int sockfd = connect_to_testserver();
249 RUNNER_ASSERT_MSG_BT(sockfd >= 0, "connect_to_testserver() failed");
251 result1 = security_server_check_privilege_by_sockfd(
255 result2 = security_server_check_privilege_by_sockfd(
262 RUNNER_ASSERT_MSG_BT(SECURITY_SERVER_API_SUCCESS == result1, "result1 = " << result1);
263 RUNNER_ASSERT_MSG_BT(SECURITY_SERVER_API_ERROR_ACCESS_DENIED == result2, " result2 = " << result2);
268 ///////////////////////////
269 /////NOSMACK ENV TESTS/////
270 ///////////////////////////
272 RUNNER_CHILD_TEST_NOSMACK(tc04_security_server_get_gid_nosmack)
276 ret = drop_root_privileges();
277 RUNNER_ASSERT_MSG_BT(ret == 0,
278 "Failed to drop root privileges. Result: " << ret << "uid = " << getuid());
280 ret = security_server_get_gid("definitely_not_existing_object");
281 RUNNER_ASSERT_MSG_BT(ret == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT, "ret = " << ret);
282 ret = security_server_get_gid("root");
283 RUNNER_ASSERT_MSG_BT(ret == 0, "ret = " << ret);
287 * NOSMACK version of tc05 test.
289 * Correct behaviour of smack_accesses_apply and smack_set_label_for_self was checked by libsmack
290 * tests. We assume, that those tests pass. Additionally security_server_check_privilege_by_cookie
291 * should return SUCCESS no matter what access_rights we give to this function.
293 RUNNER_CHILD_TEST_NOSMACK(tc05_check_privilege_by_cookie_nosmack)
295 RUNNER_IGNORED_MSG("security_server_check_privilege_by_cookie is temporarily disabled: always returns success");
297 const char* object_label = "tc05objectlabel";
299 RUNNER_ASSERT_BT(security_server_request_cookie(cookie,20) == SECURITY_SERVER_API_SUCCESS);
301 RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
303 RUNNER_ASSERT_BT(SECURITY_SERVER_API_SUCCESS ==
304 security_server_check_privilege_by_cookie(cookie, object_label, "r"));
306 //On NOSMACK env security server should return success on any accesses, even those that are
308 RUNNER_ASSERT_BT(SECURITY_SERVER_API_SUCCESS ==
309 security_server_check_privilege_by_cookie(cookie, object_label, "rw"));
313 * NOSMACK version of tc06 test.
315 * Differences between this and SMACK version (server):
316 * - Skipped setting access_rights
317 * - Skipped setting label for server
318 * - get_smacklabel_sockfd is called only once for server, almost right after fork and creation
319 * of socket (because it should do nothing when SMACK is off)
320 * - After get_smacklabel_sockfd privileges are dropped and server is prepared to accept connections
323 * For client the only difference are expected results from check_privilege_by_sockfd - both should
326 RUNNER_MULTIPROCESS_TEST_NOSMACK(tc06_check_privilege_by_sockfd_nosmack)
328 RUNNER_IGNORED_MSG("security_server_check_privilege_by_sockfd is temporarily disabled: always returns success");
329 const char* object_label = "tc06objectlabel";
336 RUNNER_ASSERT_BT(pid >= 0);
340 if (pid == 0) { //child process - server
342 int sockfd = create_new_socket();
343 RUNNER_ASSERT_MSG_BT(sockfd >= 0, "create_new_socket() failed");
345 SockUniquePtr sockfd_ptr(&sockfd);
347 //check if get_smacklabel_sockfd works correctly
348 label = security_server_get_smacklabel_sockfd(sockfd);
349 RUNNER_ASSERT_MSG_BT(label != NULL, "security_server_get_smacklabel_sockfd failed");
350 ret = strcmp(label, "");
352 RUNNER_ASSERT_MSG_BT(ret == 0, "label is \"" << label << "\"");
354 RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
356 RUNNER_ASSERT_MSG_BT(listen(sockfd, 5) >= 0, "child listen failed");
358 struct sockaddr_un client_addr;
359 socklen_t client_len = sizeof(client_addr);
362 RUNNER_ASSERT_MSG_BT((csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len)) > 0, "child accept failed");
364 //wait a little bit for parent to do it's job
367 //if everything works, cleanup and return 0
373 int sockfd = connect_to_testserver();
374 RUNNER_ASSERT_MSG_BT(sockfd >= 0, "Failed to connect to server.");
376 SockUniquePtr sockfd_ptr(&sockfd);
378 label = security_server_get_smacklabel_sockfd(sockfd);
379 RUNNER_ASSERT_MSG_BT(label != NULL, "get_smacklabel_sockfd failed.");
380 ret = strcmp(label, "");
382 RUNNER_ASSERT_MSG_BT(ret == 0, "label is \"" << label << "\"");
384 result1 = security_server_check_privilege_by_sockfd(sockfd, object_label, "r");
385 result2 = security_server_check_privilege_by_sockfd(sockfd, object_label, "rw");
388 RUNNER_ASSERT_MSG_BT(result1 == SECURITY_SERVER_API_SUCCESS, "result = " << result1);
389 RUNNER_ASSERT_MSG_BT(result2 == SECURITY_SERVER_API_SUCCESS, "result = " << result2);
393 * NOSMACK version of tc07 test.
395 RUNNER_MULTIPROCESS_TEST_NOSMACK(tc07_check_privilege_by_sockfd_nosmack)
397 RUNNER_IGNORED_MSG("security_server_check_privilege_by_sockfd is temporarily disabled: always returns success");
398 const char* object_label = "tc07objectlabel";
404 RUNNER_ASSERT_BT(-1 != pid);
409 RUNNER_ASSERT_BT(-1 != pid);
411 if (pid == 0) { //child process
413 int sockfd = create_new_socket();
414 RUNNER_ASSERT_MSG_BT(sockfd >= 0, "create_new_socket() failed");
416 SockUniquePtr sockfd_ptr(&sockfd);
419 RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
421 //Prepare for accepting
422 RUNNER_ASSERT_MSG_BT(listen(sockfd, 5) >= 0, "child listen failed");
424 struct sockaddr_un client_addr;
425 socklen_t client_len = sizeof(client_addr);
429 RUNNER_ASSERT_MSG_BT((csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len)) > 0, "child accept failed");
431 //wait a little bit for parent to do it's job
434 //cleanup and kill child
437 } else { //parent process
438 //Drop root privileges
439 RUNNER_ASSERT_MSG_BT(drop_root_privileges() == 0, "uid = " << getuid());
441 //Wait for server to set up
444 //Connect and check privileges
445 int sockfd = connect_to_testserver();
446 RUNNER_ASSERT_MSG_BT(sockfd >= 0, "Failed to create socket fd.");
448 result1 = security_server_check_privilege_by_sockfd(sockfd, object_label, "r");
449 result2 = security_server_check_privilege_by_sockfd(sockfd, object_label, "rw");
453 //Both results (just like in the previous test case) should return success.
454 RUNNER_ASSERT_MSG_BT(SECURITY_SERVER_API_SUCCESS == result1, "result1 = " << result1);
455 RUNNER_ASSERT_MSG_BT(SECURITY_SERVER_API_SUCCESS == result2, "result2 = " << result2);
460 RUNNER_TEST_SMACK(tc18_security_server_get_smacklabel_cookie) {
463 char *label_smack = NULL;
464 char *label_ss = NULL;
467 int cookie_size = security_server_get_cookie_size();
468 RUNNER_ASSERT_MSG_BT(PROPER_COOKIE_SIZE == cookie_size, "Wrong cookie size from security-server");
470 cookie = (char*) calloc(cookie_size, 1);
471 RUNNER_ASSERT_MSG_BT(NULL != cookie, "Memory allocation error");
473 res = security_server_request_cookie(cookie, cookie_size);
474 if (res != SECURITY_SERVER_API_SUCCESS) {
476 RUNNER_ASSERT_MSG_BT(res == SECURITY_SERVER_API_SUCCESS, "Error in requesting cookie from security-server");
479 label_ss = security_server_get_smacklabel_cookie(cookie);
481 RUNNER_ASSERT_MSG_BT(label_ss != NULL, "Error in getting label by cookie");
484 std::string label_cookie(label_ss);
487 res = smack_new_label_from_self(&label_smack);
490 RUNNER_ASSERT_MSG_BT(res == 0, "Error in getting self SMACK label");
492 std::string label_self(label_smack ? label_smack : "");
495 RUNNER_ASSERT_MSG_BT(label_self == label_cookie, "No match in SMACK labels");
498 //TODO: here could be label change using SMACK API and checking if it
499 //is changed using security-server API function based on the same cookie
503 * NOSMACK version of tc_security_server_get_smacklabel_cookie test.
505 * Most of this test goes exactly as the original one. The only difference are the labels:
506 * - We assume that libsmack tests passed and smack_new_label_from_self will return -1 and NULL
507 * label - there is no need to re-check it.
508 * - Label acquired from security_server_get_smacklabel_cookie should be an empty string.
510 RUNNER_TEST_NOSMACK(tc18_security_server_get_smacklabel_cookie_nosmack) {
513 char* label_ss = NULL;
516 int cookie_size = security_server_get_cookie_size();
517 RUNNER_ASSERT_MSG_BT(PROPER_COOKIE_SIZE == cookie_size,
518 "Wrong cookie size from security-server. Size: " << cookie_size);
520 cookie = (char*) calloc(cookie_size, sizeof(char));
521 RUNNER_ASSERT_MSG_BT(NULL != cookie, "Memory allocation error");
523 //Request cookie from SS
524 res = security_server_request_cookie(cookie, cookie_size);
525 CookieUniquePtr cookie_ptr(cookie);
527 RUNNER_ASSERT_MSG_BT(res == SECURITY_SERVER_API_SUCCESS,
528 "Error in requesting cookie from security-server. Result: " << res);
530 label_ss = security_server_get_smacklabel_cookie(cookie_ptr.get());
531 RUNNER_ASSERT_MSG_BT(label_ss != NULL, "Error in getting label by cookie");
533 std::string label(label_ss);
535 RUNNER_ASSERT_MSG_BT(label.empty(), "label_ss is not an empty string.");
543 int main(int argc, char *argv[])
545 SummaryCollector::Register();
546 return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);