Extend AppInstallHelper with checker methods 40/229940/15
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 6 Apr 2020 15:35:56 +0000 (17:35 +0200)
committerZofia Abramowska <z.abramowska@samsung.com>
Tue, 28 Apr 2020 15:14:17 +0000 (15:14 +0000)
Move app checkers to AppInstallHelper derived class. Too many arguments
have to be passed here and there. Writing new checkers is pain in the
back. There's still a lot to be improved. Testing framework has to be
adjusted to allow multiple apps in the package.

Change-Id: I4b363a6b0d102bd1df6ed8cce8494c884c8d088a

src/security-manager-tests/CMakeLists.txt
src/security-manager-tests/common/app_install_helper_ext.cpp [new file with mode: 0644]
src/security-manager-tests/common/app_install_helper_ext.h [new file with mode: 0644]
src/security-manager-tests/common/sm_commons.cpp
src/security-manager-tests/common/sm_commons.h
src/security-manager-tests/test_cases.cpp

index 57ed71f..fad161e 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved
+# Copyright (c) 2014-2020 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.
@@ -59,6 +59,7 @@ SET(SEC_MGR_SOURCES
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_commons.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/template_parser.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/scoped_app_launcher.cpp
+    ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/app_install_helper_ext.cpp
     ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_client.cpp
     ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_admin.cpp
     ${PROJECT_SOURCE_DIR}/src/cynara-tests/plugins/plugins.cpp
diff --git a/src/security-manager-tests/common/app_install_helper_ext.cpp b/src/security-manager-tests/common/app_install_helper_ext.cpp
new file mode 100644 (file)
index 0000000..fc59380
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2020 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.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "app_install_helper_ext.h"
+
+#include <grp.h>
+#include <unistd.h>
+#include <sys/smack.h>
+
+#include <utility>
+#include <string>
+#include <unordered_set>
+#include <algorithm>
+
+#include <security-manager-types.h>
+
+#include <sm_api.h>
+#include <label_generator.h>
+#include <cynara_test_client.h>
+
+namespace {
+constexpr char SMACK_RULES_PATH[] = "/sys/fs/smackfs/load2";
+constexpr char ANY_USER_REPRESENTATION[] = "anyuser";/*this may be actually any string*/
+
+void assertNoLabelInRule(const AccessRequest &rule, const std::string &label)
+{
+    RUNNER_ASSERT_MSG(rule.object != label && rule.subject != label,
+                      "Smack rule left after uninstallation process." <<
+                      " Subject: " << rule.subject <<
+                      " object: " << rule.object <<
+                      " access: " << rule.access);
+}
+
+std::string accessOpposite(std::string &access)
+{
+    static const std::map<char, int> accessMapping = {{'r', 0}, {'w', 1}, {'x', 2}, {'a', 3},
+                                                      {'t', 4}, {'l', 5}};
+    // May write implies may lock
+    if (access.find('w') != std::string::npos && access.find('l') == std::string::npos) {
+        access.append("l");
+    }
+    std::string oppositeAccess = "rwxatl";
+    for (char c : access) {
+        oppositeAccess[accessMapping.at(c)] = '-';
+    }
+    auto it = std::remove_if(oppositeAccess.begin(), oppositeAccess.end(), [](char c) {return c == '-';});
+    oppositeAccess.erase(it, oppositeAccess.end());
+    return oppositeAccess;
+}
+
+void checkExactSmackAccesses(const std::string &subject, const std::string &object,
+                             const std::string &access)
+{
+    std::string access_str(access);
+    auto no_access = accessOpposite(access_str);
+    for (char c : access_str) {
+        int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
+        RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object
+                          << ">, <" << c << "> errno=" << strerror(errno));
+        RUNNER_ASSERT_MSG(ret == 1, "Access " << c << " from " << subject << " to "
+                          << object << " not given");
+    }
+
+    for (char c : no_access) {
+        int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
+        RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object
+                          << ">, <" << c << "> errno=" << strerror(errno));
+        RUNNER_ASSERT_MSG(ret == 0, "Access " << c << " from " << subject << " to "
+                          << object << " unnecessarily given");
+    }
+}
+
+} // namespace anonymous
+
+namespace SecurityManagerTest
+{
+
+void AppInstallHelperExt::checkPrivileges(const PolicyConfiguration::PrivVector &allowedPrivs,
+                                          const PolicyConfiguration::PrivVector &deniedPrivs) const
+{
+    /* Privileges should be granted to all users if root installs app */
+    auto user = (m_uidGid == 0 ? ANY_USER_REPRESENTATION : std::to_string(m_uidGid));
+
+    std::string smackLabel = generateProcessLabel(m_appName, m_pkgName, m_isHybrid);
+
+    CynaraTestClient::Client ctc;
+    int result;
+
+    for (auto &priv : allowedPrivs) {
+        ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_ALLOWED);
+
+        Api::appHasPrivilege(m_appName, priv, m_uidGid, result);
+        RUNNER_ASSERT_MSG(result == 1,
+                          "Application " << m_appName << " has no access to " << priv);
+    }
+
+    for (auto &priv : deniedPrivs) {
+        ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_DENIED);
+
+        Api::appHasPrivilege(m_appName, priv, m_uidGid, result);
+        RUNNER_ASSERT_MSG(result == 0,
+                          "Application " << m_appName << " has unexpected access to " << priv);
+    }
+}
+
+void AppInstallHelperExt::checkDeniedPrivileges(const PolicyConfiguration::PrivVector &deniedPrivs) const
+{
+    checkPrivileges({}, deniedPrivs);
+}
+
+void AppInstallHelperExt::checkPrivilegeGroups(const PolicyConfiguration::PrivVector &allowedPrivs) const
+{
+    static PolicyConfiguration policy;
+    const auto allowed_groups = policy.privToGroup(allowedPrivs);
+    RUNNER_ASSERT_MSG(allowed_groups.size() == allowedPrivs.size(),
+                      "Some privileges given were not found in the policy");
+
+    std::vector<gid_t> allowed_gids;
+    for (const auto &groupName : allowed_groups) {
+        errno = 0;
+        struct group* grp = getgrnam(groupName.c_str());
+        RUNNER_ASSERT_ERRNO_MSG(grp, "Group: " << groupName << " not found");
+        allowed_gids.push_back(grp->gr_gid);
+    }
+
+    checkGids(allowed_gids);
+}
+
+void AppInstallHelperExt::checkAfterInstall() const
+{
+    static const std::vector<AccessRequest> staticRules[] =
+        {parseSmackRulesFile(PolicyConfiguration::getPkgRulesFilePath()),
+         parseSmackRulesFile(PolicyConfiguration::getAppRulesFilePath())};
+
+    checkAppIdExistence(true);
+
+    checkSmackAccesses(staticRules[m_isHybrid]);
+
+    checkPrivileges(getPrivilegesNames(), {});
+}
+
+void AppInstallHelperExt::checkAfterUninstall(bool removePkg) const
+{
+    checkAppIdExistence(false);
+
+    if (removePkg) {
+        checkPkgSmackRulesAfterUninstall();
+    }
+    // there should be no hybrid rules regardless of the app type
+    checkHybridAppSmackRulesAterUninstall();
+
+    checkDeniedPrivileges(getPrivilegesNames());
+}
+
+void AppInstallHelperExt::checkSmackAccesses(std::vector<AccessRequest> rules, bool hasAccess) const
+{
+    const std::pair<std::string, std::string> switchAliases[] = {
+        {"~PATH_RW~", generatePathRWLabel(m_pkgName)},
+        {"~PATH_RO~", generatePathROLabel(m_pkgName)},
+        {"~PROCESS~", generateProcessLabel(m_appName, m_pkgName, m_isHybrid)}
+    };
+
+    for (auto& rule : rules) {
+        if (rule.object == "~PATH_TRUSTED~") {
+            continue;
+        }
+
+        for (const auto &alias : switchAliases) {
+            if (rule.subject == alias.first) {
+                rule.subject = alias.second;
+            }
+            if (rule.object == alias.first) {
+                rule.object = alias.second;
+            }
+        }
+
+        if (!hasAccess)
+            rule.access = "";
+
+        // Special label that may occur in the template. Other special labels will not be used.
+        if (rule.object == "_") {
+            rule.access = "rx" + rule.access;
+        }
+
+        checkExactSmackAccesses(rule.subject, rule.object, rule.access);
+    }
+}
+
+void AppInstallHelperExt::checkPkgSmackRulesAfterUninstall() const
+{
+    const std::vector<AccessRequest> rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH)));
+    const std::string labels[] = {generatePathRWLabel(m_pkgName),
+                                  generatePathROLabel(m_pkgName),
+                                  generateProcessLabel(m_appName, m_pkgName, true),
+                                  generateProcessLabel(m_appName, m_pkgName)};
+
+    for (const auto &rule : rules) {
+        for (const auto &label : labels) {
+            assertNoLabelInRule(rule, label);
+        }
+    }
+}
+
+void AppInstallHelperExt::checkHybridAppSmackRulesAterUninstall() const
+{
+    const std::vector<AccessRequest> rules(parseSmackRulesFile(SMACK_RULES_PATH));
+    const std::string appLabel = generateProcessLabel(m_appName, m_pkgName, true);
+
+    for (const auto &rule : rules) {
+        assertNoLabelInRule(rule, appLabel);
+    }
+}
+
+void AppInstallHelperExt::checkAppIdExistence(bool expected) const
+{
+    lib_retcode ret = expected ? SECURITY_MANAGER_SUCCESS : SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
+    std::string retPkgId = Api::getPkgId(m_appName, ret);
+
+    if (expected) {
+        RUNNER_ASSERT_MSG(m_pkgName == retPkgId,
+                          "The given appId does not belong to the given pkgId.");
+    }
+}
+
+void AppInstallHelperExt::checkGids(const std::vector<gid_t> &allowedGids) const
+{
+    int ret;
+    std::unordered_set<gid_t> referenceGids(allowedGids.begin(), allowedGids.end());
+
+    // Reset supplementary groups
+    ret = setgroups(0, NULL);
+    RUNNER_ASSERT_MSG(ret != -1, "Unable to set supplementary groups");
+
+    Api::setProcessGroups(m_appName);
+
+    ret = getgroups(0, nullptr);
+    RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
+
+    std::vector<gid_t> actualGids(ret);
+    ret = getgroups(ret, actualGids.data());
+    RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
+
+    for (const auto &gid : actualGids) {
+        RUNNER_ASSERT_MSG(referenceGids.count(gid) > 0,
+                          "Application shouldn't get access to group " << gid);
+        referenceGids.erase(gid);
+    }
+
+    RUNNER_ASSERT_MSG(referenceGids.empty(), "Application didn't get access to some groups");
+}
+
+} // namespace SecurityManagerTest
diff --git a/src/security-manager-tests/common/app_install_helper_ext.h b/src/security-manager-tests/common/app_install_helper_ext.h
new file mode 100644 (file)
index 0000000..9e599e2
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2020 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.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+#pragma once
+
+#include <sys/types.h>
+
+#include <vector>
+
+#include <app_install_helper.h>
+#include <template_parser.h>
+#include <policy_configuration.h>
+
+namespace SecurityManagerTest {
+
+class AppInstallHelperExt : public AppInstallHelper {
+public:
+    using AppInstallHelper::AppInstallHelper;
+
+    void checkPrivileges(const PolicyConfiguration::PrivVector &allowedPrivs,
+                         const PolicyConfiguration::PrivVector &deniedPrivs) const;
+    void checkDeniedPrivileges(const PolicyConfiguration::PrivVector &deniedPrivs) const;
+    void checkPrivilegeGroups(const PolicyConfiguration::PrivVector &allowedPrivs) const;
+    void checkAfterInstall() const;
+    void checkAfterUninstall(bool removePkg = true) const;
+
+    void checkSmackAccesses(std::vector<AccessRequest> rules, bool hasAccess = true) const;
+
+private:
+    void checkPkgSmackRulesAfterUninstall() const;
+    void checkHybridAppSmackRulesAterUninstall() const;
+    void checkAppIdExistence(bool expected) const;
+    void checkGids(const std::vector<gid_t> &allowedGids) const;
+};
+
+} // namespace SecurityManagerTest
index e14f142..ce822cd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 - 2020 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.
  *    limitations under the License.
  */
 
