All *.c , *.h , *.cpp and *.hpp files changed by stylecheck-for-git.
[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  * test: security_server_check_privilege_by_sockfd
178  * description: This test will create dummy server that will accept connection
179  * and die. The client will try to check access rights using connection descriptor.
180  * expected: Function call with access rights set to "r" should return SUCCESS,
181  * with "rw" should return ACCESS DENIED.
182  */
183 RUNNER_TEST(tc06_check_privilege_by_sockfd)
184 {
185     const char *object_label = "tc06objectlabel";
186     const char *access_rights = "r";
187     const char *access_rights_ext = "rw";
188     const char *subject_label = "tc06subjectlabel";
189
190     int result1 = -1;
191     int result2 = -1;
192
193     smack_accesses *handle;
194     RUNNER_ASSERT(0 == smack_accesses_new(&handle));
195     RUNNER_ASSERT(0 == smack_accesses_add(handle,
196             subject_label,
197             object_label,
198             access_rights));
199     RUNNER_ASSERT(0 == smack_accesses_apply(handle));
200     smack_accesses_free(handle);
201
202     int pid = fork();
203     char *label;
204     RUNNER_ASSERT(-1 != pid);
205
206     if (0 == pid) {
207         // child
208         if (0 != smack_set_label_for_self(subject_label)) {
209             LogDebug("child, failed");
210             exit(1);
211         }
212
213         LogDebug("child, create_new_socket");
214         int sockfd = create_new_socket();
215
216
217         label = security_server_get_smacklabel_sockfd(sockfd);
218         RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
219         RUNNER_ASSERT_MSG(strcmp(label,"") == 0, "label is \"" << label << "\"");
220         free(label);
221
222         RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
223
224         LogDebug("child, listen");
225         if (listen(sockfd, 5) < 0) {
226             LogDebug("child, exit");
227             exit(1);
228         }
229
230         label = security_server_get_smacklabel_sockfd(sockfd);
231         RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
232         RUNNER_ASSERT_MSG(strcmp(label,"") == 0, "label is \"" << label << "\"");
233         free(label);
234
235
236         LogDebug("child, accept");
237         struct sockaddr_un client_addr;
238         socklen_t client_len = sizeof(client_addr);
239         int csockfd;
240         while (0 <= (csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len))) {
241             LogDebug("child, loop");
242             close(csockfd);
243         }
244
245
246         label = security_server_get_smacklabel_sockfd(sockfd);
247         RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
248         RUNNER_ASSERT_MSG(strcmp(label,subject_label) == 0, "label is \"" << label << "\"" << "subject_label is \"" << subject_label << "\"" );
249         free(label);
250
251         LogDebug("Exit!");
252         exit(1);
253     } else {
254         // parent
255         LogDebug("Parent, sleep 2");
256         sleep(1);
257         int sockfd = connect_to_testserver();
258
259         label = security_server_get_smacklabel_sockfd(sockfd);
260         RUNNER_ASSERT_MSG(label != NULL, "security_server_get_smacklabel_sockfd failed");
261         RUNNER_ASSERT_MSG(strcmp(label,subject_label) == 0, "label is \"" << label << "\"" << "subject_label is \"" << subject_label << "\"" );
262         free(label);
263
264         LogDebug("Parent: sockfd: " << sockfd);
265         if (sockfd >= 0) {
266             result1 = security_server_check_privilege_by_sockfd(
267                 sockfd,
268                 object_label,
269                 access_rights);
270             result2 = security_server_check_privilege_by_sockfd(
271                 sockfd,
272                 object_label,
273                 access_rights_ext);
274         }
275         LogDebug("Parent: Close desc");
276         close(sockfd);
277         LogDebug("Parent: killing child");
278         kill(pid, SIGKILL);
279     }
280
281     int status;
282     waitpid(pid, &status, 0);
283
284     RUNNER_ASSERT_MSG(SECURITY_SERVER_API_SUCCESS == result1, "result = " << result1);
285     RUNNER_ASSERT_MSG(SECURITY_SERVER_API_ERROR_ACCESS_DENIED == result2, "result = " << result2);
286 }
287
288 /*
289  * test: security_server_check_privilege_by_sockfd
290  * description: This test will create dummy server that will accept connection
291  * and die. The client will try to check access rights using connection descriptor.
292  * Because we read a smack label not from socket directly, but from from pid of process
293  * on the other end of socket - that's why smack label will be updated.
294  * In this test client is running under root and server is not - to test the extreme case.
295  * expected: Function call with access rights set to "r" should return SUCCESS,
296  * with "rw" should return ACCESS DENIED.
297  */
298 RUNNER_TEST(tc07_check_privilege_by_sockfd)
299 {
300     const char *object_label = "tc07objectlabel";
301     const char *access_rights = "r";
302     const char *access_rights_ext = "rw";
303     const char *subject_label = "tc07subjectlabel";
304
305     int result1 = -1;
306     int result2 = -1;
307     int kill_result = -1;
308
309     smack_accesses *handle;
310     RUNNER_ASSERT(0 == smack_accesses_new(&handle));
311     RUNNER_ASSERT(0 == smack_accesses_add(handle,
312             subject_label,
313             object_label,
314             access_rights));
315     RUNNER_ASSERT(0 == smack_accesses_apply(handle));
316     smack_accesses_free(handle);
317
318     int pid = fork();
319     RUNNER_ASSERT(-1 != pid);
320
321     if (0 == pid) {
322         // child
323         LogDebug("child, create_new_socket");
324         int sockfd = create_new_socket();
325
326         if (0 != smack_set_label_for_self(subject_label)) {
327             LogDebug("child, failed");
328             exit(1);
329         }
330
331         RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
332
333         LogDebug("child, listen");
334         if (listen(sockfd, 5) < 0) {
335             LogDebug("child, exit");
336             exit(1);
337         }
338         LogDebug("child, accept");
339
340         struct sockaddr_un client_addr;
341         socklen_t client_len = sizeof(client_addr);
342         int csockfd;
343         while (0 <= (csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len))) {
344             LogDebug("child, loop");
345             close(csockfd);
346         }
347         LogDebug("Exit!");
348         exit(1);
349     } else {
350         // parent
351
352         RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
353
354         LogDebug("Parent, sleep 2");
355         sleep(2);
356         int sockfd = connect_to_testserver();
357         LogDebug("Parent: sockfd: " << sockfd);
358         if (sockfd >= 0) {
359             result1 = security_server_check_privilege_by_sockfd(
360                 sockfd,
361                 object_label,
362                 access_rights);
363             result2 = security_server_check_privilege_by_sockfd(
364                 sockfd,
365                 object_label,
366                 access_rights_ext);
367         }
368         LogDebug("Parent: Close desc");
369         close(sockfd);
370         LogDebug("Parent: killing child");
371         // we cannot kill child - because of dropping privileges
372         kill_result = kill(pid, SIGKILL);
373     }
374
375     if (kill_result == 0) {
376         int status;
377         waitpid(pid, &status, 0);
378     }
379     else
380         sleep(2);
381
382     RUNNER_ASSERT_MSG(SECURITY_SERVER_API_SUCCESS == result1, "result1 = " << result1);
383     RUNNER_ASSERT_MSG(SECURITY_SERVER_API_ERROR_ACCESS_DENIED == result2, " result2 = " << result2);
384 }
385
386 int main(int argc, char *argv[])
387 {
388     return
389         DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
390 }