SM: Adjust trusted sharing tests to nonhybrid apps
[platform/core/test/security-tests.git] / src / security-manager-tests / test_cases_trusted_sharing.cpp
1 /*
2  * Copyright (c) 2016 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 #include <algorithm>
18 #include <ftw.h>
19 #include <string>
20 #include <sys/smack.h>
21 #include <vector>
22
23 #include <security-manager.h>
24
25 #include <app_install_helper.h>
26 #include <dpl/test/test_runner.h>
27 #include <sm_api.h>
28 #include <sm_commons.h>
29 #include <sm_db.h>
30 #include <sm_request.h>
31 #include <tests_common.h>
32 #include <tzplatform.h>
33
34 using namespace SecurityManagerTest;
35
36 static const std::string SM_TRUSTED_PATH =
37         TzPlatformConfig::globalAppDir() + "/sm_test_02_pkg_id_full/app_dir_trusted";
38
39 static void check_exact_access(const std::string& subject, const std::string& object, const std::string& access)
40 {
41     // check access
42     if (!access.empty()) {
43         int result = smack_have_access(subject.c_str(), object.c_str(), access.c_str());
44         RUNNER_ASSERT_MSG(result >= 0, "smack_have_access failed");
45         RUNNER_ASSERT_MSG(result == 1,
46           "No smack access: " << subject << " " << object << " " << access);
47     }
48     // check excessive access
49     auto foundInAccess = [&access](std::string::value_type c) {
50         return access.find(c) != std::string::npos; };
51
52     std::string negative = "rwxatl";
53     auto end = std::remove_if(negative.begin(), negative.end(), foundInAccess);
54     negative.erase(end, negative.end());
55
56     for(const auto& c : negative) {
57         int result = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
58         RUNNER_ASSERT_MSG(result >= 0, "smack_have_access failed");
59         RUNNER_ASSERT_MSG(result == 0, "Unexpected access for" <<
60             " subject:" << subject <<
61             " object:" << object <<
62             " right:" << std::string(1,c) <<
63             " result:" << result <<
64             " expected:0");
65     }
66 }
67
68 RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_TRUSTED_SHARING)
69
70 RUNNER_TEST(security_manager_40_set_wrong_author_id)
71 {
72     InstallRequest requestInst;
73
74     RUNNER_ASSERT(SECURITY_MANAGER_ERROR_INPUT_PARAM ==
75         security_manager_app_inst_req_set_author_id(requestInst.get(), NULL));
76
77     RUNNER_ASSERT(SECURITY_MANAGER_ERROR_INPUT_PARAM ==
78         security_manager_app_inst_req_set_author_id(requestInst.get(), ""));
79 }
80
81 RUNNER_TEST(security_manager_41_set_author_id_multiple_times)
82 {
83     for(unsigned int i=0; i<10; ++i) {
84         std::string authorId = "some-author-id" + std::to_string(i);
85
86         InstallRequest requestInst;
87         requestInst.setAuthorId(authorId);
88     }
89 }
90
91 RUNNER_TEST(security_manager_43_app_install_with_trusted_path)
92 {
93     std::vector<AppInstallHelper> helper {{"app43a"}, {"app43b"}, {"app43c"}};
94     auto &provider  = helper[0];
95     auto &user      = helper[1];
96     auto &untrusted = helper[2];
97
98     TestSecurityManagerDatabase dbtest;
99     const char *author_id = "custom_author_id_test 41";
100
101     const char *const trusted_access = "rwxatl";
102     const char *const system_access = "rwxatl";
103
104     int result;
105
106     // cleanup
107     for (auto &e : helper) {
108         e.revokeRules();
109         e.createInstallDir();
110         e.createTrustedDir();
111     }
112
113     result = nftw(provider.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
114     RUNNER_ASSERT_MSG(result == 0, "Unable to set Smack labels in " << SM_TRUSTED_PATH);
115
116     // install app with shared/trusted dir
117     InstallRequest trustingApp;
118     trustingApp.setAppId(provider.getAppId());
119     trustingApp.setPkgId(provider.getPkgId());
120     trustingApp.setAuthorId("author id to be overwritten");
121     trustingApp.setAuthorId(author_id);
122     trustingApp.addPath(provider.getTrustedDir().c_str(), SECURITY_MANAGER_PATH_TRUSTED_RW);
123     Api::install(trustingApp);
124
125     int64_t authorDb = dbtest.get_author_id(author_id);
126     const std::string trusted_label = std::string("User::Author::") + std::to_string(authorDb);
127
128     // check trusted path label
129     check_path(provider.getTrustedDir(), trusted_label);
130
131     // check rules
132     check_exact_access("System", trusted_label, system_access);
133     check_exact_access("User", trusted_label, system_access);
134     check_exact_access(generateProcessLabel(provider.getAppId(), provider.getPkgId()),
135                        trusted_label, trusted_access);
136
137     // install trusted app
138     InstallRequest trustedApp;
139     trustedApp.setAppId(user.getAppId());
140     trustedApp.setPkgId(user.getPkgId());
141     trustedApp.setAuthorId(author_id);
142     Api::install(trustedApp);
143
144     // check rules
145     check_exact_access(generateProcessLabel(user.getAppId(), user.getPkgId()),
146                        trusted_label, trusted_access);
147
148     // install untrusted app
149     InstallRequest untrustedApp;
150     untrustedApp.setAppId(untrusted.getAppId());
151     untrustedApp.setPkgId(untrusted.getPkgId());
152     Api::install(untrustedApp);
153
154     // check rules
155     check_exact_access(generateProcessLabel(untrusted.getAppId(), untrusted.getPkgId()),
156                        trusted_label, "");
157
158     // uninstall trusting app
159     Api::uninstall(trustingApp);
160
161     // there's still one app with author id, rules should be kept
162     check_exact_access("System", trusted_label, system_access);
163     check_exact_access("User", trusted_label, system_access);
164     check_exact_access(generateProcessLabel(provider.getAppId(), provider.getPkgId()),
165                        trusted_label, "");
166     check_exact_access(generateProcessLabel(user.getAppId(), user.getPkgId()),
167                        trusted_label, trusted_access);
168
169     Api::uninstall(trustedApp);
170
171     // no more apps with author id
172     check_exact_access("System", trusted_label, "");
173     check_exact_access("User", trusted_label, "");
174     check_exact_access(generateProcessLabel(user.getAppId(), user.getPkgId()),
175                        trusted_label, "");
176
177     Api::uninstall(untrustedApp);
178 }
179
180
181 RUNNER_TEST(security_manager_44_app_install_with_trusted_path_no_author_id)
182 {
183     AppInstallHelper help("app44");
184     help.createInstallDir();
185     help.createTrustedDir();
186
187     // install app with shared/trusted dir but without authors id
188     InstallRequest app;
189     app.setAppId(help.getAppId());
190     app.setPkgId(help.getPkgId());
191     app.addPath(help.getTrustedDir(), SECURITY_MANAGER_PATH_TRUSTED_RW);
192     Api::install(app, SECURITY_MANAGER_ERROR_INPUT_PARAM);
193 }
194
195 RUNNER_TEST(security_manager_45_test_authorId_identificator_creation)
196 {
197     std::vector<AppInstallHelper> helper {{"a45"}, {"b45"}};
198     auto &trusted1 = helper[0];
199     auto &trusted2 = helper[1];
200
201     TestSecurityManagerDatabase dbtest;
202     const char *authorId1 = "custom_author_id_test a45";
203     const char *authorId2 = "custom_author_id_test b45";
204
205     // cleanup
206     for (auto &e : helper) {
207         e.revokeRules();
208         e.createInstallDir();
209         e.createTrustedDir();
210     }
211
212     // install app with shared/trusted dir
213     InstallRequest trustingApp;
214     trustingApp.setAppId(trusted1.getAppId());
215     trustingApp.setPkgId(trusted1.getPkgId());
216     trustingApp.setAuthorId(authorId1);
217     trustingApp.addPath(trusted1.getTrustedDir().c_str(), SECURITY_MANAGER_PATH_TRUSTED_RW);
218     Api::install(trustingApp);
219
220     int64_t authorDb1 = dbtest.get_author_id(authorId1);
221
222     // install trusted app
223     InstallRequest trustedApp;
224     trustedApp.setAppId(trusted2.getAppId());
225     trustedApp.setPkgId(trusted2.getPkgId());
226     trustedApp.setAuthorId(authorId2);
227     Api::install(trustedApp);
228
229     int64_t authorDb2 = dbtest.get_author_id(authorId2);
230
231     Api::uninstall(trustingApp);
232     Api::uninstall(trustedApp);
233
234     RUNNER_ASSERT(authorDb1 != authorDb2);
235 }
236 /* Description:
237  * Lets assume that app1 and app2 are part of pkg1.
238  * Deinstalation of app1 mustnot remove rules:
239  * System PKG1Label rwxatl
240  * User PKGLabel rwxatl
241  */
242 void test_46_pkgId_deinstallation(bool isHybrid) {
243     std::vector<AppInstallHelper> helper {{"a46", "a46"}, {"b46", "a46"}};
244     auto &trusted1 = helper[0];
245     auto &trusted2 = helper[1];
246
247     std::string authorId1 = "author46XYZ";
248
249     for (auto &e : helper) {
250         e.revokeRules();
251         e.createInstallDir();
252         e.createTrustedDir();
253     }
254
255     InstallRequest trustingApp;
256     trustingApp.setAppId(trusted1.getAppId());
257     trustingApp.setPkgId(trusted1.getPkgId());
258     trustingApp.setAuthorId(authorId1);
259     if (isHybrid)
260         trustingApp.setHybrid();
261     trustingApp.addPath(trusted1.getTrustedDir().c_str(), SECURITY_MANAGER_PATH_TRUSTED_RW);
262     Api::install(trustingApp);
263
264     InstallRequest trustingApp2;
265     trustingApp2.setAppId(trusted2.getAppId());
266     trustingApp2.setPkgId(trusted2.getPkgId());
267     trustingApp2.setAuthorId(authorId1);
268     if (isHybrid)
269         trustingApp2.setHybrid();
270     Api::install(trustingApp2);
271
272
273     check_exact_access("System", generatePathRWLabel(trusted1.getPkgId()), "rwxatl");
274     check_exact_access("User", generatePathRWLabel(trusted1.getPkgId()), "rwxatl");
275     if (isHybrid) {
276         // Nonhybrid apps have the same label for process and private files
277         check_exact_access("System",
278                            generateProcessLabel(trusted1.getAppId(), trusted1.getPkgId(), isHybrid),
279                            "rwxl");
280         check_exact_access("User",
281                            generateProcessLabel(trusted1.getAppId(), trusted1.getPkgId(), isHybrid),
282                             "rwxl");
283         check_exact_access("System",
284                            generateProcessLabel(trusted2.getAppId(), trusted2.getPkgId(), isHybrid),
285                            "rwxl");
286         check_exact_access("User",
287                            generateProcessLabel(trusted2.getAppId(), trusted2.getPkgId(), isHybrid),
288                            "rwxl");
289     }
290
291     Api::uninstall(trustingApp2);
292
293     check_exact_access("System", generatePathRWLabel(trusted1.getPkgId()), "rwxatl");
294     check_exact_access("User", generatePathRWLabel(trusted1.getPkgId()), "rwxatl");
295
296     if (isHybrid) {
297         // Nonhybrid apps from the same package share process label
298         check_exact_access("System",
299                            generateProcessLabel(trusted1.getAppId(), trusted1.getPkgId(), isHybrid),
300                            "rwxl");
301         check_exact_access("User",
302                            generateProcessLabel(trusted1.getAppId(), trusted1.getPkgId(), isHybrid),
303                            "rwxl");
304         check_exact_access("System",
305                            generateProcessLabel(trusted2.getAppId(), trusted2.getPkgId(), isHybrid),
306                            "");
307         check_exact_access("User",
308                            generateProcessLabel(trusted2.getAppId(), trusted2.getPkgId(), isHybrid),
309                            "");
310     }
311
312     Api::uninstall(trustingApp);
313
314     check_exact_access("System",
315                        generateProcessLabel(trusted1.getAppId(), trusted1.getPkgId(), isHybrid),
316                        "");
317     check_exact_access("User",
318                        generateProcessLabel(trusted1.getAppId(), trusted1.getPkgId(), isHybrid),
319                        "");
320     check_exact_access("System", generatePathRWLabel(trusted1.getPkgId()), "");
321     check_exact_access("User", generatePathRWLabel(trusted1.getPkgId()), "");
322 }
323
324 RUNNER_TEST(security_manager_46_pkgId_deinstalation_test_hybrid)
325 {
326     test_46_pkgId_deinstallation(true);
327 }
328
329 RUNNER_TEST(security_manager_46_pkgId_deinstalation_test_nonhybrid)
330 {
331     test_46_pkgId_deinstallation(false);
332 }