-#include <algorithm>
 #include <cstring>
 #include <fcntl.h>
 #include <ftw.h>
-#include <grp.h>
 #include <string>
 #include <sys/capability.h>
 #include <sys/prctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <unistd.h>
-#include <unordered_map>
 #include <cstdlib>
 
-#include <array>
-#include <unordered_set>
 #include <utility>
 #include <vector>
+#include <unordered_map>
 
 #include <security-manager-types.h>
 #include <app-runtime.h>
-#include <sys/smack.h>
 #include <privilege_info.h>
 #include <scoped_process_label.h>
 
-#include <cynara_test_client.h>
 #include <dpl/test/test_runner.h>
 #include <memory.h>
 #include <sm_api.h>
 #include <sm_commons.h>
-#include <synchronization_pipe.h>
-#include <sm_request.h>
+
 #include <tests_common.h>
-#include <policy_configuration.h>
 #include "tzplatform.h"
-#include <label_generator.h>
 #include <template_parser.h>
 #include <temp_test_user.h>
 
 using namespace SecurityManagerTest;
 
-#define SMACK_RULES_PATH "/sys/fs/smackfs/load2"
-
 #define ALLOW 0
 #define DENY -1
 
@@ -160,189 +148,6 @@ int nftw_remove_labels(const char *fpath, const struct stat* /*sb*/,
     return 0;
 }
 
