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