6012c3a516e7ecf37c8de08fb6793a4bc6cf06a2
[platform/core/test/security-tests.git] / src / common / app_install_helper.cpp
1 /*
2  * Copyright (c) 2014-2020 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 <fcntl.h>
18 #include <map>
19 #include <string>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <sys/smack.h>
23 #include <unistd.h>
24 #include <utility>
25
26 #include <security-manager-types.h>
27
28 #include <dpl/test/test_runner.h>
29 #include <tzplatform.h>
30 #include <label_generator.h>
31 #include <tests_common.h>
32 #include <tzplatform.h>
33
34 #include "app_install_helper.h"
35
36 namespace {
37
38 const gid_t FILE_GROUP = 100;
39
40     std::string genSkelPath() {
41         static std::string skelPkgDir;
42         if (!skelPkgDir.empty())
43             return skelPkgDir;
44         std::string app = TzPlatformConfig::getEnv(TZ_USER_APP);
45         std::string home = TzPlatformConfig::getEnv(TZ_USER_HOME);
46         std::string skelDir = "/etc/skel";
47
48         skelPkgDir.assign(app);
49         skelPkgDir.replace(0, home.length(), skelDir);
50
51         return skelPkgDir;
52     }
53
54     const AppInstallHelper::TypePathMap typeToPath = {
55             {SECURITY_MANAGER_PATH_RW, "app_rw"},
56             {SECURITY_MANAGER_PATH_RO, "app_ro"},
57             {SECURITY_MANAGER_PATH_PUBLIC_RO, "public_ro"},
58             {SECURITY_MANAGER_PATH_TRUSTED_RW, "trusted_rw"},
59             {SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, "shared_ro"}
60     };
61 }
62
63 AppInstallHelper::AppInstallHelper(AppInstallHelper &&other)
64     : m_appName(std::move(other.m_appName)), m_pkgName(std::move(other.m_pkgName)),
65       m_isLocal(other.m_isLocal), m_uidGid(other.m_uidGid),
66       m_version(std::move(other.m_version)), m_installType(other.m_installType),
67       m_isHybrid(other.m_isHybrid),
68       m_rootPaths(std::move(other.m_rootPaths)),
69       m_dirTypeMap(std::move(other.m_dirTypeMap)),
70       m_fileTypeMap(std::move(other.m_fileTypeMap)),
71       m_privileges(std::move(other.m_privileges)),
72       m_appDefinedPrivileges(std::move(other.m_appDefinedPrivileges)),
73       m_author(std::move(other.m_author)),
74       m_creatorPid(other.m_creatorPid)
75 {
76     other.m_creatorPid = -1;
77 }
78
79 void AppInstallHelper::setInstallPath(RootType type) const {
80     RootInfo &info = m_rootPaths[type];
81     if (!info.path.empty())
82         return;
83
84     switch (type) {
85     case RootType::BASE:
86         if (m_isLocal)
87             info.path = TzPlatformConfig::appDirPath(getUID()) + getPkgId();
88         else
89             info.path = TzPlatformConfig::globalAppDir() + "/" + getPkgId();
90         break;
91     case RootType::EXTENDED:
92         if (m_isLocal)
93             info.path = TzPlatformConfig::extendedSdUserDir(getUID()) + "/" + getPkgId();
94         else
95             info.path = TzPlatformConfig::extendedSdDir() + "/" + getPkgId();
96         break;
97     case RootType::SKEL:
98         info.path = genSkelPath() + "/" + getPkgId();
99         break;
100     case RootType::SHARED:
101         if (m_isLocal)
102             info.path = TzPlatformConfig::appDirPath(getUID()) + ".shared/" + getPkgId();
103         else
104             info.path = TzPlatformConfig::globalAppDir() + "/.shared/" + getPkgId();
105         break;
106     case RootType::SHARED_TMP:
107         if (m_isLocal)
108             info.path = TzPlatformConfig::appDirPath(getUID()) + ".shared_tmp/" + getPkgId();
109         else
110             info.path = TzPlatformConfig::globalAppDir() + "/.shared_tmp/" + getPkgId();
111         break;
112     }
113 }
114
115 std::string AppInstallHelper::getInstallDir(RootType type) const {
116     setInstallPath(type);
117     return m_rootPaths[type].path;
118 }
119
120 std::string AppInstallHelper::getPath(app_install_path_type smType, PathType pType, int i, RootType rType) const {
121     std::string path;
122     switch (pType) {
123     case PathType::DIR:
124         path = getInstallDir(rType) + "/" + typeToPath.at(smType) + "_dir" + std::to_string(i);
125         break;
126     case PathType::FILE:
127         // put files in the directory of the same type
128         path = getPath(smType, PathType::DIR, 0, rType) + "/" + typeToPath.at(smType) + std::to_string(i);
129         break;
130     }
131     return path;
132 }
133
134 std::string AppInstallHelper::getTrustedDir(int i, RootType type) const {
135     return getPath(SECURITY_MANAGER_PATH_TRUSTED_RW, PathType::DIR, i , type);
136 }
137
138 std::string AppInstallHelper::getPrivateDir(int i, RootType type) const {
139     return getPath(SECURITY_MANAGER_PATH_RW, PathType::DIR, i, type);
140 }
141
142 std::string AppInstallHelper::getPrivateRODir(int i, RootType type) const {
143     return getPath(SECURITY_MANAGER_PATH_RO, PathType::DIR, i, type);
144 }
145
146 std::string AppInstallHelper::getPublicDir(RootType type) const {
147     return getPath(SECURITY_MANAGER_PATH_PUBLIC_RO, PathType::DIR, 0, type);
148 }
149
150 std::string AppInstallHelper::getPrivatePath(int i, RootType type) const {
151     return getPath(SECURITY_MANAGER_PATH_RW, PathType::FILE, i, type);
152 }
153
154 std::string AppInstallHelper::getSharedRODir(int i, RootType type) const {
155 return getPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, type);
156 }
157
158 std::string AppInstallHelper::getSharedROPath(int i, RootType type) const {
159     return getPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::FILE, i, type);
160 }
161
162 const std::string& AppInstallHelper::getAppId() const {
163     return m_appName;
164 }
165
166 const std::string& AppInstallHelper::getPkgId() const {
167     return m_pkgName;
168 }
169
170 void AppInstallHelper::setVersion(const std::string &version) {
171     m_version = version;
172 }
173
174 std::string AppInstallHelper::getVersion() const {
175     return m_version;
176 }
177
178 int AppInstallHelper::getUID() const {
179     return m_uidGid;
180 }
181
182 int AppInstallHelper::getGID() const {
183     return m_uidGid;
184 }
185
186 bool AppInstallHelper::createFile(app_install_path_type smType, const std::string &path) {
187     if (creat(path.c_str(), 0751) == 0) {
188         // Local paths need user change
189         m_fileTypeMap[smType].push_back(path);
190         if (!m_isLocal || chown(path.c_str(), m_uidGid, FILE_GROUP) == 0)
191             return true;
192     }
193     return false;
194 }
195
196 bool AppInstallHelper::createDir(app_install_path_type smType, const std::string &path, bool isBasePath) {
197     mktreeSafe(path, 0777);
198     // Dont pass base pkg dirs to SM, because transmute will be forced on RO subdirs
199     if (!isBasePath)
200         m_dirTypeMap[smType].push_back(path);
201     if (!m_isLocal || chown(path.c_str(), m_uidGid, FILE_GROUP) == 0)
202         return true;
203
204     return false;
205 }
206
207 void AppInstallHelper::createInstallDir(RootType type) {
208     setInstallPath(type);
209     RootInfo &info = m_rootPaths[type];
210     if (info.isCreated)
211         return;
212     createDir(SECURITY_MANAGER_PATH_PUBLIC_RO, info.path, true);
213     info.isCreated = true;
214 }
215
216 void AppInstallHelper::createPath(app_install_path_type smType, PathType pType, int i, RootType rType) {
217     createInstallDir(rType);
218     std::string path = getPath(smType, pType, i, rType);
219     switch (pType) {
220     case PathType::DIR:
221         createDir(smType, path);
222         break;
223     case PathType::FILE:
224         createPath(smType, PathType::DIR, 0, rType);
225         createFile(smType, path);
226         break;
227     }
228 }
229
230 void AppInstallHelper::createDirLink(app_install_path_type smType, const std::string &dest, int i,
231                                      RootType rType)
232 {
233     createInstallDir(rType);
234     std::string linkPath = getPath(smType, PathType::DIR, i, rType);
235     if (symlink(dest.c_str(), linkPath.c_str()) == 0) {
236         m_fileTypeMap[smType].push_back(linkPath);
237         if (m_isLocal) {
238             chown(linkPath.c_str(), m_uidGid, FILE_GROUP);
239         }
240     }
241 }
242
243 void AppInstallHelper::createTrustedDir(int i, RootType type) {
244     createPath(SECURITY_MANAGER_PATH_TRUSTED_RW, PathType::DIR, i, type);
245 }
246
247 void AppInstallHelper::createPrivateDir(int i, RootType type) {
248     createPath(SECURITY_MANAGER_PATH_RW, PathType::DIR, i, type);
249 }
250
251 void AppInstallHelper::createPublicDir(RootType type) {
252     createPath(SECURITY_MANAGER_PATH_PUBLIC_RO, PathType::DIR, 0, type);
253 }
254
255 void AppInstallHelper::createPrivateFile(int i, RootType type) {
256     createPath(SECURITY_MANAGER_PATH_RW, PathType::FILE, i, type);
257 }
258
259 void AppInstallHelper::createSharedRODir(int i, RootType type) {
260     createPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, RootType::SHARED);
261     createInstallDir(RootType::SHARED_TMP);
262     auto linkPath = getSharedRODir(i, RootType::SHARED);
263     createDirLink(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, linkPath, i, type);
264 }
265
266 void AppInstallHelper::createSharedROFile(int i, RootType type) {
267     createPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::FILE, i, type);
268 }
269
270 void AppInstallHelper::createPrivateRODir(int i, RootType type) {
271     createPath(SECURITY_MANAGER_PATH_RO, PathType::DIR, i, type);
272 }
273
274 void AppInstallHelper::setHybrid() {
275     m_isHybrid = true;
276 }
277
278 bool AppInstallHelper::getIsHybrid() const {
279     return m_isHybrid;
280 }
281
282 void AppInstallHelper::addPrivilege(Privilege privilege) {
283     m_privileges.push_back(std::move(privilege));
284 }
285
286 void AppInstallHelper::addPrivileges(const PrivilegeVector &privileges) {
287     std::copy(privileges.begin(), privileges.end(), std::back_inserter(m_privileges));
288 }
289
290 const PrivilegeVector& AppInstallHelper::getPrivileges() const {
291     return m_privileges;
292 }
293
294 void AppInstallHelper::addAppDefinedPrivilege(Privilege privilege) {
295     m_appDefinedPrivileges.push_back(std::move(privilege));
296 }
297
298 const PrivilegeVector& AppInstallHelper::getAppDefinedPrivileges() const {
299     return m_appDefinedPrivileges;
300 }
301
302 void AppInstallHelper::revokeRules() const {
303     RUNNER_ASSERT_MSG(
304         0 == smack_revoke_subject(generateAppLabel().c_str()),
305         "Revoking smack subject failed");
306 }
307
308 std::string AppInstallHelper::generateAppLabel() const {
309     return generateProcessLabel(getAppId(), getPkgId(), getIsHybrid());
310 }
311
312 std::string AppInstallHelper::generatePkgLabel() const {
313     return generatePathRWLabel(getPkgId());
314 }
315
316 const AppInstallHelper::TypePathsMap& AppInstallHelper::getDirsMap() const {
317     return m_dirTypeMap;
318 }
319
320 const AppInstallHelper::TypePathsMap& AppInstallHelper::getFilesMap() const {
321     return m_fileTypeMap;
322 }
323
324 void AppInstallHelper::removePaths() {
325     for (const auto &oneTypePaths : m_dirTypeMap)
326             for (const auto& path : oneTypePaths.second)
327                 rmdir(path.c_str());
328
329     m_dirTypeMap.clear();
330
331     for (const auto &oneTypePaths : m_fileTypeMap)
332             for (const auto& path : oneTypePaths.second)
333                 unlink(path.c_str());
334
335     m_fileTypeMap.clear();
336
337     for (auto& rootInfo : m_rootPaths) {
338         if (rootInfo.second.isCreated)
339             rmdir(rootInfo.second.path.c_str());
340         rootInfo.second.isCreated = false;
341     }
342 }
343
344 void AppInstallHelper::setAuthor(const std::string &author) {
345     m_author = author;
346 }
347 std::string AppInstallHelper::getAuthor() const {
348     return m_author;
349 }
350
351 void AppInstallHelper::setInstallType(app_install_type type) {
352     m_installType = type;
353 }
354 app_install_type AppInstallHelper::getInstallType() const {
355     return m_installType;
356 }