-void check_app_permissions(const std::string &app_id, const std::string &pkg_id,
-                           const std::string &user, const privileges_t &allowed_privs,
-                           const privileges_t &denied_privs, bool isHybrid)
-{
-    (void) pkg_id;
-    std::string smackLabel = generateProcessLabel(app_id, pkg_id, isHybrid);
-
-    CynaraTestClient::Client ctc;
-
-    for (auto &priv : allowed_privs) {
-        ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_ALLOWED);
-    }
-
-    for (auto &priv : denied_privs) {
-        ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_DENIED);
-    }
-}
-
-void sm_app_has_privileges(const AppInstallHelper &app,
-                           const std::vector<std::string> &privileges,
-                           int expectedResult)
-{
-    for (auto const &privilege : privileges) {
-        int result;
-        Api::appHasPrivilege(app.getAppId(), privilege, app.getUID(), result);
-        RUNNER_ASSERT_MSG(result == expectedResult, "Application " << app.getAppId()
-                          << " has unexpected access to " << privilege << ", is : "
-                          << " should be : " << expectedResult );
-    }
-}
-
-static void check_app_smack_accesses(const std::string &appId, const std::string &pkgId,
-                                     bool isHybrid = false)
-{
-    static const std::vector<AccessRequest> rules[] =
-        {parseSmackRulesFile(PolicyConfiguration::getPkgRulesFilePath()),
-         parseSmackRulesFile(PolicyConfiguration::getAppRulesFilePath())};
-
-    const std::pair<std::string, std::string> switchAliases[] =
-        {std::make_pair("~PATH_RW~", generatePathRWLabel(pkgId)),
-         std::make_pair("~PATH_RO~", generatePathROLabel(pkgId)),
-         std::make_pair("~PROCESS~", generateProcessLabel(appId, pkgId, isHybrid))};
-
-    for (auto rule : rules[isHybrid]) {
-        if (rule.object == "~PATH_TRUSTED~") {
-            continue;
-        }
-
-        for (const auto &alias : switchAliases) {
-            if (rule.subject == alias.first) {
-                rule.subject = alias.second;
-            }
-            if (rule.object == alias.first) {
-                rule.object = alias.second;
-            }
-        }
-
-        if (rule.object == "_") {
-            rule.access = "rx" + rule.access;
-        }
-
-        check_exact_smack_accesses(rule.subject, rule.object, rule.access);
-    }
-}
-
-static void assert_no_label_in_rule(const AccessRequest &rule, const std::string &label)
-{
-    RUNNER_ASSERT_MSG(rule.object != label && rule.subject != label,
-                      "Smack rule left after uninstallation process." <<
-                      " Subject: " << rule.subject <<
-                      " object: " << rule.object <<
-                      " access: " << rule.access);
-}
-
-static void check_pkg_smack_rules_after_uninstall(const std::string &appId, const std::string &pkgId)
-{
-    const std::vector<AccessRequest> rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH)));
-    const std::string labels[] = {generatePathRWLabel(pkgId),
-                                  generatePathROLabel(pkgId),
-                                  generateProcessLabel(appId, pkgId, true),
-                                  generateProcessLabel(appId, pkgId)};
-    for (const auto &rule : rules) {
-        for (const auto &label : labels) {
-            assert_no_label_in_rule(rule, label);
-        }
-    }
-}
-
-static void check_hybrid_app_smack_rules_after_uninstall(const std::string &appId, const std::string &pkgId)
-{
-    const std::vector<AccessRequest> rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH)));
-    const std::string appLabel = generateProcessLabel(appId, pkgId, true);
-    for (const auto &rule : rules) {
-        assert_no_label_in_rule(rule, appLabel);
-    }
-}
-
-static void check_app(const std::string &appId, const std::string &pkgId,
-                      bool shouldBeInstalled, bool isHybrid, bool removePkg)
-{
-    char *retPkgId;
-    int ret = security_manager_get_app_pkgid(&retPkgId, appId.c_str());
-
-    if (shouldBeInstalled) {
-        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "The given appId is not installed.");
-
-        if (ret == SECURITY_MANAGER_SUCCESS) {
-            CStringPtr retPkgIdPtr(retPkgId);
-            RUNNER_ASSERT_MSG(strcmp(pkgId.c_str(), retPkgId) == 0,
-                              "The given appId does not belong to the given pkgId.");
-        }
-        check_app_smack_accesses(appId, pkgId, isHybrid);
-    } else {
-        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT, "The given appId is installed.");
-
-        if (removePkg) {
-            check_pkg_smack_rules_after_uninstall(appId, pkgId);
-        } else if (isHybrid) {
-            check_hybrid_app_smack_rules_after_uninstall(appId, pkgId);
-        }
-    }
-}
-
-void check_app_after_install(const std::string &app_id, const std::string &pkg_id, bool isHybrid)
-{
-    check_app(app_id, pkg_id, true, isHybrid, false);
-}
-
-static void check_app_gids(const std::string &app_id, const std::vector<gid_t> &allowed_gids)
-{
-    int ret;
-    gid_t main_gid = getgid();
-    std::unordered_set<gid_t> reference_gids(allowed_gids.begin(), allowed_gids.end());
-
-    // Reset supplementary groups
-    ret = setgroups(0, NULL);
-    RUNNER_ASSERT_MSG(ret != -1, "Unable to set supplementary groups");
-
-    Api::setProcessGroups(app_id);
-
-    ret = getgroups(0, nullptr);
-    RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
-
-    std::vector<gid_t> actual_gids(ret);
-    ret = getgroups(ret, actual_gids.data());
-    RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
-
-    for (const auto &gid : actual_gids) {
-        RUNNER_ASSERT_MSG(gid == main_gid || reference_gids.count(gid) > 0,
-            "Application shouldn't get access to group " << gid);
-        reference_gids.erase(gid);
-    }
-
-    RUNNER_ASSERT_MSG(reference_gids.empty(), "Application didn't get access to some groups");
-}
-
-static const char *const ANY_USER_REPRESENTATION = "anyuser";/*this may be actually any string*/
-
-void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
-                             const privileges_t &allowed_privs,
-                             const privileges_t &denied_privs,
-                             bool isHybrid)
-{
-    check_app(app_id, pkg_id, true, isHybrid, false);
-    /* Privileges should be granted to all users if root installs app */
-    check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, allowed_privs, denied_privs, isHybrid);
-
-    PolicyConfiguration policy;
-    const PolicyConfiguration::GroupVector allowed_groups = policy.privToGroup(allowed_privs);
-    RUNNER_ASSERT_MSG(allowed_groups.size() == allowed_privs.size(),
-                      "Some privileges given were not found in the policy");
-
-    std::vector<gid_t> allowed_gids;
-    for (const auto &groupName : allowed_groups) {
-        errno = 0;
-        struct group* grp = getgrnam(groupName.c_str());
-        RUNNER_ASSERT_ERRNO_MSG(grp, "Group: " << groupName << " not found");
-        allowed_gids.push_back(grp->gr_gid);
-    }
-
-    check_app_gids(app_id, allowed_gids);
-}
-
 void check_path(const std::string &path, const std::string &label, bool transmute, bool execute) {
     nftw_expected_label = label;
     nftw_expected_transmute = transmute;
@@ -353,59 +158,6 @@ void check_path(const std::string &path, const std::string &label, bool transmut
     RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path);
 }
 
