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