Fix test to pass with smack_pid_have_access function.
[platform/core/test/security-tests.git] / tests / security-server-tests / security_server_tests_client_smack.cpp
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  */
4 /*
5  * @file    security_server_tests_client_smack.cpp
6  * @author  Bartlomiej Grzelewski (b.grzelewski@samsung.com)
7  * @version 1.1
8  * @brief   Test cases for security-server-client-smack.
9  */
10
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <sys/smack.h>
14 #include <sys/wait.h>
15 #include <sys/un.h>
16
17 #include <dpl/log/log.h>
18 #include <dpl/test/test_runner.h>
19 #include <dpl/test/test_runner_child.h>
20 #include "security_server_mockup.h"
21
22 #include <security-server.h>
23
24 #define ENVIRONMENT                                                  \
25 do {                                                                 \
26     const char *subject_label = "mylabel";                           \
27     RUNNER_ASSERT_MSG(-1 != system("touch /opt/home/root/pid_cycle"),\
28         "Cannot prepare environment for test.");                     \
29     RUNNER_ASSERT_MSG(0 == smack_set_label_for_self(subject_label),  \
30         "Cannot prepare environment for test.");                     \
31     RUNNER_ASSERT_MSG(-1 != setgid(1),                               \
32         "Cannot prepare environment for test.");                     \
33     RUNNER_ASSERT_MSG(-1 != setuid(1),                               \
34         "Cannot prepare environment for test");                      \
35 }while(0)
36
37 /**
38  * Dropping root privileges
39  * returns 0 on success, 1 on error
40  */
41 int drop_root_privileges()
42 {
43         if (getuid() == 0) {
44                 /* process is running as root, drop privileges */
45                 if (setgid(5000) != 0)
46                         return 1;
47                 if (setuid(5000) != 0)
48                         return 1;
49         }
50         int uid = getuid();
51         if (uid == 5000)
52                 return 0;
53
54         return 1;
55 }
56
57 RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_CLIENT_SMACK)
58
59 /*
60  * test: Check cookie size returned by security_server_get_cookie_size.
61  * description: Cookie used by security-server is 20 bytes long.
62  * Any other size of cookies should be treated as error.
63  * expected: Function security_server_get_cookie_size returns 20.
64  */
65 RUNNER_CHILD_TEST(tc01_security_server_get_cookie_size)
66 {
67     ENVIRONMENT;
68
69     int ret = security_server_get_cookie_size();
70     RUNNER_ASSERT_MSG(20 == ret, "ret = " << ret);
71 }
72
73 /*
74  * test: security_server_request_cookie
75  * description: Function security_server_request_cookie will return
76  * 20 bytes long cookie.
77  * expected: function will set up cookie in the array and return
78  * SECURITY_SERVER_API_SUCCESS.
79  */
80 RUNNER_CHILD_TEST(tc02_security_server_request_cookie_normal_case)
81 {
82     ENVIRONMENT;
83
84     char cookie[20];
85     int ret = security_server_request_cookie(cookie, 20);
86     LogDebug("ret = " << ret);
87     RUNNER_ASSERT(SECURITY_SERVER_API_SUCCESS == ret);
88 }
89
90 /*
91  * test: security_server_request_cookie
92  * description: Function security_server_request_cookie will return
93  * 20 bytes long cookie.
94  * expected: function will set up cookie in the array and return
95  * SECURITY_SERVER_API_SUCCESS.
96  */
97 RUNNER_CHILD_TEST(tc03_security_server_request_cookie_too_small_buffer_size)
98 {
99     ENVIRONMENT;
100
101     char cookie[20];
102     int ret = security_server_request_cookie(cookie, 10);
103     LogDebug("ret = " << ret);
104     RUNNER_ASSERT(SECURITY_SERVER_API_ERROR_BUFFER_TOO_SMALL == ret);
105 }
106
107 /*
108  * test: tc04_security_server_get_gid
109  * description: Checking for security_server_get_gid
110  *              with nonexisting gid and existing one
111  * expected: security_server_get_gid should return
112  *           SECURITY_SERVER_ERROR_NO_SUCH_OBJECT with first call
113  *           and group id with second call
114  */
115 RUNNER_CHILD_TEST(tc04_security_server_get_gid)
116 {
117     ENVIRONMENT;
118
119     int ret = security_server_get_gid("abc123xyz_pysiaczek");
120     LogDebug("ret = " << ret);
121     RUNNER_ASSERT_MSG(SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT == ret, "Ret: " << ret);
122     ret = security_server_get_gid("root");
123     LogDebug("ret = " << ret);
124     RUNNER_ASSERT_MSG(0 == ret, "Ret: " << ret);
125 }
126
127 /*
128  * test: tc05_check_privilege_by_cookie
129  * description: Function security_server_check_privilege_by_cookie should
130  * return status of access rights of cookie owner. In this case cookie owner
131  * is the same process that ask for the rights.
132  * expected: Function call with access rights set to "r" should return SUCCESS,
133  * with "rw" should return ACCESS DENIED.
134  */
135 RUNNER_CHILD_TEST(tc05_check_privilege_by_cookie)
136 {
137     char cookie[20];
138     const char *object_label = "tc05objectlabel";
139     const char *access_rights = "r";
140     const char *access_rights_ext = "rw";
141     const char *subject_label = "tc05subjectlabel";
142
143     smack_accesses *handle;
144
145     RUNNER_ASSERT(0 == smack_accesses_new(&handle));
146
147     RUNNER_ASSERT(0 == smack_accesses_add(handle,
148                                           subject_label,
149                                           object_label,
150                                           access_rights));
151
152     RUNNER_ASSERT(0 == smack_accesses_apply(handle));
153
154     smack_accesses_free(handle);
155
156     RUNNER_ASSERT(0 == smack_set_label_for_self(subject_label));
157
158     RUNNER_ASSERT(SECURITY_SERVER_API_SUCCESS ==
159         security_server_request_cookie(cookie,20));
160
161     RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
162
163     RUNNER_ASSERT(SECURITY_SERVER_API_SUCCESS ==
164         security_server_check_privilege_by_cookie(
165             cookie,
166             object_label,
167             access_rights));
168
169     RUNNER_ASSERT(SECURITY_SERVER_API_ERROR_ACCESS_DENIED ==
170         security_server_check_privilege_by_cookie(
171             cookie,
172             object_label,
173             access_rights_ext));
174
175 }
176
177 /*
178  * test: security_server_check_privilege_by_sockfd
179  * description: This test will create dummy server that will accept connection
180  * and die. The client will try to check access rights using connection descriptor.
181  * expected: Function call with access rights set to "r" should return SUCCESS,
182  * with "rw" should return ACCESS DENIED.
183  */
184 RUNNER_TEST(tc06_check_privilege_by_sockfd)
185 {
186
187     const char *object_label = "tc06objectlabel";
188     const char *access_rights = "r";
189     const char *access_rights_ext = "rw";
190     const char *subject_label = "tc06subjectlabel";
191
192     int result1 = -1;
193     int result2 = -1;
194
195     smack_accesses *handle;
196     RUNNER_ASSERT(0 == smack_accesses_new(&handle));
197     RUNNER_ASSERT(0 == smack_accesses_add(handle,
198                                           subject_label,
199                                           object_label,
200                                           access_rights));
201     RUNNER_ASSERT(0 == smack_accesses_apply(handle));
202     smack_accesses_free(handle);
203
204     int pid = fork();
205     char *label;
206     RUNNER_ASSERT(-1 != pid);
207
208     if (0 == pid) {
209         // child
210         if (0 != smack_set_label_for_self(subject_label)) {
211             LogDebug("child, failed");
212             exit(1);
213         }
214
215         LogDebug("child, create_new_socket");
216         int sockfd = create_new_socket();
217
218
219         label = security_server_get_smacklabel_sockfd(sockfd);
220         RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
221         RUNNER_ASSERT_MSG(strcmp(label,"")==0, "label is \""<< label<<"\"");
222         free(label);
223
224         RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
225
226         LogDebug("child, listen");
227         if (listen(sockfd, 5) < 0) {
228             LogDebug("child, exit");
229             exit(1);
230         }
231
232         label = security_server_get_smacklabel_sockfd(sockfd);
233         RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
234         RUNNER_ASSERT_MSG(strcmp(label,"")==0, "label is \""<< label<<"\"");
235         free(label);
236
237
238         LogDebug("child, accept");
239         struct sockaddr_un client_addr;
240         socklen_t client_len = sizeof(client_addr);
241         int csockfd;
242         while(0 <= (csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len))) {
243             LogDebug("child, loop");
244             close(csockfd);
245         }
246
247
248         label = security_server_get_smacklabel_sockfd(sockfd);
249         RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
250         RUNNER_ASSERT_MSG(strcmp(label,subject_label)==0, "label is \""<< label<<"\"" << "subject_label is \""<< subject_label<<"\"" );
251         free(label);
252
253         LogDebug("Exit!");
254         exit(1);
255     } else {
256         // parent
257         LogDebug("Parent, sleep 2");
258         sleep(1);
259         int sockfd = connect_to_testserver();
260
261         label = security_server_get_smacklabel_sockfd(sockfd);
262         RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
263         RUNNER_ASSERT_MSG(strcmp(label,subject_label)==0, "label is \""<< label<<"\"" << "subject_label is \""<< subject_label<<"\"" );
264         free(label);
265
266         LogDebug("Parent: sockfd: " << sockfd);
267         if (sockfd >= 0) {
268             result1 = security_server_check_privilege_by_sockfd(
269                 sockfd,
270                 object_label,
271                 access_rights);
272             result2 = security_server_check_privilege_by_sockfd(
273                 sockfd,
274                 object_label,
275                 access_rights_ext);
276         }
277         LogDebug("Parent: Close desc");
278         close(sockfd);
279         LogDebug("Parent: killing child");
280         kill(pid, SIGKILL);
281     }
282
283     int status;
284     waitpid(pid, &status, 0);
285
286     RUNNER_ASSERT_MSG(SECURITY_SERVER_API_SUCCESS == result1, "result = " << result1);
287     RUNNER_ASSERT_MSG(SECURITY_SERVER_API_ERROR_ACCESS_DENIED == result2, "result = " << result2);
288 }
289
290 /*
291  * test: security_server_check_privilege_by_sockfd
292  * description: This test will create dummy server that will accept connection
293  * and die. The client will try to check access rights using connection descriptor.
294  * Because we read a smack label not from socket directly, but from from pid of process
295  * on the other end of socket - that's why smack label will be updated.
296  * In this test client is running under root and server is not - to test the extreme case.
297  * expected: Function call with access rights set to "r" should return SUCCESS,
298  * with "rw" should return ACCESS DENIED.
299  */
300 RUNNER_TEST(tc07_check_privilege_by_sockfd)
301 {
302
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";
307
308     int result1 = -1;
309     int result2 = -1;
310     int kill_result = -1;
311
312     smack_accesses *handle;
313     RUNNER_ASSERT(0 == smack_accesses_new(&handle));
314     RUNNER_ASSERT(0 == smack_accesses_add(handle,
315                                           subject_label,
316                                           object_label,
317                                           access_rights));
318     RUNNER_ASSERT(0 == smack_accesses_apply(handle));
319     smack_accesses_free(handle);
320
321     int pid = fork();
322     RUNNER_ASSERT(-1 != pid);
323
324     if (0 == pid) {
325         // child
326         LogDebug("child, create_new_socket");
327         int sockfd = create_new_socket();
328
329         if (0 != smack_set_label_for_self(subject_label)) {
330             LogDebug("child, failed");
331             exit(1);
332         }
333
334         RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
335
336         LogDebug("child, listen");
337         if (listen(sockfd, 5) < 0) {
338             LogDebug("child, exit");
339             exit(1);
340         }
341         LogDebug("child, accept");
342
343         struct sockaddr_un client_addr;
344         socklen_t client_len = sizeof(client_addr);
345         int csockfd;
346         while(0 <= (csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len))) {
347             LogDebug("child, loop");
348             close(csockfd);
349         }
350         LogDebug("Exit!");
351         exit(1);
352     } else {
353         // parent
354
355         RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
356
357         LogDebug("Parent, sleep 2");
358         sleep(2);
359         int sockfd = connect_to_testserver();
360         LogDebug("Parent: sockfd: " << sockfd);
361         if (sockfd >= 0) {
362             result1 = security_server_check_privilege_by_sockfd(
363                 sockfd,
364                 object_label,
365                 access_rights);
366             result2 = security_server_check_privilege_by_sockfd(
367                 sockfd,
368                 object_label,
369                 access_rights_ext);
370         }
371         LogDebug("Parent: Close desc");
372         close(sockfd);
373         LogDebug("Parent: killing child");
374         // we cannot kill child - because of dropping privileges
375         kill_result = kill(pid, SIGKILL);
376     }
377
378     if (kill_result == 0) {
379         int status;
380         waitpid(pid, &status, 0);
381     }
382     else
383         sleep(2);
384
385     RUNNER_ASSERT_MSG(SECURITY_SERVER_API_SUCCESS == result1, "result1 = " << result1);
386     RUNNER_ASSERT_MSG(SECURITY_SERVER_API_ERROR_ACCESS_DENIED == result2, " result2 = " << result2);
387 }
388
389 int main(int argc, char *argv[])
390 {
391     return
392         DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
393 }