-void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
-                               bool isHybrid, bool removePkg)
-{
-    check_app(app_id, pkg_id, false, isHybrid, removePkg);
-}
-
-void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
-                               const privileges_t &privileges, bool isHybrid,
-                               bool removePkg)
-{
-    check_app(app_id, pkg_id, false, isHybrid, removePkg);
-
-    /* Privileges should not be granted anymore to any user */
-    check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, {}, privileges, isHybrid);
-}
-
-std::string access_opposite(std::string &access) {
-    static const std::map<char, int> access_mapping = {{'r', 0}, {'w', 1}, {'x', 2}, {'a', 3},
-                                                       {'t', 4}, {'l', 5}};
-    // May write implies may lock
-    if (access.find('w') != std::string::npos && access.find('l') == std::string::npos) {
-        access.append("l");
-    }
-    std::string access_opposite = "rwxatl";
-    for (char c : access) {
-        access_opposite[access_mapping.at(c)] = '-';
-    }
-    auto it = std::remove_if(access_opposite.begin(), access_opposite.end(), [](char c) {return c == '-';});
-    access_opposite.erase(it, access_opposite.end());
-    return access_opposite;
-}
-
-void check_exact_smack_accesses(const std::string &subject, const std::string &object,
-                                const std::string &access) {
-    std::string access_str(access);
-    auto no_access = access_opposite(access_str);
-    for (char c : access_str) {
-        int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
-        RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object
-                          << ">, <" << c << "> errno=" << strerror(errno));
-        RUNNER_ASSERT_MSG(ret == 1, "Access " << c << " from " << subject << " to "
-                          << object << " not given");
-    }
-
-    for (char c : no_access) {
-        int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
-        RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object
-                          << ">, <" << c << "> errno=" << strerror(errno));
-        RUNNER_ASSERT_MSG(ret == 0, "Access " << c << " from " << subject << " to "
-                          << object << " unnecessarily given");
-    }
-}
-
 CapsSetsUniquePtr setCaps(const char *cap_string)
 {
     CapsSetsUniquePtr caps(cap_init());
index 6840281..427657d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-2020 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.
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <vector>
-#include <functional>
-
-#include <security-manager-types.h>
 
 #include <app_install_helper.h>
 #include <memory.h>
 #include <temp_test_user.h>
-#include <tzplatform.h>
 
 DEFINE_SMARTPTR(cap_free, _cap_struct, CapsSetsUniquePtr);
 
 const int FTW_MAX_FDS = 16;
 
-typedef std::vector<std::string> privileges_t;
-
 int nftw_remove_labels(const char *fpath, const struct stat* /*sb*/,
                        int /*typeflag*/, struct FTW* /*ftwbuf*/);
-void check_app_permissions(const std::string &app_id, const std::string &pkg_id,
-                           const std::string &user, const privileges_t &allowed_privs,
-                           const privileges_t &denied_privs, bool isHybrid = false);
-void sm_app_has_privileges(const AppInstallHelper &app,
-                           const std::vector<std::string> &privileges,
-                           int result);
-void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
-                             bool isHybrid = false);
-void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
-                             const privileges_t &allowed_privs,
-                             const privileges_t &denied_privs,
-                             bool isHybrid = false);
 void check_path(const std::string &path, const std::string &label,
                 bool transmute = true, bool execute = false);
-void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
-                               bool isHybrid = false, bool removePkg = false);
-void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
-                               const privileges_t &privileges, bool isHybrid = false,
-                               bool removePkg = false);
-std::string access_opposite(std::string &access);
-void check_exact_smack_accesses(const std::string &subject,
-                                const std::string &object,
-                                const std::string &access);
 
 CapsSetsUniquePtr setCaps(const char *cap_string);
 
index 1f5441c..b7c75ea 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 - 2020 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.
@@ -28,7 +28,6 @@
 
 #include <cynara-admin.h>
 
-#include <app_install_helper.h>
 #include <cynara_test_admin.h>
 #include <dpl/test/test_runner.h>
 #include <label_generator.h>
 #include <tzplatform.h>
 #include <uds.h>
 #include <scoped_process_label.h>
+#include <scoped_app_launcher.h>
+#include <app_install_helper_ext.h>
+#include <privilege_names.h>
 
 using namespace SecurityManagerTest;
