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