security-server tests on DPL framework
[platform/core/test/security-tests.git] / tests / security-server-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 "security-server.h"
24 #include <dpl/test/test_runner.h>
25 #include <dlog.h>
26 #include "test.h"
27
28 #define SECURITY_SERVER_SOCK_PATH    "/tmp/.security_server.sock"
29
30 /* Message */
31 typedef struct
32 {
33     unsigned char version;
34     unsigned char msg_id;
35     unsigned short msg_len;
36 } basic_header;
37
38 typedef struct
39 {
40     basic_header basic_hdr;
41     unsigned char return_code;
42 } response_header;
43
44 int server_sockfd, client_sockfd, ret, recved_gid, client_len, i;
45 unsigned char cookie[20], recved_cookie[20], recvbuf[33], wrong_cookie[20];
46 char obj_name[30];
47 struct pollfd accept_poll[1], client_poll[1];
48 struct sockaddr_un clientaddr;
49 int olen, alen;
50 char olabel[1024];
51 char arights[32];
52
53 /* Create a Unix domain socket and bind */
54 int create_new_socket()
55 {
56     int localsockfd = 0, flags;
57     int tmp;
58     struct sockaddr_un serveraddr;
59     mode_t sock_mode;
60
61     tmp = remove(SECURITY_SERVER_TEST_SOCK_PATH);
62
63     if (tmp == -1) {
64         localsockfd = -1;
65         LOGE("%s\n", "Unable to remove /tmp/.security_server.sock");
66         goto error;
67     }
68
69     /* Create Unix domain socket */
70     if((localsockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 )
71     {
72         localsockfd = -1;
73         LOGE("%s\n", "Socket creation failed");
74         goto error;
75     }
76
77     /* Make socket as non blocking */
78     if((flags = fcntl(localsockfd, F_GETFL, 0)) < 0 ||
79             fcntl(localsockfd, F_SETFL, flags | O_NONBLOCK) < 0)
80     {
81         close(localsockfd);
82         localsockfd = -1;
83         LOGE("%s\n", "Cannot go to nonblocking mode");
84         goto error;
85     }
86
87     bzero (&serveraddr, sizeof(serveraddr));
88     serveraddr.sun_family = AF_UNIX;
89     strncpy(serveraddr.sun_path, SECURITY_SERVER_TEST_SOCK_PATH,
90             strlen(SECURITY_SERVER_TEST_SOCK_PATH) + 1);
91
92     /* Bind the socket */
93     if((bind(localsockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0)
94     {
95         LOGE("%s\n", "Cannot bind");
96         close(localsockfd);
97         localsockfd = -1;
98         goto error;
99     }
100
101     /* Change permission to accept all processes that has different uID/gID */
102     sock_mode = (S_IRWXU | S_IRWXG | S_IRWXO);
103     /* Flawfinder hits this chmod function as level 5 CRITICAL as race condition flaw *
104     * Flawfinder recommends to user fchmod insted of chmod
105     * But, fchmod doesn't work on socket file so there is no other choice at this point */
106     if(chmod(SECURITY_SERVER_TEST_SOCK_PATH, sock_mode) < 0)        /* Flawfinder: ignore */
107     {
108         LOGE("%s\n", "chmod() error");
109         close(localsockfd);
110         localsockfd = -1;
111         goto error;
112     }
113 error:
114     return localsockfd;
115 }
116
117 int check_socket_poll(int sockfd, int event, int timeout)
118 {
119     struct pollfd poll_fd[1];
120     int retval;
121
122     poll_fd[0].fd = sockfd;
123     poll_fd[0].events = event;
124     retval = poll(poll_fd, 1, timeout);
125     if(retval < 0)
126     {
127         LOGE("%s\n", "poll() error");
128         return -1;
129     }
130
131     /* Timed out */
132     if(retval == 0)
133     {
134         LOGE("%s", "poll() timeout");
135         return 0;
136     }
137     return 1;
138 }
139
140 int send_gid_request(int sock_fd, const char* object)
141 {
142     basic_header hdr;
143     int retval, send_len = 0;
144     unsigned char *buf = NULL;
145
146     hdr.version = 0x01; /* SECURITY_SERVER_MSG_VERSION; */
147     hdr.msg_id = 0x07; /* SECURITY_SERVER_MSG_TYPE_GID_REQUEST; */
148     hdr.msg_len = strlen(object);
149
150     send_len = sizeof(hdr) + strlen(object);
151
152     buf = (unsigned char *) malloc(send_len);
153     if(buf == NULL)
154     {
155         LOGE("%s\n", "out of memory");
156         return -1;
157     }
158
159     memcpy(buf, &hdr, sizeof(hdr));
160     memcpy(buf + sizeof(hdr), object, strlen(object));
161
162     /* Check poll */
163     retval = check_socket_poll(sock_fd, POLLOUT, 1000);
164     if(retval == -1)
165     {
166         LOGE("%s\n", "poll() error");
167         if(buf != NULL)
168             free(buf);
169         return -1;
170     }
171     if(retval == 0)
172     {
173         LOGE("%s\n", "poll() timeout");
174         if(buf != NULL)
175             free(buf);
176         return -1;
177     }
178
179     retval = write(sock_fd, buf, send_len);
180     if(retval < send_len)
181     {
182         /* Write error */
183         LOGE("Error on write(): %d. errno=%d, sockfd=%d\n", retval, errno, sock_fd);
184         if(buf != NULL)
185             free(buf);
186         return -1;
187     }
188     if(buf != NULL)
189         free(buf);
190
191     return 0;
192 }
193
194 int connect_to_server(int *fd)
195 {
196     struct sockaddr_un clientaddr;
197     int client_len = 0, localsockfd, ret, flags;
198     *fd = -1;
199
200     /* Create a socket */
201     localsockfd = socket(AF_UNIX, SOCK_STREAM, 0);
202     if(localsockfd < 0)
203     {
204         LOGE("%s\n", "Error on socket()");
205         return -1;
206     }
207
208     /* Make socket as non blocking */
209     if((flags = fcntl(localsockfd, F_GETFL, 0)) < 0 ||
210             fcntl(localsockfd, F_SETFL, flags | O_NONBLOCK) < 0)
211     {
212         close(localsockfd);
213         LOGE("%s\n", "Cannot go to nonblocking mode");
214         return -1;
215     }
216
217     bzero(&clientaddr, sizeof(clientaddr));
218     clientaddr.sun_family = AF_UNIX;
219     strncpy(clientaddr.sun_path, SECURITY_SERVER_SOCK_PATH, strlen(SECURITY_SERVER_SOCK_PATH));
220     clientaddr.sun_path[strlen(SECURITY_SERVER_SOCK_PATH)] = 0;
221     client_len = sizeof(clientaddr);
222
223     ret = connect(localsockfd, (struct sockaddr*)&clientaddr, client_len);
224     if( ret < 0)
225     {
226         if(errno == EINPROGRESS)
227         {
228             LOGD("%s\n", "Connection is in progress");
229             check_socket_poll(localsockfd, POLLOUT, 1000);
230             if(ret == -1)
231             {
232                 LOGE("%s\n", "poll() error");
233                 close(localsockfd);
234                 return -1;
235             }
236             ret = connect(localsockfd, (struct sockaddr*)&clientaddr, client_len);
237             if(ret < 0)
238             {
239                 LOGE("%s\n", "connection failed");
240                 close(localsockfd);
241                 return -1;
242             }
243         }
244         else
245         {
246             LOGE("%s\n", "Connection failed");
247             close(localsockfd);
248             return -1;
249         }
250     }
251
252     *fd = localsockfd;
253     return 0;
254 }
255
256
257 int fake_get_gid(const char *object)
258 {
259     int sockfd = -1, retval, gid;
260     response_header hdr;
261
262     retval = connect_to_server(&sockfd);
263     if(retval != 0)
264     {
265         /* Error on socket */
266         LOGE("Connection failed: %d\n", retval);
267         goto error;
268     }
269
270     /* make request packet and send to server*/
271     retval = send_gid_request(sockfd, object);
272     if(retval != 0)
273     {
274         /* Error on socket */
275         LOGE("Send request failed: %d\n", retval);
276         goto error;
277     }
278     LOGD("%s", "Just closing the socket and exit\n");
279
280 error:
281     if(sockfd > 0)
282         close(sockfd);
283
284     return 0;
285 }
286
287 RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_SERVER);
288
289 RUNNER_TEST(tc_getting_default_cookie)
290 {
291     printhex(cookie, 20);
292     RUNNER_ASSERT(security_server_request_cookie((char *)cookie, 20) == SECURITY_SERVER_API_SUCCESS);
293 }
294
295 RUNNER_TEST(tc_security_server_get_gid_normal_case_trying_to_get_gid_of_tel_gprs)
296 {
297     RUNNER_ASSERT(security_server_get_gid("tel_gprs") >= 0);
298 }
299
300 RUNNER_TEST(tc_security_server_get_gid_empty_object_name)
301 {
302     RUNNER_ASSERT(security_server_get_gid("") == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
303 }
304
305 RUNNER_TEST(tc_security_server_get_gid_wrong_object_name_teltel)
306 {
307     RUNNER_ASSERT(security_server_get_gid("teltel") == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT);
308 }
309
310 RUNNER_TEST(tc_security_server_get_object_name_normal_case_trying_6001)
311 {
312     ret = security_server_get_object_name(6001, obj_name, sizeof(obj_name));
313     LOGD("Result: %s\n", obj_name);
314     RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
315 }
316
317 RUNNER_TEST(tc_security_server_get_object_name_too_small_buffer_size)
318 {
319     ret = security_server_get_object_name(6001, obj_name, 5);
320     RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_BUFFER_TOO_SMALL);
321 }
322
323 RUNNER_TEST(tc_security_server_get_object_name_invalid_gid)
324 {
325     ret = security_server_get_object_name(9876, obj_name, sizeof(obj_name));
326     RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT);
327 }
328
329 RUNNER_TEST(tc_ask_for_priviege_with_default_cookie_normal_case_to_check_audio_privilege)
330 {
331     ret = security_server_get_gid("audio");
332     ret = security_server_check_privilege((char *) cookie, ret);
333     RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
334 }
335
336 RUNNER_TEST(tc_ask_for_priviege_with_default_cookie_case_with_wrong_cookie)
337 {
338     ret = security_server_get_gid("audio");
339     srand(time(NULL));
340     for(i=0;i<20;i++)
341         wrong_cookie[i] = rand() % 255;
342     ret = security_server_check_privilege((const char *) wrong_cookie, ret);
343     RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED);
344 }
345
346 RUNNER_TEST(tc_fake_security_server_get_gid)
347 {
348     /* Close socket just after sending request msg.
349      * This is done with fake security_server_get_gid()*/
350     ret = fake_get_gid("audio");
351     RUNNER_IGNORED_MSG("Watch whether security server has crashed or not.");
352 }
353
354 RUNNER_TEST(tc_get_pid_of_a_given_cookie_default_cookie_case)
355 {
356     RUNNER_ASSERT(security_server_get_cookie_pid((const char *) cookie) == 0);
357 }
358
359 RUNNER_TEST(tc_get_pid_of_non_existing_cookie)
360 {
361     RUNNER_ASSERT(security_server_get_cookie_pid((const char *) wrong_cookie)== SECURITY_SERVER_API_ERROR_NO_SUCH_COOKIE);
362 }
363
364 RUNNER_TEST(tc_get_pid_of_null_cookie)
365 {
366     RUNNER_ASSERT(security_server_get_cookie_pid(NULL) == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
367 }
368
369 RUNNER_TEST(tc_communicating_with_client_and_test_cookie_and_privilege_control)
370 {
371     server_sockfd = create_new_socket();
372     RUNNER_ASSERT_MSG(server_sockfd >= 1,"Error on creating a new socket");
373     RUNNER_ASSERT_MSG(listen(server_sockfd, 5) >= 0, "listen() failed");
374
375     while(1)
376     {
377         accept_poll[0].fd = server_sockfd;
378         accept_poll[0].events = POLLIN;
379         ret = poll(accept_poll, 1, 5000);
380
381         /* Call poll() to wait for socket connection */
382         ret = poll(accept_poll, 1, 5000);
383         RUNNER_ASSERT(ret > 0);
384         if(ret == 0)
385         {
386             continue;
387         }
388
389         errno = 0;
390         client_len = sizeof(clientaddr);
391         client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr,
392                 (socklen_t *) &client_len);
393         RUNNER_ASSERT_MSG(client_sockfd >= 0, "Cannot accept client");
394
395         LOGD("New session accepted\n");
396
397         /* Wait until packet received */
398         client_poll[0].fd = client_sockfd;
399         client_poll[0].events = POLLIN;
400
401         /* Poll here */
402         ret = poll(client_poll, 1, 500);
403         RUNNER_ASSERT(ret > 0); /* poll() error */
404         if(ret == 0)
405         {
406             close(client_sockfd);
407             client_sockfd = 0;
408             LOGD("%s\n", "No request from client. closing socket");
409             continue;
410         }
411
412         ret = read(client_sockfd, recvbuf, 4);
413         if(recvbuf[0] == 0 && recvbuf[1] == 0 && recvbuf[2] == 0 && recvbuf[3] == 0)
414         {
415             ret = read(client_sockfd, recvbuf, 24);
416             if(ret < 24)
417             {
418                 close(client_sockfd);
419                 LOGD("cannot read request:%d\n", ret);
420                 close(client_sockfd);
421                 continue;
422             }
423
424             memcpy(recved_cookie, recvbuf, 20);
425             memcpy(&recved_gid, recvbuf+20, sizeof(int));
426
427             LOGD("requested cookie: \n");
428             printhex(recved_cookie, 20);
429             LOGD("requested gid: %d\n", recved_gid);
430
431             ret = security_server_check_privilege((const char *) recved_cookie, recved_gid);
432             RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS ||
433                     ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED); /* Unexpected error occurred */
434
435             LOGD("Privilege for the request: %d\n", ret);
436
437             RUNNER_ASSERT(write(client_sockfd, &ret, sizeof(int)) >= sizeof(int)); /* Send error */
438
439             ret = security_server_get_cookie_pid((const char *) recved_cookie);
440             RUNNER_ASSERT(ret > 0); /* Unexpected error occurred */
441             if(ret == 0)
442             {
443                 LOGD("client is root process\n");
444             }
445             else
446             {
447                 LOGD("Peer PID is %d\n", ret);
448             }
449         }
450         else if(recvbuf[0] == 255 && recvbuf[1] == 255 && recvbuf[2] == 255 && recvbuf[3] == 255)
451         {
452             char *myargv[5] = {NULL};
453             int i, cnt;
454             ret = read(client_sockfd, recvbuf, 28);
455             if(ret < 28)
456             {
457                 close(client_sockfd);
458                 LOGD("cannot read request:%d\n", ret);
459                 close(client_sockfd);
460                 continue;
461             }
462
463             memcpy(recved_cookie, recvbuf, 20);
464             memcpy(&recved_gid, recvbuf + 20, sizeof(int));
465             memcpy(&cnt, recvbuf + 24, sizeof(int));
466
467             if(fork() == 0)
468             {
469                 myargv[0] = (char *) malloc(strlen("/opt/home/root/security_server_tc_pid_reuser") + 1);
470                 sprintf(myargv[0], "/opt/home/root/security_server_tc_pid_reuser");
471                 myargv[1] = (char *) malloc(6);
472                 sprintf(myargv[1], "%d", cnt);
473                 myargv[2] = (char *) malloc(6);
474                 sprintf(myargv[2], "%d", recved_gid);
475                 myargv[3] = (char *) malloc(40);
476                 myargv[4] = NULL;
477                 for(i=0, cnt=0;i<20;i++)
478                 {
479                     if(recved_cookie[i] < 0x10)
480                         sprintf(myargv[3] + cnt, "0%x", recved_cookie[i]);
481                     else
482                         sprintf(myargv[3] + cnt, "%x", recved_cookie[i]);
483                     cnt += 2;
484                 }
485                 LOGD("argv[0]=%s, argv[1]=%s, argv[2]=%s, argv[3]=%s\n", myargv[0], myargv[1], myargv[2], myargv[3]);
486                 ret = execve("/opt/home/root/security_server_tc_pid_reuser", myargv, NULL);
487                 LOGD("execve failed. errno=%d\n", errno);
488
489                 if(myargv[0] != NULL)
490                     free(myargv[0]);
491                 if(myargv[1] != NULL)
492                     free(myargv[1]);
493                 if(myargv[2] != NULL)
494                     free(myargv[2]);
495                 if(myargv[3] != NULL)
496                     free(myargv[3]);
497             }
498         }
499         else if(recvbuf[0] == 17 )
500         {
501             if (recvbuf[3] == 0)
502             {
503                 ret = read(client_sockfd, recvbuf, 20);
504                 if(ret < 20)
505                 {
506                     close(client_sockfd);
507                     LOGD("cannot read request:%d\n", ret);
508                     close(client_sockfd);
509                     continue;
510                 }
511                 memcpy(recved_cookie, recvbuf, 20);
512                 ret = read(client_sockfd, &olen, 4);
513                 if(ret < 4)
514                 {
515                     close(client_sockfd);
516                     LOGD("cannot read request:%d\n", ret);
517                     close(client_sockfd);
518                     continue;
519                 }
520                 ret = read(client_sockfd, &alen, 4);
521                 if(ret < 4)
522                 {
523                     close(client_sockfd);
524                     LOGD("cannot read request:%d\n", ret);
525                     close(client_sockfd);
526                     continue;
527                 }
528                 ret = read(client_sockfd, olabel, olen);
529                 if(ret < olen)
530                 {
531                     close(client_sockfd);
532                     LOGD("cannot read request:%d\n", ret);
533                     close(client_sockfd);
534                     continue;
535                 }
536                 olabel[olen] = '\0';
537                 ret = read(client_sockfd, arights, alen);
538                 if(ret < alen)
539                 {
540                     close(client_sockfd);
541                     LOGD("cannot read request:%d\n", ret);
542                     close(client_sockfd);
543                     continue;
544                 }
545                 arights[alen] = '\0';
546                 LOGD("Check by cookie requested.\n");
547                 LOGD("requested cookie: \n");
548                 printhex(recved_cookie, 20);
549                 LOGD("olen: %d\n", olen);
550                 LOGD("object label: >%s<\n", olabel);
551                 LOGD("alen: %d\n", alen);
552                 LOGD("access rights: >%s<\n", arights);
553
554                 ret = security_server_check_privilege_by_cookie(
555                         (const char *) recved_cookie, olabel, arights);
556
557                 LOGD("return: %d\n", ret);
558
559                 RUNNER_ASSERT(write(client_sockfd, &ret, sizeof(int)) >= sizeof(int));
560             }
561             else if (recvbuf[3] == 1)
562             {
563                 ret = read(client_sockfd, &olen, 4);
564                 if(ret < 4)
565                 {
566                     close(client_sockfd);
567                     LOGD("cannot read request:%d\n", ret);
568                     close(client_sockfd);
569                     continue;
570                 }
571                 ret = read(client_sockfd, &alen, 4);
572                 if(ret < 4)
573                 {
574                     close(client_sockfd);
575                     LOGD("cannot read request:%d\n", ret);
576                     close(client_sockfd);
577                     continue;
578                 }
579                 ret = read(client_sockfd, olabel, olen);
580                 if(ret < olen)
581                 {
582                     close(client_sockfd);
583                     LOGD("cannot read request:%d\n", ret);
584                     close(client_sockfd);
585                     continue;
586                 }
587                 olabel[olen] = '\0';
588                 ret = read(client_sockfd, arights, alen);
589                 if(ret < alen)
590                 {
591                     close(client_sockfd);
592                     LOGD("cannot read request:%d\n", ret);
593                     close(client_sockfd);
594                     continue;
595                 }
596                 arights[alen] = '\0';
597                 LOGD("Check by sockfd requested.\n");
598                 LOGD("olen: %d\n", olen);
599                 LOGD("object label: >%s<\n", olabel);
600                 LOGD("alen: %d\n", alen);
601                 LOGD("access rights: >%s<\n", arights);
602
603                 ret = security_server_check_privilege_by_sockfd(
604                         client_sockfd, olabel, arights);
605
606                 RUNNER_ASSERT(write(client_sockfd, &ret, sizeof(int)) >= sizeof(int));
607             } else {
608                 LOGE("malformed request. %d, %d, %d, %d\n", recvbuf[0], recvbuf[1],  recvbuf[2], recvbuf[3]);
609                 RUNNER_ASSERT_MSG(false, "malformed request");
610             }
611         }
612         else
613         {
614             LOGE("malformed request. %d, %d, %d, %d\n", recvbuf[0], recvbuf[1], recvbuf[2], recvbuf[3]);
615             RUNNER_ASSERT_MSG(false, "malfiormed request");
616         }
617         if(client_sockfd > 0)
618         {
619             close(client_sockfd);
620         }
621     }
622 }
623
624 int main(int argc, char *argv[])
625 {
626     server_sockfd = -1;
627
628     ret = getuid();
629     if(ret != 0)
630     {
631         printf("Error: %s must be executed by root\n", argv[0]);
632         exit(1);
633     }
634
635     int status =
636         DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
637
638     if(server_sockfd > 0)
639         close(server_sockfd);
640     if(client_sockfd > 0)
641         close(client_sockfd);
642
643     return status;
644 }