Support more types of application paths 85/158085/3
authorZofia Abramowska <z.abramowska@samsung.com>
Fri, 20 Oct 2017 14:50:04 +0000 (16:50 +0200)
committerZofia Abramowska <z.abramowska@samsung.com>
Wed, 15 Nov 2017 15:39:16 +0000 (16:39 +0100)
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
src/common/app_install_helper.h
src/common/tzplatform.cpp
src/common/tzplatform.h

index b9f3073..093da6b 100644 (file)
 #include <dpl/test/test_runner.h>
 #include <tzplatform.h>
 #include <label_generator.h>
+#include <tests_common.h>
+#include <tzplatform.h>
 
 #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<int(const char*, mode_t)> &&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) {
index a514238..e238261 100644 (file)
 struct AppInstallHelper {
 
     using TypePathsMap = std::map<app_install_path_type, std::vector<std::string>>;
+    using TypePathMap = std::map<app_install_path_type, std::string>;
+
     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<int(const char*, mode_t)> &&creatFun, const std::string &path);
+    struct RootInfo {
+        RootInfo() : isCreated(false) {}
+        std::string path;
+        int isCreated;
+    };
+    using RootTypeInfoMap = std::map<RootType, RootInfo>;
+
+    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;
index 3d3dce7..92e5535 100644 (file)
@@ -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;
 
index fff4f5e..0182ba0 100644 (file)
@@ -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);
+
 }