Merging tizen into ckm. Stage 1.
[platform/core/test/security-tests.git] / tests / 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     DB_BEGIN
202
203     result = perm_app_uninstall(app_id);
204     RUNNER_ASSERT_MSG(result == 0,
205             " perm_app_uninstall returned " << result << ". "
206                     "Errno: " << strerror(errno));
207
208     result = perm_app_install(app_id);
209     RUNNER_ASSERT_MSG(result == 0,
210             " perm_app_install returned " << result << ". "
211                     "Errno: " << strerror(errno));
212
213     // TEST:
214     result = perm_app_enable_permissions(app_id, APP_TYPE, privileges, false);
215     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
216         " Error registering app permissions. Result: " << result);
217
218     DB_END
219
220     result = test_have_all_accesses(rules);
221     RUNNER_ASSERT_MSG(result == 1, "Permissions not added.");
222
223     std::set<unsigned> groups_before;
224     read_user_gids(groups_before, APP_UID);
225
226     result = perm_app_set_privilege(app_id, type, app_path);
227     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
228             " Error in perm_app_set_privilege. Error: " << result);
229
230     // Check if SMACK label really set
231     char *label;
232     result = smack_new_label_from_self(&label);
233     RUNNER_ASSERT_MSG(result >= 0,
234             " Error getting current process label");
235     RUNNER_ASSERT_MSG(label != nullptr,
236             " Process label is not set");
237
238     result = strcmp(USER_APP_ID, label);
239     RUNNER_ASSERT_MSG(result == 0,
240             " Process label " << label << " is incorrect");
241
242     check_groups(groups_before, dac_file);
243 }
244
245 /**
246  * Set APP privileges. wgt.
247  */
248 RUNNER_CHILD_TEST_SMACK(privilege_control05_set_app_privilege_wgt)
249 {
250     test_set_app_privilege(WGT_APP_ID, APP_TYPE_WGT, PRIVS_WGT, "wgt", WGT_APP_PATH,
251             LIBPRIVILEGE_TEST_DAC_FILE_WGT, rules_wgt);
252 }
253
254 /**
255  * Set APP privileges. osp app.
256  */
257 RUNNER_CHILD_TEST_SMACK(privilege_control05_set_app_privilege_osp)
258 {
259     test_set_app_privilege(OSP_APP_ID, APP_TYPE_OSP, PRIVS_OSP, "tpk", OSP_APP_PATH,
260             LIBPRIVILEGE_TEST_DAC_FILE_OSP, rules_osp);
261 }
262
263 RUNNER_CHILD_TEST_SMACK(privilege_control05_set_app_privilege_efl)
264 {
265     test_set_app_privilege(EFL_APP_ID, APP_TYPE_EFL, PRIVS_EFL,
266             "rpm", EFL_APP_PATH,
267             LIBPRIVILEGE_TEST_DAC_FILE_EFL, rules_efl);
268 }
269
270 /**
271  * Add new API feature
272  */
273 RUNNER_TEST(privilege_control08_add_api_feature)
274 {
275     int result;
276
277     remove_smack_files();
278
279     DB_BEGIN
280
281     // argument validation
282     result = perm_add_api_feature(APP_TYPE_OSP, nullptr, nullptr, nullptr, 0);
283     RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
284
285     result = perm_add_api_feature(APP_TYPE_OSP,"", nullptr, nullptr, 0);
286     RUNNER_ASSERT(result == PC_ERR_INVALID_PARAM);
287
288
289     // Already existing feature:
290     // TODO: Database will be malformed. (Rules for these features will be removed.)
291     result = perm_add_api_feature(APP_TYPE_OSP,"http://tizen.org/privilege/messaging.read", nullptr, nullptr, 0);
292     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
293
294     result = perm_add_api_feature(APP_TYPE_WGT,"http://tizen.org/privilege/messaging.sms", nullptr, nullptr, 0);
295     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
296
297     // empty features
298     result = perm_add_api_feature(APP_TYPE_OSP,"blahblah", 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,"blahblah", nullptr, nullptr, 0);
302     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
303
304     // empty rules
305     const char *test1[] = { nullptr };
306     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[0].c_str(), test1, nullptr, 0);
307     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
308
309     const char *test2[] = { "", nullptr };
310     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[1].c_str(), test2, nullptr, 0);
311     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
312
313     const char *test3[] = { " \t\n", "\t \n", "\n\t  ", nullptr };
314     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[2].c_str(), test3, nullptr, 0);
315     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
316
317     // malformed rules
318     const char *test4[] = { "malformed", nullptr };
319     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[3].c_str(), test4, nullptr, 0);
320     RUNNER_ASSERT_MSG(result == PC_ERR_INVALID_PARAM, "perm_add_api_feature returned: " << result);
321
322     const char *test5[] = { "malformed malformed", nullptr };
323     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[4].c_str(), test5, nullptr, 0);
324     RUNNER_ASSERT_MSG(result == PC_ERR_INVALID_PARAM, "perm_add_api_feature returned: " << result);
325
326     const char *test6[] = { "-malformed malformed rwxat", nullptr };
327     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[5].c_str(), test6, nullptr, 0);
328     RUNNER_ASSERT_MSG(result == PC_ERR_INVALID_PARAM, "perm_add_api_feature returned: " << result);
329
330     const char *test7[] = { "~/\"\\ malformed rwxat", nullptr };
331     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[6].c_str(), test7, nullptr, 0);
332     RUNNER_ASSERT_MSG(result == PC_ERR_INVALID_PARAM, "perm_add_api_feature returned: " << result);
333
334     const char *test8[] = { "subject object rwxat something else", nullptr };
335     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[7].c_str(), test8, nullptr, 0);
336     RUNNER_ASSERT_MSG(result == PC_ERR_INVALID_PARAM, "perm_add_api_feature returned: " << result);
337
338
339     // correct rules
340     const char *test9[] = {
341             "~APP~    object\t rwxatl",
342             " \t \n",
343             "subject2\t~APP~ ltxarw",
344             "",
345             nullptr};
346
347     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[8].c_str(), test9, nullptr, 0);
348     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
349
350     const char *test10[] = { "Sub::jE,ct ~APP~ a-rwxl", nullptr };
351     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[9].c_str(), test10, nullptr, 0);
352     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
353
354     const char *test11[] = { "Sub::sjE,ct ~APP~ a-RwXL", nullptr }; // TODO This fails.
355     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[10].c_str(), test11, nullptr, 0);
356     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
357
358
359     // TODO For now identical/complementary rules are not merged.
360     const char *test12[] = {
361             "subject1 ~APP~ rwxatl",
362             " \t \n",
363             "subject2 ~APP~ ltxarw",
364             "",
365             nullptr};
366     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[11].c_str(), test12, nullptr, 0);
367     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
368
369     // empty group ids
370     const char *test13[] = { "~APP~ b a", nullptr};
371     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[12].c_str(), test13,(const gid_t[]) {0,1,2},0);
372     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
373     result = file_exists(OSP_BLAHBLAH_DAC[12].c_str());
374     RUNNER_ASSERT(result == -1);
375     remove_smack_files();
376
377
378     // valid group ids
379     result = perm_add_api_feature(APP_TYPE_OSP,BLAHBLAH_FEATURE[13].c_str(), test13,(const gid_t[]) {0,1,2},3);
380     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
381     osp_blahblah_dac_check(__LINE__, {0,1,2}, OSP_BLAHBLAH_DAC[13]);
382     remove_smack_files();
383
384     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[14].c_str(), test13,(const gid_t[]) {0,1,2},1);
385     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
386     osp_blahblah_dac_check(__LINE__, {0}, OSP_BLAHBLAH_DAC[14]);
387     remove_smack_files();
388
389     result = perm_add_api_feature(APP_TYPE_OSP, BLAHBLAH_FEATURE[15].c_str(), test13,(const gid_t[]) {1,1,1},3);
390     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_add_api_feature returned: " << result);
391     osp_blahblah_dac_check(__LINE__, {1,1,1},OSP_BLAHBLAH_DAC[15]);
392     remove_smack_files();
393
394     DB_END
395 }
396
397 /**
398  * Add new API feature, assign it to an app and redefine the API feature.
399  * Check if app rules has changed after redefinition.
400  */
401 RUNNER_TEST_SMACK(privilege_control09_perm_add_api_feature_redefine)
402 {
403     int result;
404     const char *permissionName[] = { "org.tizen.test.permtoberedefined", nullptr};
405
406     // Rules to be used with the first check
407     const rules_t test_rules1 = {
408         { GENERATED_APP_ID, PERM_TO_REDEFINE, "rx" },
409         { PERM_TO_REDEFINE, GENERATED_APP_ID, "rwx" },
410         { GENERATED_APP_ID, PERM_SUB_TO_REDEFINE, "rx" }
411     };
412
413     // Rules that contain differences - to be used with the second check (after re-def)
414     const rules_t test_rules2 = {
415         { GENERATED_APP_ID, PERM_TO_REDEFINE, "rwx" },
416         { PERM_TO_REDEFINE, GENERATED_APP_ID, "rx" },
417         { GENERATED_APP_ID, PERM_SUB_TO_REDEFINE, "watl" }
418     };
419
420     // Differences between rules1 and rules2 - should be revoked after re-def)
421     const rules_t diff_rules = {
422         { PERM_TO_REDEFINE, GENERATED_APP_ID, "w" },
423         { GENERATED_APP_ID, PERM_SUB_TO_REDEFINE, "rx" }
424     };
425
426     // Rules to be used with the first definition
427     const char *perm_rules1[] = {
428         "~APP~ " PERM_TO_REDEFINE " rx",
429         PERM_TO_REDEFINE " ~APP~ rwx",
430         "~APP~ " PERM_SUB_TO_REDEFINE " rx",
431         nullptr
432     };
433
434     // Rules that contain differences - to be used with the second definition (re-def)
435     const char *perm_rules2[] = {
436         "~APP~ " PERM_TO_REDEFINE " rwx",
437         PERM_TO_REDEFINE " ~APP~ rx",
438         "~APP~ " PERM_SUB_TO_REDEFINE " watl",
439         nullptr
440     };
441
442     DB_BEGIN
443
444     // uninstall app to make sure that all rules and permissions are revoked
445     result = perm_app_uninstall(APP_ID);
446     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
447             "perm_app_uninstall failed: " << perm_strerror(result));
448
449     result = perm_app_install(APP_ID);
450     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
451             "perm_app_install failed: " << perm_strerror(result));
452
453     result = perm_add_api_feature(APP_TYPE_OSP, permissionName[0], perm_rules1, nullptr, 0);
454     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
455             "perm_add_api_feature failed: " << result);
456
457     result = perm_app_enable_permissions(APP_ID, APP_TYPE_OSP, permissionName, true);
458     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
459             "perm_app_enable_permissions failed: " << perm_strerror(result));
460
461     DB_END
462
463     // Check if rules are applied
464     result = test_have_all_accesses(test_rules1);
465     RUNNER_ASSERT_MSG(result == 1, "Not all permissions added.");
466
467     DB_BEGIN
468
469     // Redefine the permission
470     result = perm_add_api_feature(APP_TYPE_OSP, permissionName[0], perm_rules2, nullptr, 0);
471     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
472             "perm_add_api_feature failed: " << result);
473
474     DB_END
475
476     // Check if rules are updated
477     result = test_have_all_accesses(test_rules2);
478     RUNNER_ASSERT_MSG(result == 1, "Not all permissions added after update.");
479     // The difference between rules1 and rules2 should be revoked!
480     result = test_have_any_accesses(diff_rules);
481     RUNNER_ASSERT_MSG(result == 0, "Permissions are not fully updated.");
482 }
483
484 /*
485  * Check perm_app_uninstall function
486  */
487 void check_perm_app_uninstall(const char* pkg_id)
488 {
489     int result;
490
491     DB_BEGIN
492
493     result = perm_app_uninstall(pkg_id);
494     RUNNER_ASSERT_MSG(result == 0, "perm_app_uninstall returned: " << perm_strerror(result));
495
496     DB_END
497 }
498
499 RUNNER_TEST(privilege_control07_app_uninstall)
500 {
501     check_perm_app_uninstall(APP_ID);
502 }
503
504 /*
505  * Check perm_app_install function
506  */
507 void check_perm_app_install(const char* pkg_id)
508 {
509     int result;
510
511     DB_BEGIN
512
513     result = perm_app_install(pkg_id);
514     RUNNER_ASSERT_MSG(result == 0, "perm_app_install returned: " << perm_strerror(result));
515
516     DB_END
517
518     TestLibPrivilegeControlDatabase db_test;
519     db_test.test_db_after__perm_app_install(USER_APP_ID);
520 }
521
522 RUNNER_TEST(privilege_control01_app_install)
523 {
524     check_perm_app_uninstall(APP_ID);
525     check_perm_app_install(APP_ID);
526     // try install second time app with the same ID - it should pass.
527     check_perm_app_install(APP_ID);
528 }
529
530 /*
531  * Check perm_rollback function
532  */
533 RUNNER_TEST(privilege_control07_app_rollback)
534 {
535     check_perm_app_uninstall(APP_ID);
536
537     int result;
538
539     DB_BEGIN
540
541     result = perm_app_install(APP_ID);
542     RUNNER_ASSERT_MSG(result == 0, "perm_app_install returned: " << perm_strerror(result));
543
544     // transaction rollback
545     result = perm_rollback();
546     RUNNER_ASSERT_MSG(result == 0, "perm_rollback returned: " << perm_strerror(result));
547
548     DB_END
549 }
550
551 RUNNER_TEST(privilege_control07_app_rollback_2)
552 {
553     check_perm_app_uninstall(APP_ID);
554
555     int result;
556
557     DB_BEGIN
558
559     result = perm_app_install(APP_ID);
560     RUNNER_ASSERT_MSG(result == 0, "perm_app_install returned: " << perm_strerror(result));
561
562     // transaction rollback
563     result = perm_rollback();
564     RUNNER_ASSERT_MSG(result == 0, "perm_rollback returned: " << perm_strerror(result));
565
566     // install once again after the rollback
567     result = perm_app_install(APP_ID);
568     RUNNER_ASSERT_MSG(result == 0, "perm_app_install returned: " << perm_strerror(result));
569
570     DB_END
571
572     TestLibPrivilegeControlDatabase db_test;
573     db_test.test_db_after__perm_app_install(USER_APP_ID);
574 }
575
576 /**
577  * Grant SMACK permissions based on permissions list.
578  */
579 RUNNER_TEST_SMACK(privilege_control11_app_enable_permissions)
580 {
581     int result;
582
583     // Clean up after test:
584     DB_BEGIN
585
586     result = perm_app_uninstall(WGT_APP_ID);
587     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_app_uninstall returned " << result << ". Errno: " << strerror(errno));
588     result = perm_app_install(WGT_APP_ID);
589     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_app_install returned " << result << ". Errno: " << strerror(errno));
590
591 /**
592  * Test - Enabling all permissions with persistant mode enabled
593  */
594     result = perm_app_revoke_permissions(WGT_APP_ID);
595     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
596         "Error revoking app permissions. Result: " << result);
597
598     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2, false);
599     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
600         " Error registering app permissions. Result: " << result);
601
602     DB_END
603
604     // Check if the accesses are realy applied..
605     result = test_have_all_accesses(rules2);
606     RUNNER_ASSERT_MSG(result == 1, "Permissions not added.");
607
608     DB_BEGIN
609
610     // Clean up
611     result = perm_app_revoke_permissions(WGT_APP_ID);
612     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
613         "Error revoking app permissions. Result: " << result);
614
615     DB_END
616
617 /**
618  * Test - Enabling all permissions with persistant mode disabled
619  */
620
621     DB_BEGIN
622     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2, false);
623     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
624         " Error registering app permissions. Result: " << result);
625
626     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2, false);
627     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
628         " Error enabling app permissions. Result: " << result);
629
630     DB_END
631
632     // Check if the accesses are realy applied..
633     result = test_have_all_accesses(rules2);
634     RUNNER_ASSERT_MSG(result == 1, "Permissions not added.");
635
636     DB_BEGIN
637
638     // Clean up
639     result = perm_app_revoke_permissions(WGT_APP_ID);
640     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
641         "Error revoking app permissions. Result: " << result);
642
643     DB_END
644
645 /**
646  * Test - Registering new permissions in two complementary files
647  */
648
649     DB_BEGIN
650
651     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_R_AND_NO_R, false);
652     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
653         " Error registering app permissions. Result: " << result);
654
655     DB_END
656
657     // Check if the accesses are realy applied..
658     result = test_have_all_accesses(rules2_no_r);
659     RUNNER_ASSERT_MSG(result == 1, "Permissions not added.");
660
661     DB_BEGIN
662
663     // Clean up
664     result = perm_app_revoke_permissions(WGT_APP_ID);
665     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
666         "Error revoking app permissions. Result: " << result);
667
668     DB_END
669
670 /**
671  * Test - Enabling some permissions and then enabling complementary permissions
672  */
673
674     DB_BEGIN
675
676     // Register permission for rules 2 no r
677     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_NO_R, false);
678     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
679         " Error registering app permissions without r. Result: " << result);
680
681     DB_END
682
683     // Check if the accesses are realy applied..
684     result = test_have_all_accesses(rules2_no_r);
685     RUNNER_ASSERT_MSG(result == 1, "Permissions without r not added.");
686
687     DB_BEGIN
688
689     // Register permission for rules 2
690     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2, false);
691     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
692         " Error registering app all permissions. Result: " << result);
693
694     DB_END
695
696     // Check if the accesses are realy applied..
697     result = test_have_all_accesses(rules2);
698     RUNNER_ASSERT_MSG(result == 1, "Permissions all not added.");
699
700     DB_BEGIN
701
702     // Clean up
703     result = perm_app_revoke_permissions(WGT_APP_ID);
704     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
705         "Error revoking app permissions. Result: " << result);
706
707 /**
708  * Test - Enabling some permissions and then enabling all permissions
709  */
710
711     // Enable permission for rules 2 no r
712     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_NO_R, false);
713     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
714         " Error registering app permissions without r. Result: " << result);
715
716     DB_END
717
718     // Check if the accesses are realy applied..
719     result = test_have_all_accesses(rules2_no_r);
720     RUNNER_ASSERT_MSG(result == 1, "Permissions without r not added.");
721
722     DB_BEGIN
723
724     // Enable permission for rules 2
725     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_R, false);
726     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
727         " Error registering app permissions with only r. Result: " << result);
728
729     DB_END
730
731     // Check if the accesses are realy applied..
732     result = test_have_all_accesses(rules2_r);
733     RUNNER_ASSERT_MSG(result == 1, "Permissions with only r not added.");
734
735     DB_BEGIN
736
737     // Clean up
738     result = perm_app_revoke_permissions(WGT_APP_ID);
739     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
740         "Error revoking app permissions. Result: " << result);
741
742
743
744     // Clean up after test:
745     result = perm_app_uninstall(WGT_APP_ID);
746     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS, "perm_app_uninstall returned " << result << ". Errno: " << strerror(errno));
747
748     DB_END
749 }
750
751 RUNNER_CHILD_TEST_SMACK(privilege_control11_app_enable_permissions_efl)
752 {
753     test_app_enable_permissions_efl(true);
754 }
755
756 /*
757  * Check perm_app_install function
758  */
759 RUNNER_CHILD_TEST_SMACK(privilege_control12_app_disable_permissions_efl)
760 {
761     test_app_disable_permissions_efl(true);
762 }
763
764
765 /**
766  * Remove previously granted SMACK permissions based on permissions list.
767  */
768 RUNNER_TEST_SMACK(privilege_control12_app_disable_permissions)
769 {
770     test_app_disable_permissions(true);
771 }
772
773 /**
774  * Reset SMACK permissions for an application by revoking all previously
775  * granted rules and enabling them again from a rules file from disk.
776  */
777 // TODO: This test is incomplete.
778 RUNNER_TEST_SMACK(privilege_control13_app_reset_permissions)
779 {
780     int result;
781
782 /**
783  * Test - doing reset and checking if rules exist again.
784  */
785
786     DB_BEGIN
787
788     result = perm_app_install(WGT_APP_ID);
789     RUNNER_ASSERT_MSG(result == 0, "perm_app_install returned " << result << ". Errno: " << strerror(errno));
790
791     // Disable permissions
792     result = perm_app_disable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2);
793     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
794         "Error disabling app permissions. Result: " << result);
795
796     // Prepare permissions to reset
797     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2, true);
798     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
799         " Error registering app permissions. Result: " << result);
800
801     // Reset permissions
802     result = perm_app_reset_permissions(WGT_APP_ID);
803     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
804         "Error reseting app permissions. Result: " << result);
805
806     DB_END
807
808     // Are all second permissions not disabled?
809     result = test_have_all_accesses(rules2);
810     RUNNER_ASSERT_MSG(result == 1, "Not all permissions added.");
811
812     DB_BEGIN
813
814     // Disable permissions
815     result = perm_app_disable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2);
816     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
817         "Error disabling app permissions. Result: " << result);
818
819     result = perm_app_uninstall(WGT_APP_ID);
820     RUNNER_ASSERT_MSG(result == 0, "perm_app_uninstall returned " << result << ". Errno: " << strerror(errno));
821
822     DB_END
823 }
824
825 static void smack_set_random_label_based_on_pid_on_self(void)
826 {
827     int result;
828     std::stringstream ss;
829
830     ss << "s-" << getpid() << "-" << getppid();
831     result = smack_set_label_for_self(ss.str().c_str());
832     RUNNER_ASSERT_MSG(result == 0, "smack_set_label_for_self("
833         << ss.str().c_str() << ") failed");
834 }
835
836 static void smack_unix_sock_server(int sock)
837 {
838     int fd, result;
839     char *smack_label;
840
841     alarm(2);
842     fd = accept(sock, nullptr, nullptr);
843     alarm(0);
844     if (fd < 0)
845         return;
846
847     FdUniquePtr fdPtr(&fd);
848
849     result = smack_new_label_from_self(&smack_label);
850     RUNNER_ASSERT_MSG(result >= 0, "smack_new_label_from_self() failed");
851     SmackLabelPtr smackLabelPtr(smack_label);
852
853     ssize_t bitsNum = write(fd, smack_label, strlen(smack_label));
854     RUNNER_ASSERT_ERRNO_MSG(bitsNum >= 0 && static_cast<size_t>(bitsNum) == strlen(smack_label),
855                                "write() failed");
856 }
857
858 RUNNER_MULTIPROCESS_TEST_SMACK(privilege_control15_app_id_from_socket)
859 {
860     int pid;
861     struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
862
863     unlink(SOCK_PATH);
864     pid = fork();
865     RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
866
867     smack_set_random_label_based_on_pid_on_self();
868
869     if (!pid) { /* child process, server */
870         int sock, result;
871
872         /* Set the process label before creating a socket */
873         sock = socket(AF_UNIX, SOCK_STREAM, 0);
874         RUNNER_ASSERT_ERRNO_MSG(sock >= 0, "socket failed");
875         SockUniquePtr sockPtr(&sock);
876
877         result = bind(sock,
878             (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
879         RUNNER_ASSERT_ERRNO_MSG(result == 0, "bind failed");
880
881         result = listen(sock, 1);
882         RUNNER_ASSERT_ERRNO_MSG(result == 0, "listen failed");
883         smack_unix_sock_server(sock);
884
885         /* Change the process label with listening socket */
886         smack_unix_sock_server(sock);
887
888         pid = fork();
889         RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
890         /* Now running two concurrent servers.
891            Test if socket label was unaffected by fork() */
892         smack_unix_sock_server(sock);
893         /* Let's give the two servers different labels */
894         smack_unix_sock_server(sock);
895
896         exit(0);
897     } else { /* parent process, client */
898         sleep(1); /* Give server some time to setup listening socket */
899         int i;
900         for (i = 0; i < 4; ++i) {
901             int sock;
902             int result;
903             char smack_label1[SMACK_LABEL_LEN + 1];
904             char *smack_label2;
905
906             sock = socket(AF_UNIX, SOCK_STREAM, 0);
907             RUNNER_ASSERT_ERRNO_MSG(sock >= 0, "socket failed");
908             SockUniquePtr sockPtr(&sock);
909
910             result = connect(sock,
911                 (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
912             RUNNER_ASSERT_ERRNO_MSG(result == 0, "connect failed");
913
914             alarm(2);
915             result = read(sock, smack_label1, SMACK_LABEL_LEN);
916             alarm(0);
917             RUNNER_ASSERT_ERRNO_MSG(result >= 0, "read failed");
918
919             smack_label1[result] = '\0';
920             smack_label2 = perm_app_id_from_socket(sock);
921             RUNNER_ASSERT_MSG(smack_label2 != nullptr, "perm_app_id_from_socket failed");
922             result = strcmp(smack_label1, smack_label2);
923             RUNNER_ASSERT_MSG(result == 0, "smack labels differ: '" << smack_label1
924                                  << "' != '" << smack_label2 << "-" << random() << "'");
925         }
926     }
927 }
928
929 RUNNER_TEST(privilege_control20_perm_app_has_permission)
930 {
931     int result;
932     const char *other_app_label = "test_other_app_label";
933
934     DB_BEGIN
935
936     result = perm_app_uninstall(WGT_APP_ID);
937     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
938             "Error uninstalling app. Result" << result);
939
940     result = perm_app_install(WGT_APP_ID);
941     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
942             "Error installing app. Result" << result);
943
944     result = perm_app_disable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_R_AND_NO_R);
945     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
946             "Error disabling app r and no r permissions. Result: " << result);
947
948     DB_END
949
950     check_perm_app_has_permission(USER_APP_ID, PRIVS2_R[0], false);
951     check_perm_app_has_permission(USER_APP_ID, PRIVS2_NO_R[0], false);
952     check_perm_app_has_permission(other_app_label, PRIVS2_R[0], false);
953     check_perm_app_has_permission(other_app_label, PRIVS2_NO_R[0], false);
954
955     DB_BEGIN
956
957     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_R, false);
958     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
959             "Error registering app r permissions. Result: " << result);
960
961     DB_END
962
963     check_perm_app_has_permission(USER_APP_ID, PRIVS2_R[0], true);
964     check_perm_app_has_permission(USER_APP_ID, PRIVS2_NO_R[0], false);
965     check_perm_app_has_permission(other_app_label, PRIVS2_R[0], false);
966     check_perm_app_has_permission(other_app_label, PRIVS2_NO_R[0], false);
967
968     DB_BEGIN
969
970     result = perm_app_enable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_NO_R, false);
971     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
972             "Error registering app r permissions. Result: " << result);
973
974     DB_END
975
976     check_perm_app_has_permission(USER_APP_ID, PRIVS2_R[0], true);
977     check_perm_app_has_permission(USER_APP_ID, PRIVS2_NO_R[0], true);
978     check_perm_app_has_permission(other_app_label, PRIVS2_R[0], false);
979     check_perm_app_has_permission(other_app_label, PRIVS2_NO_R[0], false);
980
981     DB_BEGIN
982
983     result = perm_app_disable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_R);
984     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
985             "Error disabling app r and no r permissions. Result: " << result);
986
987     DB_END
988
989     check_perm_app_has_permission(USER_APP_ID, PRIVS2_R[0], false);
990     check_perm_app_has_permission(USER_APP_ID, PRIVS2_NO_R[0], true);
991     check_perm_app_has_permission(other_app_label, PRIVS2_R[0], false);
992     check_perm_app_has_permission(other_app_label, PRIVS2_NO_R[0], false);
993
994     DB_BEGIN
995
996     result = perm_app_disable_permissions(WGT_APP_ID, APP_TYPE_WGT, PRIVS2_NO_R);
997     RUNNER_ASSERT_MSG(result == PC_OPERATION_SUCCESS,
998             "Error disabling app r and no r permissions. Result: " << result);
999
1000     DB_END
1001
1002     check_perm_app_has_permission(USER_APP_ID, PRIVS2_R[0], false);
1003     check_perm_app_has_permission(USER_APP_ID, PRIVS2_NO_R[0], false);
1004     check_perm_app_has_permission(other_app_label, PRIVS2_R[0], false);
1005     check_perm_app_has_permission(other_app_label, PRIVS2_NO_R[0], false);
1006 }
1007
1008 RUNNER_TEST(privilege_control25_test_libprivilege_strerror) {
1009     int POSITIVE_ERROR_CODE = 1;
1010     int NONEXISTING_ERROR_CODE = -239042;
1011     const char *result;
1012
1013     for (auto itr = error_codes.begin(); itr != error_codes.end(); ++itr) {
1014         RUNNER_ASSERT_MSG(strcmp(perm_strerror(*itr), "Unknown error") != 0,
1015                 "Returned invalid error code description.");
1016     }
1017
1018     result = perm_strerror(POSITIVE_ERROR_CODE);
1019     RUNNER_ASSERT_MSG(strcmp(result, "Unknown error") == 0,
1020             "Bad message returned for invalid error code: \"" << result << "\"");
1021
1022     result = perm_strerror(NONEXISTING_ERROR_CODE);
1023     RUNNER_ASSERT_MSG(strcmp(result, "Unknown error") == 0,
1024             "Bad message returned for invalid error code: \"" << result << "\"");
1025 }