From 8f398c8d86f52c099fdd9d93172e7a3b9ff5e867 Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Fri, 20 Oct 2017 16:50:04 +0200 Subject: [PATCH] Support more types of application paths Add different root types of application: EXTENDED and SKEL. This is connected with places, where application can put its own files. Change-Id: I123206ac50d779f8f557067e18b43753101b4c5e --- src/common/app_install_helper.cpp | 199 +++++++++++++++++++++++++++----------- src/common/app_install_helper.h | 73 +++++++++----- src/common/tzplatform.cpp | 38 +++++++- src/common/tzplatform.h | 11 ++- 4 files changed, 237 insertions(+), 84 deletions(-) diff --git a/src/common/app_install_helper.cpp b/src/common/app_install_helper.cpp index b9f3073..093da6b 100644 --- a/src/common/app_install_helper.cpp +++ b/src/common/app_install_helper.cpp @@ -28,14 +28,41 @@ #include #include #include +#include +#include #include "app_install_helper.h" +namespace { + std::string genSkelPath() { + static std::string skelPkgDir; + if (!skelPkgDir.empty()) + return skelPkgDir; + std::string app = TzPlatformConfig::getEnv(TZ_USER_APP); + std::string home = TzPlatformConfig::getEnv(TZ_USER_HOME); + std::string skelDir = "/etc/skel"; + + skelPkgDir.assign(app); + skelPkgDir.replace(0, home.length(), skelDir); + + return skelPkgDir; + } + + const AppInstallHelper::TypePathMap typeToPath = { + {SECURITY_MANAGER_PATH_RW, "app_rw"}, + {SECURITY_MANAGER_PATH_RO, "app_ro"}, + {SECURITY_MANAGER_PATH_PUBLIC_RO, "public_ro"}, + {SECURITY_MANAGER_PATH_TRUSTED_RW, "trusted_rw"}, + {SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, "shared_ro"} + }; +} + AppInstallHelper::AppInstallHelper(AppInstallHelper &&other) : m_appName(std::move(other.m_appName)), m_pkgName(std::move(other.m_pkgName)), m_isLocal(other.m_isLocal), m_uidGid(other.m_uidGid), m_version(std::move(other.m_version)), m_installType(other.m_installType), - m_isHybrid(other.m_isHybrid), m_installDir(std::move(other.m_installDir)), + m_isHybrid(other.m_isHybrid), + m_rootPaths(std::move(other.m_rootPaths)), m_dirTypeMap(std::move(other.m_dirTypeMap)), m_fileTypeMap(std::move(other.m_fileTypeMap)), m_privileges(std::move(other.m_privileges)), @@ -46,32 +73,71 @@ AppInstallHelper::AppInstallHelper(AppInstallHelper &&other) other.m_creatorPid = -1; } -std::string AppInstallHelper::getInstallDir() const { - return m_installDir + getPkgId(); +void AppInstallHelper::setInstallPath(RootType type) const { + RootInfo &info = m_rootPaths[type]; + if (!info.path.empty()) + return; + + switch (type) { + case RootType::BASE: + if (m_isLocal) + info.path = TzPlatformConfig::appDirPath(getUID()) + getPkgId(); + else + info.path = TzPlatformConfig::globalAppDir() + "/" + getPkgId(); + break; + case RootType::EXTENDED: + if (m_isLocal) + info.path = TzPlatformConfig::extendedSdUserDir(getUID()) + "/" + getPkgId(); + else + info.path = TzPlatformConfig::extendedSdDir() + "/" + getPkgId(); + break; + case RootType::SKEL: + info.path = genSkelPath() + "/" + getPkgId(); + break; + } } -std::string AppInstallHelper::getTrustedDir(int i) const { - return getInstallDir() + "/trustedDir" + std::to_string(i); +std::string AppInstallHelper::getInstallDir(RootType type) const { + setInstallPath(type); + return m_rootPaths[type].path; } -std::string AppInstallHelper::getPrivateDir(int i) const { - return getInstallDir() + "/app_dir" + std::to_string(i) +"/"; +std::string AppInstallHelper::getPath(app_install_path_type smType, PathType pType, int i, RootType rType) const { + std::string path; + switch (pType) { + case PathType::DIR: + path = getInstallDir(rType) + "/" + typeToPath.at(smType) + "_dir" + std::to_string(i); + break; + case PathType::FILE: + // put files in the directory of the same type + path = getInstallDir(rType) + "/" + typeToPath.at(smType) + "_dir0/" + typeToPath.at(smType) + std::to_string(i); + break; + } + return path; +} + +std::string AppInstallHelper::getTrustedDir(int i, RootType type) const { + return getPath(SECURITY_MANAGER_PATH_TRUSTED_RW, PathType::DIR, i , type); } -std::string AppInstallHelper::getPrivateRODir(int i) const { - return getInstallDir() + "/app_dir_ro" + std::to_string(i) +"/"; +std::string AppInstallHelper::getPrivateDir(int i, RootType type) const { + return getPath(SECURITY_MANAGER_PATH_RW, PathType::DIR, i, type); } -std::string AppInstallHelper::getPublicDir() const { - return getInstallDir() + "/app_public_ro/"; +std::string AppInstallHelper::getPrivateRODir(int i, RootType type) const { + return getPath(SECURITY_MANAGER_PATH_RO, PathType::DIR, i, type); } -std::string AppInstallHelper::getPrivatePath(int i) const { - return getPrivateDir() + "shareme" + std::to_string(i); +std::string AppInstallHelper::getPublicDir(RootType type) const { + return getPath(SECURITY_MANAGER_PATH_PUBLIC_RO, PathType::DIR, 0, type); } -std::string AppInstallHelper::getSharedRODir(int i) const { - return getInstallDir() + "/app_dir_rw_others_ro" + std::to_string(i) +"/"; +std::string AppInstallHelper::getPrivatePath(int i, RootType type) const { + return getPath(SECURITY_MANAGER_PATH_RW, PathType::FILE, i, type); +} + +std::string AppInstallHelper::getSharedRODir(int i, RootType type) const { + return getPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, type); } std::string AppInstallHelper::getAppId() const { @@ -98,42 +164,72 @@ int AppInstallHelper::getGID() const { return m_uidGid; } -void AppInstallHelper::createInstallDir() { - create(mkdir, getInstallDir()); - m_isInstallDirCreated = true; +bool AppInstallHelper::createFile(app_install_path_type smType, const std::string &path) { + if (creat(path.c_str(), 0751) == 0) { + // Local paths need user change + m_fileTypeMap[smType].push_back(std::move(path)); + if (!m_isLocal || chown(path.c_str(), m_uidGid, m_uidGid) == 0) + return true; + } + return false; } -void AppInstallHelper::createTrustedDir(int i) { - if (create(mkdir, getTrustedDir(i))) - m_dirTypeMap[SECURITY_MANAGER_PATH_TRUSTED_RW].emplace_back(getTrustedDir(i)); -} +bool AppInstallHelper::createDir(app_install_path_type smType, const std::string &path, bool isBasePath) { + mktreeSafe(path, 0777); + // Dont pass base pkg dirs to SM, because transmute will be forced on RO subdirs + if (!isBasePath) + m_dirTypeMap[smType].push_back(std::move(path)); + if (!m_isLocal || chown(path.c_str(), m_uidGid, m_uidGid) == 0) + return true; -void AppInstallHelper::createPrivateDir(int i) { - if (create(mkdir, getPrivateDir(i))) - m_dirTypeMap[SECURITY_MANAGER_PATH_RW].emplace_back(getPrivateDir(i)); + return false; } -void AppInstallHelper::createPublicDir() { - if (mkdir(getPublicDir().c_str(), 0777) == 0) { - m_dirTypeMap[SECURITY_MANAGER_PATH_PUBLIC_RO].emplace_back(getPublicDir()); +void AppInstallHelper::createInstallDir(RootType type) { + setInstallPath(type); + RootInfo &info = m_rootPaths[type]; + if (info.isCreated) + return; + createDir(SECURITY_MANAGER_PATH_PUBLIC_RO, info.path, true); + info.isCreated = true; +} + +void AppInstallHelper::createPath(app_install_path_type smType, PathType pType, int i, RootType rType) { + createInstallDir(rType); + std::string path = getPath(smType, pType, i, rType); + switch (pType) { + case PathType::DIR: + createDir(smType, path); + break; + case PathType::FILE: + createPath(smType, PathType::DIR, i, rType); + createFile(smType, path); + break; } } -void AppInstallHelper::createPrivateFile(int i) { - // This is intentional, let all private file be in one directory - createPrivateDir(); - if (create(creat, getPrivatePath(i))) - m_fileTypeMap[SECURITY_MANAGER_PATH_RW].emplace_back(getPrivatePath(i)); +void AppInstallHelper::createTrustedDir(int i, RootType type) { + createPath(SECURITY_MANAGER_PATH_TRUSTED_RW, PathType::DIR, i, type); +} + +void AppInstallHelper::createPrivateDir(int i, RootType type) { + createPath(SECURITY_MANAGER_PATH_RW, PathType::DIR, i, type); +} + +void AppInstallHelper::createPublicDir(RootType type) { + createPath(SECURITY_MANAGER_PATH_PUBLIC_RO, PathType::DIR, 0, type); +} + +void AppInstallHelper::createPrivateFile(int i, RootType type) { + createPath(SECURITY_MANAGER_PATH_RW, PathType::FILE, i, type); } -void AppInstallHelper::createSharedRODir(int i) { - if (create(mkdir, getSharedRODir(i))) - m_dirTypeMap[SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO].emplace_back(getSharedRODir(i)); +void AppInstallHelper::createSharedRODir(int i, RootType type) { + createPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, type); } -void AppInstallHelper::createPrivateRODir(int i) { - if (create(mkdir, getPrivateRODir(i))) - m_dirTypeMap[SECURITY_MANAGER_PATH_RO].emplace_back(getPrivateRODir(i)); +void AppInstallHelper::createPrivateRODir(int i, RootType type) { + createPath(SECURITY_MANAGER_PATH_RO, PathType::DIR, i, type); } void AppInstallHelper::setHybrid() { @@ -213,26 +309,11 @@ void AppInstallHelper::removePaths() { m_fileTypeMap.clear(); - rmdir(getInstallDir().c_str()); - m_isInstallDirCreated = false; -} - -void AppInstallHelper::setInstallPath() { - if (m_isLocal) - m_installDir = TzPlatformConfig::appDirPath(getUID()); - else - m_installDir = TzPlatformConfig::globalAppDir() + "/"; -} - -bool AppInstallHelper::create(std::function &&creatFun, const std::string &path) { - if (!m_isInstallDirCreated && path != getInstallDir()) - createInstallDir(); - if (creatFun(path.c_str(), 0751) == 0) { - // Local paths need user change - if (!m_isLocal || chown(path.c_str(), m_uidGid, m_uidGid) == 0) - return true; - } - return false; + for (auto& rootInfo : m_rootPaths) { + if (rootInfo.second.isCreated) + rmdir(rootInfo.second.path.c_str()); + rootInfo.second.isCreated = false; + } } void AppInstallHelper::setAuthor(const std::string &author) { diff --git a/src/common/app_install_helper.h b/src/common/app_install_helper.h index a514238..e238261 100644 --- a/src/common/app_install_helper.h +++ b/src/common/app_install_helper.h @@ -31,16 +31,16 @@ struct AppInstallHelper { using TypePathsMap = std::map>; + using TypePathMap = std::map; + AppInstallHelper(const std::string &appNamePrefix, const std::string &pkgNamePrefix, bool isLocal, uid_t uid, std::string version = std::string()) : m_appName(appNamePrefix), m_pkgName(pkgNamePrefix), m_isLocal(isLocal), m_uidGid(uid), m_version(version), - m_installType(SM_APP_INSTALL_NONE), m_isHybrid(false), m_isInstallDirCreated(false), m_creatorPid(getpid()) - { - setInstallPath(); - } + m_installType(SM_APP_INSTALL_NONE), m_isHybrid(false), m_creatorPid(getpid()) + {} AppInstallHelper(const std::string &appNamePrefix, const std::string &pkgNamePrefix, @@ -87,24 +87,40 @@ struct AppInstallHelper { void setHybrid(); bool getIsHybrid() const; + enum RootType { + BASE, + SKEL, + EXTENDED + }; + + enum PathType { + FILE, + DIR + }; + // Path types creation and removal on file system - void createInstallDir(); - void createTrustedDir(int i = 0); - void createPrivateDir(int i = 0); - void createPublicDir(); - void createPrivateFile(int i = 0); - void createSharedRODir(int i = 0); - void createPrivateRODir(int i = 0); + void createPath(app_install_path_type smType, PathType pType, int i = 0, RootType rType = RootType::BASE); + + // below methods are deprecated + void createTrustedDir(int i = 0, RootType type = RootType::BASE); + void createPrivateDir(int i = 0, RootType type = RootType::BASE); + void createPublicDir(RootType type = RootType::BASE); + void createPrivateFile(int i = 0, RootType type = RootType::BASE); + void createSharedRODir(int i = 0, RootType type = RootType::BASE); + void createPrivateRODir(int i = 0, RootType type = RootType::BASE); void removePaths(); // Path getters - std::string getInstallDir() const; - std::string getTrustedDir(int i = 0) const; - std::string getPrivateDir(int i = 0) const; - std::string getPrivateRODir(int i = 0) const; - std::string getPublicDir() const; - std::string getPrivatePath(int i = 0) const; - std::string getSharedRODir(int i = 0) const; + std::string getPath(app_install_path_type smType, PathType pType, int i = 0, RootType rType = RootType::BASE) const; + + // below methods are deprecated + std::string getInstallDir(RootType type) const; + std::string getTrustedDir(int i = 0, RootType type = RootType::BASE) const; + std::string getPrivateDir(int i = 0, RootType type = RootType::BASE) const; + std::string getPrivateRODir(int i = 0, RootType type = RootType::BASE) const; + std::string getPublicDir(RootType type = RootType::BASE) const; + std::string getPrivatePath(int i = 0, RootType type = RootType::BASE) const; + std::string getSharedRODir(int i = 0, RootType type = RootType::BASE) const; const TypePathsMap& getDirsMap() const; const TypePathsMap& getFilesMap() const; @@ -128,8 +144,19 @@ struct AppInstallHelper { } protected: - void setInstallPath(); - bool create(std::function &&creatFun, const std::string &path); + struct RootInfo { + RootInfo() : isCreated(false) {} + std::string path; + int isCreated; + }; + using RootTypeInfoMap = std::map; + + void setInstallPath(RootType type) const; + + bool createFile(app_install_path_type smType, const std::string &path); + bool createDir(app_install_path_type smType, const std::string &path, bool isBasePath = false); + void createInstallDir(RootType type); + std::string m_appName; std::string m_pkgName; bool m_isLocal; @@ -137,12 +164,14 @@ protected: std::string m_version; app_install_type m_installType; bool m_isHybrid; - std::string m_installDir; - bool m_isInstallDirCreated; + + mutable RootTypeInfoMap m_rootPaths; TypePathsMap m_dirTypeMap; TypePathsMap m_fileTypeMap; + PrivilegeVector m_privileges; PrivilegeVector m_appDefinedPrivileges; + std::string m_author; pid_t m_creatorPid; diff --git a/src/common/tzplatform.cpp b/src/common/tzplatform.cpp index 3d3dce7..92e5535 100644 --- a/src/common/tzplatform.cpp +++ b/src/common/tzplatform.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,13 @@ namespace TzPlatformConfig { DEFINE_SMARTPTR(tzplatform_context_destroy, tzplatform_context, TzPlatformContextPtr); +std::string getEnv(enum tzplatform_variable id) +{ + auto env = tzplatform_getenv(id); + RUNNER_ASSERT_MSG(env != nullptr, "Tzplatform-config returned null for " << id); + return env; +} + uid_t getGlobalUserId(void) { return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); @@ -78,6 +85,35 @@ const std::string globalAppDir() return appDir; } +const std::string extendedSdDir() +{ + struct tzplatform_context *tzCtxPtr = nullptr; + + RUNNER_ASSERT_MSG(0 == tzplatform_context_create(&tzCtxPtr), "Couldn't create tzplatform context"); + TzPlatformContextPtr tzCtxPtrSmart(tzCtxPtr); + + const char *appDir = tzplatform_context_getenv(tzCtxPtr, TZ_SYS_EXTENDEDSD_APP); + RUNNER_ASSERT_MSG(nullptr != appDir, + "tzplatform_context_getenv failed for getting sys extended sd"); + return appDir; +} + +const std::string extendedSdUserDir(uid_t uid) +{ + struct tzplatform_context *tzCtxPtr = nullptr; + + RUNNER_ASSERT_MSG(0 == tzplatform_context_create(&tzCtxPtr), "Couldn't create tzplatform context"); + TzPlatformContextPtr tzCtxPtrSmart(tzCtxPtr); + + RUNNER_ASSERT_MSG(0 == tzplatform_context_set_user(tzCtxPtr, uid), + "Unable to set user with uid <" << uid << "> for tzplatform context"); + + const char *appDir = tzplatform_context_getenv(tzCtxPtr, TZ_USER_EXTENDEDSD_APP); + RUNNER_ASSERT_MSG(nullptr != appDir, + "tzplatform_context_getenv failed for getting user extended sd"); + return appDir; +} + const std::string getPath(enum tzplatform_variable id) { struct tzplatform_context *tzCtxPtr = nullptr; diff --git a/src/common/tzplatform.h b/src/common/tzplatform.h index fff4f5e..0182ba0 100644 --- a/src/common/tzplatform.h +++ b/src/common/tzplatform.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,8 @@ namespace TzPlatformConfig { +std::string getEnv(enum tzplatform_variable id); + const std::string getPath(enum tzplatform_variable id); uid_t getGlobalUserId(void); @@ -33,8 +35,13 @@ uid_t getGlobalGroupId(void); const std::string appDirPath(const TemporaryTestUser &user, const std::string &appId, const std::string &pkgId); +const std::string appDirPath(uid_t uid); + const std::string globalAppDir(); -const std::string appDirPath(uid_t uid); +const std::string extendedSdDir(); + +const std::string extendedSdUserDir(uid_t uid); + } -- 2.7.4