Fix libprivilege-control tests
[platform/core/test/security-tests.git] / src / libprivilege-control-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      Jan Olszak (j.olszak@samsung.com)
20  * @author      Rafal Krypa (r.krypa@samsung.com)
21  * @author      Lukasz Wojciechowski (l.wojciechow@partner.samsung.com)
22  * @version     1.0
23  * @brief       libprivilege-control test runner
24  */
25
26 #include <string>
27 #include <vector>
28 #include <fstream>
29 #include <sstream>
30 #include <set>
31
32 #include <fcntl.h>
33 #include <errno.h>
34 #include <unistd.h>
35
36 #include <sys/types.h>
37 #include <sys/stat.h>
38
39 #include <sys/socket.h>
40 #include <sys/un.h>
41 #include <sys/smack.h>
42
43 #include <privilege-control.h>
44 #include <dpl/test/test_runner.h>
45 #include <dpl/test/test_runner_child.h>
46 #include <dpl/test/test_runner_multiprocess.h>
47 #include <dpl/log/log.h>
48 #include <tests_common.h>
49 #include <libprivilege-control_test_common.h>
50 #include "common/duplicates.h"
51 #include "common/db.h"
52 #include "memory.h"
53
54 // Error codes for test_libprivilege_strerror
55 const std::vector<int> error_codes {
56     PC_OPERATION_SUCCESS, PC_ERR_FILE_OPERATION, PC_ERR_MEM_OPERATION, PC_ERR_NOT_PERMITTED,
57     PC_ERR_INVALID_PARAM, PC_ERR_INVALID_OPERATION, PC_ERR_DB_OPERATION, PC_ERR_DB_LABEL_TAKEN,
58     PC_ERR_DB_QUERY_PREP, PC_ERR_DB_QUERY_BIND, PC_ERR_DB_QUERY_STEP, PC_ERR_DB_CONNECTION,
59     PC_ERR_DB_NO_SUCH_APP, PC_ERR_DB_PERM_FORBIDDEN
60 };
61
62 namespace {
63
64 std::vector<std::string> gen_names(std::string prefix, std::string suffix, size_t size)
65 {
66     std::vector<std::string> names;
67     for(size_t i = 0; i < size; ++i) {
68         names.push_back(prefix + "_" + std::to_string(i) + suffix);
69     }
70     return names;
71 }
72
73 const char *OSP_BLAHBLAH = "/usr/share/privilege-control/OSP_feature.blah.blahblah.smack";
74 const char *WRT_BLAHBLAH  ="/usr/share/privilege-control/WGT_blahblah.smack";
75 const char *OTHER_BLAHBLAH  ="/usr/share/privilege-control/blahblah.smack";
76 const std::vector<std::string> OSP_BLAHBLAH_DAC = gen_names("/usr/share/privilege-control/OSP_feature.blah.blahblah", ".dac", 16);
77 const char *WRT_BLAHBLAH_DAC  ="/usr/share/privilege-control/WGT_blahblah.dac";
78 const char *OTHER_BLAHBLAH_DAC = "/usr/share/privilege-control/blahblah.dac";
79 const std::vector<std::string> BLAHBLAH_FEATURE = gen_names("http://feature/blah/blahblah", "", 16);
80
81 void osp_blahblah_dac_check(int line_no, const std::vector<unsigned> &gids, std::string dac_file_path)
82 {
83     std::ifstream dac_file(dac_file_path);
84     RUNNER_ASSERT_MSG(dac_file, "Line: " << line_no << " Failed to create " << dac_file_path);
85
86     auto it = gids.begin();
87     std::string line;
88     while (std::getline(dac_file,line)) {
89         std::istringstream is(line);
90         unsigned gid;
91         is >> gid;
92         RUNNER_ASSERT_MSG(it != gids.end(), "Line: " << line_no << "Additional line in file: " << gid);
93         RUNNER_ASSERT_MSG(*it == gid, "Line: " << line_no << " " << *it << "!=" << gid);
94         it++;
95     }
96
97     RUNNER_ASSERT_MSG(it == gids.end(), "Line: " << line_no << " Missing line in file: " << *it);
98
99     dac_file.close();
100 }
101
102 void remove_smack_files()
103 {
104     // TODO array
105     unlink(OSP_BLAHBLAH);
106     unlink(WRT_BLAHBLAH);
107     unlink(OTHER_BLAHBLAH);
108     unlink(WRT_BLAHBLAH_DAC);
109     unlink(OTHER_BLAHBLAH_DAC);
110
111     for(size_t i=0; i<OSP_BLAHBLAH_DAC.size(); ++i)
112         unlink(OSP_BLAHBLAH_DAC[i].c_str());
113
114     for(size_t i=0; i<OSP_BLAHBLAH_DAC.size(); ++i)
115         unlink(OSP_BLAHBLAH_DAC[i].c_str());
116 }
117
118 } // namespace
119
120 RUNNER_TEST_GROUP_INIT(libprivilegecontrol)
121
122 RUNNER_TEST(privilege_control02_perm_app_setup_path_01_PRIVATE)
123 {
124     int result;
125
126     result = nftw(TEST_APP_DIR, &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
127     RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << TEST_APP_DIR);
128
129     result = nftw(TEST_NON_APP_DIR, &nftw_set_labels_non_app_dir, FTW_MAX_FDS, FTW_PHYS);
130     RUNNER_ASSERT_MSG(result == 0, "Unable to set Smack labels in " << TEST_NON_APP_DIR);
131
132     DB_BEGIN
133
134     result = perm_app_setup_path(APPID_DIR, TEST_APP_DIR, APP_PATH_PRIVATE);
135     RUNNER_ASSERT_MSG(result == 0, "perm_app_setup_path() for APP_PATH_PRIVATE failed");
136
137     DB_END
138
139     result = nftw(TEST_APP_DIR, &nftw_check_labels_app_private_dir, FTW_MAX_FDS, FTW_PHYS);
140     RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for app dir");
141
142     result = nftw(TEST_NON_APP_DIR, &nftw_check_labels_non_app_dir, FTW_MAX_FDS, FTW_PHYS);
143     RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for non-app dir");
144 }
145
146 RUNNER_TEST(privilege_control02_perm_app_setup_path_02_FLOOR)
147 {
148     int result;
149
150     result = nftw(TEST_APP_DIR, &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
151     RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << TEST_APP_DIR);
152
153     result = nftw(TEST_NON_APP_DIR, &nftw_set_labels_non_app_dir, FTW_MAX_FDS, FTW_PHYS);
154     RUNNER_ASSERT_MSG(result == 0, "Unable to set Smack labels in " << TEST_NON_APP_DIR);
155
156     DB_BEGIN
157
158     result = perm_app_setup_path(APPID_DIR, TEST_APP_DIR, APP_PATH_FLOOR);
159     RUNNER_ASSERT_MSG(result == 0, "perm_app_setup_path() for APP_PATH_FLOOR type failed");
160
161     DB_END
162
163     result = nftw(TEST_APP_DIR, &nftw_check_labels_app_floor_dir, FTW_MAX_FDS, FTW_PHYS);
164     RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for app dir");
165
166     result = nftw(TEST_NON_APP_DIR, &nftw_check_labels_non_app_dir, FTW_MAX_FDS, FTW_PHYS);
167     RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for non-app dir");
168 }
169
170
171 RUNNER_TEST_SMACK(privilege_control02_perm_app_setup_path_03_PUBLIC_RO)
172 {
173     test_perm_app_setup_path_PUBLIC_RO(true);
174 }
175
176 /**
177  * Revoke permissions from the list. Should be executed as privileged user.
178  */
179 RUNNER_CHILD_TEST_SMACK(privilege_control06_revoke_permissions_wgt)
180 {
181     test_revoke_permissions(__LINE__, WGT_APP_ID);
182 }
183
184 /**
185  * Revoke permissions from the list. Should be executed as privileged user.
186  */
187 RUNNER_CHILD_TEST_SMACK(privilege_control06_revoke_permissions_osp)
188 {
189     test_revoke_permissions(__LINE__, OSP_APP_ID);
190 }
191
192 void test_set_app_privilege(
193                        const char* app_id, app_type_t APP_TYPE,
194                        const char** privileges, const char* type,
195                        const char* app_path, const char* dac_file,
196                        const rules_t &rules) {
197     check_app_installed(app_path);
198
199     int result;
200
201     /* Remove the group file to make sure other tests do not affect current one. This is because all
202        apps get the same label "User" */
203     const char* db_file = tzplatform_mkpath(TZ_SYS_DB,".privilege_control_app_gids.db");
204     RUNNER_ASSERT_MSG(db_file, "Failed to get groups db path");
205     result = unlink(db_file);
206     RUNNER_ASSERT_MSG(result == 0, "Removing group db failed " << strerror(errno));
207
208     DB_BEGIN
209
210     result = perm_app_uninstall(app_id);
211     RUNNER_ASSERT_MSG(result == 0,
212             " perm_app_uninstall returned " << result << ". "
213                     "Errno: " << strerror(errno));
214
215     result = perm_app_install(app_id);
216     RUNNER_ASSERT_MSG(result == 0,
217             " perm_app_install returned " << result << ". "
218                     "Errno: " << strerror(errno));
219
220     // TEST:
221     result = perm_app_enable_permissions(app_id, APP_TYPE, privileges, false);
222     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
223         " Error registering app permissions. Result: " << result);
224
225     DB_END
226
227     result = test_have_all_accesses(rules);
228     RUNNER_ASSERT_MSG(result == 1, "Permissions not added.");
229
230     std::set<unsigned> groups_before;
231     read_user_gids(groups_before, APP_UID);
232
233     result = perm_app_set_privilege(app_id, type, app_path);
234     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
235             " Error in perm_app_set_privilege. Error: " << result);
236
237     // Check if SMACK label really set
238     char *label;
239     result = smack_new_label_from_self(&label);
240     RUNNER_ASSERT_MSG(result >= 0,
241             " Error getting current process label");
242     RUNNER_ASSERT_MSG(label != nullptr,
243             " Process label is not set");
244
245     result = strcmp(USER_APP_ID, label);
246     RUNNER_ASSERT_MSG(result == 0,
247             " Process label " << label << " is incorrect");
248
249     check_groups(groups_before, dac_file);
250 }
251
252 /**
253  * Set APP privileges. wgt.
254  */
255 RUNNER_CHILD_TEST_SMACK(privilege_control05_set_app_privilege_wgt)
256 {
257     test_set_app_privilege(GENERATED_APP_ID, APP_TYPE_WGT, PRIVS_WGT, "wgt", WGT_APP_PATH,
258             LIBPRIVILEGE_TEST_DAC_FILE_WGT, rules_wgt);
259 }
260
261 /**
262  * Set APP privileges. osp app.
263  */
264 RUNNER_CHILD_TEST_SMACK(privilege_control05_set_app_privilege_osp)
265 {
266     test_set_app_privilege(GENERATED_APP_ID, APP_TYPE_OSP, PRIVS_OSP, "tpk", OSP_APP_PATH,
267             LIBPRIVILEGE_TEST_DAC_FILE_OSP, rules_osp);
268 }
269
270 RUNNER_CHILD_TEST_SMACK(privilege_control05_set_app_privilege_efl)
271 {
272     test_set_app_privilege(GENERATED_APP_ID, APP_TYPE_EFL, PRIVS_EFL,
273             "rpm", EFL_APP_PATH,
274             LIBPRIVILEGE_TEST_DAC_FILE_EFL, rules_efl);
275 }
276
277 /**
278  * Add new API feature
279  */
280 RUNNER_TEST(privilege_control08_add_api_feature)
281 {
282     int result;
283
284     remove_smack_files();
285
286     DB_BEGIN
287
288     // argument validation
289     result = perm_add_api_feature(APP_TYPE_OSP, nullptr, nullptr, nullptr, 0);
290     RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
291
292     result = perm_add_api_feature(APP_TYPE_OSP,"", nullptr, nullptr, 0);
293     RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
294
295
296     // Already existing feature:
297     // TODO: Database will be malformed. (Rules for these features will be removed.)
298     result = perm_add_api_feature(APP_TYPE_OSP,"http://tizen.org/privilege/messaging.read", nullptr, nullptr, 0);
299     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
300
301     result = perm_add_api_feature(APP_TYPE_WGT,"http://tizen.org/privilege/messaging.sms", nullptr, nullptr, 0);
302     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
303
304     // empty features
305     result = perm_add_api_feature(APP_TYPE_OSP,"blahblah", nullptr, nullptr, 0);
306     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
307
308     result = perm_add_api_feature(APP_TYPE_WGT,"blahblah", nullptr, nullptr, 0);
309     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
310
311     // empty rules
312     const char *test1[] = { nullptr };
313     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[0].c_str(), test1, nullptr, 0);
314     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
315
316     const char *test2[] = { "", nullptr };
317     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[1].c_str(), test2, nullptr, 0);
318     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
319
320     const char *test3[] = { " \t\n", "\t \n", "\n\t  ", nullptr };
321     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[2].c_str(), test3, nullptr, 0);
322     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
323
324     // malformed rules
325     const char *test4[] = { "malformed", nullptr };
326     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[3].c_str(), test4, nullptr, 0);
327     RUNNER_ASSERT_MSG(result == PC_ERR_INVALID_PARAM, "perm_add_api_feature returned: " << result);
328
329     const char *test5[] = { "malformed malformed", nullptr };
330     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[4].c_str(), test5, nullptr, 0);
331     RUNNER_ASSERT_MSG(result == PC_ERR_INVALID_PARAM, "perm_add_api_feature returned: " << result);
332
333     const char *test6[] = { "-malformed malformed rwxat", nullptr };
334     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[5].c_str(), test6, nullptr, 0);
335     RUNNER_ASSERT_MSG(result == PC_ERR_INVALID_PARAM, "perm_add_api_feature returned: " << result);
336
337     const char *test7[] = { "~/\"\\ malformed rwxat", nullptr };
338     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[6].c_str(), test7, nullptr, 0);
339     RUNNER_ASSERT_MSG(result == PC_ERR_INVALID_PARAM, "perm_add_api_feature returned: " << result);
340
341     const char *test8[] = { "subject object rwxat something else", nullptr };
342     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[7].c_str(), test8, nullptr, 0);
343     RUNNER_ASSERT_MSG(result == PC_ERR_INVALID_PARAM, "perm_add_api_feature returned: " << result);
344
345
346     // correct rules
347     const char *test9[] = {
348             "~APP~    object\t rwxatl",
349             " \t \n",
350             "subject2\t~APP~ ltxarw",
351             "",
352             nullptr};
353
354     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[8].c_str(), test9, nullptr, 0);
355     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
356
357     const char *test10[] = { "Sub::jE,ct ~APP~ a-rwxl", nullptr };
358     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[9].c_str(), test10, nullptr, 0);
359     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
360
361     const char *test11[] = { "Sub::sjE,ct ~APP~ a-RwXL", nullptr }; // TODO This fails.
362     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[10].c_str(), test11, nullptr, 0);
363     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
364
365
366     // TODO For now identical/complementary rules are not merged.
367     const char *test12[] = {
368             "subject1 ~APP~ rwxatl",
369             " \t \n",
370             "subject2 ~APP~ ltxarw",
371             "",
372             nullptr};
373     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[11].c_str(), test12, nullptr, 0);
374     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
375
376     // empty group ids
377     const char *test13[] = { "~APP~ b a", nullptr};
378     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[12].c_str(), test13,(const gid_t[]) {0,1,2},0);
379     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
380     result = file_exists(OSP_BLAHBLAH_DAC[12].c_str());
381     RUNNER_ASSERT(result == -1);
382     remove_smack_files();
383
384
385     // valid group ids
386     result = perm_add_api_feature(APP_TYPE_OSP,BLAHBLAH_FEATURE[13].c_str(), test13,(const gid_t[]) {0,1,2},3);
387     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
388     osp_blahblah_dac_check(__LINE__, {0,1,2}, OSP_BLAHBLAH_DAC[13]);
389     remove_smack_files();
390
391     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[14].c_str(), test13,(const gid_t[]) {0,1,2},1);
392     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
393     osp_blahblah_dac_check(__LINE__, {0}, OSP_BLAHBLAH_DAC[14]);
394     remove_smack_files();
395
396     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[15].c_str(), test13,(const gid_t[]) {1,1,1},3);
397     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
398     osp_blahblah_dac_check(__LINE__, {1,1,1},OSP_BLAHBLAH_DAC[15]);
399     remove_smack_files();
400
401     DB_END
402 }
403
404 /**
405  * Add new API feature, assign it to an app and redefine the API feature.
406  * Check if app rules has changed after redefinition.
407  */
408 RUNNER_TEST_SMACK(privilege_control09_perm_add_api_feature_redefine)
409 {
410     int result;
411     const char *permissionName[] = { "org.tizen.test.permtoberedefined", nullptr};
412
413     // Rules to be used with the first check
414     const rules_t test_rules1 = {
415         { GENERATED_APP_ID, PERM_TO_REDEFINE, "rx" },
416         { PERM_TO_REDEFINE, GENERATED_APP_ID, "rwx" },
417         { GENERATED_APP_ID, PERM_SUB_TO_REDEFINE, "rx" }
418     };
419
420     // Rules that contain differences - to be used with the second check (after re-def)
421     const rules_t test_rules2 = {
422         { GENERATED_APP_ID, PERM_TO_REDEFINE, "rwx" },
423         { PERM_TO_REDEFINE, GENERATED_APP_ID, "rx" },
424         { GENERATED_APP_ID, PERM_SUB_TO_REDEFINE, "watl" }
425     };
426
427     // Differences between rules1 and rules2 - should be revoked after re-def)
428     const rules_t diff_rules = {
429         { PERM_TO_REDEFINE, GENERATED_APP_ID, "w" },
430         { GENERATED_APP_ID, PERM_SUB_TO_REDEFINE, "rx" }
431     };
432
433     // Rules to be used with the first definition
434     const char *perm_rules1[] = {
435         "~APP~ " PERM_TO_REDEFINE " rx",
436         PERM_TO_REDEFINE " ~APP~ rwx",
437         "~APP~ " PERM_SUB_TO_REDEFINE " rx",
438         nullptr
439     };
440
441     // Rules that contain differences - to be used with the second definition (re-def)
442     const char *perm_rules2[] = {
443         "~APP~ " PERM_TO_REDEFINE " rwx",
444         PERM_TO_REDEFINE " ~APP~ rx",
445         "~APP~ " PERM_SUB_TO_REDEFINE " watl",
446         nullptr
447     };
448
449     DB_BEGIN
450
451     // uninstall app to make sure that all rules and permissions are revoked
452     result = perm_app_uninstall(APP_ID);
453     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
454             "perm_app_uninstall failed: " << perm_strerror(result));
455
456     result = perm_app_install(APP_ID);
457     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
458             "perm_app_install failed: " << perm_strerror(result));
459
460     result = perm_add_api_feature(APP_TYPE_OSP, permissionName[0], perm_rules1, nullptr, 0);
461     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
462             "perm_add_api_feature failed: " << result);
463
464     result = perm_app_enable_permissions(APP_ID, APP_TYPE_OSP, permissionName, true);
465     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
466             "perm_app_enable_permissions failed: " << perm_strerror(result));
467
468     DB_END
469
470     // Check if rules are applied
471     result = test_have_all_accesses(test_rules1);
472     RUNNER_ASSERT_MSG(result == 1, "Not all permissions added.");
473
474     DB_BEGIN
475
476     // Redefine the permission
477     result = perm_add_api_feature(APP_TYPE_OSP, permissionName[0], perm_rules2, nullptr, 0);
478     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
479             "perm_add_api_feature failed: " << result);
480
481     DB_END
482
483     // Check if rules are updated
484     result = test_have_all_accesses(test_rules2);
485     RUNNER_ASSERT_MSG(result == 1, "Not all permissions added after update.");
486     // The difference between rules1 and rules2 should be revoked!
487     result = test_have_any_accesses(diff_rules);
488     RUNNER_ASSERT_MSG(result == 0, "Permissions are not fully updated.");
489 }
490
491 /*
492  * Check perm_app_uninstall function
493  */
494 void check_perm_app_uninstall(const char* pkg_id)
495 {
496     int result;
497
498     DB_BEGIN
499
500     result = perm_app_uninstall(pkg_id);
501     RUNNER_ASSERT_MSG(result == 0, "perm_app_uninstall returned: " << perm_strerror(result));
502
503     DB_END
504 }
505
506 RUNNER_TEST(privilege_control07_app_uninstall)
507 {
508     check_perm_app_uninstall(APP_ID);
509 }
510
511 /*
512  * Check perm_app_install function
513  */
514 void check_perm_app_install(const char* pkg_id)
515 {
516     int result;
517
518     DB_BEGIN
519
520     result = perm_app_install(pkg_id);
521     RUNNER_ASSERT_MSG(result == 0, "perm_app_install returned: " << perm_strerror(result));
522
523     DB_END
524
525     TestLibPrivilegeControlDatabase db_test;
526     db_test.test_db_after__perm_app_install(USER_APP_ID);
527 }
528
529 RUNNER_TEST(privilege_control01_app_install)
530 {
531     check_perm_app_uninstall(APP_ID);
532     check_perm_app_install(APP_ID);
533     // try install second time app with the same ID - it should pass.
534     check_perm_app_install(APP_ID);
535 }
536
537 /*
538  * Check perm_rollback function
539  */
540 RUNNER_TEST(privilege_control07_app_rollback)
541 {
542     check_perm_app_uninstall(APP_ID);
543
544     int result;
545
546     DB_BEGIN
547
548     result = perm_app_install(APP_ID);
549     RUNNER_ASSERT_MSG(result == 0, "perm_app_install returned: " << perm_strerror(result));
550
551     // transaction rollback
552     result = perm_rollback();
553     RUNNER_ASSERT_MSG(result == 0, "perm_rollback returned: " << perm_strerror(result));
554
555     DB_END
556 }
557
558 RUNNER_TEST(privilege_control07_app_rollback_2)
559 {
560     check_perm_app_uninstall(APP_ID);
561
562     int result;
563
564     DB_BEGIN
565
566     result = perm_app_install(APP_ID);
567     RUNNER_ASSERT_MSG(result == 0, "perm_app_install returned: " << perm_strerror(result));
568
569     // transaction rollback
570     result = perm_rollback();
571     RUNNER_ASSERT_MSG(result == 0, "perm_rollback returned: " << perm_strerror(result));
572
573     // install once again after the rollback
574     result = perm_app_install(APP_ID);
575     RUNNER_ASSERT_MSG(result == 0, "perm_app_install returned: " << perm_strerror(result));
576
577     DB_END
578
579     TestLibPrivilegeControlDatabase db_test;
580     db_test.test_db_after__perm_app_install(USER_APP_ID);
581 }
582
583 /**
584  * Grant SMACK permissions based on permissions list.
585  */
586 RUNNER_TEST_SMACK(privilege_control11_app_enable_permissions)
587 {
588     int result;
589
590     // Clean up after test:
591     DB_BEGIN
592
593     result = perm_app_uninstall(WGT_APP_ID);
594     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_app_uninstall returned " << result << ". Errno: " << strerror(errno));
595     result = perm_app_install(WGT_APP_ID);
596     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_app_install returned " << result << ". Errno: " << strerror(errno));
597
598 /**
599  * Test - Enabling all permissions with persistant mode enabled
600  */
601     result = perm_app_revoke_permissions(WGT_APP_ID);
602     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
603         "Error revoking app permissions. Result: " << result);
604
605     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2, false);
606     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
607         " Error registering app permissions. Result: " << result);
608
609     DB_END
610
611     // Check if the accesses are realy applied..
612     result = test_have_all_accesses(rules2);
613     RUNNER_ASSERT_MSG(result == 1, "Permissions not added.");
614
615     DB_BEGIN
616
617     // Clean up
618     result = perm_app_revoke_permissions(WGT_APP_ID);
619     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
620         "Error revoking app permissions. Result: " << result);
621
622     DB_END
623
624 /**
625  * Test - Enabling all permissions with persistant mode disabled
626  */
627
628     DB_BEGIN
629     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2, false);
630     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
631         " Error registering app permissions. Result: " << result);
632
633     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2, false);
634     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
635         " Error enabling app permissions. Result: " << result);
636
637     DB_END
638
639     // Check if the accesses are realy applied..
640     result = test_have_all_accesses(rules2);
641     RUNNER_ASSERT_MSG(result == 1, "Permissions not added.");
642
643     DB_BEGIN
644
645     // Clean up
646     result = perm_app_revoke_permissions(WGT_APP_ID);
647     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
648         "Error revoking app permissions. Result: " << result);
649
650     DB_END
651
652 /**
653  * Test - Registering new permissions in two complementary files
654  */
655
656     DB_BEGIN
657
658     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_R_AND_NO_R, false);
659     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
660         " Error registering app permissions. Result: " << result);
661
662     DB_END
663
664     // Check if the accesses are realy applied..
665     result = test_have_all_accesses(rules2_no_r);
666     RUNNER_ASSERT_MSG(result == 1, "Permissions not added.");
667
668     DB_BEGIN
669
670     // Clean up
671     result = perm_app_revoke_permissions(WGT_APP_ID);
672     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
673         "Error revoking app permissions. Result: " << result);
674
675     DB_END
676
677 /**
678  * Test - Enabling some permissions and then enabling complementary permissions
679  */
680
681     DB_BEGIN
682
683     // Register permission for rules 2 no r
684     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_NO_R, false);
685     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
686         " Error registering app permissions without r. Result: " << result);
687
688     DB_END
689
690     // Check if the accesses are realy applied..
691     result = test_have_all_accesses(rules2_no_r);
692     RUNNER_ASSERT_MSG(result == 1, "Permissions without r not added.");
693
694     DB_BEGIN
695
696     // Register permission for rules 2
697     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2, false);
698     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
699         " Error registering app all permissions. Result: " << result);
700
701     DB_END
702
703     // Check if the accesses are realy applied..
704     result = test_have_all_accesses(rules2);
705     RUNNER_ASSERT_MSG(result == 1, "Permissions all not added.");
706
707     DB_BEGIN
708
709     // Clean up
710     result = perm_app_revoke_permissions(WGT_APP_ID);
711     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
712         "Error revoking app permissions. Result: " << result);
713
714 /**
715  * Test - Enabling some permissions and then enabling all permissions
716  */
717
718     // Enable permission for rules 2 no r
719     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_NO_R, false);
720     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
721         " Error registering app permissions without r. Result: " << result);
722
723     DB_END
724
725     // Check if the accesses are realy applied..
726     result = test_have_all_accesses(rules2_no_r);
727     RUNNER_ASSERT_MSG(result == 1, "Permissions without r not added.");
728
729     DB_BEGIN
730
731     // Enable permission for rules 2
732     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_R, false);
733     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
734         " Error registering app permissions with only r. Result: " << result);
735
736     DB_END
737
738     // Check if the accesses are realy applied..
739     result = test_have_all_accesses(rules2_r);
740     RUNNER_ASSERT_MSG(result == 1, "Permissions with only r not added.");
741
742     DB_BEGIN
743
744     // Clean up
745     result = perm_app_revoke_permissions(WGT_APP_ID);
746     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
747         "Error revoking app permissions. Result: " << result);
748
749
750
751     // Clean up after test:
752     result = perm_app_uninstall(WGT_APP_ID);
753     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_app_uninstall returned " << result << ". Errno: " << strerror(errno));
754
755     DB_END
756 }
757
758 RUNNER_CHILD_TEST_SMACK(privilege_control11_app_enable_permissions_efl)
759 {
760     test_app_enable_permissions_efl(true);
761 }
762
763 /*
764  * Check perm_app_install function
765  */
766 RUNNER_CHILD_TEST_SMACK(privilege_control12_app_disable_permissions_efl)
767 {
768     test_app_disable_permissions_efl(true);
769 }
770
771
772 /**
773  * Remove previously granted SMACK permissions based on permissions list.
774  */
775 RUNNER_TEST_SMACK(privilege_control12_app_disable_permissions)
776 {
777     test_app_disable_permissions(true);
778 }
779
780 /**
781  * Reset SMACK permissions for an application by revoking all previously
782  * granted rules and enabling them again from a rules file from disk.
783  */
784 // TODO: This test is incomplete.
785 RUNNER_TEST_SMACK(privilege_control13_app_reset_permissions)
786 {
787     int result;
788
789 /**
790  * Test - doing reset and checking if rules exist again.
791  */
792
793     DB_BEGIN
794
795     result = perm_app_install(WGT_APP_ID);
796     RUNNER_ASSERT_MSG(result == 0, "perm_app_install returned " << result << ". Errno: " << strerror(errno));
797
798     // Disable permissions
799     result = perm_app_disable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2);
800     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
801         "Error disabling app permissions. Result: " << result);
802
803     // Prepare permissions to reset
804     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2, true);
805     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
806         " Error registering app permissions. Result: " << result);
807
808     // Reset permissions
809     result = perm_app_reset_permissions(WGT_APP_ID);
810     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
811         "Error reseting app permissions. Result: " << result);
812
813     DB_END
814
815     // Are all second permissions not disabled?
816     result = test_have_all_accesses(rules2);
817     RUNNER_ASSERT_MSG(result == 1, "Not all permissions added.");
818
819     DB_BEGIN
820
821     // Disable permissions
822     result = perm_app_disable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2);
823     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
824         "Error disabling app permissions. Result: " << result);
825
826     result = perm_app_uninstall(WGT_APP_ID);
827     RUNNER_ASSERT_MSG(result == 0, "perm_app_uninstall returned " << result << ". Errno: " << strerror(errno));
828
829     DB_END
830 }
831
832 static void smack_set_random_label_based_on_pid_on_self(void)
833 {
834     int result;
835     std::stringstream ss;
836
837     ss << "s-" << getpid() << "-" << getppid();
838     result = smack_set_label_for_self(ss.str().c_str());
839     RUNNER_ASSERT_MSG(result == 0, "smack_set_label_for_self("
840         << ss.str().c_str() << ") failed");
841 }
842
843 static void smack_unix_sock_server(int sock)
844 {
845     int fd, result;
846     char *smack_label;
847
848     alarm(2);
849     fd = accept(sock, nullptr, nullptr);
850     alarm(0);
851     if (fd < 0)
852         return;
853
854     FdUniquePtr fdPtr(&fd);
855
856     result = smack_new_label_from_self(&smack_label);
857     RUNNER_ASSERT_MSG(result >= 0, "smack_new_label_from_self() failed");
858     SmackLabelPtr smackLabelPtr(smack_label);
859
860     ssize_t bitsNum = write(fd, smack_label, strlen(smack_label));
861     RUNNER_ASSERT_ERRNO_MSG(bitsNum >= 0 && static_cast<size_t>(bitsNum) == strlen(smack_label),
862                                "write() failed");
863 }
864
865 RUNNER_MULTIPROCESS_TEST_SMACK(privilege_control15_app_id_from_socket)
866 {
867     int pid;
868     struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
869
870     unlink(SOCK_PATH);
871     pid = fork();
872     RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
873
874     smack_set_random_label_based_on_pid_on_self();
875
876     if (!pid) { /* child process, server */
877         int sock, result;
878
879         /* Set the process label before creating a socket */
880         sock = socket(AF_UNIX, SOCK_STREAM, 0);
881         RUNNER_ASSERT_ERRNO_MSG(sock >= 0, "socket failed");
882         SockUniquePtr sockPtr(&sock);
883
884         result = bind(sock,
885             (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
886         RUNNER_ASSERT_ERRNO_MSG(result == 0, "bind failed");
887
888         result = listen(sock, 1);
889         RUNNER_ASSERT_ERRNO_MSG(result == 0, "listen failed");
890         smack_unix_sock_server(sock);
891
892         /* Change the process label with listening socket */
893         smack_unix_sock_server(sock);
894
895         pid = fork();
896         RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
897         /* Now running two concurrent servers.
898            Test if socket label was unaffected by fork() */
899         smack_unix_sock_server(sock);
900         /* Let's give the two servers different labels */
901         smack_unix_sock_server(sock);
902
903         exit(0);
904     } else { /* parent process, client */
905         sleep(1); /* Give server some time to setup listening socket */
906         int i;
907         for (i = 0; i < 4; ++i) {
908             int sock;
909             int result;
910             char smack_label1[SMACK_LABEL_LEN + 1];
911             char *smack_label2;
912
913             sock = socket(AF_UNIX, SOCK_STREAM, 0);
914             RUNNER_ASSERT_ERRNO_MSG(sock >= 0, "socket failed");
915             SockUniquePtr sockPtr(&sock);
916
917             result = connect(sock,
918                 (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
919             RUNNER_ASSERT_ERRNO_MSG(result == 0, "connect failed");
920
921             alarm(2);
922             result = read(sock, smack_label1, SMACK_LABEL_LEN);
923             alarm(0);
924             RUNNER_ASSERT_ERRNO_MSG(result >= 0, "read failed");
925
926             smack_label1[result] = '\0';
927             smack_label2 = perm_app_id_from_socket(sock);
928             RUNNER_ASSERT_MSG(smack_label2 != nullptr, "perm_app_id_from_socket failed");
929             result = strcmp(smack_label1, smack_label2);
930             RUNNER_ASSERT_MSG(result == 0, "smack labels differ: '" << smack_label1
931                                  << "' != '" << smack_label2 << "-" << random() << "'");
932         }
933     }
934 }
935
936 RUNNER_TEST(privilege_control20_perm_app_has_permission)
937 {
938     int result;
939     const char *other_app_label = "test_other_app_label";
940
941     DB_BEGIN
942
943     result = perm_app_uninstall(WGT_APP_ID);
944     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
945             "Error uninstalling app. Result" << result);
946
947     result = perm_app_install(WGT_APP_ID);
948     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
949             "Error installing app. Result" << result);
950
951     result = perm_app_disable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_R_AND_NO_R);
952     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
953             "Error disabling app r and no r permissions. Result: " << result);
954
955     DB_END
956
957     check_perm_app_has_permission(USER_APP_ID, PRIVS2_R[0], false);
958     check_perm_app_has_permission(USER_APP_ID, PRIVS2_NO_R[0], false);
959     check_perm_app_has_permission(other_app_label, PRIVS2_R[0], false);
960     check_perm_app_has_permission(other_app_label, PRIVS2_NO_R[0], false);
961
962     DB_BEGIN
963
964     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_R, false);
965     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
966             "Error registering app r permissions. Result: " << result);
967
968     DB_END
969
970     check_perm_app_has_permission(USER_APP_ID, PRIVS2_R[0], true);
971     check_perm_app_has_permission(USER_APP_ID, PRIVS2_NO_R[0], false);
972     check_perm_app_has_permission(other_app_label, PRIVS2_R[0], false);
973     check_perm_app_has_permission(other_app_label, PRIVS2_NO_R[0], false);
974
975     DB_BEGIN
976
977     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_NO_R, false);
978     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
979             "Error registering app r permissions. Result: " << result);
980
981     DB_END
982
983     check_perm_app_has_permission(USER_APP_ID, PRIVS2_R[0], true);
984     check_perm_app_has_permission(USER_APP_ID, PRIVS2_NO_R[0], true);
985     check_perm_app_has_permission(other_app_label, PRIVS2_R[0], false);
986     check_perm_app_has_permission(other_app_label, PRIVS2_NO_R[0], false);
987
988     DB_BEGIN
989
990     result = perm_app_disable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_R);
991     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
992             "Error disabling app r and no r permissions. Result: " << result);
993
994     DB_END
995
996     check_perm_app_has_permission(USER_APP_ID, PRIVS2_R[0], false);
997     check_perm_app_has_permission(USER_APP_ID, PRIVS2_NO_R[0], true);
998     check_perm_app_has_permission(other_app_label, PRIVS2_R[0], false);
999     check_perm_app_has_permission(other_app_label, PRIVS2_NO_R[0], false);
1000
1001     DB_BEGIN
1002
1003     result = perm_app_disable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_NO_R);
1004     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
1005             "Error disabling app r and no r permissions. Result: " << result);
1006
1007     DB_END
1008
1009     check_perm_app_has_permission(USER_APP_ID, PRIVS2_R[0], false);
1010     check_perm_app_has_permission(USER_APP_ID, PRIVS2_NO_R[0], false);
1011     check_perm_app_has_permission(other_app_label, PRIVS2_R[0], false);
1012     check_perm_app_has_permission(other_app_label, PRIVS2_NO_R[0], false);
1013 }
1014
1015 RUNNER_TEST(privilege_control25_test_libprivilege_strerror) {
1016     int POSITIVE_ERROR_CODE = 1;
1017     int NONEXISTING_ERROR_CODE = -239042;
1018     const char *result;
1019
1020     for (auto itr = error_codes.begin(); itr != error_codes.end(); ++itr) {
1021         RUNNER_ASSERT_MSG(strcmp(perm_strerror(*itr), "Unknown error") != 0,
1022                 "Returned invalid error code description.");
1023     }
1024
1025     result = perm_strerror(POSITIVE_ERROR_CODE);
1026     RUNNER_ASSERT_MSG(strcmp(result, "Unknown error") == 0,
1027             "Bad message returned for invalid error code: \"" << result << "\"");
1028
1029     result = perm_strerror(NONEXISTING_ERROR_CODE);
1030     RUNNER_ASSERT_MSG(strcmp(result, "Unknown error") == 0,
1031             "Bad message returned for invalid error code: \"" << result << "\"");
1032 }