-
-namespace {
-std::vector<std::string> merge(const std::vector<std::string> &one, const std::vector<std::string> &two) {
-    std::vector<std::string> sum;
-    sum.reserve(one.size() + two.size());
-    sum.insert(sum.end(), one.begin(), one.end());
-    sum.insert(sum.end(), two.begin(), two.end());
-    return sum;
-}
-}
+using namespace PrivilegeNames;
 
 RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER)
 
 RUNNER_TEST(security_manager_01a_app_double_install_double_uninstall)
 {
-    AppInstallHelper app("sm_test_01a_app");
+    AppInstallHelperExt app("sm_test_01a_app");
     {
         ScopedInstaller appInstall(app);
-        check_app_after_install(app.getAppId(), app.getPkgId());
+        app.checkAfterInstall();
         {
             ScopedInstaller appInstall2(app);
-            check_app_after_install(app.getAppId(), app.getPkgId());
+            app.checkAfterInstall();
         }
-        check_app_after_uninstall(app.getAppId(), app.getPkgId());
+        app.checkAfterUninstall();
     }
 }
 
 RUNNER_TEST(security_manager_01b_app_double_install_wrong_pkg_id)
 {
-    AppInstallHelper app("sm_test_01b");
+    AppInstallHelperExt app("sm_test_01b");
     {
         ScopedInstaller appInstall(app);
 
@@ -86,17 +79,17 @@ RUNNER_TEST(security_manager_01b_app_double_install_wrong_pkg_id)
 
         Api::install(requestInst2, SECURITY_MANAGER_ERROR_INPUT_PARAM);
 
-        check_app_after_install(app.getAppId(), app.getPkgId());
+        app.checkAfterInstall();
     }
-    check_app_after_uninstall(app.getAppId(), app.getPkgId());
+    app.checkAfterUninstall();
 }
 
 RUNNER_TEST(security_manager_01c_app_uninstall_wrong_pkg_id)
 {
-    AppInstallHelper app("sm_test_01c");
+    AppInstallHelperExt app("sm_test_01c");
     ScopedInstaller appInstall(app);
 
-    check_app_after_install(app.getAppId(), app.getPkgId());
+    app.checkAfterInstall();
 
     InstallRequest requestUninst;
     requestUninst.setAppId(app.getAppId());
@@ -144,24 +137,18 @@ RUNNER_TEST(security_manager_01d_app_install_complicated_dir_tree)
 
 RUNNER_TEST(security_manager_02_app_install_uninstall_full)
 {
-    privileges_t defaultPrivs = {
-        "http://tizen.org/privilege/internal/device/audio",
-        "http://tizen.org/privilege/internal/device/display",
-        "http://tizen.org/privilege/internal/device/video"
-    };
-    privileges_t allowedPrivs = {
-        "http://tizen.org/privilege/camera",
-        "http://tizen.org/privilege/mediastorage"
-    };
-    privileges_t someDeniedPrivs = {
-        "http://tizen.org/privilege/internet",
-        "http://tizen.org/privilege/externalstorage"
+    const PolicyConfiguration::PrivVector defaultPrivs = {
+        PRIV_INTERNAL_AUDIO,
+        PRIV_INTERNAL_DISPLAY,
+        PRIV_INTERNAL_VIDEO,
     };
+    const PolicyConfiguration::PrivVector allowedPrivs = {PRIV_CAMERA, PRIV_MEDIASTORAGE};
+    const PolicyConfiguration::PrivVector someDeniedPrivs = {PRIV_INTERNET, PRIV_EXTERNALSTORAGE};
 
-    privileges_t defaultAllowedPrivs = defaultPrivs;
+    PolicyConfiguration::PrivVector defaultAllowedPrivs = defaultPrivs;
     defaultAllowedPrivs.insert(defaultAllowedPrivs.end(), allowedPrivs.begin(), allowedPrivs.end());
 
-    AppInstallHelper app("sm_test_02");
+    AppInstallHelperExt app("sm_test_02");
     app.createPrivateDir();
     app.createPrivateRODir();
     app.createPublicDir();
@@ -170,8 +157,9 @@ RUNNER_TEST(security_manager_02_app_install_uninstall_full)
     {
         ScopedInstaller appInstall(app);
 
-        check_app_after_install(app.getAppId(), app.getPkgId(),
-                                defaultAllowedPrivs, someDeniedPrivs);
+        app.checkAfterInstall();
+        app.checkDeniedPrivileges(someDeniedPrivs);
+        app.checkPrivilegeGroups(defaultAllowedPrivs);
 
         check_path(app.getPrivateDir(), generatePathRWLabel(app.getPkgId()));
         check_path(app.getPrivateRODir(), generatePathROLabel(app.getPkgId()), false);
@@ -179,7 +167,7 @@ RUNNER_TEST(security_manager_02_app_install_uninstall_full)
         check_path(app.getSharedRODir(), getSharedROPathLabel());
     }
 
-    check_app_after_uninstall(app.getAppId(), app.getPkgId(), app.getPrivilegesNames());
+    app.checkAfterUninstall();
 }
 
 RUNNER_CHILD_TEST_SMACK(security_manager_03_set_label_from_appid)
@@ -242,58 +230,46 @@ RUNNER_CHILD_TEST_SMACK(security_manager_03_set_label_from_appid)
 
 RUNNER_CHILD_TEST(security_manager_04a_app_install_uninstall_by_app_user_for_self)
 {
-    const std::vector<std::string> allowedPrivs = {
-        "http://tizen.org/privilege/bluetooth",
-        "http://tizen.org/privilege/power"
-    };
-    const std::vector<std::string> someDeniedPrivs = {
-        "http://tizen.org/privilege/display",
-        "http://tizen.org/privilege/nfc"
-    };
+    const PolicyConfiguration::PrivVector allowedPrivs = {PRIV_BLUETOOTH, PRIV_POWER};
+    const PolicyConfiguration::PrivVector someDeniedPrivs = {PRIV_DISPLAY, PRIV_NFC};
 
     TemporaryTestUser testUser("sm_test_04a_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
 
-    AppInstallHelper app("sm_test_04a", testUser.getUid());
+    AppInstallHelperExt app("sm_test_04a", testUser.getUid());
     app.addPrivileges(allowedPrivs);
 
     RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
                             "drop_root_privileges failed");
     {
         ScopedInstaller appInstall(app, false);
-        check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
-                              allowedPrivs, someDeniedPrivs);
+        app.checkAfterInstall();
+        app.checkDeniedPrivileges(someDeniedPrivs);
     }
-    check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
-                          {}, merge(allowedPrivs, someDeniedPrivs));
+    app.checkAfterUninstall();
+    app.checkDeniedPrivileges(someDeniedPrivs);
 }
 
 RUNNER_CHILD_TEST(security_manager_04b_app_install_by_root_for_app_user) {
-    const std::vector<std::string> allowedPrivs = {
-        "http://tizen.org/privilege/internet",
-        "http://tizen.org/privilege/led"
-    };
-    const std::vector<std::string> someDeniedPrivs = {
-        "http://tizen.org/privilege/location",
-        "http://tizen.org/privilege/notification"
-    };
+    const PolicyConfiguration::PrivVector allowedPrivs = {PRIV_INTERNET, PRIV_LED};
+    const PolicyConfiguration::PrivVector someDeniedPrivs = {PRIV_LOCATION, PRIV_NOTIFICATION};
 
     TemporaryTestUser testUser("sm_test_04b_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
 
-    AppInstallHelper app("sm_test_04b", testUser.getUid());
+    AppInstallHelperExt app("sm_test_04b", testUser.getUid());
     app.addPrivileges(allowedPrivs);
 
     {
         ScopedInstaller appInstall(app);
-        check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
-                              allowedPrivs, someDeniedPrivs);
+        app.checkAfterInstall();
+        app.checkDeniedPrivileges(someDeniedPrivs);
 
         RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
                                 "drop_root_privileges failed");
     }
-    check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
-                          {}, merge(allowedPrivs, someDeniedPrivs));
+    app.checkAfterUninstall();
+    app.checkDeniedPrivileges(someDeniedPrivs);
 }
 
 RUNNER_CHILD_TEST(security_manager_05_drop_process_capabilities)
@@ -327,21 +303,15 @@ RUNNER_TEST(security_manager_06_install_app_offline)
     // TODO - check if app is uninstalled properly
 }
 
