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