Split existing tests into environment categories.
[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/log/log.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <sys/mman.h>
34 #include <sys/smack.h>
35 #include <sys/xattr.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38 #include <sys/wait.h>
39 #include "tests_common.h"
40
41 #define TEST_SUBJECT  "test_subject"
42 #define TEST_OBJECT   "test_oject"
43 #define TEST_OBJECT_2 "test_oject_2"
44
45 #define SOCK_PATH "/tmp/test-smack-socket"
46
47 std::vector<std::string> accessesBasic = { "r", "w", "x", "wx", "rx", "rw", "rwx", "rwxat" };
48
49
50
51
52 int files_compare(int fd1, int fd2)
53 {
54     int result = 0;
55
56     //for getting files sizes
57     struct stat fs1, fs2;
58
59     //handlers for mmap()
60     void *h1 = MAP_FAILED;
61     void *h2 = MAP_FAILED;
62
63     //getting files information
64     if (fstat(fd1, &fs1) == -1) {
65         perror("fstat");
66         return -1;
67     }
68     if (fstat(fd2, &fs2) == -1) {
69         perror("fstat");
70         return -1;
71     }
72
73     if (fs1.st_size != fs2.st_size) //if files are identical size will be the same
74         return -1;
75
76     //mapping files to process memory
77     if ((h1 = mmap(0, fs1.st_size, PROT_READ, MAP_SHARED, fd1, 0 )) == MAP_FAILED) {
78         result = -1;
79         goto end;
80     }
81     if ((h2 = mmap(0, fs2.st_size, PROT_READ, MAP_SHARED, fd2, 0 )) == MAP_FAILED) {
82         result = -1;
83         goto end;
84     }
85
86     result = memcmp(h1, h2, fs1.st_size);
87
88     //cleaning after mmap()
89 end:
90     if (h2 != MAP_FAILED)
91         munmap(h2, fs2.st_size);
92     if (h1 != MAP_FAILED)
93         munmap(h1, fs1.st_size);
94
95     return result;
96 }
97
98
99 RUNNER_TEST_GROUP_INIT(libsmack)
100 /**
101  * Helper method to reset privileges at the begginning of tests.
102  */
103 void clean_up()
104 {
105     struct smack_accesses *rules = NULL;
106     int result = smack_accesses_new(&rules);
107     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
108
109     // CLEAN UP
110     smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","rwxat");
111     smack_accesses_apply(rules);
112     smack_accesses_free(rules);
113
114     // PREINIT CHECK.
115     RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") != 1, "Rule has previous privileges after cleaning up!");
116     RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"w") != 1, "Rule has previous privileges after cleaning up!");
117     RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"x") != 1, "Rule has previous privileges after cleaning up!");
118     RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"a") != 1, "Rule has previous privileges after cleaning up!");
119     RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"t") != 1, "Rule has previous privileges after cleaning up!");
120 }
121
122 /**
123  * Checking if subject has any access to object
124  */
125 bool checkNoAccesses(const char *subject, const char *object)
126 {
127     int result;
128     result = smack_have_access(subject, object,"r");
129     if (result == 1) {
130         return false;
131     }
132     result = smack_have_access(subject, object,"w");
133     if (result == 1) {
134         return false;
135     }
136     result = smack_have_access(subject, object,"x");
137     if (result == 1) {
138         return false;
139     }
140     result = smack_have_access(subject, object,"a");
141     if (result == 1) {
142         return false;
143     }
144     result = smack_have_access(subject, object,"t");
145     if (result == 1) {
146         return false;
147     }
148     return true;
149 }
150
151 void removeAccessesAll()
152 {
153     struct smack_accesses *rules = NULL;
154     int result = smack_accesses_new(&rules);
155     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
156
157     result = smack_accesses_add_modify(rules, "test_subject_01", "test_object_01", "", "rxwat");
158     result = smack_accesses_add_modify(rules, "test_subject_01", "test_object_02", "", "rxwat");
159     result = smack_accesses_add_modify(rules, "test_subject_01", "test_object_03", "", "rxwat");
160     result = smack_accesses_add_modify(rules, "test_subject_02", "test_object_01", "", "rxwat");
161     result = smack_accesses_add_modify(rules, "test_subject_02", "test_object_02", "", "rxwat");
162     result = smack_accesses_add_modify(rules, "test_subject_02", "test_object_03", "", "rxwat");
163     result = smack_accesses_add_modify(rules, "test_subject_03", "test_object_01", "", "rxwat");
164     result = smack_accesses_add_modify(rules, "test_subject_03", "test_object_02", "", "rxwat");
165     result = smack_accesses_add_modify(rules, "test_subject_03", "test_object_03", "", "rxwat");
166
167     smack_accesses_apply(rules);
168     RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
169     smack_accesses_free(rules);
170 }
171
172
173 /**
174  * Add a new access with smack_accesses_add_modify()
175  */
176 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_1){
177     int result;
178
179     clean_up();
180
181     struct smack_accesses *rules = NULL;
182     result = smack_accesses_new(&rules);
183
184     // THE TEST
185     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"xr","");
186     RUNNER_ASSERT_MSG(result == 0, "Unable to add modify by empty rules");
187     RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
188
189     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"xr");
190     RUNNER_ASSERT_MSG(result == 1, "Rule modified (added 'xr'), but no change made.");
191
192     // CLEAN UP
193     clean_up();
194     smack_accesses_free(rules);
195 }
196
197
198 /**
199  * Test if rules are applied in the right order, and modification works.
200  */
201 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_2){
202     int result;
203     struct smack_accesses *rules = NULL;
204     result = smack_accesses_new(&rules);
205     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
206
207     clean_up();
208
209     // THE TEST
210     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"r","");
211     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
212
213     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
214     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
215
216     RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
217     RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") == 0, "Modification didn't work");
218
219     // CLEAN UP
220     clean_up();
221     smack_accesses_free(rules);
222 }
223
224
225 /**
226  * Test if rules are applied in the right order, and modification works.
227  * Using different smack_accesses list to add and delete.
228  */
229 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_3){
230     int result;
231     struct smack_accesses *rules = NULL;
232     result = smack_accesses_new(&rules);
233     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
234
235     clean_up();
236
237     // THE TEST
238     // Add r privilage
239     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"r","");
240     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
241     RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
242     RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") == 1, "Adding privileges didn't work");
243     smack_accesses_free(rules);
244
245     // Revoke r privilege
246     result = smack_accesses_new(&rules);
247     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
248     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
249     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
250     RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
251
252     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
253     RUNNER_ASSERT_MSG(result == 0, "Modification didn't work, rule has still 'r' privileges.");
254
255     // CLEAN UP
256     clean_up();
257     smack_accesses_free(rules);
258 }
259
260 /**
261  * Add a list of privileges and then revoke just ONE of them.
262  */
263 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_4){
264     int result;
265     struct smack_accesses *rules = NULL;
266     result = smack_accesses_new(&rules);
267     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
268
269     clean_up();
270
271     // THE TEST
272     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"rwxat","");
273     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
274     RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
275
276     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
277     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
278     RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
279
280     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"awxt");
281     RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule should have 'awxt' privileges.");
282     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
283     RUNNER_ASSERT_MSG(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
284
285     // CLEAN UP
286     clean_up();
287     smack_accesses_free(rules);
288 }
289
290 /**
291  * Add a list of privileges and then revoke just ONE of them.
292  * Without applying privileges in between those actions.
293  */
294 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_5){
295     int result;
296     struct smack_accesses *rules = NULL;
297     result = smack_accesses_new(&rules);
298     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
299
300     clean_up();
301
302     // THE TEST
303     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"rwxat","");
304     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
305
306     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
307     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
308     RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
309
310     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"awxt");
311     RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule should have 'awxt' privileges.");
312     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
313     RUNNER_ASSERT_MSG(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
314
315     // CLEAN UP
316     clean_up();
317     smack_accesses_free(rules);
318 }
319
320
321 /**
322  * Add a list of privileges and then revoke just TWO of them.
323  */
324 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_6){
325     int result;
326     struct smack_accesses *rules = NULL;
327     result = smack_accesses_new(&rules);
328     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
329
330     clean_up();
331
332     // THE TEST
333     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"rwt","");
334     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
335     RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
336
337     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"ax","rt");
338     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
339     RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
340
341     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"wax");
342     RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule should have 'wax' privileges.");
343     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
344     RUNNER_ASSERT_MSG(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
345
346     // CLEAN UP
347     clean_up();
348     smack_accesses_free(rules);
349 }
350
351 /**
352  * Run smack_accesses_add_modify with the same accesses_add and accesses_del.
353  */
354 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_7){
355     unsigned int i;
356     int result;
357
358     struct smack_accesses *rules = NULL;
359
360     for (i = 0; i < accessesBasic.size(); ++i) {
361         result = smack_accesses_new(&rules);
362         RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
363
364         result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str(),accessesBasic[i].c_str());
365         RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
366         RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
367
368         RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
369             " Error while checking smack access. Accesses exist.");
370
371         // CLEAN UP
372         clean_up();
373         smack_accesses_free(rules);
374     }
375 }
376
377 /**
378  * Revoke subject with previously added rules and revoke it again.
379  */
380 RUNNER_TEST_SMACK(smack_revoke_subject_test_1){
381     unsigned int i;
382     int result;
383
384     struct smack_accesses *rules = NULL;
385
386     for (i = 0; i < accessesBasic.size(); ++i) {
387         // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
388         result = smack_accesses_new(&rules);
389         RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
390         result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str(),"");
391         result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str(),"");
392         RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
393         RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
394         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
395         RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
396         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
397         RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
398
399         // Revoking subject
400         result = smack_revoke_subject(TEST_SUBJECT);
401         RUNNER_ASSERT_MSG(result == 0, "Revoking subject didn't work.");
402
403         RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
404             " Revoke didn't work. Accesses exist.");
405         RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
406             " Revoke didn't work. Accesses exist.");
407
408
409         // Revoking subject again
410         result = smack_revoke_subject(TEST_SUBJECT);
411         RUNNER_ASSERT_MSG(result == 0, "Revoking subject didn't work.");
412
413         RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
414             " Revoke didn't work. Accesses exist.");
415         RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
416             " Revoke didn't work. Accesses exist.");
417
418         smack_accesses_free(rules);
419     }
420 }
421
422 /**
423  * Clearing accesses
424  */
425 RUNNER_TEST_SMACK(smack_accesses_clear_test_1){
426     unsigned int i;
427     int result;
428
429     struct smack_accesses *rules = NULL;
430
431     for (i = 0; i < accessesBasic.size(); ++i) {
432         // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
433         result = smack_accesses_new(&rules);
434         RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
435         result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
436         RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
437         result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
438         RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
439         RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
440
441         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
442         RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
443         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
444         RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
445
446         smack_accesses_free(rules);
447
448         // Creating and clearing rules with TEST_OBJECT
449         result = smack_accesses_new(&rules);
450         RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
451         result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
452         RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
453         result = smack_accesses_clear(rules);
454         RUNNER_ASSERT_MSG(result == 0, "Clearing rules didn't work.");
455
456         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
457         RUNNER_ASSERT_MSG(result == 0, "Clearing rules didn't work. Rule " << accessesBasic[i].c_str() << " does exist.");
458         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
459         RUNNER_ASSERT_MSG(result == 1, "Clearing rules didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
460
461         smack_accesses_free(rules);
462
463         // Creating and clearing rules with TEST_OBJECT_2
464         result = smack_accesses_new(&rules);
465         RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
466
467         result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
468         RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
469         result = smack_accesses_clear(rules);
470         RUNNER_ASSERT_MSG(result == 0, "Clearing rules didn't work.");
471
472         smack_accesses_free(rules);
473
474         RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
475             " Clear didn't work. Accesses exist.");
476         RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
477             " Clear didn't work. Accesses exist.");
478     }
479 }
480
481 RUNNER_TEST(smack01_storing_and_restoring_rules)
482 {
483     /*
484      * author: Pawel Polawski
485      * test: smack_accesses_new, smack_accesses_add, smack_accesses_add_modify, smack_accesses_add_from_file,
486      *       smack_accesses_free, smack_accesses_save
487      * description: This test case will create structure holding SMACK rules and add new one to it. Next rules will be
488      *              stored and restored from file.
489      * expect: Rules created and stored in file should be identical to predefined template.
490      */
491
492     struct smack_accesses *rules = NULL;        //rules prepared in this test case
493     struct smack_accesses *import_test = NULL;  //rules imported from file
494
495     int result;             //result of each operation to be tested by RUNNER_ASSERT
496     int fd, tmp, sample;    //file descripptors for save / restore rules tests
497
498     //int smack_accesses_new(struct smack_accesses **accesses);
499     result = smack_accesses_new(&rules);        //rules struct init
500     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
501     result = smack_accesses_new(&import_test);  //rules struct init
502     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
503
504     //opening files
505     fd = open("/tmp/smack01_rules", O_RDWR | O_CREAT | O_TRUNC, 0644);  //for export prepared rules
506     RUNNER_ASSERT_MSG(fd >= 0, "Unable to create /tmp/smack01_rules");
507     tmp = open("/tmp/smack01_tmp", O_RDWR | O_CREAT | O_TRUNC, 0644);   //for import rules exported before
508     RUNNER_ASSERT_MSG(fd >= 0, "Unable to create /tmp/smack01_tmp");
509     sample = open("/etc/smack/test_smack_rules", O_RDONLY, 0644);             //reference preinstalled rules
510     RUNNER_ASSERT_MSG(sample >= 0, "Unable to open /etc/smack/test_smack_rules");
511
512     //int smack_accesses_add(struct smack_accesses *handle, const char *subject,
513     //               const char *object, const char *access_type);
514     result = smack_accesses_add(rules, "writer", "book", "rw");
515     RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
516     result = smack_accesses_add(rules, "reader", "book", "wx");
517     RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
518
519     //int smack_accesses_add_modify(struct smack_accesses *handle, const char *subject,
520     //               const char *object, const char *access_add, const char *access_del);
521     result = smack_accesses_add_modify(rules, "reader", "book", "r", "wx");
522     RUNNER_ASSERT_MSG(0 == result, "Unable to modify smack rules");
523
524     //int smack_accesses_save(struct smack_accesses *handle, int fd);
525     result = smack_accesses_save(rules, fd);
526     RUNNER_ASSERT_MSG(0 == result, "Unable to save smack_accesses instance in file");
527
528     //int smack_accesses_add_from_file(struct smack_accesses *accesses, int fd);
529     result = lseek(fd, 0, SEEK_SET);
530     RUNNER_ASSERT_MSG(result == 0, "lseek() error");
531     result = smack_accesses_add_from_file(import_test, fd);
532     RUNNER_ASSERT_MSG(result == 0, "Unable to import rules from file");
533
534     result = smack_accesses_save(import_test, tmp);
535     RUNNER_ASSERT_MSG(result == 0, "Unable to save smack_accesses instance in file");
536
537     result = files_compare(fd, tmp);    //comparing rules saved in file, restored from it and stored one more time
538     RUNNER_ASSERT_MSG(result == 0, "No match in stored and restored rules");
539
540     result = files_compare(tmp, sample);    //comparing rules stored in file with reference preinstalled rules
541     RUNNER_ASSERT_MSG(result == 0, "No match in stored rules and pattern file");
542
543     //void smack_accesses_free(struct smack_accesses *handle);
544     smack_accesses_free(rules);
545     smack_accesses_free(import_test);
546
547     //closing file descriptors
548     close(fd);
549     close(tmp);
550     close(sample);
551 }
552
553 RUNNER_TEST_SMACK(smack02_aplying_rules_into_kernel)
554 {
555     /*
556      * author: Pawel Polawski
557      * test: smack_accesses_apply, smack_have_access, smack_revoke_subject, smack_accesses_clear, smack_accesses_new,
558      *       smack_accesses_add, smack_accesses_free
559      * description: In this test case aplying rules to kernel will be tested. After that function for test
560      *              accesses will be used.
561      * expect: In case of correct rules access should be granted.
562      */
563
564     //CAP_MAC_ADMIN needed for process to be able to change rules in kernel (apllying, removing)
565
566     struct smack_accesses *rules = NULL;        //rules prepared in this test case
567     int result;                                 //for storing functions results
568
569     result = smack_accesses_new(&rules);        //rules struct init
570     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
571
572     //adding test rules to struct
573     result = smack_accesses_add(rules, "writer", "book", "rwx");
574     RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
575     result = smack_accesses_add(rules, "reader", "book", "r");
576     RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
577     result = smack_accesses_add(rules, "spy", "book", "rwx");
578     RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
579
580     //int smack_accesses_apply(struct smack_accesses *handle);
581     result = smack_accesses_apply(rules);       //applying rules to kernel
582     RUNNER_ASSERT_MSG(result == 0, "Unable to apply rules into kernel");
583
584     //int smack_have_access(const char *subject, const char *object,
585     //                  const char *access_type);
586     result = smack_have_access("spy", "book", "rwx");       //should have access - rule exist
587     RUNNER_ASSERT_MSG(result == 1, "Error while checking Smack access");
588     result = smack_have_access("reader", "book", "rwx");    //should have no access - wrong rule, should be "r" only
589     RUNNER_ASSERT_MSG(result == 0, "Error while checking Smack access");
590     result = smack_have_access("mars", "book", "rwx");      //should fail - rule not exist
591     RUNNER_ASSERT_MSG(result == -1, "Error while checking Smack access");
592
593     //int smack_revoke_subject(const char *subject);
594     result = smack_revoke_subject("snickers");  //this subject do not exist in kernel rules
595     RUNNER_ASSERT_MSG(result == 0, "Error in removing not existing subject from kernel");
596     result = smack_revoke_subject("spy");       //this subject exist in kernel rules
597     RUNNER_ASSERT_MSG(result == 0, "Error in removing existing subject from kernel");
598
599     result = smack_have_access("spy", "book", "rwx");                   //testing access after revoke_subject() from kernel
600     RUNNER_ASSERT_MSG(result == 0, "Error in acces aplied to kernel");  //now spy should have no access
601
602     result = smack_accesses_add(rules, "twix", "book", "rwx");          //for create new rule as a consequence of use accesses_clear() below
603     RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
604
605     //int smack_accesses_clear(struct smack_accesses *handle);
606     result = smack_accesses_clear(rules);    //"spy" removed before by using smack_revoke_subject()
607     RUNNER_ASSERT_MSG(result == 0, "Error in clearing rules in kernel");
608
609     result = smack_have_access("writer", "book", "rwx");                //testing acces after acces_clear()
610     RUNNER_ASSERT_MSG(result == 0, "Error in acces aplied to kernel");  //now writer also should have no access
611
612     //free resources
613     smack_accesses_free(rules);
614 }
615
616 //pairs of rules for test with mixed cases, different length and mixed order
617 const char *rules_tab[] = {
618     "reader1",  "-",                "-----",
619     "reader2",  "--------",         "-----",
620     "reader3",  "RwXaT",            "rwxat",
621     "reader4",  "RrrXXXXTTT",       "r-x-t",
622     "reader5",  "-r-w-a-t",         "rw-at",
623     "reader6",  "",                 "-----",
624     "reader7",  "xa--Rt---W",       "rwxat",
625     "reader8",  "#Ax[T].!~W@1}",    "-wxat"
626 };
627
628 RUNNER_TEST_SMACK(smack03_mixed_rule_string_add)
629 {
630     /*
631      * author: Pawel Polawski
632      * test: smack_have_access, smack_accesses_new, smack_accesses_add, smack_accesses_apply, smack_accesses_free
633      * description: In thist test case rules based on mixed string are added to kernel.
634      *              Strings are presented above and contains lower / upper case alpha, numbers and special signs.
635      * expect: Rules should be parsed correct and aplied to kernel.
636      */
637
638     //In thist test case mixed string are used as rules applied to kernel, next they are
639     //readed and compared with correct form of rules
640
641     struct smack_accesses *rules = NULL;        //rules prepared in this test case
642     int result;                                 //for storing functions results
643     int i;
644     int expected;
645
646     result = smack_accesses_new(&rules);        //rules struct init
647     RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
648
649     //adding test rules with mixed string
650     for (i = 0; i < (3 * 8); i += 3) {
651         result = smack_accesses_add(rules, rules_tab[i], "book", rules_tab[i + 1]); //using mixed rules from table
652         RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
653     }
654
655     //clearing
656     //FIXME: Using clear() here can cover error in accesses_apply() function
657     //result = smack_accesses_clear(rules);
658     //RUNNER_ASSERT_MSG(result == 0, "Error in clearing rules in kernel");
659
660     //applying rules to kernel
661     result = smack_accesses_apply(rules);
662     RUNNER_ASSERT_MSG(result == 0, "Unable to apply rules into kernel");
663
664     //checking accesses using normal rules
665     for (i = 0; i < (3 * 8); i += 3) {
666         if (!strcmp(rules_tab[i + 2], "-----"))
667             expected = 0;
668         else
669             expected = 1;
670         result = smack_have_access(rules_tab[i], "book", rules_tab[i + 2]); //using normal rules from table
671         RUNNER_ASSERT_MSG(result == expected, "Error while checking Smack access");
672     }
673
674     //free resources
675     smack_accesses_free(rules);
676 }
677
678 RUNNER_TEST_SMACK(smack04_mixed_rule_string_have_access)
679 {
680     /*
681      * author: Pawel Polawski
682      * test: smack_have_access
683      * description: In this test case we testing aplied before SMACK rules and comparing them using mixed strings.
684      * expect: Subjects should have accesses to the objects.
685      */
686
687     //In this test case we checking previous aplied rules but for compare mixed strings are used
688
689     int result;
690     int i;
691     int expected;
692
693     //rules were added in previous RUNNER_TEST section
694     //checking accesses using mixed rules
695     for (i = 0; i < (3 * 8); i += 3) {
696         if (!strcmp(rules_tab[i + 2], "-----"))
697             expected = 0;
698         else
699             expected = 1;
700         result = smack_have_access(rules_tab[i], "book", rules_tab[i + 1]); //using mixed rules from table
701         RUNNER_ASSERT_MSG(result == expected, "Error while checking Smack access");
702     }
703 }
704
705 //RUNNER_TEST(smackXX_accesses_add_modify)
706 //{
707 //IDEAS FOR TESTS
708 // - what if we want to apply rule that is already in kernel?
709 // - tests for smack_accesses_add_modify() + smack_have_access() (check if add_modify sets the proper rule)
710 // - smack_accesses_add_modify("subject", "object", "rwx", "rwx") should create empty rule
711 //}
712
713 RUNNER_TEST_SMACK(smack05_self_label)
714 {
715     /*
716      * author: Pawel Polawski
717      * test: smack_set_label_for_self, smack_new_label_from_self
718      * description: In this test case process test it own default label. Next label is changed
719      *              and tested one more time if change was successfull.
720      * expect: Proces should have default "-" label and can change it to the oter one.
721      */
722
723     //In this test case process will manipulate it own label
724
725     char *label = NULL;
726     int result;
727     int fd;
728
729     const int B_SIZE = 8;
730     char buff[B_SIZE];
731
732     const char *def_rule = "_";
733
734     //int smack_new_label_from_self(char **label);
735     result = smack_new_label_from_self(&label);
736     RUNNER_ASSERT_MSG(result == 0, "Error in getting self label");
737
738     //comparing this label with default one "_"
739     result = strcmp(label, def_rule);
740     RUNNER_ASSERT_MSG(result == 0, "Wrong default process label");
741
742     //comparing this rule with received from /proc/self/attr/current
743     fd = open("/proc/self/attr/current", O_RDONLY, 0644);
744     RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /proc/self/attr/current");
745     result = read(fd, buff, B_SIZE);
746     RUNNER_ASSERT_MSG(result >= 0, "Error in reading from file /proc/self/attr/current");
747     result = strncmp(buff, def_rule, result);
748     RUNNER_ASSERT_MSG(result == 0, "Wrong default process rule");
749
750     free(label);
751
752     //now time for setting labels:
753
754     //int smack_set_label_for_self(const char *label);
755     result = smack_set_label_for_self("cola");
756     RUNNER_ASSERT_MSG(result == 0, "Error in setting self label");
757
758     //checking new label using smack function
759     result = smack_new_label_from_self(&label);
760     RUNNER_ASSERT_MSG(result == 0, "Error in getting self label");
761     result = strcmp(label, "cola");
762     RUNNER_ASSERT_MSG(result == 0, "Wrong process label");
763
764     //checking new label using /proc/self/attr/current
765     result = lseek(fd, 0, SEEK_SET);    //going to the file beginning
766     RUNNER_ASSERT_MSG(result == 0, "lseek() error");
767     result = read(fd, buff, B_SIZE);
768     RUNNER_ASSERT_MSG(result >= 0, "Error in reading from file /proc/self/attr/current");
769     result = strncmp(buff, "cola", result);
770     RUNNER_ASSERT_MSG(result == 0, "Proces rule in /proc/self/attr/current other than set");
771
772     free(label);
773     close(fd);
774 }
775
776 //RUNNER_TEST(smackXX_parent_child_label)
777 //{
778 //In this test case parent process and child labels will be tested
779 //Parent will fork and check child's label. First fork will be with default "_" parent label,
780 //second one witch changed label.
781 //}
782
783 //bellow function is from libsmack.c witch changed name
784 const char *xattr(enum smack_label_type type)
785 {
786     switch (type) {
787         case SMACK_LABEL_ACCESS:
788             return "security.SMACK64";
789         case SMACK_LABEL_EXEC:
790             return "security.SMACK64EXEC";
791         case SMACK_LABEL_MMAP:
792             return "security.SMACK64MMAP";
793         case SMACK_LABEL_TRANSMUTE:
794             return "security.SMACK64TRANSMUTE";
795         case SMACK_LABEL_IPIN:
796             return "security.SMACK64IPIN";
797         case SMACK_LABEL_IPOUT:
798             return "security.SMACK64IPOUT";
799         default:
800             /*  Should not reach this point */
801             return NULL;
802     }
803 }
804
805 //TODO: In bellow RUNNER_TEST add  lget / lset functions to be testet the same way as normal get / set
806 RUNNER_TEST(smack06_get_set_label)
807 {
808     /*
809      * author: Pawel Polawski
810      * test: smack_getlabel, smack_setlabel
811      * description: In this test case file label is tested using SMACK API functions and system xattr functions.
812      *              Functions tested here is used for normal files.
813      * expect: Function should return default label, and the new one after change it.
814      */
815
816     //In this test case will be tested setting and getting file label
817     //If file is symbolic link functions should follow it
818
819     //SMACK xattr from libsmack.c:
820     //
821     //case SMACK_LABEL_ACCESS:
822     //    return "security.SMACK64";
823     //case SMACK_LABEL_EXEC:
824     //    return "security.SMACK64EXEC";
825     //case SMACK_LABEL_MMAP:
826     //    return "security.SMACK64MMAP";
827     //case SMACK_LABEL_TRANSMUTE:
828     //    return "security.SMACK64TRANSMUTE";
829     //case SMACK_LABEL_IPIN:
830     //    return "security.SMACK64IPIN";
831     //case SMACK_LABEL_IPOUT:
832     //    return "security.SMACK64IPOUT";
833
834     int result;
835     char *label = NULL;
836
837     const int B_SIZE = 8;
838     char buff[B_SIZE];
839
840     const char *file_path = "/etc/smack/test_smack_rules";
841
842
843     //preparing environment by restoring default "_" label
844     result = smack_setlabel(file_path, "_", SMACK_LABEL_ACCESS);
845     RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
846
847
848     //int smack_getlabel(const char *path, char** label,
849     //          enum smack_label_type type);
850     result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
851     RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
852     //get label, should be default "_"
853     result = strcmp(label, "_");
854     RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
855     free(label);
856     //get label using xattr function
857     result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
858     RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
859     //check label, should match the one readed by smack function
860     result = strncmp(buff, "_", result);
861     RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
862
863
864     //int smack_setlabel(const char *path, const char* label,
865     //          enum smack_label_type type);
866     result = smack_setlabel(file_path, "fanta", SMACK_LABEL_ACCESS);
867     RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
868
869
870     //get label using smack function
871     result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
872     RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
873     //get label, should be default "fanta"
874     result = strcmp(label, "fanta");
875     RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
876     free(label);
877     //get label using xattr function
878     result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
879     RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
880     //check label, should match the one readed by smack function
881     result = strncmp(buff, "fanta", result);
882     RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
883 }
884
885 //RUNNER_TEST(smackXX_get_label_exec)
886 //{
887 //In this test case EXEC label will be tested
888 //by setting this type of label, reading it and testing executed binary exit status
889 //}
890
891 RUNNER_TEST(smack07_l_get_set_label)
892 {
893     /*
894      * author: Pawel Polawski
895      * test: smack_lgetlabel, smack_lsetlabel, smack_getlabel
896      * description: Functions tested here are similar to one from previous test case. The difference
897      *              is that in case of symbolic link they follows it and operates on file pointed by it.
898      * expect: All label manipulations should affect file pointed by symbolic link.
899      */
900
901     int result;
902     char *label = NULL;
903
904     const int B_SIZE = 8;
905     char buff[B_SIZE];
906
907     const char *file_path = "/etc/smack/test_smack_rules_lnk";
908
909
910     //preparing environment by restoring default "_" label
911     result = smack_lsetlabel(file_path, "_", SMACK_LABEL_ACCESS);
912     RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
913     result = smack_setlabel(file_path, "_", SMACK_LABEL_ACCESS);
914     RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
915
916
917     //int smack_lgetlabel(const char *path, char** label,
918     //          enum smack_label_type type);
919     result = smack_lgetlabel(file_path, &label, SMACK_LABEL_ACCESS);
920     RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
921     //get label of symbolic link, should be default "_"
922     result = strcmp(label, "_");
923     RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
924     free(label);
925     //get label using xattr function
926     result = lgetxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
927     RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
928     //check label, should match the one readed by smack function
929     result = strncmp(buff, "_", result);
930     RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
931
932
933     //int smack_lsetlabel(const char *path, const char* label,
934     //          enum smack_label_type type);
935     result = smack_lsetlabel(file_path, "7up", SMACK_LABEL_ACCESS);
936     RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
937     //and set label for file pointed by link
938     result = smack_setlabel(file_path, "mirinda", SMACK_LABEL_ACCESS);
939     RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
940
941
942     //get label using smack function
943     result = smack_lgetlabel(file_path, &label, SMACK_LABEL_ACCESS);
944     RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
945     //check label, should be "7up"
946     result = strcmp(label, "7up");
947     RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
948     free(label);
949     //get label using xattr function
950     result = lgetxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
951     RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
952     //check label, should match the one readed by smack function
953     result = strncmp(buff, "7up", result);
954     RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
955
956
957     //now similar to above, but folowing symbolic link set before to "mirinda"
958     result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
959     RUNNER_ASSERT_MSG(result == 0, "Error gettin label of file pointed by symbolic link");
960     //now label should be "mirinda" for file instead of "7up" set for link
961     result = strcmp(label, "mirinda");
962     RUNNER_ASSERT_MSG(result == 0, "Wrong label of file pointed by symbolic link");
963     free(label);
964     //get label using xattr function
965     result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
966     RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
967     //check label, should match the one readed by smack function
968     result = strncmp(buff, "mirinda", result);
969     RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
970 }
971
972 RUNNER_TEST(smack08_f_get_set_label)
973 {
974     /*
975      * author: Pawel Polawski
976      * test: smack_fgetlabel, smack_fsetlabel
977      * description: This test case is similar to test case smack06 above. The difference
978      *              is that argument is file descriptor instead of file path.
979      *              Function not follow symbolic link and operates directly on it.
980      * expect: All label manipulations should affect symbolic link itself.
981      */
982
983     int result;
984     char *label = NULL;
985
986     const int B_SIZE = 8;
987     char buff[B_SIZE];
988
989     int fd;
990     const char *file_path = "/etc/smack/test_smack_rules";
991
992     fd = open(file_path, O_RDWR, 0644);             //reference preinstalled rules
993     RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules");
994
995     //preparing environment by restoring default "_" label
996     result = smack_fsetlabel(fd, "_", SMACK_LABEL_ACCESS);
997     RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
998
999
1000     //int smack_fgetlabel(int fd, char** label,
1001     //          enum smack_label_type type);
1002     result = smack_fgetlabel(fd, &label, SMACK_LABEL_ACCESS);
1003     RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
1004     //check label, should be "_"
1005     result = strcmp(label, "_");
1006     RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
1007     free(label);
1008     //get label using xattr function
1009     result = fgetxattr(fd, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
1010     RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
1011     //check label, should match the one readed by smack function
1012     result = strncmp(buff, "_", result);
1013     RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
1014
1015
1016     //int smack_fsetlabel(int fd, const char* label,
1017     //          enum smack_label_type type);
1018     result = smack_fsetlabel(fd, "sprite", SMACK_LABEL_ACCESS);
1019     RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
1020
1021
1022     //get label using smack function
1023     result = smack_fgetlabel(fd, &label, SMACK_LABEL_ACCESS);
1024     RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
1025     //check label, should be "sprite"
1026     result = strcmp(label, "sprite");
1027     RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
1028     free(label);
1029     //get label using xattr function
1030     result = fgetxattr(fd, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
1031     RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
1032     //check label, should match the one readed by smack function
1033     result = strncmp(buff, "sprite", result);
1034     RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
1035
1036
1037     close(fd);
1038 }
1039
1040 RUNNER_TEST_SMACK(smack10_adding_removing_rules)
1041 {
1042     unsigned int i;
1043     int result;
1044
1045     struct smack_accesses *rulesBasic = NULL;
1046
1047     for (i = 0; i < accessesBasic.size(); ++i)
1048     {
1049         // Creating rules
1050         result = smack_accesses_new(&rulesBasic);
1051         RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1052
1053         // Adding accesses
1054         result = smack_accesses_add(rulesBasic, TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1055         RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1056
1057         // Applying rules
1058         result = smack_accesses_apply(rulesBasic);
1059         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1060
1061         // Checking if accesses were created
1062         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1063         RUNNER_ASSERT_MSG(result == 1,
1064             " Error while checking smack access. Result: " << result);
1065
1066         smack_accesses_free(rulesBasic);
1067         rulesBasic = NULL;
1068
1069         // Deleting all rules
1070         clean_up();
1071     }
1072
1073     for (i = 0; i < 3; ++i)
1074     {
1075         // --- Creating rules (r or w or x)
1076         result = smack_accesses_new(&rulesBasic);
1077         RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1078
1079         // Adding accesses
1080         result = smack_accesses_add(rulesBasic, TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1081         RUNNER_ASSERT_MSG(result == 0, "Unable to add rulesBasic. Result: " << result);
1082
1083         // Applying rules
1084         result = smack_accesses_apply(rulesBasic);
1085         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1086         // Checking if accesses were created
1087         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1088         RUNNER_ASSERT_MSG(result == 1,
1089             " Error while checking smack access. Result: " << result);
1090
1091         // Checking if wrong accesses were not created
1092         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1093         RUNNER_ASSERT_MSG(result == 0,
1094             " Error while checking smack access. Result: " << result);
1095
1096         // --- Modifying accesses (r for wx or w for rx or x for rw)
1097         result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i + 3].c_str(),accessesBasic[i].c_str());
1098         RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1099
1100         // Applying rules
1101         result = smack_accesses_apply(rulesBasic);
1102         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1103
1104         // Checking if accesses were created
1105         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1106         RUNNER_ASSERT_MSG(result == 1,
1107             " Error while checking smack access. Result: " << result);
1108
1109         // Checking if wrong accesses were not created
1110         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1111         RUNNER_ASSERT_MSG(result == 0,
1112             " Error while checking smack access. Result: " << result);
1113
1114         smack_accesses_free(rulesBasic);
1115         rulesBasic = NULL;
1116
1117         // --- Creating complementary rules (r or w or x)
1118         result = smack_accesses_new(&rulesBasic);
1119         RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1120
1121         // Adding accesses
1122         result = smack_accesses_add(rulesBasic, TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1123         RUNNER_ASSERT_MSG(result == 0, "Unable to add rulesBasic. Result: " << result);
1124
1125         // Checking if accesses were created
1126         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1127         RUNNER_ASSERT_MSG(result == 1,
1128             " Error while checking smack access. Result: " << result);
1129
1130         // Applying rules
1131         result = smack_accesses_apply(rulesBasic);
1132         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1133
1134         // Checking if accesses were created
1135         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1136         RUNNER_ASSERT_MSG(result == 1,
1137             " Error while checking smack access. Result: " << result);
1138
1139         // --- Modifying accesses (adding rwx and removing r or w or x)
1140         result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,"rwx",accessesBasic[i].c_str());
1141         RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1142
1143         // Applying rules
1144         result = smack_accesses_apply(rulesBasic);
1145         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1146
1147         // Checking if accesses were created
1148         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1149         RUNNER_ASSERT_MSG(result == 1,
1150             " Error while checking smack access. Result: " << result);
1151
1152         // Checking if wrong accesses were not created
1153         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1154         RUNNER_ASSERT_MSG(result == 0,
1155             " Error while checking smack access. Result: " << result);
1156
1157         // --- Adding crossing accesses (rx or rw or wx)
1158         result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,accessesBasic[3 + ((i + 1) % 3)].c_str(),"");
1159         RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1160
1161         // Applying rules
1162         result = smack_accesses_apply(rulesBasic);
1163         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1164
1165         // Checking if accesses were created
1166         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[3 + ((i + 1) % 3)].c_str());
1167         RUNNER_ASSERT_MSG(result == 1,
1168             " Error while checking smack access. Result: " << result);
1169
1170         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
1171         RUNNER_ASSERT_MSG(result == 1,
1172             " Error while checking smack access. Result: " << result);
1173
1174         // Deleting all rules
1175         result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,"","rwx");
1176         RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1177
1178         result = smack_accesses_apply(rulesBasic);
1179         RUNNER_ASSERT_MSG(result == 0, "Error while checking smack access. Result: " << result);
1180
1181         smack_accesses_free(rulesBasic);
1182         rulesBasic = NULL;
1183
1184         // Deleting all rules
1185         clean_up();
1186     }
1187 }
1188
1189 RUNNER_TEST_SMACK(smack11_saving_loading_rules)
1190 {
1191     int result;
1192     int fd;
1193
1194     struct smack_accesses *rulesBasic = NULL;
1195
1196     // Pre-cleanup
1197     removeAccessesAll();
1198
1199     // Creating rules
1200     result = smack_accesses_new(&rulesBasic);
1201     RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1202
1203     // Loading file with rwxat rules - test_smack_rules_full
1204     fd = open("/etc/smack/test_smack_rules_full", O_RDONLY, 0644);
1205     RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules_full");
1206
1207     // Adding rules from file
1208     result = smack_accesses_add_from_file(rulesBasic, fd);
1209     close(fd);
1210     RUNNER_ASSERT_MSG(result == 0, "Error importing accesses from file");
1211
1212     // Applying rules
1213     result = smack_accesses_apply(rulesBasic);
1214     RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1215
1216     // Checking rules
1217     result = smack_have_access("test_subject_01", "test_object_01", "rwxat");
1218     RUNNER_ASSERT_MSG(result == 1,
1219         " Error while checking smack accesses.");
1220     result = smack_have_access("test_subject_01", "test_object_02", "rwxat");
1221     RUNNER_ASSERT_MSG(result == 1,
1222         " Error while checking smack accesses.");
1223     result = smack_have_access("test_subject_01", "test_object_03", "rwxat");
1224     RUNNER_ASSERT_MSG(result == 1,
1225         " Error while checking smack accesses.");
1226     result = smack_have_access("test_subject_02", "test_object_01", "rwxat");
1227     RUNNER_ASSERT_MSG(result == 1,
1228         " Error while checking smack accesses.");
1229     result = smack_have_access("test_subject_02", "test_object_02", "rwxat");
1230     RUNNER_ASSERT_MSG(result == 1,
1231         " Error while checking smack accesses.");
1232     result = smack_have_access("test_subject_02", "test_object_03", "rwxat");
1233     RUNNER_ASSERT_MSG(result == 1,
1234         " Error while checking smack accesses.");
1235     result = smack_have_access("test_subject_03", "test_object_01", "rwxat");
1236     RUNNER_ASSERT_MSG(result == 1,
1237         " Error while checking smack accesses.");
1238     result = smack_have_access("test_subject_03", "test_object_02", "rwxat");
1239     RUNNER_ASSERT_MSG(result == 1,
1240         " Error while checking smack accesses.");
1241     result = smack_have_access("test_subject_03", "test_object_03", "rwxat");
1242     RUNNER_ASSERT_MSG(result == 1,
1243         " Error while checking smack accesses.");
1244
1245     // Removing rules
1246     removeAccessesAll();
1247
1248     smack_accesses_free(rulesBasic);
1249
1250     // Creating rules
1251     result = smack_accesses_new(&rulesBasic);
1252     RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1253
1254     // Loading file with partial wrong rules - test_smack_rules2
1255     fd = open("/etc/smack/test_smack_rules2", O_RDONLY, 0644);
1256     RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules2");
1257
1258     // Adding rules from file
1259     result = smack_accesses_add_from_file(rulesBasic, fd);
1260     close(fd);
1261     RUNNER_ASSERT_MSG(result == 0, "Accesses were loaded from file");
1262
1263     // Applying rules
1264     result = smack_accesses_apply(rulesBasic);
1265     RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1266
1267     // Checking rules
1268     RUNNER_ASSERT_MSG(checkNoAccesses("test_subject_01", "test_object_01"),
1269         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
1270     result = smack_have_access("test_subject_01", "test_object_02", "rwat");
1271     RUNNER_ASSERT_MSG(result == 1,
1272         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1273     result = smack_have_access("test_subject_01", "test_object_03", "wat");
1274     RUNNER_ASSERT_MSG(result == 1,
1275         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1276     RUNNER_ASSERT_MSG(checkNoAccesses("test_subject_02", "test_object_01"),
1277         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
1278     result = smack_have_access("test_subject_02", "test_object_02", "wa-ft");
1279     RUNNER_ASSERT_MSG(result == 1,
1280         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1281     result = smack_have_access("test_subject_02", "test_object_03", "wr");
1282     RUNNER_ASSERT_MSG(result == 1,
1283         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1284     result = smack_have_access("test_subject_03", "test_object_01", "a");
1285     RUNNER_ASSERT_MSG(result == 1,
1286         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1287     result = smack_have_access("test_subject_03", "test_object_02", "rwat");
1288     RUNNER_ASSERT_MSG(result == 1,
1289         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1290     result = smack_have_access("test_subject_03", "test_object_03", "w");
1291     RUNNER_ASSERT_MSG(result == 1,
1292         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1293
1294     // Removing rules
1295     removeAccessesAll();
1296
1297     smack_accesses_free(rulesBasic);
1298
1299     // Creating rules
1300     result = smack_accesses_new(&rulesBasic);
1301     RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1302
1303     // Loading file with partial wrong rules - test_smack_rules3
1304     fd = open("/etc/smack/test_smack_rules3", O_RDONLY, 0644);
1305     RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules3");
1306
1307     // Adding rules from file
1308     result = smack_accesses_add_from_file(rulesBasic, fd);
1309     close(fd);
1310     RUNNER_ASSERT_MSG(result != 0, "Accesses were loaded from file");
1311
1312     // Applying rules
1313     result = smack_accesses_apply(rulesBasic);
1314     RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1315
1316     // Checking rules
1317     result = smack_have_access("test_subject_01", "test_object_01", "rwat");
1318     RUNNER_ASSERT_MSG(result == 1,
1319         " Error while checking smack access loaded from /etc/smack/test_smack_rules3. Result: " << result );
1320     RUNNER_ASSERT_MSG(checkNoAccesses("test_subject_01", "test_object_02"),
1321         " Error while checking smack access loaded from /etc/smack/test_smack_rules3. Accesses exist.");
1322     result = smack_have_access("test_subject_01", "test_object_03", "x");
1323     RUNNER_ASSERT_MSG(result == 0,
1324         " Error while checking smack access loaded from /etc/smack/test_smack_rules3. Result: " << result );
1325
1326     // Removing rules
1327     removeAccessesAll();
1328
1329     smack_accesses_free(rulesBasic);
1330
1331     // Creating rules
1332     result = smack_accesses_new(&rulesBasic);
1333     RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1334
1335     // Loading file with partial wrong rules - test_smack_rules4
1336     fd = open("/etc/smack/test_smack_rules4", O_RDONLY, 0644);
1337     RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules4");
1338
1339     // Adding rules from file
1340     result = smack_accesses_add_from_file(rulesBasic, fd);
1341     close(fd);
1342     RUNNER_ASSERT_MSG(result != 0, "Accesses were loaded from file");
1343
1344     // Applying rules
1345     result = smack_accesses_apply(rulesBasic);
1346     RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1347
1348     // Checking rules
1349     result = smack_have_access("test_subject_01", "test_object_01", "rxwat");
1350     RUNNER_ASSERT_MSG(result == 1,
1351         " Error while checking smack access loaded from /etc/smack/test_smack_rules4. Result: " << result );
1352     RUNNER_ASSERT_MSG(checkNoAccesses("test_subject_01", "test_object_02"),
1353         " Error while checking smack access loaded from /etc/smack/test_smack_rules4. Accesses exist.");
1354     result = smack_have_access("test_subject_01", "test_object_03", "a");
1355     RUNNER_ASSERT_MSG(result == 0,
1356         " Error while checking smack access loaded from /etc/smack/test_smack_rules4. Result: " << result );
1357
1358     // Removing rules
1359     removeAccessesAll();
1360
1361     smack_accesses_free(rulesBasic);
1362 }
1363
1364 //int smack_new_label_from_socket(int fd, char **label);
1365
1366
1367 static void smack_set_another_label_for_self(void)
1368 {
1369     static int number = time(NULL);
1370     int result;
1371     char *smack_label;
1372
1373     number++;
1374     result = asprintf(&smack_label, "s%d", number);
1375     RUNNER_ASSERT_MSG(result > 0, "asprintf failed");
1376     result = smack_set_label_for_self(smack_label);
1377     RUNNER_ASSERT_MSG(result == 0, "smack_set_label_for_self(" << smack_label << ") failed");
1378     free(smack_label);
1379 }
1380
1381 static void smack_unix_sock_server(int sock)
1382 {
1383     int fd, result;
1384     char *smack_label;
1385
1386     alarm(2);
1387     fd = accept(sock, NULL, NULL);
1388     alarm(0);
1389     if (fd < 0)
1390         return;
1391     result = smack_new_label_from_self(&smack_label);
1392     RUNNER_ASSERT_MSG(result == 0, "smack_new_label_from_self() failed");
1393     result = write(fd, smack_label, strlen(smack_label));
1394     RUNNER_ASSERT_MSG(result == (int)strlen(smack_label), "write() failed");
1395     close(fd);
1396     free(smack_label);
1397 }
1398
1399 RUNNER_TEST_SMACK(smack09_new_label_from_socket)
1400 {
1401     int pid;
1402     struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
1403     unlink(SOCK_PATH);
1404     smack_set_another_label_for_self();
1405     pid = fork();
1406     RUNNER_ASSERT_MSG(pid >= 0, "Fork failed");
1407     if (!pid) { /* child process, server */
1408         int sock, result;
1409
1410
1411         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1412         RUNNER_ASSERT_MSG(sock >= 0, "socket failed: " << strerror(errno));
1413         result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1414         RUNNER_ASSERT_MSG(result == 0, "bind failed: " << strerror(errno));
1415         result = listen(sock, 1);
1416         RUNNER_ASSERT_MSG(result == 0, "listen failed: " << strerror(errno));
1417         smack_unix_sock_server(sock);
1418
1419         pid = fork();
1420         RUNNER_ASSERT_MSG(pid >= 0, "Fork failed");
1421         /*  Test if socket label was unaffected by fork() */
1422         smack_unix_sock_server(sock);
1423         if (!pid) {
1424             usleep (100);
1425             smack_set_another_label_for_self();
1426             smack_unix_sock_server(sock);
1427         }
1428         close(sock);
1429         if (pid)
1430             waitpid(pid, NULL, 0);
1431         exit(0);
1432     } else { /* parent process, client */
1433         sleep(1); /* Give server some time to setup listening socket */
1434         for (int i = 0; i < 4; ++i) {
1435             int sock, result;
1436             char smack_label1[SMACK_LABEL_LEN + 1];
1437             char *smack_label2;
1438
1439             sock = socket(AF_UNIX, SOCK_STREAM, 0);
1440             RUNNER_ASSERT_MSG(sock >= 0, "socket failed: " << strerror(errno));
1441             result = connect(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1442             RUNNER_ASSERT_MSG(result == 0, "connect failed: " << strerror(errno));
1443             alarm(2);
1444             result = read(sock, smack_label1, SMACK_LABEL_LEN);
1445             RUNNER_ASSERT_MSG(result >= 0, "read failed: " << strerror(errno));
1446             alarm(0);
1447             smack_label1[result] = '\0';
1448             result = smack_new_label_from_socket(sock, &smack_label2);
1449             RUNNER_ASSERT_MSG(result == 0, "smack_label_from_socket failed");
1450             result = strcmp(smack_label1, smack_label2);
1451             if (i < 3)
1452                 RUNNER_ASSERT_MSG(result == 0, "smack labels differ: '" << smack_label1 << "' != '" << smack_label2 << "' i == " << i);
1453             else
1454                 RUNNER_ASSERT_MSG(result != 0, "smack labels do not differ: '" << smack_label1 << "' != '" << smack_label2 << "' i == " << i);
1455             close(sock);
1456         }
1457         waitpid(pid, NULL, 0);
1458     }
1459 }