-RUNNER_TEST(security_manager_07a_user_add_app_install)
+RUNNER_CHILD_TEST(security_manager_07a_user_add_app_install)
 {
-    const std::vector<std::string> allowedPrivs = {
-        "http://tizen.org/privilege/internet",
-        "http://tizen.org/privilege/led"
-    };
-    const std::vector<std::string> someDeniedPrivs = {
-        "http://tizen.org/privilege/location",
-        "http://tizen.org/privilege/notification"
-    };
+    const PolicyConfiguration::PrivVector allowedPrivs = {PRIV_INTERNET, PRIV_LED};
+    const PolicyConfiguration::PrivVector someDeniedPrivs = {PRIV_LOCATION, PRIV_NOTIFICATION};
 
     TemporaryTestUser testUser("sm_test_07a_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
 
-    AppInstallHelper app("sm_test_07a", testUser.getUid());
+    AppInstallHelperExt app("sm_test_07a", testUser.getUid());
     app.addPrivileges(allowedPrivs);
 
     InstallRequest req;
@@ -352,16 +322,13 @@ RUNNER_TEST(security_manager_07a_user_add_app_install)
         req.addPrivilege(priv);
     }
     Api::install(req);
-
-    check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
-                          allowedPrivs, someDeniedPrivs);
+    app.checkAfterInstall();
+    app.checkDeniedPrivileges(someDeniedPrivs);
 
     testUser.remove();
 
-    check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
-                          {}, merge(allowedPrivs, someDeniedPrivs));
-
-    // TODO - check if app is uninstalled
+    app.checkAfterUninstall();
+    app.checkDeniedPrivileges(someDeniedPrivs);
 }
 
 RUNNER_TEST(security_manager_07b_user_add_offline)
@@ -374,22 +341,20 @@ RUNNER_TEST(security_manager_07b_user_add_offline)
     TemporaryTestUser testUser("sm_test_07b_user_name", GUM_USERTYPE_NORMAL, true);
     testUser.create();
 
-    AppInstallHelper app("sm_test_07b", testUser.getUid());
+    AppInstallHelperExt app("sm_test_07b", testUser.getUid());
     ScopedInstaller appInstall(app);
 
     serviceManager.startService();
-    check_app_after_install(app.getAppId(), app.getPkgId());
+    app.checkAfterInstall();
 
     testUser.remove();
-    check_app_after_uninstall(app.getAppId(), app.getPkgId());
+    app.checkAfterUninstall();
 }
 
 RUNNER_TEST(security_manager_08_user_double_add_double_remove)
 {
-    std::vector<std::string> somePrivs = {
-        "http://tizen.org/privilege/internet", "http://tizen.org/privilege/led",
-        "http://tizen.org/privilege/location", "http://tizen.org/privilege/notification"
-    };
+    const PolicyConfiguration::PrivVector somePrivs = {PRIV_LED, PRIV_NOTIFICATION};
+
     // gumd
     TemporaryTestUser testUser("sm_test_08_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
@@ -400,17 +365,16 @@ RUNNER_TEST(security_manager_08_user_double_add_double_remove)
     addUserRequest.setUserType(SM_USER_TYPE_NORMAL);
     Api::addUser(addUserRequest);
 
-    AppInstallHelper app("sm_test_08", testUser.getUid());
+    AppInstallHelperExt app("sm_test_08", testUser.getUid());
     ScopedInstaller appInstall(app);
 
-    check_app_after_install(app.getAppId(), app.getPkgId());
-    check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(), {}, somePrivs);
+    app.checkAfterInstall();
+    app.checkDeniedPrivileges(somePrivs);
 
     // gumd
     testUser.remove();
 
-    check_app_after_uninstall(app.getAppId(), app.getPkgId());
-    check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(), {}, somePrivs);
+    app.checkAfterUninstall();
 
     // security-manager
     UserRequest deleteUserRequest;
@@ -468,12 +432,12 @@ RUNNER_TEST(security_manager_09_app_install_constraint_check)
         }
     };
 
