Add test cases for updating an app package
[platform/core/test/security-tests.git] / src / security-manager-tests / test_cases.cpp
index b7c75ea..2d8cf74 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 - 2020 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.
@@ -14,9 +14,7 @@
  *    limitations under the License.
  */
 
-// cstdlibg has to be included before attr/xattr
-#include <cstdlib>
-#include <attr/xattr.h>
+#include <linux/xattr.h>
 #include <fstream>
 #include <memory>
 #include <regex>
@@ -47,6 +45,7 @@
 #include <scoped_app_launcher.h>
 #include <app_install_helper_ext.h>
 #include <privilege_names.h>
+#include <app_def_privilege.h>
 
 using namespace SecurityManagerTest;
 using namespace PrivilegeNames;
@@ -135,17 +134,17 @@ RUNNER_TEST(security_manager_01d_app_install_complicated_dir_tree)
     check_path(sharedRODir, getSharedROPathLabel());
 }
 
-RUNNER_TEST(security_manager_02_app_install_uninstall_full)
+RUNNER_CHILD_TEST(security_manager_02_app_install_uninstall_full)
 {
-    const PolicyConfiguration::PrivVector defaultPrivs = {
+    const PrivilegeVector 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};
+    const PrivilegeVector allowedPrivs = {PRIV_CAMERA, PRIV_MEDIASTORAGE};
+    const PrivilegeVector someDeniedPrivs = {PRIV_INTERNET, PRIV_EXTERNALSTORAGE};
 
-    PolicyConfiguration::PrivVector defaultAllowedPrivs = defaultPrivs;
+    PrivilegeVector defaultAllowedPrivs = defaultPrivs;
     defaultAllowedPrivs.insert(defaultAllowedPrivs.end(), allowedPrivs.begin(), allowedPrivs.end());
 
     AppInstallHelperExt app("sm_test_02");
@@ -159,7 +158,9 @@ RUNNER_TEST(security_manager_02_app_install_uninstall_full)
 
         app.checkAfterInstall();
         app.checkDeniedPrivileges(someDeniedPrivs);
-        app.checkPrivilegeGroups(defaultAllowedPrivs);
+        {
+            ScopedAppLauncher launcher(app, [&]{ app.checkGroupPrivileges(defaultAllowedPrivs); });
+        }
 
         check_path(app.getPrivateDir(), generatePathRWLabel(app.getPkgId()));
         check_path(app.getPrivateRODir(), generatePathROLabel(app.getPkgId()), false);
@@ -170,6 +171,38 @@ RUNNER_TEST(security_manager_02_app_install_uninstall_full)
     app.checkAfterUninstall();
 }
 
