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>
24 #include "security-server.h"
25 #include <dpl/test/test_runner.h>
26 #include <dpl/test/test_runner_child.h>
30 #define SECURITY_SERVER_SOCK_PATH "/tmp/.security_server.sock"
31 #define COOKIE_SIZE 20
32 #define OBJ_NAME_SIZE 30
33 #define OLABEL_SIZE 1024
34 #define ARIGHTS_SIZE 32
40 unsigned char version;
42 unsigned short msg_len;
47 basic_header basic_hdr;
48 unsigned char return_code;
51 int server_sockfd, client_sockfd, ret, recved_gid, client_len, i;
52 unsigned char cookie[COOKIE_SIZE], wrong_cookie[COOKIE_SIZE];
53 char obj_name[OBJ_NAME_SIZE];
54 struct sockaddr_un clientaddr;
56 /* Create a Unix domain socket and bind */
57 int create_new_socket()
59 int localsockfd = 0, flags;
60 struct sockaddr_un serveraddr;
63 if (unlink(SECURITY_SERVER_TEST_SOCK_PATH) == -1 && errno != ENOENT) {
64 LOGE("%s : %s\n", "unlink()", strerror(errno));
68 /* Create Unix domain socket */
69 if((localsockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
71 LOGE("%s : %s\n", "socket()", strerror(errno));
75 /* Make socket as non blocking */
76 if((flags = fcntl(localsockfd, F_GETFL, 0)) < 0 ||
77 fcntl(localsockfd, F_SETFL, flags | O_NONBLOCK) < 0)
79 LOGE("%s : %s\n", "fcntl()", strerror(errno));
83 bzero (&serveraddr, sizeof(serveraddr));
84 serveraddr.sun_family = AF_UNIX;
85 strncpy(serveraddr.sun_path, SECURITY_SERVER_TEST_SOCK_PATH,
86 strlen(SECURITY_SERVER_TEST_SOCK_PATH) + 1);
89 if((bind(localsockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0)
91 LOGE("%s : %s\n", "bind()", strerror(errno));
95 /* Change permission to accept all processes that has different uID/gID */
96 sock_mode = (S_IRWXU | S_IRWXG | S_IRWXO);
97 /* Flawfinder hits this chmod function as level 5 CRITICAL as race condition flaw *
98 * Flawfinder recommends to user fchmod insted of chmod
99 * But, fchmod doesn't work on socket file so there is no other choice at this point */
100 if(chmod(SECURITY_SERVER_TEST_SOCK_PATH, sock_mode) < 0) /* Flawfinder: ignore */
102 LOGE("%s : %s\n", "chmod()", strerror(errno));
114 int check_socket_poll(int sockfd, int event, int timeout)
116 struct pollfd poll_fd[1];
119 poll_fd[0].fd = sockfd;
120 poll_fd[0].events = event;
121 retval = poll(poll_fd, 1, timeout);
124 LOGE("%s : %s\n", "poll()", strerror(errno));
131 LOGE("%s", "poll() timeout");
137 int send_gid_request(int sock_fd, const char* object)
140 int retval, send_len = 0;
141 unsigned char *buf = NULL;
143 hdr.version = 0x01; /* SECURITY_SERVER_MSG_VERSION; */
144 hdr.msg_id = 0x07; /* SECURITY_SERVER_MSG_TYPE_GID_REQUEST; */
145 hdr.msg_len = strlen(object);
147 send_len = sizeof(hdr) + strlen(object);
149 buf = (unsigned char *) malloc(send_len);
152 LOGE("%s\n", "out of memory");
156 memcpy(buf, &hdr, sizeof(hdr));
157 memcpy(buf + sizeof(hdr), object, strlen(object));
160 retval = check_socket_poll(sock_fd, POLLOUT, 1000);
163 LOGE("%s\n", "poll() error");
170 LOGE("%s\n", "poll() timeout");
176 retval = write(sock_fd, buf, send_len);
177 if(retval < send_len)
180 LOGE("Error on write(): %d. errno=%d, sockfd=%d\n", retval, errno, sock_fd);
191 int connect_to_server(int *fd)
193 struct sockaddr_un clientaddr;
194 int client_len = 0, localsockfd, ret, flags;
197 /* Create a socket */
198 localsockfd = socket(AF_UNIX, SOCK_STREAM, 0);
201 LOGE("%s : %s\n", "socket()", strerror(errno));
205 /* Make socket as non blocking */
206 if((flags = fcntl(localsockfd, F_GETFL, 0)) < 0 ||
207 fcntl(localsockfd, F_SETFL, flags | O_NONBLOCK) < 0)
210 LOGE("%s : %s\n", "fcntl()", strerror(errno));
214 bzero(&clientaddr, sizeof(clientaddr));
215 clientaddr.sun_family = AF_UNIX;
216 strncpy(clientaddr.sun_path, SECURITY_SERVER_SOCK_PATH, strlen(SECURITY_SERVER_SOCK_PATH));
217 clientaddr.sun_path[strlen(SECURITY_SERVER_SOCK_PATH)] = 0;
218 client_len = sizeof(clientaddr);
220 ret = connect(localsockfd, (struct sockaddr*)&clientaddr, client_len);
223 if(errno == EINPROGRESS)
225 LOGD("%s\n", "Connection is in progress");
226 check_socket_poll(localsockfd, POLLOUT, 1000);
229 LOGE("%s\n", "poll() error");
233 ret = connect(localsockfd, (struct sockaddr*)&clientaddr, client_len);
236 LOGE("%s\n", "connection failed");
243 LOGE("%s\n", "Connection failed");
254 int fake_get_gid(const char *object)
256 int sockfd = -1, retval, gid;
259 retval = connect_to_server(&sockfd);
262 /* Error on socket */
263 LOGE("Connection failed: %d\n", retval);
267 /* make request packet and send to server*/
268 retval = send_gid_request(sockfd, object);
271 /* Error on socket */
272 LOGE("Send request failed: %d\n", retval);
275 LOGD("%s", "Just closing the socket and exit\n");
284 RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_SERVER);
286 RUNNER_TEST(tc_getting_default_cookie)
288 printhex(cookie, COOKIE_SIZE);
289 RUNNER_ASSERT(security_server_request_cookie((char *)cookie, 20) == SECURITY_SERVER_API_SUCCESS);
292 RUNNER_TEST(tc_security_server_get_gid_normal_case_trying_to_get_gid_of_tel_gprs)
294 RUNNER_ASSERT(security_server_get_gid("tel_gprs") >= 0);
297 RUNNER_TEST(tc_security_server_get_gid_empty_object_name)
299 RUNNER_ASSERT(security_server_get_gid("") == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
302 RUNNER_TEST(tc_security_server_get_gid_wrong_object_name_teltel)
304 RUNNER_ASSERT(security_server_get_gid("teltel") == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT);
307 RUNNER_TEST(tc_security_server_get_object_name_normal_case_trying_6001)
309 ret = security_server_get_object_name(6001, obj_name, sizeof(obj_name));
310 LOGD("Result: %s\n", obj_name);
311 RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
314 RUNNER_TEST(tc_security_server_get_object_name_too_small_buffer_size)
316 ret = security_server_get_object_name(6001, obj_name, 5);
317 RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_BUFFER_TOO_SMALL);
320 RUNNER_TEST(tc_security_server_get_object_name_invalid_gid)
322 ret = security_server_get_object_name(9876, obj_name, sizeof(obj_name));
323 RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT);
326 RUNNER_TEST(tc_ask_for_privilege_with_default_cookie_normal_case_to_check_audio_privilege)
328 printhex(cookie, COOKIE_SIZE);
329 RUNNER_ASSERT(security_server_request_cookie((char *)cookie, COOKIE_SIZE) == SECURITY_SERVER_API_SUCCESS);
330 ret = security_server_get_gid("audio");
331 ret = security_server_check_privilege((char *) cookie, ret);
332 RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
335 RUNNER_TEST(tc_ask_for_privilege_with_default_cookie_case_with_wrong_cookie)
337 ret = security_server_get_gid("audio");
339 for(i=0; i<COOKIE_SIZE; i++)
340 wrong_cookie[i] = rand() % 255;
341 ret = security_server_check_privilege((const char *) wrong_cookie, ret);
342 RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED);
346 RUNNER_TEST(tc_fake_security_server_get_gid)
349 /* Close socket just after sending request msg.
350 * This is done with fake security_server_get_gid()*/
352 ret = fake_get_gid("audio");
353 RUNNER_IGNORED_MSG("Watch whether security server has crashed or not.");
356 RUNNER_TEST(tc_get_pid_of_a_given_cookie_default_cookie_case)
358 RUNNER_ASSERT(security_server_get_cookie_pid((const char *) cookie) == getpid());
361 RUNNER_TEST(tc_get_pid_of_non_existing_cookie)
363 RUNNER_ASSERT(security_server_get_cookie_pid((const char *) wrong_cookie)== SECURITY_SERVER_API_ERROR_NO_SUCH_COOKIE);
366 RUNNER_TEST(tc_get_pid_of_null_cookie)
368 RUNNER_ASSERT(security_server_get_cookie_pid(NULL) == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
371 RUNNER_CHILD_TEST(tc01a_security_server_app_give_access)
373 const char *subject = "abc345v34sfa";
374 const char *object = "efg678x2lkjz";
375 smack_accesses *tmp = NULL;
377 RUNNER_ASSERT(0 == smack_accesses_new(&tmp));
379 std::unique_ptr<smack_accesses,std::function<void(smack_accesses*)>>
380 smack(tmp, smack_accesses_free);
382 RUNNER_ASSERT(0 == smack_accesses_add(smack.get(), subject, object, "-----"));
383 RUNNER_ASSERT(0 == smack_accesses_apply(smack.get()));
385 smack_set_label_for_self(object);
386 security_server_app_give_access(subject, getpid());
388 RUNNER_ASSERT(1 == smack_have_access(subject, object, "rwxat"));
391 RUNNER_TEST(tc01b_security_server_app_give_access)
393 const char *subject = "abc345v34sfa";
394 const char *object = "efg678x2lkjz";
396 // After part A thread from security-server will be notified about
397 // process end and revoke permissions. We need to give him some
401 RUNNER_ASSERT(0 == smack_have_access(subject, object, "r----"));
402 RUNNER_ASSERT(0 == smack_have_access(subject, object, "-w---"));
403 RUNNER_ASSERT(0 == smack_have_access(subject, object, "--x--"));
404 RUNNER_ASSERT(0 == smack_have_access(subject, object, "---a-"));
405 RUNNER_ASSERT(0 == smack_have_access(subject, object, "----t"));
408 int main(int argc, char *argv[])
415 printf("Error: %s must be executed by root\n", argv[0]);
420 DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
422 if(server_sockfd > 0)
423 close(server_sockfd);
424 if(client_sockfd > 0)
425 close(client_sockfd);