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.
12 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <sys/smack.h>
18 #include <dpl/log/log.h>
19 #include <dpl/test/test_runner.h>
20 #include <dpl/test/test_runner_child.h>
21 #include "security_server_mockup.h"
23 #include <security-server.h>
25 #include "tests_common.h"
29 const char *subject_label = "mylabel"; \
30 RUNNER_ASSERT_MSG(-1 != system("touch /opt/home/root/pid_cycle"), \
31 "Cannot prepare environment for test."); \
32 RUNNER_ASSERT_MSG(0 == smack_set_label_for_self(subject_label), \
33 "Cannot prepare environment for test."); \
34 RUNNER_ASSERT_MSG(-1 != setgid(1), \
35 "Cannot prepare environment for test."); \
36 RUNNER_ASSERT_MSG(-1 != setuid(1), \
37 "Cannot prepare environment for test"); \
41 * Dropping root privileges
42 * returns 0 on success, 1 on error
44 int drop_root_privileges()
47 /* process is running as root, drop privileges */
48 if (setgid(5000) != 0)
50 if (setuid(5000) != 0)
60 RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_CLIENT_SMACK)
63 * test: Check cookie size returned by security_server_get_cookie_size.
64 * description: Cookie used by security-server is 20 bytes long.
65 * Any other size of cookies should be treated as error.
66 * expected: Function security_server_get_cookie_size returns 20.
68 RUNNER_CHILD_TEST_SMACK(tc01_security_server_get_cookie_size)
72 int ret = security_server_get_cookie_size();
73 RUNNER_ASSERT_MSG(20 == ret, "ret = " << ret);
77 * test: security_server_request_cookie
78 * description: Function security_server_request_cookie will return
79 * 20 bytes long cookie.
80 * expected: function will set up cookie in the array and return
81 * SECURITY_SERVER_API_SUCCESS.
83 RUNNER_CHILD_TEST_SMACK(tc02_security_server_request_cookie_normal_case)
88 int ret = security_server_request_cookie(cookie, 20);
89 LogDebug("ret = " << ret);
90 RUNNER_ASSERT(SECURITY_SERVER_API_SUCCESS == ret);
94 * test: security_server_request_cookie
95 * description: Function security_server_request_cookie will return
96 * 20 bytes long cookie.
97 * expected: function will set up cookie in the array and return
98 * SECURITY_SERVER_API_SUCCESS.
100 RUNNER_CHILD_TEST_SMACK(tc03_security_server_request_cookie_too_small_buffer_size)
105 int ret = security_server_request_cookie(cookie, 10);
106 LogDebug("ret = " << ret);
107 RUNNER_ASSERT(SECURITY_SERVER_API_ERROR_BUFFER_TOO_SMALL == ret);
111 * test: tc04_security_server_get_gid
112 * description: Checking for security_server_get_gid
113 * with nonexisting gid and existing one
114 * expected: security_server_get_gid should return
115 * SECURITY_SERVER_ERROR_NO_SUCH_OBJECT with first call
116 * and group id with second call
118 RUNNER_CHILD_TEST_SMACK(tc04_security_server_get_gid)
122 int ret = security_server_get_gid("abc123xyz_pysiaczek");
123 LogDebug("ret = " << ret);
124 RUNNER_ASSERT_MSG(SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT == ret, "Ret: " << ret);
125 ret = security_server_get_gid("root");
126 LogDebug("ret = " << ret);
127 RUNNER_ASSERT_MSG(0 == ret, "Ret: " << ret);
131 * test: tc05_check_privilege_by_cookie
132 * description: Function security_server_check_privilege_by_cookie should
133 * return status of access rights of cookie owner. In this case cookie owner
134 * is the same process that ask for the rights.
135 * expected: Function call with access rights set to "r" should return SUCCESS,
136 * with "rw" should return ACCESS DENIED.
138 RUNNER_CHILD_TEST_SMACK(tc05_check_privilege_by_cookie)
141 const char *object_label = "tc05objectlabel";
142 const char *access_rights = "r";
143 const char *access_rights_ext = "rw";
144 const char *subject_label = "tc05subjectlabel";
146 smack_accesses *handle;
148 RUNNER_ASSERT(0 == smack_accesses_new(&handle));
150 RUNNER_ASSERT(0 == smack_accesses_add(handle,
155 RUNNER_ASSERT(0 == smack_accesses_apply(handle));
157 smack_accesses_free(handle);
159 RUNNER_ASSERT(0 == smack_set_label_for_self(subject_label));
161 RUNNER_ASSERT(SECURITY_SERVER_API_SUCCESS ==
162 security_server_request_cookie(cookie,20));
164 RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
166 RUNNER_ASSERT(SECURITY_SERVER_API_SUCCESS ==
167 security_server_check_privilege_by_cookie(
172 RUNNER_ASSERT(SECURITY_SERVER_API_ERROR_ACCESS_DENIED ==
173 security_server_check_privilege_by_cookie(
180 * test: security_server_check_privilege_by_sockfd
181 * description: This test will create dummy server that will accept connection
182 * and die. The client will try to check access rights using connection descriptor.
183 * expected: Function call with access rights set to "r" should return SUCCESS,
184 * with "rw" should return ACCESS DENIED.
186 RUNNER_TEST_SMACK(tc06_check_privilege_by_sockfd)
188 const char *object_label = "tc06objectlabel";
189 const char *access_rights = "r";
190 const char *access_rights_ext = "rw";
191 const char *subject_label = "tc06subjectlabel";
196 smack_accesses *handle;
197 RUNNER_ASSERT(0 == smack_accesses_new(&handle));
198 RUNNER_ASSERT(0 == smack_accesses_add(handle,
202 RUNNER_ASSERT(0 == smack_accesses_apply(handle));
203 smack_accesses_free(handle);
207 RUNNER_ASSERT(-1 != pid);
211 if (0 != smack_set_label_for_self(subject_label)) {
212 LogDebug("child, failed");
216 LogDebug("child, create_new_socket");
217 int sockfd = create_new_socket();
220 label = security_server_get_smacklabel_sockfd(sockfd);
221 RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
222 RUNNER_ASSERT_MSG(strcmp(label,"") == 0, "label is \"" << label << "\"");
225 RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
227 LogDebug("child, listen");
228 if (listen(sockfd, 5) < 0) {
229 LogDebug("child, exit");
233 label = security_server_get_smacklabel_sockfd(sockfd);
234 RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
235 RUNNER_ASSERT_MSG(strcmp(label,"") == 0, "label is \"" << label << "\"");
239 LogDebug("child, accept");
240 struct sockaddr_un client_addr;
241 socklen_t client_len = sizeof(client_addr);
243 while (0 <= (csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len))) {
244 LogDebug("child, loop");
249 label = security_server_get_smacklabel_sockfd(sockfd);
250 RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
251 RUNNER_ASSERT_MSG(strcmp(label,subject_label) == 0, "label is \"" << label << "\"" << "subject_label is \"" << subject_label << "\"" );
258 LogDebug("Parent, sleep 2");
260 int sockfd = connect_to_testserver();
262 label = security_server_get_smacklabel_sockfd(sockfd);
263 RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
264 RUNNER_ASSERT_MSG(strcmp(label,subject_label) == 0, "label is \"" << label << "\"" << "subject_label is \"" << subject_label << "\"" );
267 LogDebug("Parent: sockfd: " << sockfd);
269 result1 = security_server_check_privilege_by_sockfd(
273 result2 = security_server_check_privilege_by_sockfd(
278 LogDebug("Parent: Close desc");
280 LogDebug("Parent: killing child");
285 waitpid(pid, &status, 0);
287 RUNNER_ASSERT_MSG(SECURITY_SERVER_API_SUCCESS == result1, "result = " << result1);
288 RUNNER_ASSERT_MSG(SECURITY_SERVER_API_ERROR_ACCESS_DENIED == result2, "result = " << result2);
292 * test: security_server_check_privilege_by_sockfd
293 * description: This test will create dummy server that will accept connection
294 * and die. The client will try to check access rights using connection descriptor.
295 * Because we read a smack label not from socket directly, but from from pid of process
296 * on the other end of socket - that's why smack label will be updated.
297 * In this test client is running under root and server is not - to test the extreme case.
298 * expected: Function call with access rights set to "r" should return SUCCESS,
299 * with "rw" should return ACCESS DENIED.
301 RUNNER_TEST_SMACK(tc07_check_privilege_by_sockfd)
303 const char *object_label = "tc07objectlabel";
304 const char *access_rights = "r";
305 const char *access_rights_ext = "rw";
306 const char *subject_label = "tc07subjectlabel";
310 int kill_result = -1;
312 smack_accesses *handle;
313 RUNNER_ASSERT(0 == smack_accesses_new(&handle));
314 RUNNER_ASSERT(0 == smack_accesses_add(handle,
318 RUNNER_ASSERT(0 == smack_accesses_apply(handle));
319 smack_accesses_free(handle);
322 RUNNER_ASSERT(-1 != pid);
326 LogDebug("child, create_new_socket");
327 int sockfd = create_new_socket();
329 if (0 != smack_set_label_for_self(subject_label)) {
330 LogDebug("child, failed");
334 RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
336 LogDebug("child, listen");
337 if (listen(sockfd, 5) < 0) {
338 LogDebug("child, exit");
341 LogDebug("child, accept");
343 struct sockaddr_un client_addr;
344 socklen_t client_len = sizeof(client_addr);
346 while (0 <= (csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len))) {
347 LogDebug("child, loop");
355 RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
357 LogDebug("Parent, sleep 2");
359 int sockfd = connect_to_testserver();
360 LogDebug("Parent: sockfd: " << sockfd);
362 result1 = security_server_check_privilege_by_sockfd(
366 result2 = security_server_check_privilege_by_sockfd(
371 LogDebug("Parent: Close desc");
373 LogDebug("Parent: killing child");
374 // we cannot kill child - because of dropping privileges
375 kill_result = kill(pid, SIGKILL);
378 if (kill_result == 0) {
380 waitpid(pid, &status, 0);
385 RUNNER_ASSERT_MSG(SECURITY_SERVER_API_SUCCESS == result1, "result1 = " << result1);
386 RUNNER_ASSERT_MSG(SECURITY_SERVER_API_ERROR_ACCESS_DENIED == result2, " result2 = " << result2);
389 int main(int argc, char *argv[])
392 DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);