+RUNNER_CHILD_TEST(security_manager_02a_set_process_groups)
+{
+    const PrivilegeVector defaultPrivs = {
+        PRIV_INTERNAL_AUDIO,
+        PRIV_INTERNAL_DISPLAY,
+        PRIV_INTERNAL_VIDEO,
+    };
+    const PrivilegeVector allowedPrivs = {PRIV_CAMERA, PRIV_MEDIASTORAGE};
+
+    auto defaultAllowedPrivs = defaultPrivs;
+    defaultAllowedPrivs.insert(defaultAllowedPrivs.end(), allowedPrivs.begin(), allowedPrivs.end());
+
+    AppInstallHelperExt app("sm_test_02a");
+    app.addPrivileges(allowedPrivs);
+    {
+        ScopedInstaller appInstall(app);
+
+        app.checkAfterInstall();
+
+        pid_t pid = fork();
+        RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+        if (pid != 0) {
+            waitPid(pid);
+        } else {
+            Api::setProcessGroups(app.getAppId());
+            app.checkGroupPrivileges(defaultAllowedPrivs);
+            exit(0);
+        }
+    }
+    app.checkAfterUninstall();
+}
+
 RUNNER_CHILD_TEST_SMACK(security_manager_03_set_label_from_appid)
 {
     std::string expectedSockLabel = "labelExpectedOnlyFromSocket";
@@ -230,8 +263,8 @@ 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 PolicyConfiguration::PrivVector allowedPrivs = {PRIV_BLUETOOTH, PRIV_POWER};
-    const PolicyConfiguration::PrivVector someDeniedPrivs = {PRIV_DISPLAY, PRIV_NFC};
+    const PrivilegeVector allowedPrivs = {PRIV_BLUETOOTH, PRIV_POWER};
+    const PrivilegeVector someDeniedPrivs = {PRIV_DISPLAY, PRIV_NFC};
 
     TemporaryTestUser testUser("sm_test_04a_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
@@ -251,8 +284,8 @@ RUNNER_CHILD_TEST(security_manager_04a_app_install_uninstall_by_app_user_for_sel
 }
 
 RUNNER_CHILD_TEST(security_manager_04b_app_install_by_root_for_app_user) {
-    const PolicyConfiguration::PrivVector allowedPrivs = {PRIV_INTERNET, PRIV_LED};
-    const PolicyConfiguration::PrivVector someDeniedPrivs = {PRIV_LOCATION, PRIV_NOTIFICATION};
+    const PrivilegeVector allowedPrivs = {PRIV_INTERNET, PRIV_LED};
+    const PrivilegeVector someDeniedPrivs = {PRIV_LOCATION, PRIV_NOTIFICATION};
 
     TemporaryTestUser testUser("sm_test_04b_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
@@ -305,8 +338,8 @@ RUNNER_TEST(security_manager_06_install_app_offline)
 
 RUNNER_CHILD_TEST(security_manager_07a_user_add_app_install)
 {
-    const PolicyConfiguration::PrivVector allowedPrivs = {PRIV_INTERNET, PRIV_LED};
-    const PolicyConfiguration::PrivVector someDeniedPrivs = {PRIV_LOCATION, PRIV_NOTIFICATION};
+    const PrivilegeVector allowedPrivs = {PRIV_INTERNET, PRIV_LED};
+    const PrivilegeVector someDeniedPrivs = {PRIV_LOCATION, PRIV_NOTIFICATION};
 
     TemporaryTestUser testUser("sm_test_07a_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
@@ -353,7 +386,7 @@ RUNNER_TEST(security_manager_07b_user_add_offline)
 
 RUNNER_TEST(security_manager_08_user_double_add_double_remove)
 {
-    const PolicyConfiguration::PrivVector somePrivs = {PRIV_LED, PRIV_NOTIFICATION};
+    const PrivilegeVector somePrivs = {PRIV_LED, PRIV_NOTIFICATION};
 
     // gumd
     TemporaryTestUser testUser("sm_test_08_user_name", GUM_USERTYPE_NORMAL);
@@ -384,52 +417,26 @@ RUNNER_TEST(security_manager_08_user_double_add_double_remove)
 
 RUNNER_TEST(security_manager_09_app_install_constraint_check)
 {
-    auto install = [](const TemporaryTestUser& user,
-                      const char *pkgId,
-                      const char *appId,
-                      const char *version,
-                      const char *author,
-                      bool isHybrid,
-                      enum lib_retcode expected,
-                      bool uninstall = true)
+    auto install = [](const AppInstallHelperExt& app, bool success)
     {
-        InstallRequest request;
-        request.setAppId(appId);
-        request.setPkgId(pkgId);
-        request.setAppTizenVersion(version);
-        request.setAuthorId(author);
-        request.setUid(user.getUid());
-        if (isHybrid)
-            request.setHybrid();
-        Api::install(request, expected);
-
-        if(expected == SECURITY_MANAGER_SUCCESS && uninstall) {
-            Api::uninstall(request);
-        }
+        auto expected = success ? SECURITY_MANAGER_SUCCESS : SECURITY_MANAGER_ERROR_INPUT_PARAM;
+        ScopedInstaller appInstall(app, true, expected);
+        if (success)
+            app.checkAfterInstall();
+        return appInstall;
     };
 
-    auto update = [](const TemporaryTestUser& user,
-                     const char *pkgId,
-                     const char *appId,
-                     const char *version,
-                     const char *author,
-                     bool isHybrid,
-                     enum lib_retcode expected,
-                     bool uninstall = true)
+    auto update = [](const AppInstallHelperExt& app)
     {
         InstallRequest request;
-        request.setAppId(appId);
-        request.setPkgId(pkgId);
-        request.setAppTizenVersion(version);
-        request.setAuthorId(author);
-        request.setUid(user.getUid());
-        if (isHybrid)
+        request.setAppId(app.getAppId());
+        request.setPkgId(app.getPkgId());
+        request.setAppTizenVersion(app.getVersion());
+        request.setAuthorId(app.getAuthor());
+        request.setUid(app.getUID());
+        if (app.getIsHybrid())
             request.setHybrid();
-        Api::update(request, expected);
-
-        if(expected == SECURITY_MANAGER_SUCCESS && uninstall) {
-            Api::uninstall(request);
-        }
+        Api::update(request);
     };
 
     TemporaryTestUser users[] = {
@@ -440,36 +447,76 @@ RUNNER_TEST(security_manager_09_app_install_constraint_check)
     for (auto& gu : users)
         gu.create();
 
-    const char *const pkgId[] =   {"sm_test_09_pkg_id_0",  "sm_test_09_pkg_id_1"};
-    const char *const appId[] =   {"sm_test_09_app_id_0",  "sm_test_09_app_id_1"};
-    const char *const version[] = {"sm_test_09_version_0", "sm_test_09_version_1"};
-    const char *const author[] =  {"sm_test_09_author_0",  "sm_test_09_author_1"};
+    const char *const pkgIdPrefix[] =   {"sm_test_09_0",            "sm_test_09_1"};
+    const char *const appIdPrefix[] =   {"sm_test_09_0",            "sm_test_09_1"};
+    const char *const version[] =       {"sm_test_09_0_version",    "sm_test_09_1_version"};
+    const char *const author[] =        {"sm_test_09_0_author",     "sm_test_09_1_author"};
     bool hybrid[] = {false, true};
 
-    // uid_0, pkg_0, app_0, version_0, author_0, not hybrid
-    install(users[0], pkgId[0], appId[0], version[0], author[0], hybrid[0], SECURITY_MANAGER_SUCCESS, false);
+    std::list<AppInstallHelperExt> apps;
+
+    auto make_helper = [&](size_t userIdx,
+                           size_t pkgIdx,
+                           size_t appIdx,
+                           size_t verIdx,
+                           size_t authorIdx,
+                           size_t hybridIdx) -> AppInstallHelperExt&
+    {
+        apps.emplace_back(appIdPrefix[appIdx], pkgIdPrefix[pkgIdx], users[userIdx].getUid());
+        apps.back().setAuthor(author[authorIdx]);
+        apps.back().setVersion(version[verIdx]);
+        if (hybrid[hybridIdx])
+            apps.back().setHybrid();
+        return apps.back();
+    };
+
+    // uid_0, pkg_0, app_0, version_0, author_0, not hybrid -> ok
+    auto &app000000 = make_helper(0, 0, 0, 0, 0, 0);
+    auto i1 = install(app000000, true);
+
     // uid_1, pkg_0, app_0, version_0, author_0, not hybrid -> ok (different uid)
-    install(users[1], pkgId[0], appId[0], version[0], author[0], hybrid[0], SECURITY_MANAGER_SUCCESS);
-    // uid_0, pkg_0, app_0, version_0, author_0, hybrid -> ok for update (different hybrid setting)
-    install(users[0], pkgId[0], appId[0], version[0], author[0], hybrid[1], SECURITY_MANAGER_ERROR_INPUT_PARAM);
-    update(users[0], pkgId[0], appId[0], version[0], author[0], hybrid[1], SECURITY_MANAGER_SUCCESS, false);
+    auto& app100000 = make_helper(1, 0, 0, 0, 0, 0);
+    install(app100000, true);
+
+    // uid_0, pkg_0, app_0, version_0, author_0, hybrid -> conflicts with existing non hybrid app
+    auto& app000001 = make_helper(0, 0, 0, 0, 0, 1);
+    install(app000001, false);
+
+    // uid_0, pkg_0, app_0, version_0, author_0, hybrid -> ok (app updated to hybrid)
+    update(app000001);
+
+    // uid_0, pkg_0, app_0, version_0, author_0, hybrid -> ok (app installed again)
+    auto i2 = install(app000001, true);
+
+    // uid_0, pkg_0, app_0, version_0, author_0, not hybrid -> conflicts with existing hybrid app
+    install(app000000, false);
+
     // uid_0, pkg_0, app_1, version_0, author_0, hybrid -> ok (new app id)
-    install(users[0], pkgId[0], appId[1], version[0], author[0], hybrid[1], SECURITY_MANAGER_SUCCESS, false);
-    // uid_1, pkg_0, app_0, version_0, author_0, hybrid -> ok (different hybrid setting)
-    install(users[1], pkgId[0], appId[0], version[0], author[0], hybrid[1], SECURITY_MANAGER_SUCCESS, false);
-    // uid_1, pkg_0, app_0, version_0, author_1, not hybrid -> fail (author of app_0 must be the same)
-    install(users[1], pkgId[0], appId[0], version[0], author[1], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
-    // uid_1, pkg_0, app_0, version_1, author_0, not hybrid -> ok (version upgrade and different hybrid setting)
-    install(users[1], pkgId[0], appId[0], version[1], author[0], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
-    update(users[1], pkgId[0], appId[0], version[1], author[0], hybrid[0], SECURITY_MANAGER_SUCCESS);
-    // uid_1, pkg_1, app_0, version_0, author_0, not hybrid -> fail (pkg of app_0 must be the same)
-    install(users[1], pkgId[1], appId[0], version[0], author[0], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
-    // uid_0, pkg_0, app_0, version_0, author_0, not hybrid -> ok (the same app again)
-    install(users[0], pkgId[0], appId[0], version[0], author[0], hybrid[0], SECURITY_MANAGER_SUCCESS, false);
-    // uid_0, pkg_1, app_0, version_0, author_0, not hybrid -> fail (app_name + uid must be unique)
-    install(users[0], pkgId[1], appId[0], version[0], author[0], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
-    // uid_0, pkg_0, app_0, version_0, author_1, not hybrid -> fail (app_name + uid must be unique)
-    install(users[0], pkgId[0], appId[0], version[0], author[1], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
+    auto& app001001 = make_helper(0, 0, 1, 0, 0, 1);
+    auto i3 = install(app001001, true);
+
+    // uid_1, pkg_0, app_0, version_0, author_0, hybrid -> ok (hybrid, different uid)
+    auto& app100001 = make_helper(1, 0, 0, 0, 0, 1);
+    auto i4 = install(app100001, true);
+
+    // uid_1, pkg_0, app_0, version_0, author_1, not hybrid -> author of app_0 must be the same
+    auto& app100010 = make_helper(1, 0, 0, 0, 1, 0);
+    install(app100010, false);
+
+    // uid_1, pkg_0, app_0, version_1, author_0, not hybrid -> ok (app version and hybridity changed)
+    auto& app100100 = make_helper(1, 0, 0, 1, 0, 0);
+    update(app100100);
+
+    // uid_1, pkg_1, app_0, version_1, author_0, not hybrid -> pkg of app_0 must be the same
+    auto& app110100 = make_helper(1, 1, 0, 1, 0, 0);
+    install(app110100, false);
+
+    for (auto& gu : users)
+        gu.remove();
+
+    RUNNER_IGNORED_MSG("Disabled until hybridity update works properly for all users");
+    for (auto& app : apps)
+        app.checkAfterUninstall();
 }
 
 RUNNER_TEST(security_manager_09a_install_many_apps_in_single_request)
@@ -595,10 +642,60 @@ RUNNER_TEST(security_manager_09d_uninstall_app_from_hybrid_package)
     }
 }
 
+RUNNER_TEST(security_manager_09e_update_app_nonhybrid_package)
+{
+    constexpr char pkgId[] = "sm_test_09e";
+    AppInstallHelperExt apps[] = {{"sm_test_09e_0", pkgId},
+                                  {"sm_test_09e_1", pkgId}};
+
+    InstallRequest installRequest;
+    installRequest.setPkgId(apps[0].getPkgId());
+    installRequest.setAppId(apps[0].getAppId());
+    // following installation will install sm_test_09e_0
+    Api::install(installRequest, SECURITY_MANAGER_SUCCESS);
+    apps[0].checkAfterInstall();
+    InstallRequest updateRequest;
+    updateRequest.setPkgId(apps[1].getPkgId());
+    updateRequest.setAppId(apps[1].getAppId());
+    // following update should uninstall sm_test_09e_0 and leave sm_test_09e_1 in the DB
+    Api::update(updateRequest, SECURITY_MANAGER_SUCCESS);
+    apps[1].checkAfterInstall();
+    apps[0].checkAfterUninstall(false);
+    // this uninstall should succeed and make sure DB contains NO applications from this package
+    Api::uninstall(updateRequest, SECURITY_MANAGER_SUCCESS);
+    apps[1].checkAfterUninstall(true);
+}
+
+RUNNER_TEST(security_manager_09f_update_app_hybrid_package)
+{
+    constexpr char pkgId[] = "sm_test_09f";
+    AppInstallHelperExt apps[] = {{"sm_test_09f_0", pkgId},
+                                  {"sm_test_09f_1", pkgId}};
+
+    InstallRequest installRequest;
+    installRequest.setPkgId(apps[0].getPkgId());
+    installRequest.setAppId(apps[0].getAppId());
+    installRequest.setHybrid();
+    // following installation will install sm_test_09f_0
+    Api::install(installRequest, SECURITY_MANAGER_SUCCESS);
+    apps[0].checkAfterInstall();
+    InstallRequest updateRequest;
+    updateRequest.setPkgId(apps[1].getPkgId());
+    updateRequest.setAppId(apps[1].getAppId());
+    updateRequest.setHybrid();
+    // following update should uninstall sm_test_09f_0 and leave sm_test_09f_1 in the DB
+    Api::update(updateRequest, SECURITY_MANAGER_SUCCESS);
+    apps[1].checkAfterInstall();
+    apps[0].checkAfterUninstall(false);
+    // this uninstall should succeed and make sure DB contains NO applications from this package
+    Api::uninstall(updateRequest, SECURITY_MANAGER_SUCCESS);
+    apps[1].checkAfterUninstall(true);
+}
+
 RUNNER_CHILD_TEST(security_manager_10_app_has_privilege)
 {
-    const PolicyConfiguration::PrivVector allowedPrivs = {PRIV_WIFIDIRECT, PRIV_TELEPHONY};
-    const PolicyConfiguration::PrivVector someDeniedPrivs = {PRIV_VPNSERVICE, PRIV_NOTIFICATION};
+    const PrivilegeVector allowedPrivs = {PRIV_WIFIDIRECT, PRIV_TELEPHONY};
+    const PrivilegeVector someDeniedPrivs = {PRIV_VPNSERVICE, PRIV_NOTIFICATION};
 
     AppInstallHelperExt app("sm_test_10");
     app.addPrivileges(allowedPrivs);
@@ -641,13 +738,10 @@ RUNNER_TEST(security_manager_20_user_cynara_policy)
 
 RUNNER_CHILD_TEST(security_manager_21_security_manager_admin_deny_user_priv)
 {
-    const PolicyConfiguration::PrivVector adminRequiredPrivs = {
-        PRIV_NOTEXIST,
-        PRIV_INTERNAL_USERMANAGEMENT
-    };
-    const PolicyConfiguration::PrivVector manifestPrivs = {PRIV_INTERNET, PRIV_DATASHARING};
-    const PolicyConfiguration::PrivVector allowedPrivsAfterChange = {PRIV_DATASHARING};
-    const PolicyConfiguration::PrivVector deniedPrivsAfterChange = {PRIV_INTERNET};
+    const PrivilegeVector adminRequiredPrivs = {PRIV_NOTEXIST, PRIV_INTERNAL_USERMANAGEMENT};
+    const PrivilegeVector manifestPrivs = {PRIV_INTERNET, PRIV_DATASHARING};
+    const PrivilegeVector allowedPrivsAfterChange = {PRIV_DATASHARING};
+    const PrivilegeVector 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);
@@ -705,8 +799,8 @@ RUNNER_TEST(security_manager_22_security_manager_cmd_install)
     const std::string appopt = " --app=" + app_id;
     const std::string uidopt = " --uid=" + user.getUidString();
 
-    mktreeSafe(path1.c_str(), 0);
-    mktreeSafe(path2.c_str(), 0);
+    mktreeSafe(path1, 0);
+    mktreeSafe(path2, 0);
 
     const std::string installcmd = "security-manager-cmd --install " + appopt + pkgopt + uidopt;
 
@@ -891,16 +985,8 @@ RUNNER_CHILD_TEST(security_manager_25f_unprivileged_install_type_preloaded)
 
 RUNNER_CHILD_TEST(security_manager_25g_local_user_set_install_type_local)
 {
-    const PolicyConfiguration::PrivVector allowedPrivs = {
-        PRIV_VOLUME_SET,
-        PRIV_SYSTEMMONITOR,
-        PRIV_INTERNET
-    };
-    const PolicyConfiguration::PrivVector someDeniedPrivs = {
-        PRIV_PUSH,
-        PRIV_POWER,
-        PRIV_NOTIFICATION,
-    };
+    const PrivilegeVector allowedPrivs = {PRIV_VOLUME_SET, PRIV_SYSTEMMONITOR, PRIV_INTERNET};
+    const PrivilegeVector someDeniedPrivs = {PRIV_PUSH, PRIV_POWER, PRIV_NOTIFICATION};
 
     TemporaryTestUser testUser("sm_test_25g_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
@@ -979,7 +1065,7 @@ RUNNER_CHILD_TEST(security_manager_26_hybrid_pkg_uninstall_artifacts_check)
     TemporaryTestUser testUser("sm_test_26_user_name", GUM_USERTYPE_NORMAL);
     testUser.create();
 
-    const PolicyConfiguration::PrivVector allowedPrivs = {PRIV_WIFIDIRECT, PRIV_TELEPHONY};
+    const PrivilegeVector allowedPrivs = {PRIV_WIFIDIRECT, PRIV_TELEPHONY};
 
     AppInstallHelperExt app1("sm_test_26_1", "sm_test_26", testUser.getUid());
     app1.addPrivileges(allowedPrivs);