Fixing libsmack tests.
[platform/core/test/security-tests.git] / tests / libsmack-tests / test_cases.cpp
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 /*
18  * @file        test_cases.cpp
19  * @author      Pawel Polawski (p.polawski@samsung.com)
20  * @author      Jan Olszak (j.olszak@samsung.com)
21  * @version     1.0
22  * @brief       libprivilege test runer
23  */
24
25 #include <string>
26 #include <sstream>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <dpl/test/test_runner.h>
30 #include <dpl/test/test_runner_multiprocess.h>
31 #include <dpl/log/log.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/mman.h>
35 #include <sys/smack.h>
36 #include <sys/xattr.h>
37 #include <sys/socket.h>
38 #include <sys/un.h>
39 #include <sys/file.h>
40 #include <sys/wait.h>
41 #include "tests_common.h"
42 #include <access_provider.h>
43
44 #define TEST_SUBJECT  "test_subject"
45 #define TEST_OBJECT   "test_oject"
46 #define TEST_OBJECT_2 "test_oject_2"
47
48 #define SOCK_PATH "/tmp/test-smack-socket"
49
50 std::string testDir = "/opt/home/app/";
51 std::vector<std::string> accessesBasic = { "r", "w", "x", "wx", "rx", "rw", "rwx", "rwxat" };
52
53 int files_compare(int fd1, int fd2)
54 {
55     int result = 0;
56
57     //for getting files sizes
58     struct stat fs1, fs2;
59
60     //handlers for mmap()
61     void *h1 = MAP_FAILED;
62     void *h2 = MAP_FAILED;
63
64     //getting files information
65     if (fstat(fd1, &fs1) == -1) {
66         perror("fstat");
67         return -1;
68     }
69     if (fstat(fd2, &fs2) == -1) {
70         perror("fstat");
71         return -1;
72     }
73
74     if (fs1.st_size != fs2.st_size) //if files are identical size will be the same
75         return -1;
76
77     //mapping files to process memory
78     if ((h1 = mmap(0, fs1.st_size, PROT_READ, MAP_SHARED, fd1, 0 )) == MAP_FAILED) {
79         result = -1;
80         goto end;
81     }
82     if ((h2 = mmap(0, fs2.st_size, PROT_READ, MAP_SHARED, fd2, 0 )) == MAP_FAILED) {
83         result = -1;
84         goto end;
85     }
86
87     result = memcmp(h1, h2, fs1.st_size);
88
89     //cleaning after mmap()
90 end:
91     if (h2 != MAP_FAILED)
92         munmap(h2, fs2.st_size);
93     if (h1 != MAP_FAILED)
94         munmap(h1, fs1.st_size);
95
96     return result;
97 }
98
99
100 RUNNER_TEST_GROUP_INIT(libsmack)
101 /**
102  * Helper method to reset privileges at the begginning of tests.
103  */
104 void clean_up()
105 {
106     struct smack_accesses *rules = NULL;
107     int result = smack_accesses_new(&rules);
108     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
109
110     // CLEAN UP
111     smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","rwxat");
112     smack_accesses_apply(rules);
113     smack_accesses_free(rules);
114
115     // PREINIT CHECK.
116     RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") != 1, "Rule has previous privileges after cleaning up!");
117     RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"w") != 1, "Rule has previous privileges after cleaning up!");
118     RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"x") != 1, "Rule has previous privileges after cleaning up!");
119     RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"a") != 1, "Rule has previous privileges after cleaning up!");
120     RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"t") != 1, "Rule has previous privileges after cleaning up!");
121 }
122
123 /**
124  * Checking if subject has any access to object
125  */
126 bool checkNoAccesses(const char *subject, const char *object)
127 {
128     int result;
129     result = smack_have_access(subject, object,"r");
130     if (result == 1) {
131         return false;
132     }
133     result = smack_have_access(subject, object,"w");
134     if (result == 1) {
135         return false;
136     }
137     result = smack_have_access(subject, object,"x");
138     if (result == 1) {
139         return false;
140     }
141     result = smack_have_access(subject, object,"a");
142     if (result == 1) {
143         return false;
144     }
145     result = smack_have_access(subject, object,"t");
146     if (result == 1) {
147         return false;
148     }
149     return true;
150 }
151
152 void removeAccessesAll()
153 {
154     struct smack_accesses *rules = NULL;
155     int result = smack_accesses_new(&rules);
156     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
157
158     result = smack_accesses_add_modify(rules, "test_subject_01", "test_object_01", "", "rxwat");
159     result = smack_accesses_add_modify(rules, "test_subject_01", "test_object_02", "", "rxwat");
160     result = smack_accesses_add_modify(rules, "test_subject_01", "test_object_03", "", "rxwat");
161     result = smack_accesses_add_modify(rules, "test_subject_02", "test_object_01", "", "rxwat");
162     result = smack_accesses_add_modify(rules, "test_subject_02", "test_object_02", "", "rxwat");
163     result = smack_accesses_add_modify(rules, "test_subject_02", "test_object_03", "", "rxwat");
164     result = smack_accesses_add_modify(rules, "test_subject_03", "test_object_01", "", "rxwat");
165     result = smack_accesses_add_modify(rules, "test_subject_03", "test_object_02", "", "rxwat");
166     result = smack_accesses_add_modify(rules, "test_subject_03", "test_object_03", "", "rxwat");
167
168     smack_accesses_apply(rules);
169     RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
170     smack_accesses_free(rules);
171 }
172
173
174 /**
175  * Add a new access with smack_accesses_add_modify()
176  */
177 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_1){
178     int result;
179
180     clean_up();
181
182     struct smack_accesses *rules = NULL;
183     result = smack_accesses_new(&rules);
184
185     // THE TEST
186     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"xr","");
187     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify by empty rules");
188     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
189
190     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"xr");
191     RUNNER_ASSERT_MSG_BT(result == 1, "Rule modified (added 'xr'), but no change made.");
192
193     // CLEAN UP
194     clean_up();
195     smack_accesses_free(rules);
196 }
197
198
199 /**
200  * Test if rules are applied in the right order, and modification works.
201  */
202 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_2){
203     int result;
204     struct smack_accesses *rules = NULL;
205     result = smack_accesses_new(&rules);
206     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
207
208     clean_up();
209
210     // THE TEST
211     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"r","");
212     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
213
214     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
215     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
216
217     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
218     RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") == 0, "Modification didn't work");
219
220     // CLEAN UP
221     clean_up();
222     smack_accesses_free(rules);
223 }
224
225
226 /**
227  * Test if rules are applied in the right order, and modification works.
228  * Using different smack_accesses list to add and delete.
229  */
230 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_3){
231     int result;
232     struct smack_accesses *rules = NULL;
233     result = smack_accesses_new(&rules);
234     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
235
236     clean_up();
237
238     // THE TEST
239     // Add r privilage
240     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"r","");
241     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
242     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
243     RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") == 1, "Adding privileges didn't work");
244     smack_accesses_free(rules);
245
246     // Revoke r privilege
247     result = smack_accesses_new(&rules);
248     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
249     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
250     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
251     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
252
253     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
254     RUNNER_ASSERT_MSG_BT(result == 0, "Modification didn't work, rule has still 'r' privileges.");
255
256     // CLEAN UP
257     clean_up();
258     smack_accesses_free(rules);
259 }
260
261 /**
262  * Add a list of privileges and then revoke just ONE of them.
263  */
264 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_4){
265     int result;
266     struct smack_accesses *rules = NULL;
267     result = smack_accesses_new(&rules);
268     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
269
270     clean_up();
271
272     // THE TEST
273     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"rwxat","");
274     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
275     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
276
277     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
278     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
279     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
280
281     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"awxt");
282     RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule should have 'awxt' privileges.");
283     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
284     RUNNER_ASSERT_MSG_BT(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
285
286     // CLEAN UP
287     clean_up();
288     smack_accesses_free(rules);
289 }
290
291 /**
292  * Add a list of privileges and then revoke just ONE of them.
293  * Without applying privileges in between those actions.
294  */
295 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_5){
296     int result;
297     struct smack_accesses *rules = NULL;
298     result = smack_accesses_new(&rules);
299     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
300
301     clean_up();
302
303     // THE TEST
304     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"rwxat","");
305     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
306
307     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
308     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
309     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
310
311     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"awxt");
312     RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule should have 'awxt' privileges.");
313     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
314     RUNNER_ASSERT_MSG_BT(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
315
316     // CLEAN UP
317     clean_up();
318     smack_accesses_free(rules);
319 }
320
321
322 /**
323  * Add a list of privileges and then revoke just TWO of them.
324  */
325 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_6){
326     int result;
327     struct smack_accesses *rules = NULL;
328     result = smack_accesses_new(&rules);
329     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
330
331     clean_up();
332
333     // THE TEST
334     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"rwt","");
335     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
336     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
337
338     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"ax","rt");
339     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
340     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
341
342     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"wax");
343     RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule should have 'wax' privileges.");
344     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
345     RUNNER_ASSERT_MSG_BT(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
346
347     // CLEAN UP
348     clean_up();
349     smack_accesses_free(rules);
350 }
351
352 /**
353  * Run smack_accesses_add_modify with the same accesses_add and accesses_del.
354  */
355 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_7){
356     unsigned int i;
357     int result;
358
359     struct smack_accesses *rules = NULL;
360
361     for (i = 0; i < accessesBasic.size(); ++i) {
362         result = smack_accesses_new(&rules);
363         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
364
365         result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str(),accessesBasic[i].c_str());
366         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
367         RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
368
369         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
370             " Error while checking smack access. Accesses exist.");
371
372         // CLEAN UP
373         clean_up();
374         smack_accesses_free(rules);
375     }
376 }
377
378 /**
379  * Revoke subject with previously added rules and revoke it again.
380  */
381 RUNNER_TEST_SMACK(smack_revoke_subject_test_1){
382     unsigned int i;
383     int result;
384
385     struct smack_accesses *rules = NULL;
386
387     for (i = 0; i < accessesBasic.size(); ++i) {
388         // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
389         result = smack_accesses_new(&rules);
390         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
391         result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str(),"");
392         result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str(),"");
393         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
394         RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
395         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
396         RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
397         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
398         RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
399
400         // Revoking subject
401         result = smack_revoke_subject(TEST_SUBJECT);
402         RUNNER_ASSERT_MSG_BT(result == 0, "Revoking subject didn't work.");
403
404         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
405             " Revoke didn't work. Accesses exist.");
406         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
407             " Revoke didn't work. Accesses exist.");
408
409
410         // Revoking subject again
411         result = smack_revoke_subject(TEST_SUBJECT);
412         RUNNER_ASSERT_MSG_BT(result == 0, "Revoking subject didn't work.");
413
414         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
415             " Revoke didn't work. Accesses exist.");
416         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
417             " Revoke didn't work. Accesses exist.");
418
419         smack_accesses_free(rules);
420     }
421 }
422
423 /**
424  * Clearing accesses
425  */
426 RUNNER_TEST_SMACK(smack_accesses_clear_test_1){
427     unsigned int i;
428     int result;
429
430     struct smack_accesses *rules = NULL;
431
432     for (i = 0; i < accessesBasic.size(); ++i) {
433         // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
434         result = smack_accesses_new(&rules);
435         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
436         result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
437         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
438         result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
439         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
440         RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules) == 0, "Unable to apply rules");
441
442         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
443         RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
444         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
445         RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
446
447         smack_accesses_free(rules);
448
449         // Creating and clearing rules with TEST_OBJECT
450         result = smack_accesses_new(&rules);
451         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
452         result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
453         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
454         result = smack_accesses_clear(rules);
455         RUNNER_ASSERT_MSG_BT(result == 0, "Clearing rules didn't work.");
456
457         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
458         RUNNER_ASSERT_MSG_BT(result == 0, "Clearing rules didn't work. Rule " << accessesBasic[i].c_str() << " does exist.");
459         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
460         RUNNER_ASSERT_MSG_BT(result == 1, "Clearing rules didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
461
462         smack_accesses_free(rules);
463
464         // Creating and clearing rules with TEST_OBJECT_2
465         result = smack_accesses_new(&rules);
466         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
467
468         result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
469         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
470         result = smack_accesses_clear(rules);
471         RUNNER_ASSERT_MSG_BT(result == 0, "Clearing rules didn't work.");
472
473         smack_accesses_free(rules);
474
475         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
476             " Clear didn't work. Accesses exist.");
477         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
478             " Clear didn't work. Accesses exist.");
479     }
480 }
481
482 RUNNER_TEST(smack01_storing_and_restoring_rules)
483 {
484     /*
485      * author: Pawel Polawski
486      * test: smack_accesses_new, smack_accesses_add, smack_accesses_add_modify, smack_accesses_add_from_file,
487      *       smack_accesses_free, smack_accesses_save
488      * description: This test case will create structure holding SMACK rules and add new one to it. Next rules will be
489      *              stored and restored from file.
490      * expect: Rules created and stored in file should be identical to predefined template.
491      */
492
493     struct smack_accesses *rules = NULL;        //rules prepared in this test case
494     struct smack_accesses *import_test = NULL;  //rules imported from file
495
496     int result;             //result of each operation to be tested by RUNNER_ASSERT
497     int fd, tmp, sample;    //file descripptors for save / restore rules tests
498
499     //int smack_accesses_new(struct smack_accesses **accesses);
500     result = smack_accesses_new(&rules);        //rules struct init
501     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
502     result = smack_accesses_new(&import_test);  //rules struct init
503     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
504
505     //opening files
506     fd = open("/tmp/smack01_rules", O_RDWR | O_CREAT | O_TRUNC, 0644);  //for export prepared rules
507     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to create /tmp/smack01_rules");
508     tmp = open("/tmp/smack01_tmp", O_RDWR | O_CREAT | O_TRUNC, 0644);   //for import rules exported before
509     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to create /tmp/smack01_tmp");
510     sample = open("/etc/smack/test_smack_rules", O_RDONLY, 0644);             //reference preinstalled rules
511     RUNNER_ASSERT_MSG_BT(sample >= 0, "Unable to open /etc/smack/test_smack_rules");
512
513     //int smack_accesses_add(struct smack_accesses *handle, const char *subject,
514     //               const char *object, const char *access_type);
515     result = smack_accesses_add(rules, "writer", "book", "rw");
516     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
517     result = smack_accesses_add(rules, "reader", "book", "wx");
518     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
519
520     //int smack_accesses_add_modify(struct smack_accesses *handle, const char *subject,
521     //               const char *object, const char *access_add, const char *access_del);
522     result = smack_accesses_add_modify(rules, "reader", "book", "r", "wx");
523     RUNNER_ASSERT_MSG_BT(0 == result, "Unable to modify smack rules");
524
525     //int smack_accesses_save(struct smack_accesses *handle, int fd);
526     result = smack_accesses_save(rules, fd);
527     RUNNER_ASSERT_MSG_BT(0 == result, "Unable to save smack_accesses instance in file");
528
529     //int smack_accesses_add_from_file(struct smack_accesses *accesses, int fd);
530     result = lseek(fd, 0, SEEK_SET);
531     RUNNER_ASSERT_MSG_BT(result == 0, "lseek() error");
532     result = smack_accesses_add_from_file(import_test, fd);
533     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to import rules from file");
534
535     result = smack_accesses_save(import_test, tmp);
536     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to save smack_accesses instance in file");
537
538     result = files_compare(fd, tmp);    //comparing rules saved in file, restored from it and stored one more time
539     RUNNER_ASSERT_MSG_BT(result == 0, "No match in stored and restored rules");
540
541     result = files_compare(tmp, sample);    //comparing rules stored in file with reference preinstalled rules
542     RUNNER_ASSERT_MSG_BT(result == 0, "No match in stored rules and pattern file");
543
544     //void smack_accesses_free(struct smack_accesses *handle);
545     smack_accesses_free(rules);
546     smack_accesses_free(import_test);
547
548     //closing file descriptors
549     close(fd);
550     close(tmp);
551     close(sample);
552 }
553
554 RUNNER_TEST_SMACK(smack02_aplying_rules_into_kernel)
555 {
556     /*
557      * author: Pawel Polawski
558      * test: smack_accesses_apply, smack_have_access, smack_revoke_subject, smack_accesses_clear, smack_accesses_new,
559      *       smack_accesses_add, smack_accesses_free
560      * description: In this test case aplying rules to kernel will be tested. After that function for test
561      *              accesses will be used.
562      * expect: In case of correct rules access should be granted.
563      */
564
565     //CAP_MAC_ADMIN needed for process to be able to change rules in kernel (apllying, removing)
566
567     struct smack_accesses *rules = NULL;        //rules prepared in this test case
568     int result;                                 //for storing functions results
569
570     result = smack_accesses_new(&rules);        //rules struct init
571     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
572
573     //adding test rules to struct
574     result = smack_accesses_add(rules, "writer", "book", "rwx");
575     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
576     result = smack_accesses_add(rules, "reader", "book", "r");
577     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
578     result = smack_accesses_add(rules, "spy", "book", "rwx");
579     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
580
581     //int smack_accesses_apply(struct smack_accesses *handle);
582     result = smack_accesses_apply(rules);       //applying rules to kernel
583     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to apply rules into kernel");
584
585     //int smack_have_access(const char *subject, const char *object,
586     //                  const char *access_type);
587     result = smack_have_access("spy", "book", "rwx");       //should have access - rule exist
588     RUNNER_ASSERT_MSG_BT(result == 1, "Error while checking Smack access");
589     result = smack_have_access("reader", "book", "rwx");    //should have no access - wrong rule, should be "r" only
590     RUNNER_ASSERT_MSG_BT(result == 0, "Error while checking Smack access");
591     result = smack_have_access("s02badsubjectlabel", "book", "rwx"); //should fail - rule not exist
592     RUNNER_ASSERT_MSG_BT(result == -1, "Error while checking Smack access");
593
594     //int smack_revoke_subject(const char *subject);
595     result = smack_revoke_subject("s02nonexistinglabel"); //this subject do not exist in kernel rules
596     RUNNER_ASSERT_MSG_BT(result == 0, "Error in removing not existing subject from kernel");
597     result = smack_revoke_subject("spy");       //this subject exist in kernel rules
598     RUNNER_ASSERT_MSG_BT(result == 0, "Error in removing existing subject from kernel");
599
600     result = smack_have_access("spy", "book", "rwx");                   //testing access after revoke_subject() from kernel
601     RUNNER_ASSERT_MSG_BT(result == 0, "Error in acces aplied to kernel");  //now spy should have no access
602
603     //for create new rule as a consequence of use accesses_clear() below
604     result = smack_accesses_add(rules, "s02subjectlabel", "book", "rwx");
605     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
606
607     //int smack_accesses_clear(struct smack_accesses *handle);
608     result = smack_accesses_clear(rules);    //"spy" removed before by using smack_revoke_subject()
609     RUNNER_ASSERT_MSG_BT(result == 0, "Error in clearing rules in kernel");
610
611     result = smack_have_access("writer", "book", "rwx");                //testing acces after acces_clear()
612     RUNNER_ASSERT_MSG_BT(result == 0, "Error in acces aplied to kernel");  //now writer also should have no access
613
614     //free resources
615     smack_accesses_free(rules);
616 }
617
618 //pairs of rules for test with mixed cases, different length and mixed order
619 std::vector< std::vector<std::string> > correct_rules = {
620     { "reader1",  "-",                "------" },
621     { "reader2",  "--------",         "------" },
622     { "reader3",  "RwXaTl",           "rwxatl" },
623     { "reader4",  "RrrXXXXTTT",       "r-x-t-" },
624     { "reader5",  "-r-w-a-t-",        "rw-at-" },
625     { "reader6",  "",                 "------" },
626     { "reader7",  "xa--Rt---W--L",    "rwxatl" },
627 };
628
629 RUNNER_TEST_SMACK(smack03_mixed_rule_string_add)
630 {
631     /*
632      * author: Pawel Polawski
633      * test: smack_have_access, smack_accesses_new, smack_accesses_add, smack_accesses_apply, smack_accesses_free
634      * description: In thist test case rules based on mixed string are added to kernel.
635      *              Strings are presented above and contains lower / upper case alpha, numbers and special signs.
636      * expect: Rules should be parsed correct and aplied to kernel.
637      */
638
639     //In thist test case mixed string are used as rules applied to kernel, next they are
640     //readed and compared with correct form of rules
641
642     struct smack_accesses *rules = NULL;        //rules prepared in this test case
643     int result;                                 //for storing functions results
644     int expected;
645
646     result = smack_accesses_new(&rules);        //rules struct init
647     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
648
649     //adding test rules with mixed string
650     for (auto rule=correct_rules.begin(); rule != correct_rules.end(); ++rule) {
651         //using mixed rules from table
652         result = smack_accesses_add(rules,
653                                     (*rule)[0].c_str(),
654                                     "book",
655                                     (*rule)[1].c_str());
656         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
657     }
658
659     //clearing
660     //FIXME: Using clear() here can cover error in accesses_apply() function
661     //result = smack_accesses_clear(rules);
662     //RUNNER_ASSERT_MSG_BT(result == 0, "Error in clearing rules in kernel");
663
664     //applying rules to kernel
665     result = smack_accesses_apply(rules);
666     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to apply rules into kernel");
667
668     //checking accesses using normal rules
669     for (auto rule=correct_rules.begin(); rule != correct_rules.end(); ++rule) {
670         if ((*rule)[2] == "------")
671             expected = 0;
672         else
673             expected = 1;
674         //using normal rules from table
675         result = smack_have_access((*rule)[0].c_str(),
676                                    "book",
677                                    (*rule)[2].c_str());
678         RUNNER_ASSERT_MSG_BT(result == expected, "Error while checking Smack access");
679     }
680
681     //free resources
682     smack_accesses_free(rules);
683 }
684
685 RUNNER_TEST_SMACK(smack04_mixed_rule_string_have_access)
686 {
687     /*
688      * author: Pawel Polawski
689      * test: smack_have_access
690      * description: In this test case we testing aplied before SMACK rules and comparing them using mixed strings.
691      * expect: Subjects should have accesses to the objects.
692      */
693
694     //In this test case we checking previous aplied rules but for compare mixed strings are used
695
696     int result;
697     int expected;
698
699     //rules were added in previous RUNNER_TEST section
700     //checking accesses using mixed rules
701     for (auto rule=correct_rules.begin(); rule != correct_rules.end(); ++rule) {
702         if ((*rule)[2] == "------")
703             expected = 0;
704         else
705             expected = 1;
706         //using mixed rules from table
707         result = smack_have_access((*rule)[0].c_str(),
708                                    "book",
709                                    (*rule)[1].c_str());
710         RUNNER_ASSERT_MSG_BT(result == expected, "Error while checking Smack access");
711     }
712 }
713
714 //RUNNER_TEST(smackXX_accesses_add_modify)
715 //{
716 //IDEAS FOR TESTS
717 // - what if we want to apply rule that is already in kernel?
718 // - tests for smack_accesses_add_modify() + smack_have_access() (check if add_modify sets the proper rule)
719 // - smack_accesses_add_modify("subject", "object", "rwx", "rwx") should create empty rule
720 //}
721
722 RUNNER_TEST_SMACK(smack05_self_label)
723 {
724     /*
725      * author: Pawel Polawski
726      * test: smack_set_label_for_self, smack_new_label_from_self
727      * description: In this test case process test it own default label. Next label is changed
728      *              and tested one more time if change was successfull.
729      * expect: Proces should have default "-" label and can change it to the oter one.
730      */
731
732     //In this test case process will manipulate it own label
733
734     char *label = NULL;
735     int result;
736     int fd;
737
738     const int B_SIZE = 8;
739     char buff[B_SIZE];
740
741     const char *def_rule = "_";
742
743     //int smack_new_label_from_self(char **label);
744     result = smack_new_label_from_self(&label);
745     RUNNER_ASSERT_MSG_BT(result >= 0, "Error in getting self label");
746
747     //comparing this label with default one "_"
748     result = strcmp(label, def_rule);
749     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong default process label");
750
751     //comparing this rule with received from /proc/self/attr/current
752     fd = open("/proc/self/attr/current", O_RDONLY, 0644);
753     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /proc/self/attr/current");
754     result = read(fd, buff, B_SIZE);
755     RUNNER_ASSERT_MSG_BT(result >= 0, "Error in reading from file /proc/self/attr/current");
756     result = strncmp(buff, def_rule, result);
757     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong default process rule");
758
759     free(label);
760
761     //now time for setting labels:
762
763     //int smack_set_label_for_self(const char *label);
764     result = smack_set_label_for_self("cola");
765     RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting self label");
766
767     //checking new label using smack function
768     result = smack_new_label_from_self(&label);
769     RUNNER_ASSERT_MSG_BT(result >= 0, "Error in getting self label");
770     result = strcmp(label, "cola");
771     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong process label");
772
773     //checking new label using /proc/self/attr/current
774     result = lseek(fd, 0, SEEK_SET);    //going to the file beginning
775     RUNNER_ASSERT_MSG_BT(result == 0, "lseek() error");
776     result = read(fd, buff, B_SIZE);
777     RUNNER_ASSERT_MSG_BT(result >= 0, "Error in reading from file /proc/self/attr/current");
778     result = strncmp(buff, "cola", result);
779     RUNNER_ASSERT_MSG_BT(result == 0, "Proces rule in /proc/self/attr/current other than set");
780
781     free(label);
782     close(fd);
783 }
784
785 //RUNNER_TEST(smackXX_parent_child_label)
786 //{
787 //In this test case parent process and child labels will be tested
788 //Parent will fork and check child's label. First fork will be with default "_" parent label,
789 //second one witch changed label.
790 //}
791
792 //bellow function is from libsmack.c witch changed name
793 const char *xattr(enum smack_label_type type)
794 {
795     switch (type) {
796         case SMACK_LABEL_ACCESS:
797             return "security.SMACK64";
798         case SMACK_LABEL_EXEC:
799             return "security.SMACK64EXEC";
800         case SMACK_LABEL_MMAP:
801             return "security.SMACK64MMAP";
802         case SMACK_LABEL_TRANSMUTE:
803             return "security.SMACK64TRANSMUTE";
804         case SMACK_LABEL_IPIN:
805             return "security.SMACK64IPIN";
806         case SMACK_LABEL_IPOUT:
807             return "security.SMACK64IPOUT";
808         default:
809             /*  Should not reach this point */
810             return NULL;
811     }
812 }
813
814 //TODO: In bellow RUNNER_TEST add  lget / lset functions to be testet the same way as normal get / set
815 RUNNER_TEST(smack06_get_set_label)
816 {
817     /*
818      * author: Pawel Polawski
819      * test: smack_getlabel, smack_setlabel
820      * description: In this test case file label is tested using SMACK API functions and system xattr functions.
821      *              Functions tested here is used for normal files.
822      * expect: Function should return default label, and the new one after change it.
823      */
824
825     //In this test case will be tested setting and getting file label
826     //If file is symbolic link functions should follow it
827
828     //SMACK xattr from libsmack.c:
829     //
830     //case SMACK_LABEL_ACCESS:
831     //    return "security.SMACK64";
832     //case SMACK_LABEL_EXEC:
833     //    return "security.SMACK64EXEC";
834     //case SMACK_LABEL_MMAP:
835     //    return "security.SMACK64MMAP";
836     //case SMACK_LABEL_TRANSMUTE:
837     //    return "security.SMACK64TRANSMUTE";
838     //case SMACK_LABEL_IPIN:
839     //    return "security.SMACK64IPIN";
840     //case SMACK_LABEL_IPOUT:
841     //    return "security.SMACK64IPOUT";
842
843     int result;
844     char *label = NULL;
845
846     char buff[SMACK_LABEL_LEN+1];
847     const char* s06testlabel = "s06testlabel";
848
849     const char *file_path = "/etc/smack/test_smack_rules";
850
851
852     //preparing environment by restoring default "_" label
853     result = smack_setlabel(file_path, "_", SMACK_LABEL_ACCESS);
854     RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
855
856
857     //int smack_getlabel(const char *path, char** label,
858     //          enum smack_label_type type);
859     result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
860     RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
861     //get label, should be default "_"
862     result = strcmp(label, "_");
863     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
864     free(label);
865     //get label using xattr function
866     result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
867     RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
868     //check label, should match the one readed by smack function
869     result = strncmp(buff, "_", result);
870     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
871
872
873     //int smack_setlabel(const char *path, const char* label,
874     //          enum smack_label_type type);
875     result = smack_setlabel(file_path, s06testlabel, SMACK_LABEL_ACCESS);
876     RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
877
878
879     //get label using smack function
880     result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
881     RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
882     //get label, should be default s06testlabel
883     result = strcmp(label, s06testlabel);
884     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
885     free(label);
886     //get label using xattr function
887     result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
888     RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
889     //check label, should match the one readed by smack function
890     result = strncmp(buff, s06testlabel, result);
891     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
892 }
893
894 //RUNNER_TEST(smackXX_get_label_exec)
895 //{
896 //In this test case EXEC label will be tested
897 //by setting this type of label, reading it and testing executed binary exit status
898 //}
899
900 RUNNER_TEST(smack07_l_get_set_label)
901 {
902     /*
903      * author: Pawel Polawski
904      * test: smack_lgetlabel, smack_lsetlabel, smack_getlabel
905      * description: Functions tested here are similar to one from previous test case. The difference
906      *              is that in case of symbolic link they follows it and operates on file pointed by it.
907      * expect: All label manipulations should affect file pointed by symbolic link.
908      */
909
910     int result;
911     char *label = NULL;
912
913     char buff[SMACK_LABEL_LEN+1];
914     const char* s07testlabel1 = "s07testlabel1";
915     const char* s07testlabel2 = "s07testlabel2";
916
917     const char *file_path = "/etc/smack/test_smack_rules_lnk";
918
919
920     //preparing environment by restoring default "_" label
921     result = smack_lsetlabel(file_path, "_", SMACK_LABEL_ACCESS);
922     RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
923     result = smack_setlabel(file_path, "_", SMACK_LABEL_ACCESS);
924     RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
925
926
927     //int smack_lgetlabel(const char *path, char** label,
928     //          enum smack_label_type type);
929     result = smack_lgetlabel(file_path, &label, SMACK_LABEL_ACCESS);
930     RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
931     //get label of symbolic link, should be default "_"
932     result = strcmp(label, "_");
933     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
934     free(label);
935     //get label using xattr function
936     result = lgetxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
937     RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
938     //check label, should match the one readed by smack function
939     result = strncmp(buff, "_", result);
940     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
941
942
943     //int smack_lsetlabel(const char *path, const char* label,
944     //          enum smack_label_type type);
945     result = smack_lsetlabel(file_path, s07testlabel1, SMACK_LABEL_ACCESS);
946     RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
947     //and set label for file pointed by link
948     result = smack_setlabel(file_path, s07testlabel2, SMACK_LABEL_ACCESS);
949     RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
950
951
952     //get label using smack function
953     result = smack_lgetlabel(file_path, &label, SMACK_LABEL_ACCESS);
954     RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
955     //check label, should be s07testlabel1
956     result = strcmp(label, s07testlabel1);
957     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
958     free(label);
959     //get label using xattr function
960     result = lgetxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
961     RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
962     //check label, should match the one readed by smack function
963     result = strncmp(buff, s07testlabel1, result);
964     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
965
966
967     //now similar to above, but folowing symbolic link set before to s07testlabel2
968     result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
969     RUNNER_ASSERT_MSG_BT(result == 0, "Error gettin label of file pointed by symbolic link");
970     //now label should be s07testlabel2 for file instead of s07testlabel1 set for link
971     result = strcmp(label, s07testlabel2);
972     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong label of file pointed by symbolic link");
973     free(label);
974     //get label using xattr function
975     result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
976     RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
977     //check label, should match the one readed by smack function
978     result = strncmp(buff, s07testlabel2, result);
979     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
980 }
981
982 RUNNER_TEST(smack08_f_get_set_label)
983 {
984     /*
985      * author: Pawel Polawski
986      * test: smack_fgetlabel, smack_fsetlabel
987      * description: This test case is similar to test case smack06 above. The difference
988      *              is that argument is file descriptor instead of file path.
989      *              Function not follow symbolic link and operates directly on it.
990      * expect: All label manipulations should affect symbolic link itself.
991      */
992
993     int result;
994     char *label = NULL;
995
996     char buff[SMACK_LABEL_LEN+1];
997     const char* s08testlabel = "s08testlabel";
998
999     int fd;
1000     const char *file_path = "/etc/smack/test_smack_rules";
1001
1002     fd = open(file_path, O_RDWR, 0644);             //reference preinstalled rules
1003     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules");
1004
1005     //preparing environment by restoring default "_" label
1006     result = smack_fsetlabel(fd, "_", SMACK_LABEL_ACCESS);
1007     RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
1008
1009
1010     //int smack_fgetlabel(int fd, char** label,
1011     //          enum smack_label_type type);
1012     result = smack_fgetlabel(fd, &label, SMACK_LABEL_ACCESS);
1013     RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
1014     //check label, should be "_"
1015     result = strcmp(label, "_");
1016     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
1017     free(label);
1018     //get label using xattr function
1019     result = fgetxattr(fd, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
1020     RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
1021     //check label, should match the one readed by smack function
1022     result = strncmp(buff, "_", result);
1023     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
1024
1025
1026     //int smack_fsetlabel(int fd, const char* label,
1027     //          enum smack_label_type type);
1028     result = smack_fsetlabel(fd, s08testlabel, SMACK_LABEL_ACCESS);
1029     RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
1030
1031
1032     //get label using smack function
1033     result = smack_fgetlabel(fd, &label, SMACK_LABEL_ACCESS);
1034     RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
1035     //check label, should be s08testlabel
1036     result = strcmp(label, s08testlabel);
1037     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
1038     free(label);
1039     //get label using xattr function
1040     result = fgetxattr(fd, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
1041     RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
1042     //check label, should match the one readed by smack function
1043     result = strncmp(buff, s08testlabel, result);
1044     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
1045
1046
1047     close(fd);
1048 }
1049
1050 RUNNER_TEST_SMACK(smack10_adding_removing_rules)
1051 {
1052     unsigned int i;
1053     int result;
1054
1055     struct smack_accesses *rulesBasic = NULL;
1056
1057     for (i = 0; i < accessesBasic.size(); ++i)
1058     {
1059         // Creating rules
1060         result = smack_accesses_new(&rulesBasic);
1061         RUNNER_ASSERT_MSG_BT(result == 0, "Error while creating new accesses. Result: " << result);
1062
1063         // Adding accesses
1064         result = smack_accesses_add(rulesBasic, TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1065         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1066
1067         // Applying rules
1068         result = smack_accesses_apply(rulesBasic);
1069         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
1070
1071         // Checking if accesses were created
1072         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1073         RUNNER_ASSERT_MSG_BT(result == 1,
1074             " Error while checking smack access. Result: " << result);
1075
1076         smack_accesses_free(rulesBasic);
1077         rulesBasic = NULL;
1078
1079         // Deleting all rules
1080         clean_up();
1081     }
1082
1083     for (i = 0; i < 3; ++i)
1084     {
1085         // --- Creating rules (r or w or x)
1086         result = smack_accesses_new(&rulesBasic);
1087         RUNNER_ASSERT_MSG_BT(result == 0, "Error while creating new accesses. Result: " << result);
1088
1089         // Adding accesses
1090         result = smack_accesses_add(rulesBasic, TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1091         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add rulesBasic. Result: " << result);
1092
1093         // Applying rules
1094         result = smack_accesses_apply(rulesBasic);
1095         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
1096         // Checking if accesses were created
1097         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1098         RUNNER_ASSERT_MSG_BT(result == 1,
1099             " Error while checking smack access. Result: " << result);
1100
1101         // Checking if wrong accesses were not created
1102         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1103         RUNNER_ASSERT_MSG_BT(result == 0,
1104             " Error while checking smack access. Result: " << result);
1105
1106         // --- Modifying accesses (r for wx or w for rx or x for rw)
1107         result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i + 3].c_str(),accessesBasic[i].c_str());
1108         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1109
1110         // Applying rules
1111         result = smack_accesses_apply(rulesBasic);
1112         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
1113
1114         // Checking if accesses were created
1115         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1116         RUNNER_ASSERT_MSG_BT(result == 1,
1117             " Error while checking smack access. Result: " << result);
1118
1119         // Checking if wrong accesses were not created
1120         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1121         RUNNER_ASSERT_MSG_BT(result == 0,
1122             " Error while checking smack access. Result: " << result);
1123
1124         smack_accesses_free(rulesBasic);
1125         rulesBasic = NULL;
1126
1127         // --- Creating complementary rules (r or w or x)
1128         result = smack_accesses_new(&rulesBasic);
1129         RUNNER_ASSERT_MSG_BT(result == 0, "Error while creating new accesses. Result: " << result);
1130
1131         // Adding accesses
1132         result = smack_accesses_add(rulesBasic, TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1133         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add rulesBasic. Result: " << result);
1134
1135         // Checking if accesses were created
1136         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1137         RUNNER_ASSERT_MSG_BT(result == 1,
1138             " Error while checking smack access. Result: " << result);
1139
1140         // Applying rules
1141         result = smack_accesses_apply(rulesBasic);
1142         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
1143
1144         // Checking if accesses were created
1145         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1146         RUNNER_ASSERT_MSG_BT(result == 1,
1147             " Error while checking smack access. Result: " << result);
1148
1149         // --- Modifying accesses (adding rwx and removing r or w or x)
1150         result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,"rwx",accessesBasic[i].c_str());
1151         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1152
1153         // Applying rules
1154         result = smack_accesses_apply(rulesBasic);
1155         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
1156
1157         // Checking if accesses were created
1158         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1159         RUNNER_ASSERT_MSG_BT(result == 1,
1160             " Error while checking smack access. Result: " << result);
1161
1162         // Checking if wrong accesses were not created
1163         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1164         RUNNER_ASSERT_MSG_BT(result == 0,
1165             " Error while checking smack access. Result: " << result);
1166
1167         // --- Adding crossing accesses (rx or rw or wx)
1168         result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,accessesBasic[3 + ((i + 1) % 3)].c_str(),"");
1169         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1170
1171         // Applying rules
1172         result = smack_accesses_apply(rulesBasic);
1173         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
1174
1175         // Checking if accesses were created
1176         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[3 + ((i + 1) % 3)].c_str());
1177         RUNNER_ASSERT_MSG_BT(result == 1,
1178             " Error while checking smack access. Result: " << result);
1179
1180         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
1181         RUNNER_ASSERT_MSG_BT(result == 1,
1182             " Error while checking smack access. Result: " << result);
1183
1184         // Deleting all rules
1185         result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,"","rwx");
1186         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1187
1188         result = smack_accesses_apply(rulesBasic);
1189         RUNNER_ASSERT_MSG_BT(result == 0, "Error while checking smack access. Result: " << result);
1190
1191         smack_accesses_free(rulesBasic);
1192         rulesBasic = NULL;
1193
1194         // Deleting all rules
1195         clean_up();
1196     }
1197 }
1198
1199 RUNNER_TEST_SMACK(smack11_saving_loading_rules)
1200 {
1201     int result;
1202     int fd;
1203
1204     struct smack_accesses *rulesBasic = NULL;
1205
1206     // Pre-cleanup
1207     removeAccessesAll();
1208
1209     // Creating rules
1210     result = smack_accesses_new(&rulesBasic);
1211     RUNNER_ASSERT_MSG_BT(result == 0, "Error while creating new accesses. Result: " << result);
1212
1213     // Loading file with rwxat rules - test_smack_rules_full
1214     fd = open("/etc/smack/test_smack_rules_full", O_RDONLY, 0644);
1215     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules_full");
1216
1217     // Adding rules from file
1218     result = smack_accesses_add_from_file(rulesBasic, fd);
1219     close(fd);
1220     RUNNER_ASSERT_MSG_BT(result == 0, "Error importing accesses from file");
1221
1222     // Applying rules
1223     result = smack_accesses_apply(rulesBasic);
1224     RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
1225
1226     // Checking rules
1227     result = smack_have_access("test_subject_01", "test_object_01", "rwxat");
1228     RUNNER_ASSERT_MSG_BT(result == 1,
1229         " Error while checking smack accesses.");
1230     result = smack_have_access("test_subject_01", "test_object_02", "rwxat");
1231     RUNNER_ASSERT_MSG_BT(result == 1,
1232         " Error while checking smack accesses.");
1233     result = smack_have_access("test_subject_01", "test_object_03", "rwxat");
1234     RUNNER_ASSERT_MSG_BT(result == 1,
1235         " Error while checking smack accesses.");
1236     result = smack_have_access("test_subject_02", "test_object_01", "rwxat");
1237     RUNNER_ASSERT_MSG_BT(result == 1,
1238         " Error while checking smack accesses.");
1239     result = smack_have_access("test_subject_02", "test_object_02", "rwxat");
1240     RUNNER_ASSERT_MSG_BT(result == 1,
1241         " Error while checking smack accesses.");
1242     result = smack_have_access("test_subject_02", "test_object_03", "rwxat");
1243     RUNNER_ASSERT_MSG_BT(result == 1,
1244         " Error while checking smack accesses.");
1245     result = smack_have_access("test_subject_03", "test_object_01", "rwxat");
1246     RUNNER_ASSERT_MSG_BT(result == 1,
1247         " Error while checking smack accesses.");
1248     result = smack_have_access("test_subject_03", "test_object_02", "rwxat");
1249     RUNNER_ASSERT_MSG_BT(result == 1,
1250         " Error while checking smack accesses.");
1251     result = smack_have_access("test_subject_03", "test_object_03", "rwxat");
1252     RUNNER_ASSERT_MSG_BT(result == 1,
1253         " Error while checking smack accesses.");
1254
1255     // Removing rules
1256     removeAccessesAll();
1257
1258     smack_accesses_free(rulesBasic);
1259
1260     // Creating rules
1261     result = smack_accesses_new(&rulesBasic);
1262     RUNNER_ASSERT_MSG_BT(result == 0, "Error while creating new accesses. Result: " << result);
1263
1264     // Loading file with partial wrong rules - test_smack_rules2
1265     fd = open("/etc/smack/test_smack_rules2", O_RDONLY, 0644);
1266     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules2");
1267
1268     // Adding rules from file
1269     result = smack_accesses_add_from_file(rulesBasic, fd);
1270     close(fd);
1271     RUNNER_ASSERT_MSG_BT(result == 0, "Error importing accesses from file");
1272
1273     // Applying rules
1274     result = smack_accesses_apply(rulesBasic);
1275     RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
1276
1277     // Checking rules
1278     RUNNER_ASSERT_MSG_BT(checkNoAccesses("test_subject_01", "test_object_01"),
1279         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
1280     result = smack_have_access("test_subject_01", "test_object_02", "rwatl");
1281     RUNNER_ASSERT_MSG_BT(result == 1,
1282         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1283     result = smack_have_access("test_subject_01", "test_object_03", "wat");
1284     RUNNER_ASSERT_MSG_BT(result == 1,
1285         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1286     RUNNER_ASSERT_MSG_BT(checkNoAccesses("test_subject_02", "test_object_01"),
1287         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
1288     result = smack_have_access("test_subject_02", "test_object_02", "wa-lt");
1289     RUNNER_ASSERT_MSG_BT(result == 1,
1290         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1291     result = smack_have_access("test_subject_02", "test_object_03", "wr");
1292     RUNNER_ASSERT_MSG_BT(result == 1,
1293         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1294     result = smack_have_access("test_subject_03", "test_object_01", "a");
1295     RUNNER_ASSERT_MSG_BT(result == 1,
1296         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1297     result = smack_have_access("test_subject_03", "test_object_02", "rwat");
1298     RUNNER_ASSERT_MSG_BT(result == 1,
1299         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1300     result = smack_have_access("test_subject_03", "test_object_03", "w---l-");
1301     RUNNER_ASSERT_MSG_BT(result == 1,
1302         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1303
1304     // Removing rules
1305     removeAccessesAll();
1306
1307     smack_accesses_free(rulesBasic);
1308
1309     // Creating rules
1310     result = smack_accesses_new(&rulesBasic);
1311     RUNNER_ASSERT_MSG_BT(result == 0, "Error while creating new accesses. Result: " << result);
1312
1313     // Loading file with partial wrong rules - test_smack_rules3
1314     fd = open("/etc/smack/test_smack_rules3", O_RDONLY, 0644);
1315     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules3");
1316
1317     // Adding rules from file
1318     result = smack_accesses_add_from_file(rulesBasic, fd);
1319     close(fd);
1320     RUNNER_ASSERT_MSG_BT(result != 0, "Accesses were loaded from file");
1321
1322     // Removing rules
1323     removeAccessesAll();
1324
1325     smack_accesses_free(rulesBasic);
1326
1327     // Creating rules
1328     result = smack_accesses_new(&rulesBasic);
1329     RUNNER_ASSERT_MSG_BT(result == 0, "Error while creating new accesses. Result: " << result);
1330
1331     // Loading file with partial wrong rules - test_smack_rules4
1332     fd = open("/etc/smack/test_smack_rules4", O_RDONLY, 0644);
1333     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules4");
1334
1335     // Adding rules from file
1336     result = smack_accesses_add_from_file(rulesBasic, fd);
1337     close(fd);
1338     RUNNER_ASSERT_MSG_BT(result != 0, "Accesses were loaded from file");
1339
1340     // Removing rules
1341     removeAccessesAll();
1342
1343     smack_accesses_free(rulesBasic);
1344 }
1345
1346 //int smack_new_label_from_socket(int fd, char **label);
1347
1348
1349 static void smack_set_another_label_for_self(void)
1350 {
1351     static int number = time(NULL);
1352
1353     number++;
1354     std::string smack_label("s" + std::to_string(number));
1355
1356     int result = smack_set_label_for_self(smack_label.c_str());
1357     RUNNER_ASSERT_MSG_BT(result == 0, "smack_set_label_for_self(" << smack_label << ") failed");
1358 }
1359
1360 static void smack_unix_sock_server(int sock)
1361 {
1362     int fd, result;
1363     char *smack_label;
1364
1365     alarm(2);
1366     fd = accept(sock, NULL, NULL);
1367     alarm(0);
1368     if (fd < 0)
1369         return;
1370     result = smack_new_label_from_self(&smack_label);
1371     RUNNER_ASSERT_MSG_BT(result >= 0, "smack_new_label_from_self() failed");
1372     result = write(fd, smack_label, strlen(smack_label));
1373     RUNNER_ASSERT_MSG_BT(result == (int)strlen(smack_label), "write() failed");
1374     close(fd);
1375     free(smack_label);
1376 }
1377
1378 RUNNER_MULTIPROCESS_TEST_SMACK(smack09_new_label_from_socket)
1379 {
1380     int pid;
1381     struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
1382     unlink(SOCK_PATH);
1383     smack_set_another_label_for_self();
1384     pid = fork();
1385     RUNNER_ASSERT_MSG_BT(pid >= 0, "Fork failed");
1386     if (!pid) { /* child process, server */
1387         int sock, result;
1388
1389
1390         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1391         RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
1392         result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1393         RUNNER_ASSERT_MSG_BT(result == 0, "bind failed: " << strerror(errno));
1394         result = listen(sock, 1);
1395         RUNNER_ASSERT_MSG_BT(result == 0, "listen failed: " << strerror(errno));
1396         smack_unix_sock_server(sock);
1397
1398         pid = fork();
1399         RUNNER_ASSERT_MSG_BT(pid >= 0, "Fork failed");
1400         /*  Test if socket label was unaffected by fork() */
1401         smack_unix_sock_server(sock);
1402         if (!pid) {
1403             usleep (100);
1404             smack_set_another_label_for_self();
1405             smack_unix_sock_server(sock);
1406         }
1407         close(sock);
1408
1409         exit(0);
1410     } else { /* parent process, client */
1411         sleep(1); /* Give server some time to setup listening socket */
1412         for (int i = 0; i < 4; ++i) {
1413             int sock, result;
1414             char smack_label1[SMACK_LABEL_LEN + 1];
1415             char *smack_label2;
1416
1417             sock = socket(AF_UNIX, SOCK_STREAM, 0);
1418             RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
1419             result = connect(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1420             RUNNER_ASSERT_MSG_BT(result == 0, "connect failed: " << strerror(errno));
1421             alarm(2);
1422             result = read(sock, smack_label1, SMACK_LABEL_LEN);
1423             RUNNER_ASSERT_MSG_BT(result >= 0, "read failed: " << strerror(errno));
1424             alarm(0);
1425             smack_label1[result] = '\0';
1426             result = smack_new_label_from_socket(sock, &smack_label2);
1427             RUNNER_ASSERT_MSG_BT(result >= 0, "smack_label_from_socket failed");
1428             result = strcmp(smack_label1, smack_label2);
1429             if (i < 3)
1430                 RUNNER_ASSERT_MSG_BT(result == 0, "smack labels differ: '" << smack_label1 << "' != '" << smack_label2 << "' i == " << i);
1431             else
1432                 RUNNER_ASSERT_MSG_BT(result != 0, "smack labels do not differ: '" << smack_label1 << "' != '" << smack_label2 << "' i == " << i);
1433             close(sock);
1434         }
1435     }
1436 }
1437
1438 void createFileWithLabel(const std::string &filePath, const std::string &fileLabel)
1439 {
1440     //create temporary file and set label for it
1441     mode_t systemMask;
1442
1443     unlink(filePath.c_str());
1444     //allow to create file with 777 rights
1445     systemMask = umask(0000);
1446     int fd = open(filePath.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
1447     //restore system mask
1448     umask(systemMask);
1449     RUNNER_ASSERT_MSG_BT(fd > -1, "Unable to create file for tests: " << strerror(errno));
1450
1451     //for descriptor protection
1452     FDUniquePtr fp(&fd, closeFdPtr);
1453
1454     //change owner and group to user APP
1455     int ret = chown(filePath.c_str(), APP_UID, APP_GID);
1456     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to change file owner: " << strerror(errno));
1457
1458     //set smack label on file
1459     ret = smack_setlabel(filePath.c_str(), fileLabel.c_str(), SMACK_LABEL_ACCESS);
1460     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to set label for file: " << ret);
1461
1462     char *label = NULL;
1463     ret = smack_getlabel(filePath.c_str(), &label, SMACK_LABEL_ACCESS);
1464     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to get label from file");
1465     std::string label_str(label ? label : "");
1466     free(label);
1467     RUNNER_ASSERT_MSG_BT(label_str == fileLabel, "File label not match set label");
1468 }
1469
1470 void prepareEnvironment(const std::string &subject, const std::string &object, const std::string &access)
1471 {
1472     const std::string ruleAll = "x";
1473
1474     SecurityServer::AccessProvider provider(subject);
1475     provider.allowAPI("system::homedir", ruleAll);
1476     provider.allowAPI(object, access);
1477     provider.applyAndSwithToUser(APP_UID, APP_GID);
1478 }
1479
1480 //- Add "l" rule to system
1481 //
1482 //Should be able to add "l" rule to system
1483 RUNNER_CHILD_TEST_SMACK(smack13_0_checking_laccess_mode_enabled_on_device)
1484 {
1485     std::string selfLabel = "smack13_0";
1486     std::string filename = "smack13_0_file";
1487
1488     //function inside checks if rule exist after add it
1489     SecurityServer::AccessProvider provider(selfLabel);
1490     provider.allowAPI(filename, "l");
1491     provider.apply();
1492
1493     int ret = smack_have_access(selfLabel.c_str(), filename.c_str(), "l");
1494     RUNNER_ASSERT_MSG_BT(ret == 1, "Error in adding laccess rule - l");
1495 }
1496
1497 //- Create file
1498 //- Set label for file and self
1499 //- Drop privileges
1500 //
1501 //Should have no access due to missing SMACK rule
1502 RUNNER_CHILD_TEST_SMACK(smack13_1_checking_laccess_mode)
1503 {
1504     std::string selfLabel = "smack13_1";
1505     std::string filename = "smack13_1_file";
1506     std::string filePath = testDir + filename;
1507
1508     createFileWithLabel(filePath, filename);
1509     int fd = open(filePath.c_str(), O_RDWR, 0);
1510     FDUniquePtr fp(&fd, closeFdPtr);
1511
1512     SecurityServer::AccessProvider provider(selfLabel);
1513     provider.applyAndSwithToUser(APP_UID, APP_GID);
1514
1515     int ret = flock(fd, LOCK_EX | LOCK_NB);
1516     RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file: " << strerror(errno));
1517     ret = flock(fd, LOCK_UN | LOCK_NB);
1518     RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file: " << strerror(errno));
1519     ret = flock(fd, LOCK_SH | LOCK_NB);
1520     RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file: " << strerror(errno));
1521 }
1522
1523 //- Create file
1524 //- Set label for file and self
1525 //- Add SMACK rule "l"
1526 //- Drop privileges
1527 //
1528 //Should be able to lock file even without "w" rule
1529 RUNNER_CHILD_TEST_SMACK(smack13_2_checking_laccess_mode_with_l_rule)
1530 {
1531     std::string selfLabel = "smack13_2";
1532     std::string filename = "smack13_2_file";
1533     std::string filePath = testDir + filename;
1534
1535     createFileWithLabel(filePath, filename);
1536     int fd = open(filePath.c_str(), O_RDWR, 0);
1537     FDUniquePtr fp(&fd, closeFdPtr);
1538
1539     prepareEnvironment(selfLabel, filename, "l");
1540
1541     int ret = flock(fd, LOCK_EX | LOCK_NB);
1542     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
1543     ret = flock(fd, LOCK_UN | LOCK_NB);
1544     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to unlock file: " << strerror(errno));
1545     ret = flock(fd, LOCK_SH | LOCK_NB);
1546     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
1547 }
1548
1549 //- Create file
1550 //- Set label for file and self
1551 //- Add SMACK rule "w"
1552 //- Drop privileges
1553 //
1554 //Should be able to lock file even without "l" rule
1555 RUNNER_CHILD_TEST_SMACK(smack13_3_checking_laccess_mode_with_w_rule)
1556 {
1557     std::string selfLabel = "smack13_3";
1558     std::string filename = "smack13_3_file";
1559     std::string filePath = testDir + filename;
1560
1561     createFileWithLabel(filePath, filename);
1562     int fd = open(filePath.c_str(), O_RDWR, 0);
1563     FDUniquePtr fp(&fd, closeFdPtr);
1564
1565     prepareEnvironment(selfLabel, filename, "w");
1566
1567     int ret = flock(fd, LOCK_EX | LOCK_NB);
1568     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
1569     ret = flock(fd, LOCK_UN | LOCK_NB);
1570     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to unlock file: " << strerror(errno));
1571     ret = flock(fd, LOCK_SH | LOCK_NB);
1572     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
1573 }
1574
1575 //- Create file
1576 //- Set label for file and self
1577 //- Add SMACK rule "rw"
1578 //- Drop privileges
1579 //- Lock file (shared lock)
1580 //- Spawn child process
1581 //- Child tries to lock file (shared)
1582 //
1583 //Child should be able to lock file due to shared lock
1584 RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_0_checking_laccess_mode_w_rule_child)
1585 {
1586     std::string selfLabel = "smack13_4_0";
1587     std::string filename = "smack13_4_0_file";
1588     std::string filePath = testDir + filename;
1589
1590     createFileWithLabel(filePath, filename);
1591     int fd = open(filePath.c_str(), O_RDWR);
1592     FDUniquePtr fp(&fd, closeFdPtr);
1593     int ret = flock(fd, LOCK_SH | LOCK_NB);
1594     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
1595
1596     pid_t pid = fork();
1597     if (pid == 0) {
1598         //child process
1599         prepareEnvironment(selfLabel, filename, "rw");
1600
1601         int child_fd = open(filePath.c_str(), O_RDWR);
1602         RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
1603
1604         //for descriptor protection
1605         FDUniquePtr fp(&child_fd, closeFdPtr);
1606
1607         ret = flock(child_fd, LOCK_SH | LOCK_NB);
1608         RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to lock file with shared lock: "
1609                           << strerror(errno));
1610     }
1611 }
1612
1613 //- Create file
1614 //- Set label for file and self
1615 //- Add SMACK rule "l"
1616 //- Drop privileges
1617 //- Lock file (shared lock)
1618 //- Spawn child process
1619 //- Child tries to lock file (shared)
1620 //
1621 //Child should be able to lock file due to shared lock
1622 RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_1_checking_laccess_mode_l_rule_child)
1623 {
1624     std::string selfLabel = "smack13_4_1";
1625     std::string filename = "smack13_4_1_file";
1626     std::string filePath = testDir + filename;
1627
1628     createFileWithLabel(filePath, filename);
1629     int fd = open(filePath.c_str(), O_RDWR);
1630     FDUniquePtr fp(&fd, closeFdPtr);
1631     int ret = flock(fd, LOCK_SH | LOCK_NB);
1632     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
1633
1634     pid_t pid = fork();
1635     if (pid == 0) {
1636         //child process
1637         //"r" is only for open in O_RDONLY mode
1638         prepareEnvironment(selfLabel, filename, "rl");
1639
1640         int child_fd = open(filePath.c_str(), O_RDONLY, 0);
1641         RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
1642
1643         //for descriptor protection
1644         FDUniquePtr fp(&child_fd, closeFdPtr);
1645
1646         ret = flock(child_fd, LOCK_SH | LOCK_NB);
1647         RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to lock file with shared lock: "
1648                           << strerror(errno));
1649     }
1650 }
1651
1652 //- Create file
1653 //- Set label for file and self
1654 //- Add SMACK rule "rw"
1655 //- Drop privileges
1656 //- Lock file (exclusive lock)
1657 //- Spawn child process
1658 //- Child tries to lock file (exclusive / shared)
1659 //
1660 //Child should not be able to lock file due to exclusive lock
1661 RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_2_checking_laccess_mode_w_rule_child)
1662 {
1663     std::string selfLabel = "smack13_4_2";
1664     std::string filename = "smack13_4_2_file";
1665     std::string filePath = testDir + filename;
1666
1667     createFileWithLabel(filePath, filename);
1668     int fd = open(filePath.c_str(), O_RDWR);
1669     FDUniquePtr fp(&fd, closeFdPtr);
1670     int ret = flock(fd, LOCK_EX | LOCK_NB);
1671     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
1672
1673     pid_t pid = fork();
1674     if (pid == 0) {
1675         //child process
1676         prepareEnvironment(selfLabel, filename, "rw");
1677
1678         int child_fd = open(filePath.c_str(), O_RDWR, 0);
1679         RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
1680
1681         //for descriptor protection
1682         FDUniquePtr fp(&child_fd, closeFdPtr);
1683
1684         ret = flock(child_fd, LOCK_EX | LOCK_NB);
1685         RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file with exclusive lock");
1686     }
1687 }
1688
1689 //- Create file
1690 //- Set label for file and self
1691 //- Add SMACK rule "l"
1692 //- Drop privileges
1693 //- Lock file (exclusive lock)
1694 //- Spawn child process
1695 //- Child tries to lock file (exclusive / shared)
1696 //
1697 //Child should not be able to lock file due to exclusive lock
1698 RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_3_checking_laccess_mode_l_rule_child)
1699 {
1700     std::string selfLabel = "smack13_4_3";
1701     std::string filename = "smack13_4_3_file";
1702     std::string filePath = testDir + filename;
1703
1704     createFileWithLabel(filePath, filename);
1705     int fd = open(filePath.c_str(), O_RDWR, 0);
1706     FDUniquePtr fp(&fd, closeFdPtr);
1707     int ret = flock(fd, LOCK_EX | LOCK_NB);
1708     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
1709
1710     pid_t pid = fork();
1711     if (pid == 0) {
1712         //child process
1713         //"r" is only for open in O_RDONLY mode
1714         prepareEnvironment(selfLabel, filename, "rl");
1715
1716         int child_fd = open(filePath.c_str(), O_RDONLY, 0);
1717         RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
1718
1719         //for descriptor protection
1720         FDUniquePtr fp(&child_fd, closeFdPtr);
1721
1722         ret = flock(child_fd, LOCK_EX | LOCK_NB);
1723         RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file with eclusive lock");
1724     }
1725 }
1726
1727
1728 /////////////////////////////////////////
1729 //////NOSMACK ENVIRONMENT TESTS//////////
1730 /////////////////////////////////////////
1731
1732 /**
1733  * NOSMACK version of smack02 test. Functions, that should return error instead of success:
1734  * - smack_accesses_apply
1735  * - smack_have_access
1736  * - smack_revoke_subject
1737  * - smack_acceesses_clear
1738  *
1739  * Tests smack03, smack04, smack10, smack_accesses_clear, smack_revoke_subject all use functions
1740  * tested in smack02 test. Results from those functions (smack_have_access, smack_accesses_apply,
1741  * smack_accesses_clear, smack_revoke_subject) would be the same as in this test. Tests mentioned
1742  * above doesn't make much sense on NOSMACK environment when test smack02 exists and passes
1743  * correctly, thus those tests are are not implemented.
1744  */
1745 RUNNER_TEST_NOSMACK(smack02_aplying_rules_into_kernel_nosmack)
1746 {
1747
1748     smack_accesses *tmp = NULL;
1749     int result;
1750
1751     //init rules
1752     result = smack_accesses_new(&tmp);
1753     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to create smack_accesses instance");
1754
1755     //pass rules to unique_ptr
1756     AccessesUniquePtr rules(tmp, smack_accesses_free);
1757
1758     //adding test rules to struct (same as SMACK version of smack02 test)
1759     result = smack_accesses_add(rules.get(), "writer", "book", "rwx");
1760     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
1761     result = smack_accesses_add(rules.get(), "reader", "book", "r");
1762     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
1763     result = smack_accesses_add(rules.get(), "spy", "book", "rwx");
1764     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
1765
1766     //applying rules to kernel (should fail)
1767     result = smack_accesses_apply(rules.get());
1768     RUNNER_ASSERT_MSG_BT(result == -1, "Unable to apply rules into kernel");
1769
1770     //calls from SMACK version of this test - all should fail because of SMACK being turned off
1771     result = smack_have_access("spy", "book", "rwx");
1772     RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off)");
1773     result = smack_have_access("reader", "book", "rwx");
1774     RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off)");
1775     result = smack_have_access("s02badsubjectlabel", "book", "rwx");
1776     RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off)");
1777
1778     //testing subject revoking - should return error (no accesses applied = no subjects to revoke)
1779     result = smack_revoke_subject("s02nonexistinglabel");
1780     RUNNER_ASSERT_MSG_BT(result == -1, "smack_revoke_subject error - subject doesn't exist.");
1781     result = smack_revoke_subject("spy");
1782     RUNNER_ASSERT_MSG_BT(result == -1, "smack_revoke_subject error - subject doesn't exist.");
1783
1784     //after revoking smack_have_access still should return error
1785     result = smack_have_access("spy", "book", "rwx");
1786     RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off).");
1787
1788     result = smack_accesses_add(rules.get(), "s02subjectlabel", "book", "rwx");
1789     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
1790
1791     //smack_accesses_clear should return error aswell
1792     result = smack_accesses_clear(rules.get());
1793     RUNNER_ASSERT_MSG_BT(result == -1, "Clearing rules should return error - no SMACK on system.");
1794
1795     result = smack_have_access("writer", "book", "rwx");
1796     RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off).");
1797 }
1798
1799 /**
1800  * NOSMACK version of smack11 test. Tests functions:
1801  * - smack_accesses_add_from_file
1802  *
1803  * Since other SMACK functions were tested in smack02 test, the only function needed to be checked
1804  * is applying rules loaded from file.
1805  */
1806 RUNNER_TEST_NOSMACK(smack03_saving_loading_rules_nosmack)
1807 {
1808     int result;
1809     int fd;
1810
1811     smack_accesses* tmp = NULL;
1812
1813     result = smack_accesses_new(&tmp);
1814     RUNNER_ASSERT_MSG_BT(result == 0, "Error during rules creation.");
1815
1816     AccessesUniquePtr rules(tmp, smack_accesses_free);
1817
1818     //open file with rules
1819     fd = open("/etc/smack/test_smack_rules_full", O_RDONLY, 0644);
1820     RUNNER_ASSERT_MSG_BT(fd >= 0,
1821             "Unable to open /etc/smack/test_smack_rules_full. Errno: " << strerror(errno));
1822
1823     //load accesses from file
1824     result = smack_accesses_add_from_file(rules.get(), fd);
1825     close(fd);
1826     RUNNER_ASSERT_MSG_BT(result == 0, "Error while importing accesses from file. Result: " << result);
1827 }
1828
1829 /**
1830  * NOSMACK version of smack05 test. Tests if functions getting, or
1831  * setting self label work correctly (that is, return error).
1832  */
1833 RUNNER_TEST_NOSMACK(smack04_self_label_nosmack)
1834 {
1835     char* label = NULL;
1836     int result;
1837     int fd;
1838
1839     char buff[SMACK_LABEL_LEN+1];
1840
1841     //smack_new_label_from_self should fail
1842     result = smack_new_label_from_self(&label);
1843     RUNNER_ASSERT_MSG_BT(result == -1, "new_label_from_self should return error (SMACK is off).");
1844     RUNNER_ASSERT_MSG_BT(label == NULL, "new_label_from_self shouldn't allocate memory to label.");
1845
1846     //We don't need to remember about freeing label - smack_new_label_from_self must return NULL
1847     //label if it's working properly.
1848
1849     // /proc/self/attr/current shouldn't keep any rules inside
1850     fd = open("/proc/self/attr/current", O_RDONLY, 0644);   //file exists, so it should open
1851     RUNNER_ASSERT_MSG_BT(fd >= 0, "/proc/self/attr/current failed to open.");
1852
1853     result = read(fd, buff, SMACK_LABEL_LEN);   //however reading it should return error
1854     if(result >= 0) {
1855         close(fd);
1856         RUNNER_ASSERT_MSG_BT(false, "Reading /proc/self/attr/current should return error.");
1857     }
1858
1859     //setting label for self should fail
1860     result = smack_set_label_for_self("s04testlabel");
1861     if(result != -1) {
1862         close(fd);
1863         RUNNER_ASSERT_MSG_BT(false, "set_label_for_self should return error (SMACK is off).");
1864     }
1865
1866     //getting previously set label should also fail
1867     result = smack_new_label_from_self(&label);
1868     if(result != -1) {
1869         close(fd);
1870         RUNNER_ASSERT_MSG_BT(false, "new_label_from_self should return error (SMACK is off).");
1871     }
1872     if(label != NULL) {
1873         close(fd);
1874         RUNNER_ASSERT_MSG_BT(false, "new_label_from_self shouldn't allocate memory to label.");
1875     }
1876
1877     // /proc/self/attr/current still shouldn't keep any rules inside
1878     result = lseek(fd, 0, SEEK_SET);    //going to the file beginning
1879     if(result != 0) {
1880         close(fd);
1881         RUNNER_ASSERT_MSG_BT(false, "lseek() error.");
1882     }
1883
1884     result = read(fd, buff, SMACK_LABEL_LEN);   //however it should return error
1885     if(result >= 0) {
1886         close(fd);
1887         RUNNER_ASSERT_MSG_BT(false, "Reading /proc/self/attr/current should return error.");
1888     }
1889
1890     close(fd);
1891 }
1892
1893 /**
1894  * NOSMACK version of smack_accesses_add_modify_x tests.
1895  *
1896  * Because all smack_accesses_add_modify tests are basically the same (all use smack_accesses_apply
1897  * and smack_have_access, which return -1 when SMACK is turned off), it makes much more sense to
1898  * write one test which will create rules using smack_accesses_add_modify and then check if
1899  * smack_accesses_apply and smack_have_access indeed return -1 when SMACK is turned off.
1900  */
1901 RUNNER_TEST_NOSMACK(smack05_accesses_add_modify_nosmack)
1902 {
1903     int result;
1904     smack_accesses* tmp = NULL;
1905
1906     result = smack_accesses_new(&tmp);
1907     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to allocate memory for rules. Result: " << result);
1908
1909     AccessesUniquePtr rules(tmp, smack_accesses_free);
1910
1911     //Not doing clean_up() every RUNNER_ASSERT_MSG - what clean_up does is just a creation of new
1912     //rule struct and removal of currenctly added and applied rules. clean_up() must be done only
1913     //after smack_accesses_apply().
1914     result = smack_accesses_add_modify(rules.get(), TEST_SUBJECT, TEST_OBJECT, "rwx", "");
1915     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule. Result: " << result);
1916
1917     result = smack_accesses_add_modify(rules.get(), TEST_SUBJECT, TEST_OBJECT, "rwx", "");
1918     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule. Result: " << result);
1919
1920     result = smack_accesses_apply(rules.get());
1921     RUNNER_ASSERT_MSG_BT(result == -1,
1922             "smack_accesses_apply should return error (SMACK is off). Result: " << result);
1923
1924     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
1925     if(result != -1) {
1926         clean_up();
1927         RUNNER_ASSERT_MSG_BT(false,
1928                 "smack_have_access should return error (SMACK is off). Result: " << result);
1929     }
1930
1931     clean_up();
1932 }
1933
1934 /**
1935  * NOSMACK version of smack09 test.
1936  *
1937  * This test checks if smack_new_label_from_socket reacts correctly. Since label should be
1938  * acquired from getsockopt, and it should fail, we must only set up socket and call
1939  * smack_new_label_from_socket. It should return error.
1940  */
1941 RUNNER_MULTIPROCESS_TEST_NOSMACK(smack09_new_label_from_socket_nosmack)
1942 {
1943     int pid;
1944     struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
1945     unlink(SOCK_PATH);
1946     char* smack_label;
1947
1948     pid = fork();
1949     RUNNER_ASSERT_MSG_BT(pid >= 0, "Fork failed");
1950     if (!pid) { //child (server)
1951         int sock, result;
1952         int fd;
1953
1954         //Create new socket
1955         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1956         RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
1957
1958         //Bind it to sockaddr
1959         result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1960         if (result != 0) {
1961             close(sock);
1962             RUNNER_ASSERT_MSG_BT(false, "bind failed: " << strerror(errno));
1963         }
1964
1965         //Prepare for listening
1966         result = listen(sock, 1);
1967         if (result != 0) {
1968             close(sock);
1969             RUNNER_ASSERT_MSG_BT(false, "listen failed: " << strerror(errno));
1970         }
1971
1972         //Accept client
1973         alarm(2);
1974         fd = accept(sock, NULL, NULL);
1975         alarm(0);
1976         if (fd < 0) {
1977             close(sock);
1978             RUNNER_ASSERT_MSG_BT(false, "Failed when accepting connection from client.");
1979         }
1980
1981         //wait for smack_new_label_from_socket execution
1982         usleep(200);
1983
1984         //Close socket and server
1985         close(sock);
1986         exit(0);
1987     }
1988     else { //parent (client)
1989         //Wait a little bit until server is set up
1990         sleep(1);
1991         int sock, result;
1992
1993         //Create socket
1994         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1995         RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
1996
1997         //Connect to sockaddr
1998         result = connect(sock, (struct sockaddr*) &sockaddr,
1999                 sizeof(struct sockaddr_un));
2000         if (result != 0) {
2001             close(sock);
2002             RUNNER_ASSERT_MSG_BT(false, "connect failed: " << strerror(errno));
2003         }
2004
2005         //Try getting label, should fail beacuse getsockopt won't get anything
2006         result = smack_new_label_from_socket(sock, &smack_label);
2007         close(sock);
2008         RUNNER_ASSERT_MSG_BT(result == -1, "smack_new_label_from_socket should fail.");
2009     }
2010 }