Clean up libprivilege-control test cases
[platform/core/test/security-tests.git] / tests / libprivilege-control-tests / libprivilege-control_test_common.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  * @file    libprivilege-control-test.cpp
18  * @author  Jan Olszak (j.olszak@samsung.com)
19  * @version 1.0
20  * @brief   Main file for libprivilege-control unit tests.
21  */
22
23 #include <string>
24 #include <set>
25 #include <libprivilege-control_test_common.h>
26 #include <sys/smack.h>
27 #include <dpl/test/test_runner.h>
28
29 #define CANARY_LABEL             "tiny_yellow_canary"
30
31 const char *PRIVS[] = { "WRT", "test_privilege_control_rules", NULL };
32 const char *PRIVS2[] = { "test_privilege_control_rules2", NULL };
33
34 const char *PRIVS_WGT[] = { "test_privilege_control_rules_wgt", NULL };
35 const char *PRIVS_OSP[] = { "test_privilege_control_rules_osp", NULL };
36
37 const char* PRIV_APPSETTING[] {"org.tizen.privilege.appsetting", NULL};
38
39 void cleaning_smack_app_files (void)
40 {
41     unlink(SMACK_RULES_DIR APP_TEST_APP_1);
42     unlink(SMACK_RULES_DIR APP_TEST_APP_2);
43     unlink(SMACK_RULES_DIR APP_TEST_APP_3);
44     unlink(SMACK_RULES_DIR APP_TEST_AV_1);
45     unlink(SMACK_RULES_DIR APP_TEST_AV_2);
46     unlink(SMACK_RULES_DIR APP_TEST_AV_3);
47 }
48
49 /**
50  * Check if every rule is true.
51  * @return 1 if ALL rules in SMACK, 0 if ANY rule isn't
52  */
53 int test_have_all_accesses(const std::vector< std::vector<std::string> > &rules)
54 {
55     int result;
56     for (uint i = 0; i < rules.size(); ++i) {
57         result = smack_have_access(rules[i][0].c_str(),rules[i][1].c_str(),rules[i][2].c_str());
58         if (result != 1)
59             return result;
60     }
61     return 1;
62 }
63
64 /**
65  * Check if every rule is true.
66  * @return 1 if ANY rule in SMACK, 0 if
67  */
68 int test_have_any_accesses(const std::vector< std::vector<std::string> > &rules)
69 {
70     int result;
71     for (uint i = 0; i < rules.size(); ++i) {
72         result = smack_have_access(rules[i][0].c_str(),rules[i][1].c_str(),rules[i][2].c_str());
73         if (result == 1)
74             return 1;
75     }
76     return 0;
77 }
78
79 void read_gids(std::set<unsigned> &set, const char *file_path)
80 {
81     FILE *f = fopen(file_path, "r");
82     RUNNER_ASSERT_MSG(f != NULL, "Unable to open file " << file_path);
83     unsigned gid;
84     while (fscanf(f, "%u\n", &gid) == 1) {
85         set.insert(gid);
86     }
87 }
88
89 void check_groups(const char *dac_file)
90 {
91     std::set<unsigned> groups_check;
92     read_gids(groups_check, LIBPRIVILEGE_APP_GROUP_LIST);
93     read_gids(groups_check, dac_file);
94
95     int groups_cnt = getgroups(0, NULL);
96     RUNNER_ASSERT_MSG(groups_cnt > 0, "Wrong number of supplementary groupsCnt");
97     gid_t *groups_list = (gid_t*) calloc(groups_cnt, sizeof(gid_t));
98     RUNNER_ASSERT_MSG(groups_list != NULL, "Memory allocation failed");
99     RUNNER_ASSERT(-1 != getgroups(groups_cnt, groups_list));
100
101     for (int i = 0; i < groups_cnt; ++i) {
102         //getgroups() can return multiple number of the same group
103         //they are returned in sequence, so we will given number when last
104         //element of this number is reached
105         if ((i < groups_cnt - 1) && (groups_list[i + 1] == groups_list[i]))
106             continue;
107         if (groups_check.erase(groups_list[i]) == 0) {
108             // getgroups() may also return process' main group
109             if (groups_list[i] != getgid())
110                 RUNNER_ASSERT_MSG(false, "Application belongs to unknown group (GID=" << groups_list[i] << ")");
111         }
112     }
113     free(groups_list);
114     std::string groups_left;
115     for (std::set<unsigned>::iterator it = groups_check.begin(); it != groups_check.end(); it++) {
116         groups_left.append(std::to_string(*it)).append(" ");
117     }
118     RUNNER_ASSERT_MSG(groups_check.empty(), "Application doesn't belong to some required groups: " << groups_left);
119 }
120
121 int nftw_remove_labels(const char *fpath, const struct stat* /*sb*/,
122                        int /*typeflag*/, struct FTW* /*ftwbuf*/)
123 {
124     smack_lsetlabel(fpath, NULL, SMACK_LABEL_ACCESS);
125     smack_lsetlabel(fpath, NULL, SMACK_LABEL_EXEC);
126     smack_lsetlabel(fpath, NULL, SMACK_LABEL_TRANSMUTE);
127
128     return 0;
129 }
130
131 int nftw_check_labels_app_dir(const char *fpath, const struct stat *sb,
132                                int /*typeflag*/, struct FTW* /*ftwbuf*/)
133 {
134     int result;
135     char *label;
136
137     /* ACCESS */
138     result = smack_lgetlabel(fpath, &label, SMACK_LABEL_ACCESS);
139     RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path");
140     RUNNER_ASSERT_MSG(label != NULL, "ACCESS label on " << fpath << " is not set");
141     result = strcmp(APPID_DIR, label);
142     RUNNER_ASSERT_MSG(result == 0, "ACCESS label on " << fpath << " is incorrect");
143
144     /* EXEC */
145     result = smack_lgetlabel(fpath, &label, SMACK_LABEL_EXEC);
146     RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path");
147     if (S_ISREG(sb->st_mode) && (sb->st_mode & S_IXUSR)) {
148         RUNNER_ASSERT_MSG(label != NULL, "EXEC label on " << fpath << " is not set");
149         result = strcmp(APPID_DIR, label);
150         RUNNER_ASSERT_MSG(result == 0, "EXEC label on executable file " << fpath << " is incorrect");
151     } else if (S_ISLNK(sb->st_mode)) {
152         struct stat buf;
153         char *target = realpath(fpath, NULL);
154         RUNNER_ASSERT_MSG(0 == stat(target, &buf),"Stat failed for " << fpath);
155         free(target);
156         if (buf.st_mode != (buf.st_mode | S_IXUSR | S_IFREG)) {
157             RUNNER_ASSERT_MSG(label == NULL, "EXEC label on " << fpath << " is set");
158         } else {
159             RUNNER_ASSERT_MSG(label != NULL, "EXEC label on " << fpath << " is not set");
160             result = strcmp(APPID_DIR, label);
161             RUNNER_ASSERT_MSG(result == 0, "EXEC label on link to executable file " << fpath << " is incorrect");
162         }
163     } else
164         RUNNER_ASSERT_MSG(label == NULL, "EXEC label on " << fpath << " is set");
165
166     /* TRANSMUTE */
167     result = smack_lgetlabel(fpath, &label, SMACK_LABEL_TRANSMUTE);
168     RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path");
169     RUNNER_ASSERT_MSG(label == NULL, "TRANSMUTE label on " << fpath << " is set");
170
171     return 0;
172  }
173
174 int nftw_set_labels_non_app_dir(const char *fpath, const struct stat* /*sb*/,
175                                 int /*typeflag*/, struct FTW* /*ftwbuf*/)
176 {
177     smack_lsetlabel(fpath, CANARY_LABEL, SMACK_LABEL_ACCESS);
178     smack_lsetlabel(fpath, CANARY_LABEL, SMACK_LABEL_EXEC);
179     smack_lsetlabel(fpath, NULL, SMACK_LABEL_TRANSMUTE);
180
181     return 0;
182 }
183
184 int nftw_check_labels_non_app_dir(const char *fpath, const struct stat* /*sb*/,
185                                   int /*typeflag*/, struct FTW* /*ftwbuf*/)
186 {
187     int result;
188     char *label;
189
190     /* ACCESS */
191     result = smack_lgetlabel(fpath, &label, SMACK_LABEL_ACCESS);
192     RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path");
193     result = strcmp(CANARY_LABEL, label);
194     RUNNER_ASSERT_MSG(result == 0, "ACCESS label on " << fpath << " is overwritten");
195
196     /* EXEC */
197     result = smack_lgetlabel(fpath, &label, SMACK_LABEL_EXEC);
198     RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path");
199     result = strcmp(CANARY_LABEL, label);
200     RUNNER_ASSERT_MSG(result == 0, "EXEC label on " << fpath << " is overwritten");
201
202     /* TRANSMUTE */
203     result = smack_lgetlabel(fpath, &label, SMACK_LABEL_TRANSMUTE);
204     RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path");
205     RUNNER_ASSERT_MSG(label == NULL, "TRANSMUTE label on " << fpath << " is set");
206
207     return 0;
208 }