-    std::array<TemporaryTestUser, 2> users{
-        TemporaryTestUser{"sm_test_09_user_name_0", GUM_USERTYPE_NORMAL, false},
-        TemporaryTestUser{"sm_test_09_user_name_1", GUM_USERTYPE_NORMAL, false}
+    TemporaryTestUser users[] = {
+        {"sm_test_09_user_name_0", GUM_USERTYPE_NORMAL, false},
+        {"sm_test_09_user_name_1", GUM_USERTYPE_NORMAL, false}
     };
 
-    for(auto& gu : users)
+    for (auto& gu : users)
         gu.create();
 
     const char *const pkgId[] =   {"sm_test_09_pkg_id_0",  "sm_test_09_pkg_id_1"};
@@ -510,78 +474,103 @@ RUNNER_TEST(security_manager_09_app_install_constraint_check)
 
 RUNNER_TEST(security_manager_09a_install_many_apps_in_single_request)
 {
-    const std::string pkgId = "sm_test_09a_pkg_id_0";
-    const std::vector<std::string> appIds = {"sm_test_09a_app_id_0", "sm_test_09a_app_id_1", "sm_test_09a_app_id_2"};
+    constexpr char pkgIdPrefix[] = "sm_test_09a";
+    const AppInstallHelperExt apps[] = {{"sm_test_09a_0", pkgIdPrefix},
+                                        {"sm_test_09a_1", pkgIdPrefix},
+                                        {"sm_test_09a_2", pkgIdPrefix}};
+    static_assert(sizeof(apps) > 0);
+
+    std::vector<std::string> appIds;
+    for (auto &app : apps)
+        appIds.push_back(app.getAppId());
 
     {
-        ScopedInstaller appsInstall(appIds, pkgId);
+        ScopedInstaller appsInstall(appIds, apps[0].getPkgId());
         // Installing many applications in single request
-        for (const auto &appId : appIds) {
-            check_app_after_install(appId, pkgId);
+        for (auto &app : apps) {
+            app.checkAfterInstall();
         }
     }
 
-    for (const auto &appId : appIds) {
-        check_app_after_uninstall(appId, pkgId);
+    for (auto &app : apps) {
+        app.checkAfterUninstall();
     }
 }
 
 RUNNER_TEST(security_manager_09b_install_many_apps_in_single_request_duplicated_ids)
 {
-    const std::string pkgId = "sm_test_09b_pkg_id_0";
-    const std::string appId = "sm_test_09b_app_id_0";
-
+    AppInstallHelperExt app("sm_test_09b");
     {
-        ScopedInstaller appsInstall({appId, appId}, pkgId);
-        check_app_after_install(appId, pkgId);
+        ScopedInstaller appsInstall({app.getAppId(), app.getAppId()}, app.getPkgId());
+        app.checkAfterInstall();
     }
 
-    check_app_after_uninstall(appId, pkgId);
+    app.checkAfterUninstall();
 }
 
 RUNNER_TEST(security_manager_09c_update_many_apps_in_single_request_hybrid_package)
 {
-    const std::vector<std::string> appIds = {"sm_test_09c_app_id_0", "sm_test_09c_app_id_1", "sm_test_09c_app_id_2"};
-    const std::string pkgId = "sm_test_09c_pkg_id_0";
+    constexpr char pkgIdPrefix[] = "sm_test_09c";
+    AppInstallHelperExt apps[] = {{"sm_test_09c_0", pkgIdPrefix},
+                                  {"sm_test_09c_1", pkgIdPrefix},
+                                  {"sm_test_09c_2", pkgIdPrefix}};
+    static_assert(sizeof(apps) > 0);
+
+    std::vector<std::string> appIds;
+    for (const auto &app : apps)
+        appIds.push_back(app.getAppId());
 
     {
-        ScopedInstaller appsInstall(appIds, pkgId);
+        ScopedInstaller appsInstall(appIds, apps[0].getPkgId());
         // Package is not hybrid, every app has same policy.
-        for (const auto &appId : appIds) {
-            check_app_after_install(appId, pkgId);
+        for (const auto &app : apps) {
+            app.checkAfterInstall();
         }
 
         // Updating package -- changing set of apps in package and setting hybrid mode
         InstallRequest updateRequest;
-        updateRequest.setPkgId(pkgId);
+        updateRequest.setPkgId(apps[0].getPkgId());
         updateRequest.setAppId(appIds[0]);
         updateRequest.nextApp();
         updateRequest.setAppId(appIds[1]);
         updateRequest.setHybrid();
 
         Api::update(updateRequest);
+
         // Package became hybrid, so every app has its own Smack label
-        check_app_after_install(appIds[0], pkgId, true);
-        check_app_after_install(appIds[1], pkgId, true);
+        for (auto &app : apps) {
+            app.setHybrid();
+        }
+        apps[0].checkAfterInstall();
+        apps[1].checkAfterInstall();
+
         // Package became hybrid properly,
         // so app not included in updated version of package was uninstalled.
-        check_app_after_uninstall(appIds[2], pkgId);
+        apps[2].checkAfterUninstall(false);
     }
 
-    for (const auto &appId : appIds) {
-        check_app_after_uninstall(appId, pkgId, true, true);
+    for (const auto &app : apps) {
+        app.checkAfterUninstall();
     }
 }
 
 RUNNER_TEST(security_manager_09d_uninstall_app_from_hybrid_package)
 {
-    const std::vector<std::string> appIds = {"sm_test_09d_app_id_0", "sm_test_09d_app_id_1", "sm_test_09d_app_id_2"};
-    const std::string pkgId = "sm_test_09d_pkg_id_0";
+    constexpr char pkgIdPrefix[] = "sm_test_09d";
+    AppInstallHelperExt apps[] = {{"sm_test_09d_0", pkgIdPrefix},
+                                  {"sm_test_09d_1", pkgIdPrefix},
+                                  {"sm_test_09d_2", pkgIdPrefix}};
+    static_assert(sizeof(apps) > 0);
+
+    std::vector<std::string> appIds;
+    for (const auto &app : apps)
+        appIds.push_back(app.getAppId());
+
     {
-        ScopedInstaller appsInstall(appIds, pkgId);
+        ScopedInstaller appsInstall(appIds, apps[0].getPkgId());
 
         InstallRequest updateRequest;
-        updateRequest.setPkgId(pkgId);
+        updateRequest.setPkgId(apps[0].getPkgId());
         for (unsigned int i = 0; i < appIds.size(); i++) {
             if (i > 0) {
                 updateRequest.nextApp();
@@ -592,31 +581,32 @@ RUNNER_TEST(security_manager_09d_uninstall_app_from_hybrid_package)
         Api::update(updateRequest);
 
         InstallRequest uninstRequest;
-        uninstRequest.setPkgId(pkgId);
+        uninstRequest.setPkgId(apps[0].getPkgId());
         uninstRequest.setAppId(appIds[0]);
         Api::uninstall(uninstRequest);
 
-        check_app_after_uninstall(appIds[0], pkgId, true);
+        for (auto &app : apps) {
+            app.setHybrid();
+        }
+        apps[0].checkAfterUninstall(false);
+    }
+    for (const auto &app : apps) {
+        app.checkAfterUninstall();
     }
 }
 
 RUNNER_CHILD_TEST(security_manager_10_app_has_privilege)
 {
-    const std::vector<std::string> allowedPrivs = {
-        "http://tizen.org/privilege/wifidirect",
-        "http://tizen.org/privilege/telephony"
-    };
-    const std::vector<std::string> someDeniedPrivs = {
-        "http://tizen.org/privilege/vpnservice",
-        "http://tizen.org/privilege/notification"
-    };
-    AppInstallHelper app("sm_test_10");
+    const PolicyConfiguration::PrivVector allowedPrivs = {PRIV_WIFIDIRECT, PRIV_TELEPHONY};
+    const PolicyConfiguration::PrivVector someDeniedPrivs = {PRIV_VPNSERVICE, PRIV_NOTIFICATION};
+
+    AppInstallHelperExt app("sm_test_10");
     app.addPrivileges(allowedPrivs);
     ScopedInstaller appInstall(app);
 
-    sm_app_has_privileges(app, allowedPrivs, 1);
+    app.checkAfterInstall();
+    app.checkDeniedPrivileges(someDeniedPrivs);
     // FIXME - all other existing privileges should be checked
-    sm_app_has_privileges(app, someDeniedPrivs, 0);
 }
 
 RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_POLICY)
@@ -651,40 +641,34 @@ RUNNER_TEST(security_manager_20_user_cynara_policy)
 
 RUNNER_CHILD_TEST(security_manager_21_security_manager_admin_deny_user_priv)
 {
-    const privileges_t adminRequiredPrivs = {
-        "http://tizen.org/privilege/notexist",
-        "http://tizen.org/privilege/internal/usermanagement"
-    };
-    const privileges_t manifestPrivs = {
-         "http://tizen.org/privilege/internet",
-         "http://tizen.org/privilege/datasharing"
+    const PolicyConfiguration::PrivVector adminRequiredPrivs = {
+        PRIV_NOTEXIST,
+        PRIV_INTERNAL_USERMANAGEMENT
     };
-    const privileges_t allowedPrivsAfterChange = {"http://tizen.org/privilege/datasharing"};
-    const privileges_t deniedPrivsAfterChange = {"http://tizen.org/privilege/internet"};
+    const PolicyConfiguration::PrivVector manifestPrivs = {PRIV_INTERNET, PRIV_DATASHARING};
+    const PolicyConfiguration::PrivVector allowedPrivsAfterChange = {PRIV_DATASHARING};
+    const PolicyConfiguration::PrivVector deniedPrivsAfterChange = {PRIV_INTERNET};
+
     TemporaryTestUser adminUser("sm_test_21_admin_user_name", GUM_USERTYPE_ADMIN, false);
     TemporaryTestUser normalUser("sm_test_21_normal_user_name", GUM_USERTYPE_NORMAL, false);
 
     adminUser.create();
     normalUser.create();
-    std::string childUidStr = normalUser.getUidString();
 
     AppInstallHelper adminApp("sm_test_21_admin", adminUser.getUid());
     adminApp.addPrivileges(adminRequiredPrivs);
     ScopedInstaller adminAppInstall(adminApp);
 
-    AppInstallHelper normalApp("sm_test_21_normal", normalUser.getUid());
+    AppInstallHelperExt normalApp("sm_test_21_normal", normalUser.getUid());
     normalApp.addPrivileges(manifestPrivs);
     ScopedInstaller normalAppInstall(normalApp);
-
-    check_app_permissions(normalApp.getAppId(), normalApp.getPkgId(), childUidStr,
-                          manifestPrivs, {});
+    normalApp.checkAfterInstall();
 
     pid_t pid = fork();
     RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
     if (pid != 0) { //parent process
         waitPid(pid);
-        check_app_permissions(normalApp.getAppId(), normalApp.getPkgId(), childUidStr,
-                              allowedPrivsAfterChange, deniedPrivsAfterChange);
+        normalApp.checkPrivileges(allowedPrivsAfterChange, deniedPrivsAfterChange);
     } else {
         Api::setProcessLabel(adminApp.getAppId());
         RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(adminUser.getUid(),adminUser.getGid()) == 0,
@@ -819,16 +803,16 @@ RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_INSTALL_TYPE)
 
 RUNNER_TEST(security_manager_25a_global_user_set_install_type_global)
 {
-    AppInstallHelper app("sm_test_25a");
+    AppInstallHelperExt app("sm_test_25a");
     app.setInstallType(SM_APP_INSTALL_GLOBAL);
     {
         ScopedInstaller appInstall(app);
 
-        check_app_after_install(app.getAppId(), app.getPkgId());
+        app.checkAfterInstall();
     }
 
     // Check records in the security-manager database
-    check_app_after_uninstall(app.getAppId(), app.getPkgId());
+    app.checkAfterUninstall();
 }
 
 RUNNER_TEST(security_manager_25b_global_user_set_install_type_local)
@@ -845,13 +829,13 @@ RUNNER_TEST(security_manager_25b_global_user_set_install_type_local)
 
 RUNNER_TEST(security_manager_25c_global_user_set_install_type_preloaded)
 {
-    AppInstallHelper app("sm_test_25c");
+    AppInstallHelperExt app("sm_test_25c");
     app.setInstallType(SM_APP_INSTALL_PRELOADED);
     {
         ScopedInstaller appInstall(app);
-        check_app_after_install(app.getAppId(), app.getPkgId());
+        app.checkAfterInstall();
     }
-    check_app_after_uninstall(app.getAppId(), app.getPkgId());
+    app.checkAfterUninstall();
 }
 
 RUNNER_TEST(security_manager_25d_local_user_set_install_type_invalid)
@@ -907,21 +891,21 @@ RUNNER_CHILD_TEST(security_manager_25f_unprivileged_install_type_preloaded)
 
 RUNNER_CHILD_TEST(security_manager_25g_local_user_set_install_type_local)
 {
-    std::vector<std::string> allowedPrivs = {
-        "http://tizen.org/privilege/volume.set",
-        "http://tizen.org/privilege/systemmonitor",
-        "http://tizen.org/privilege/internet"
+    const PolicyConfiguration::PrivVector allowedPrivs = {
+        PRIV_VOLUME_SET,
+        PRIV_SYSTEMMONITOR,
+        PRIV_INTERNET
     };
-    std::vector<std::string> someDeniedPrivs = {
-        "http://tizen.org/privilege/push",
-        "http://tizen.org/privilege/power",
-        "http://tizen.org/privilege/notification"
+    const PolicyConfiguration::PrivVector someDeniedPrivs = {
+        PRIV_PUSH,
+        PRIV_POWER,
+        PRIV_NOTIFICATION,
     };
 
     TemporaryTestUser testUser("sm_test_25g_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
 
-    AppInstallHelper app("sm_test_25g", testUser.getUid());
+    AppInstallHelperExt app("sm_test_25g", testUser.getUid());
     app.createPrivateDir();
     app.setInstallType(SM_APP_INSTALL_LOCAL);
     app.addPrivileges(allowedPrivs);
@@ -930,13 +914,10 @@ RUNNER_CHILD_TEST(security_manager_25g_local_user_set_install_type_local)
                             "drop_root_privileges failed");
     {
         ScopedInstaller appInstall(app);
-        check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
-                              allowedPrivs, someDeniedPrivs);
-
+        app.checkAfterInstall();
+        app.checkDeniedPrivileges(someDeniedPrivs);
     }
-    check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
-                          {}, merge(allowedPrivs, someDeniedPrivs));
-    // TODO - check if app is properly uninstalled
+    app.checkAfterUninstall();
 }
 
 RUNNER_CHILD_TEST(security_manager_25h_local_path_global_install)
@@ -998,30 +979,23 @@ RUNNER_CHILD_TEST(security_manager_26_hybrid_pkg_uninstall_artifacts_check)
     TemporaryTestUser testUser("sm_test_26_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
 
-    const std::vector<std::string> allowedPrivs = {
-        "http://tizen.org/privilege/wifidirect",
-        "http://tizen.org/privilege/telephony"
-    };
+    const PolicyConfiguration::PrivVector allowedPrivs = {PRIV_WIFIDIRECT, PRIV_TELEPHONY};
 
-    AppInstallHelper app1("sm_test_26_1", "sm_test_26", testUser.getUid());
+    AppInstallHelperExt app1("sm_test_26_1", "sm_test_26", testUser.getUid());
     app1.addPrivileges(allowedPrivs);
     app1.setHybrid();
 
-    AppInstallHelper app2("sm_test_26_2", "sm_test_26", testUser.getUid());
+    AppInstallHelperExt app2("sm_test_26_2", "sm_test_26", testUser.getUid());
     app2.addPrivileges(allowedPrivs);
     app2.setHybrid();
 
     {
         ScopedInstaller appInstall1(app1);
         ScopedInstaller appInstall2(app2);
-        check_app_permissions(app1.getAppId(), app1.getPkgId(), testUser.getUidString(),
-                              allowedPrivs, {}, app1.getIsHybrid());
-        check_app_permissions(app2.getAppId(), app2.getPkgId(), testUser.getUidString(),
-                              allowedPrivs, {}, app2.getIsHybrid());
+        app1.checkAfterInstall();
+        app2.checkAfterInstall();
 
     }
-    check_app_permissions(app1.getAppId(), app1.getPkgId(), testUser.getUidString(),
-                          {}, allowedPrivs, app1.getIsHybrid());
-    check_app_permissions(app2.getAppId(), app2.getPkgId(), testUser.getUidString(),
-                          {}, allowedPrivs, app2.getIsHybrid());
+    app1.checkAfterUninstall(false);
+    app2.checkAfterUninstall();
 }