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