X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=tests%2Fsecurity-manager-tests%2Fsecurity_manager_tests.cpp;h=241a24bf0e07a42dd89b17d8931312251524891e;hb=52dbcaab9f1a32342cd89169417357f647231f26;hp=d9c041c4a28c3aa47bbb25a37ff39c9ff9ffa565;hpb=e0782175542f0384ebc59c96e9f2609d96bc6676;p=platform%2Fcore%2Ftest%2Fsecurity-tests.git diff --git a/tests/security-manager-tests/security_manager_tests.cpp b/tests/security-manager-tests/security_manager_tests.cpp index d9c041c..241a24b 100644 --- a/tests/security-manager-tests/security_manager_tests.cpp +++ b/tests/security-manager-tests/security_manager_tests.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,36 +6,47 @@ #include #include #include +#include #include #include #include #include +#include +#include +#include + #include #include #include #include +#include #include #include #include #include +#include +#include #include +#include +#include using namespace SecurityManagerTest; DEFINE_SMARTPTR(cap_free, _cap_struct, CapsSetsUniquePtr); +DEFINE_SMARTPTR(tzplatform_context_destroy, tzplatform_context, TzPlatformContextPtr); static const privileges_t SM_ALLOWED_PRIVILEGES = { - "security_manager_test_rules2_r", - "security_manager_test_rules2_no_r" + "http://tizen.org/privilege/location", + "http://tizen.org/privilege/camera" }; static const privileges_t SM_DENIED_PRIVILEGES = { - "security_manager_test_rules1", - "security_manager_test_rules2" + "http://tizen.org/privilege/bluetooth", + "http://tizen.org/privilege/power" }; static const privileges_t SM_NO_PRIVILEGES = { @@ -45,8 +57,60 @@ static const std::vector SM_ALLOWED_GROUPS = {"db_browser", "db_ala static const char *const SM_PRIVATE_PATH = "/usr/apps/test_DIR/app_dir"; static const char *const SM_PUBLIC_RO_PATH = "/usr/apps/test_DIR/app_dir_public_ro"; static const char *const SM_DENIED_PATH = "/usr/apps/test_DIR/non_app_dir"; -static const char *const SM_PRIVATE_PATH_FOR_USER = "/home/" APP_USER "/test_DIR"; static const char *const ANY_USER_REPRESENTATION = "anyuser";/*this may be actually any string*/ +static const std::string EXEC_FILE("exec"); +static const std::string NORMAL_FILE("normal"); +static const std::string LINK_PREFIX("link_to_"); + +static const std::string PRIVILEGE_MANAGER_APP = "privilege_manager"; +static const std::string PRIVILEGE_MANAGER_PKG = "privilege_manager"; +static const std::string PRIVILEGE_MANAGER_SELF_PRIVILEGE = "http://tizen.org/privilege/systemsettings"; +static const std::string PRIVILEGE_MANAGER_ADMIN_PRIVILEGE = "http://tizen.org/privilege/systemsettings.admin"; + +static const std::vector MANY_APPS = { + "security_manager_10_app_1", + "security_manager_10_app_2", + "security_manager_10_app_3", + "security_manager_10_app_4", + "security_manager_10_app_5" +}; + +static const std::map MANY_APPS_PKGS = { + {"security_manager_10_app_1", "security_manager_10_pkg_1"}, + {"security_manager_10_app_2", "security_manager_10_pkg_2"}, + {"security_manager_10_app_3", "security_manager_10_pkg_3"}, + {"security_manager_10_app_4", "security_manager_10_pkg_4"}, + {"security_manager_10_app_5", "security_manager_10_pkg_5"}, + {PRIVILEGE_MANAGER_APP, PRIVILEGE_MANAGER_PKG} +}; + +static const std::vector MANY_APPS_PRIVILEGES = { + { + "http://tizen.org/privilege/internet", + "http://tizen.org/privilege/location" + }, + { + "http://tizen.org/privilege/telephony", + "http://tizen.org/privilege/camera" + }, + { + "http://tizen.org/privilege/contact.read", + "http://tizen.org/privilege/led", + "http://tizen.org/privilege/email" + }, + { + "http://tizen.org/privilege/led", + "http://tizen.org/privilege/email", + "http://tizen.org/privilege/telephony", + "http://tizen.org/privilege/camera" + }, + { + "http://tizen.org/privilege/internet", + "http://tizen.org/privilege/location", + "http://tizen.org/privilege/led", + "http://tizen.org/privilege/email" + } +}; static void generateAppLabel(const std::string &pkgId, std::string &label) { @@ -156,7 +220,7 @@ static void check_app_permissions(const char *const app_id, const char *const pk std::string smackLabel; generateAppLabel(pkg_id, smackLabel); - CynaraTestClient ctc; + CynaraTestClient::Client ctc; for (auto &priv : allowed_privs) { ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_ALLOWED); @@ -249,12 +313,12 @@ static void check_app_after_uninstall(const char *const app_id, const char *cons dbtest.test_db_after__app_uninstall(app_id, pkg_id, is_pkg_removed); } -static void install_app(const char *app_id, const char *pkg_id) +static void install_app(const char *app_id, const char *pkg_id, uid_t uid = 0) { InstallRequest request; request.setAppId(app_id); request.setPkgId(pkg_id); - + request.setUid(uid); Api::install(request); check_app_after_install(app_id, pkg_id); @@ -271,14 +335,48 @@ static void uninstall_app(const char *app_id, const char *pkg_id, bool expect_pk check_app_after_uninstall(app_id, pkg_id, expect_pkg_removed); } +static inline void register_current_process_as_privilege_manager(uid_t uid, bool forAdmin = false) +{ + InstallRequest request; + request.setAppId(PRIVILEGE_MANAGER_APP.c_str()); + request.setPkgId(PRIVILEGE_MANAGER_PKG.c_str()); + request.setUid(uid); + request.addPrivilege(PRIVILEGE_MANAGER_SELF_PRIVILEGE.c_str()); + if (forAdmin) + request.addPrivilege(PRIVILEGE_MANAGER_ADMIN_PRIVILEGE.c_str()); + Api::install(request); + Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str()); +}; + +static inline struct passwd *getUserStruct(const std::string &userName) { + struct passwd *pw = nullptr; + errno = 0; + + while(!(pw = getpwnam(userName.c_str()))) { + RUNNER_ASSERT_ERRNO_MSG(errno == EINTR, "getpwnam() failed"); + }; + + return pw; +}; + +static inline struct passwd *getUserStruct(const uid_t uid) { + struct passwd *pw = nullptr; + errno = 0; + + while(!(pw = getpwuid(uid))) { + RUNNER_ASSERT_ERRNO_MSG(errno == EINTR, "getpwnam() failed"); + }; + + return pw; +}; RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER) -RUNNER_TEST(security_manager_01_app_double_install_double_uninstall) +RUNNER_TEST(security_manager_01a_app_double_install_double_uninstall) { - const char *const sm_app_id = "sm_test_01_app_id_double"; - const char *const sm_pkg_id = "sm_test_01_pkg_id_double"; + const char *const sm_app_id = "sm_test_01a_app_id_double"; + const char *const sm_pkg_id = "sm_test_01a_pkg_id_double"; InstallRequest requestInst; requestInst.setAppId(sm_app_id); @@ -300,6 +398,65 @@ RUNNER_TEST(security_manager_01_app_double_install_double_uninstall) check_app_after_uninstall(sm_app_id, sm_pkg_id, TestSecurityManagerDatabase::REMOVED); } + +RUNNER_TEST(security_manager_01b_app_double_install_wrong_pkg_id) +{ + const char *const sm_app_id = "sm_test_01b_app"; + const char *const sm_pkg_id = "sm_test_01b_pkg"; + const char *const sm_pkg_id_wrong = "sm_test_01b_pkg_BAD"; + + InstallRequest requestInst; + requestInst.setAppId(sm_app_id); + requestInst.setPkgId(sm_pkg_id); + + Api::install(requestInst); + + InstallRequest requestInst2; + requestInst2.setAppId(sm_app_id); + requestInst2.setPkgId(sm_pkg_id_wrong); + + Api::install(requestInst2, SECURITY_MANAGER_ERROR_INPUT_PARAM); + + + /* Check records in the security-manager database */ + check_app_after_install(sm_app_id, sm_pkg_id); + + InstallRequest requestUninst; + requestUninst.setAppId(sm_app_id); + + Api::uninstall(requestUninst); + + + /* Check records in the security-manager database */ + check_app_after_uninstall(sm_app_id, sm_pkg_id, TestSecurityManagerDatabase::REMOVED); + +} + +RUNNER_TEST(security_manager_01c_app_uninstall_pkg_id_ignored) +{ + const char * const sm_app_id = "SM_TEST_01c_APPID"; + const char * const sm_pkg_id = "SM_TEST_01c_PKGID"; + const char * const sm_pkg_id_wrong = "SM_TEST_01c_PKGID_wrong"; + + InstallRequest requestInst; + requestInst.setAppId(sm_app_id); + requestInst.setPkgId(sm_pkg_id); + + Api::install(requestInst); + + /* Check records in the security-manager database */ + check_app_after_install(sm_app_id, sm_pkg_id); + + InstallRequest requestUninst; + requestUninst.setAppId(sm_app_id); + requestUninst.setPkgId(sm_pkg_id_wrong); + + Api::uninstall(requestUninst); + + check_app_after_uninstall(sm_app_id, sm_pkg_id, TestSecurityManagerDatabase::REMOVED); + +} + RUNNER_TEST(security_manager_02_app_install_uninstall_full) { const char *const sm_app_id = "sm_test_02_app_id_full"; @@ -411,8 +568,6 @@ RUNNER_CHILD_TEST_NOSMACK(security_manager_03_set_label_from_appid_nosmack) uninstall_app(app_id, pkg_id, true); } - - static void prepare_request(InstallRequest &request, const char *const app_id, const char *const pkg_id, @@ -428,26 +583,52 @@ static void prepare_request(InstallRequest &request, request.setUid(uid); } +static uid_t getGlobalUserId(void) +{ + return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); +} -static struct passwd* get_app_pw() +static const std::string appDirPath(const TemporaryTestUser &user) { - struct passwd *pw = nullptr; - errno = 0; - while(!(pw = getpwnam(APP_USER))) { - RUNNER_ASSERT_ERRNO_MSG(errno == EINTR, "getpwnam() failed"); - } - return pw; + struct tzplatform_context *tzCtxPtr = nullptr; + + RUNNER_ASSERT(0 == tzplatform_context_create(&tzCtxPtr)); + TzPlatformContextPtr tzCtxPtrSmart(tzCtxPtr); + + RUNNER_ASSERT_MSG(0 == tzplatform_context_set_user(tzCtxPtr, user.getUid()), + "Unable to set user <" << user.getUserName() << "> for tzplatform context"); + + const char *appDir = tzplatform_context_getenv(tzCtxPtr, + getGlobalUserId() == user.getUid() ? TZ_SYS_RW_APP : TZ_USER_APP); + RUNNER_ASSERT_MSG(nullptr != appDir, + "tzplatform_context_getenv failed" + << "for getting sys rw app of user <" << user.getUserName() << ">"); + + return appDir; } +static const std::string nonAppDirPath(const TemporaryTestUser &user) +{ + return TMP_DIR + "/" + user.getUserName(); +} + +static const std::string uidToStr(const uid_t uid) +{ + return std::to_string(static_cast(uid)); +} static void install_and_check(const char *const sm_app_id, const char *const sm_pkg_id, - const std::string &user, uid_t uid) + const TemporaryTestUser& user, + const std::string &appDir, + bool requestUid) { InstallRequest requestPublic; //install app for non-root user and try to register public path (should fail) - prepare_request(requestPublic, sm_app_id, sm_pkg_id, SECURITY_MANAGER_PATH_PUBLIC, SM_PRIVATE_PATH_FOR_USER, uid); + prepare_request(requestPublic, sm_app_id, sm_pkg_id, + SECURITY_MANAGER_PATH_PUBLIC, appDir.c_str(), + requestUid ? user.getUid() : 0); Api::install(requestPublic, SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED); @@ -455,7 +636,9 @@ static void install_and_check(const char *const sm_app_id, //install app for non-root user //should fail (users may only register folders inside their home) - prepare_request(requestPrivate, sm_app_id, sm_pkg_id, SECURITY_MANAGER_PATH_PRIVATE, SM_PRIVATE_PATH, uid); + prepare_request(requestPrivate, sm_app_id, sm_pkg_id, + SECURITY_MANAGER_PATH_PRIVATE, SM_PRIVATE_PATH, + requestUid ? user.getUid() : 0); Api::install(requestPrivate, SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED); @@ -463,14 +646,73 @@ static void install_and_check(const char *const sm_app_id, //install app for non-root user //should succeed - this time i register folder inside user's home dir - prepare_request(requestPrivateUser, sm_app_id, sm_pkg_id, SECURITY_MANAGER_PATH_PRIVATE, SM_PRIVATE_PATH_FOR_USER, uid); + prepare_request(requestPrivateUser, sm_app_id, sm_pkg_id, + SECURITY_MANAGER_PATH_PRIVATE, appDir.c_str(), + requestUid ? user.getUid() : 0); for (auto &privilege : SM_ALLOWED_PRIVILEGES) requestPrivateUser.addPrivilege(privilege.c_str()); Api::install(requestPrivateUser); - check_app_permissions(sm_app_id, sm_pkg_id, user.c_str(), SM_ALLOWED_PRIVILEGES, SM_DENIED_PRIVILEGES); + check_app_permissions(sm_app_id, sm_pkg_id, + uidToStr(user.getUid()).c_str(), + SM_ALLOWED_PRIVILEGES, SM_DENIED_PRIVILEGES); +} + +static void createTestDir(const std::string &dir) +{ + mode_t dirMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; + mode_t execFileMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; + mode_t normalFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; + + mkdirSafe(dir, dirMode); + creatSafe(dir + "/" + EXEC_FILE, execFileMode); + creatSafe(dir + "/" + NORMAL_FILE, normalFileMode); + symlinkSafe(dir + "/" + EXEC_FILE, dir + "/" + LINK_PREFIX + EXEC_FILE); + symlinkSafe(dir + "/" + NORMAL_FILE, dir + "/" + LINK_PREFIX + NORMAL_FILE); +} + +static void createInnerAppDir(const std::string &dir, const std::string &nonAppDir) +{ + createTestDir(dir); + + symlinkSafe(nonAppDir, dir + "/" + LINK_PREFIX + "non_app_dir"); + symlinkSafe(nonAppDir + "/" + EXEC_FILE, + dir + "/" + LINK_PREFIX + "non_app_" + EXEC_FILE); + symlinkSafe(nonAppDir + "/" + NORMAL_FILE, + dir + "/" + LINK_PREFIX + "non_app_" + NORMAL_FILE); +} + +static void generateAppDir(const TemporaryTestUser &user) +{ + const std::string dir = appDirPath(user); + const std::string nonAppDir = nonAppDirPath(user); + + createInnerAppDir(dir, nonAppDir); + createInnerAppDir(dir + "/.inner_dir", nonAppDir); + createInnerAppDir(dir + "/inner_dir", nonAppDir); +} + +static void generateNonAppDir(const TemporaryTestUser &user) +{ + const std::string dir = nonAppDirPath(user); + + createTestDir(dir); + createTestDir(dir + "/.inner_dir"); + createTestDir(dir + "/inner_dir"); +} + +static void createTestDirs(const TemporaryTestUser &user) +{ + generateAppDir(user); + generateNonAppDir(user); +} + +static void removeTestDirs(const TemporaryTestUser &user) +{ + removeDir(appDirPath(user)); + removeDir(nonAppDirPath(user)); } RUNNER_CHILD_TEST(security_manager_04a_app_install_uninstall_by_app_user_for_self) @@ -478,15 +720,21 @@ RUNNER_CHILD_TEST(security_manager_04a_app_install_uninstall_by_app_user_for_sel int result; const char *const sm_app_id = "sm_test_04a_app_id_uid"; const char *const sm_pkg_id = "sm_test_04a_pkg_id_uid"; + const std::string new_user_name = "sm_test_04a_user_name"; - struct passwd *pw = get_app_pw(); - const std::string user = std::to_string(static_cast(pw->pw_uid)); + TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false); + testUser.create(); + + removeTestDirs(testUser); + createTestDirs(testUser); + + const std::string userAppDirPath = appDirPath(testUser); //switch user to non-root - result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + result = drop_root_privileges(testUser.getUid(), testUser.getGid()); RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); - install_and_check(sm_app_id, sm_pkg_id, user, 0); + install_and_check(sm_app_id, sm_pkg_id, testUser, userAppDirPath, false); //uninstall app as non-root user InstallRequest request; @@ -494,7 +742,9 @@ RUNNER_CHILD_TEST(security_manager_04a_app_install_uninstall_by_app_user_for_sel Api::uninstall(request); - check_app_permissions(sm_app_id, sm_pkg_id, user.c_str(), SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); + check_app_permissions(sm_app_id, sm_pkg_id, + uidToStr(testUser.getUid()).c_str(), + SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); } RUNNER_CHILD_TEST(security_manager_04b_app_install_by_root_for_app_user) @@ -502,14 +752,18 @@ RUNNER_CHILD_TEST(security_manager_04b_app_install_by_root_for_app_user) int result; const char *const sm_app_id = "sm_test_04b_app_id_uid"; const char *const sm_pkg_id = "sm_test_04b_pkg_id_uid"; + const std::string new_user_name = "sm_test_04b_user_name"; + + TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false); + testUser.create(); - struct passwd *pw = get_app_pw(); - const std::string user = std::to_string(static_cast(pw->pw_uid)); + removeTestDirs(testUser); + createTestDirs(testUser); - install_and_check(sm_app_id, sm_pkg_id, user, pw->pw_uid); + install_and_check(sm_app_id, sm_pkg_id, testUser, appDirPath(testUser), true); //switch user to non-root - root may not uninstall apps for specified users - result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + result = drop_root_privileges(testUser.getUid(), testUser.getGid()); RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); //uninstall app as non-root user @@ -518,7 +772,9 @@ RUNNER_CHILD_TEST(security_manager_04b_app_install_by_root_for_app_user) Api::uninstall(request); - check_app_permissions(sm_app_id, sm_pkg_id, user.c_str(), SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); + check_app_permissions(sm_app_id, sm_pkg_id, + uidToStr(testUser.getUid()).c_str(), + SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); } @@ -543,6 +799,1267 @@ RUNNER_CHILD_TEST(security_manager_05_drop_process_capabilities) "capabilities not dropped. Current: " << cap_to_text(caps.get(), NULL)); } +RUNNER_CHILD_TEST(security_manager_06_install_app_offline) +{ + const char *const app_id = "sm_test_06_app_id_install_app_offline"; + const char *const pkg_id = "sm_test_06_pkg_id_install_app_offline"; + ServiceManager serviceManager("security-manager.service"); + + uninstall_app(app_id, pkg_id, true); + serviceManager.maskService(); + serviceManager.stopService(); + + install_app(app_id, pkg_id); + + serviceManager.unmaskService(); + serviceManager.startService(); + + uninstall_app(app_id, pkg_id, true); +} + +RUNNER_CHILD_TEST(security_manager_07_user_add_app_install) +{ + const char *const sm_app_id = "sm_test_07_app_id_user"; + const char *const sm_pkg_id = "sm_test_07_pkg_id_user"; + const std::string new_user_name = "sm_test_07_user_name"; + std::string uid_string; + TemporaryTestUser test_user(new_user_name, GUM_USERTYPE_NORMAL, false); + test_user.create(); + uid_string = std::to_string(static_cast(test_user.getUid())); + + install_app(sm_app_id, sm_pkg_id, test_user.getUid()); + + check_app_after_install(sm_app_id, sm_pkg_id); + + test_user.remove(); + + check_app_permissions(sm_app_id, sm_pkg_id, uid_string.c_str(), SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); + + check_app_after_uninstall(sm_app_id, sm_pkg_id, true); +} + +RUNNER_CHILD_TEST(security_manager_08_user_double_add_double_remove) +{ + UserRequest addUserRequest; + + const char *const sm_app_id = "sm_test_08_app_id_user"; + const char *const sm_pkg_id = "sm_test_08_pkg_id_user"; + const char *const new_user_name = "sm_test_08_user_name"; + std::string uid_string; + + // gumd user add + TemporaryTestUser test_user(new_user_name, GUM_USERTYPE_NORMAL, false); + test_user.create(); + uid_string = std::to_string(static_cast(test_user.getUid())); + + addUserRequest.setUid(test_user.getUid()); + addUserRequest.setUserType(SM_USER_TYPE_NORMAL); + + //sm user add + Api::addUser(addUserRequest); + + install_app(sm_app_id, sm_pkg_id, test_user.getUid()); + + check_app_after_install(sm_app_id, sm_pkg_id); + + test_user.remove(); + + UserRequest deleteUserRequest; + deleteUserRequest.setUid(test_user.getUid()); + + Api::deleteUser(deleteUserRequest); + + check_app_permissions(sm_app_id, sm_pkg_id, uid_string.c_str(), SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); + + check_app_after_uninstall(sm_app_id, sm_pkg_id, true); +} + +RUNNER_CHILD_TEST(security_manager_09_add_user_offline) +{ + const char *const app_id = "security_manager_09_add_user_offline_app"; + const char *const pkg_id = "security_manager_09_add_user_offline_pkg"; + const std::string username("sm_test_09_user_name"); + ServiceManager serviceManager("security-manager.service"); + serviceManager.maskService(); + serviceManager.stopService(); + + TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, true); + user.create(); + + install_app(app_id, pkg_id, user.getUid()); + + check_app_after_install(app_id, pkg_id); + + serviceManager.unmaskService(); + serviceManager.startService(); + + user.remove(); + + check_app_after_uninstall(app_id, pkg_id, true); +} + +RUNNER_TEST(security_manager_10_privacy_manager_fetch_whole_policy_for_self) +{ + //TEST DATA + const std::string username("sm_test_10_user_name"); + unsigned int privileges_count = 0; + + std::map>> users2AppsMap; + std::map> apps2PrivsMap; + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + apps2PrivsMap.insert(std::pair>( + MANY_APPS.at(i), std::set( + MANY_APPS_PRIVILEGES.at(i).begin(), + MANY_APPS_PRIVILEGES.at(i).end()))); + privileges_count+=MANY_APPS_PRIVILEGES.at(i).size(); + }; + + apps2PrivsMap.insert(std::pair>( + PRIVILEGE_MANAGER_APP, std::set{PRIVILEGE_MANAGER_SELF_PRIVILEGE})); + ++privileges_count; + users2AppsMap.insert(std::pair>>(username, apps2PrivsMap)); + //TEST DATA END + + sem_t *mutex; + errno = 0; + RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno); + pid_t pid = fork(); + + if (pid != 0) { //parent process + TemporaryTestUser tmpUser(username, GUM_USERTYPE_NORMAL, false); + tmpUser.create(); + + for(const auto &user : users2AppsMap) { + + for(const auto &app : user.second) { + InstallRequest requestInst; + requestInst.setAppId(app.first.c_str()); + try { + requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).c_str()); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first); + }; + requestInst.setUid(tmpUser.getUid()); + + for (const auto &privilege : app.second) { + requestInst.addPrivilege(privilege.c_str()); + }; + + Api::install(requestInst); + }; + + //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str()); + }; + //Start child process + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno); + + int status; + wait(&status); + + tmpUser.remove(); + }; + + if (pid == 0) { //child process + errno = 0; + RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child process failed, errno: " << errno); + //the above call, registers 1 new privilege for the given user, hence the incrementation of below variable + + struct passwd *pw = getUserStruct(username); + register_current_process_as_privilege_manager(pw->pw_uid); + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + std::vector policyEntries; + PolicyEntry filter; + Api::getPolicy(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty"); + RUNNER_ASSERT_MSG(policyEntries.size() == privileges_count, "Number of policies doesn't match - should be: " << privileges_count << " and is " << policyEntries.size()); + + for (const auto &policyEntry : policyEntries) { + std::string user = policyEntry.getUser(); + std::string app = policyEntry.getAppId(); + std::string privilege = policyEntry.getPrivilege(); + + try { + struct passwd *pw_current = getUserStruct(static_cast(std::stoul(user))); + std::set::iterator tmp = users2AppsMap.at(pw_current->pw_name).at(app).find(privilege); + if (tmp == users2AppsMap.at(pw_current->pw_name).at(app).end()) + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected privilege: " << policyEntry); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected user or app: " << policyEntry << ". Exception: " << e.what()); + } catch (const std::invalid_argument& e) { + RUNNER_FAIL_MSG("Incorrect UID: " << user << ". Exception: " << e.what()); + }; + }; + exit(0); + }; +} + +RUNNER_TEST(security_manager_11_privacy_manager_fetch_whole_policy_for_admin_unprivileged) +{ + //TEST DATA + const std::vector usernames = {"sm_test_11_user_name_1", "sm_test_11_user_name_2"}; + unsigned int privileges_count = 0; + + std::map>> users2AppsMap; + std::map> apps2PrivsMap; + + for (const auto &username : usernames) { + //Only entries for one of the users will be listed + privileges_count = 0; + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + apps2PrivsMap.insert(std::pair>( + MANY_APPS.at(i), std::set( + MANY_APPS_PRIVILEGES.at(i).begin(), + MANY_APPS_PRIVILEGES.at(i).end()))); + privileges_count+=MANY_APPS_PRIVILEGES.at(i).size(); + }; + + users2AppsMap.insert(std::pair>>(username, apps2PrivsMap)); + }; + + users2AppsMap.at(usernames.at(0)).insert(std::pair>( + PRIVILEGE_MANAGER_APP, std::set{PRIVILEGE_MANAGER_SELF_PRIVILEGE})); + + ++privileges_count; + //TEST DATA END + + sem_t *mutex; + errno = 0; + RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno); + pid_t pid = fork(); + + if (pid != 0) { //parent process + std::vector users = { + TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false), + TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false) + }; + + users.at(0).create(); + users.at(1).create(); + + //Install apps for both users + for(const auto &user : users) { + for(const auto &app : users2AppsMap.at(user.getUserName())) { + InstallRequest requestInst; + requestInst.setAppId(app.first.c_str()); + try { + requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).c_str()); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first); + }; + requestInst.setUid(user.getUid()); + + for (const auto &privilege : app.second) { + requestInst.addPrivilege(privilege.c_str()); + }; + + Api::install(requestInst); + }; + + //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str()); + }; + //Start child + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno); + + int status; + wait(&status); + + for(auto &user : users) { + user.remove(); + }; + }; + + if (pid == 0) { + errno = 0; + RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child failed, errno: " << errno); + struct passwd *pw = getUserStruct(usernames.at(0)); + register_current_process_as_privilege_manager(pw->pw_uid); + + //change uid to normal user + errno = 0; + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + std::vector policyEntries; + PolicyEntry filter; + + //this call should only return privileges belonging to the current uid + Api::getPolicy(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty"); + RUNNER_ASSERT_MSG(policyEntries.size() == privileges_count, "Number of policies doesn't match - should be: " << privileges_count << " and is " << policyEntries.size()); + + for (const auto &policyEntry : policyEntries) { + std::string user = policyEntry.getUser(); + std::string app = policyEntry.getAppId(); + std::string privilege = policyEntry.getPrivilege(); + + try { + struct passwd *pw_current = getUserStruct(static_cast(std::stoul(user))); + std::set::iterator tmp = users2AppsMap.at(pw_current->pw_name).at(app).find(privilege); + if (tmp == users2AppsMap.at(pw_current->pw_name).at(app).end()) + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected privilege: " << policyEntry); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected user or app: " << policyEntry << ". Exception: " << e.what()); + } catch (const std::invalid_argument& e) { + RUNNER_FAIL_MSG("Incorrect UID: " << user << ". Exception: " << e.what()); + }; + }; + exit(0); + }; +} + +RUNNER_TEST(security_manager_12_privacy_manager_fetch_whole_policy_for_admin_privileged) +{ + //TEST DATA + const std::vector usernames = {"sm_test_12_user_name_1", "sm_test_12_user_name_2"}; + unsigned int privileges_count = 0; + + std::map>> users2AppsMap; + std::map> apps2PrivsMap; + + for (const auto &username : usernames) { + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + apps2PrivsMap.insert(std::pair>( + MANY_APPS.at(i), std::set( + MANY_APPS_PRIVILEGES.at(i).begin(), + MANY_APPS_PRIVILEGES.at(i).end()))); + privileges_count+=MANY_APPS_PRIVILEGES.at(i).size(); + }; + + users2AppsMap.insert(std::pair>>(username, apps2PrivsMap)); + }; + + users2AppsMap.at(usernames.at(1)).insert(std::pair>( + PRIVILEGE_MANAGER_APP, std::set{PRIVILEGE_MANAGER_SELF_PRIVILEGE, PRIVILEGE_MANAGER_ADMIN_PRIVILEGE})); + + privileges_count += 2; + //TEST DATA END + + sem_t *mutex; + errno = 0; + RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno); + pid_t pid = fork(); + + if (pid != 0) { //parent process + std::vector users = { + TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false), + TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false) + }; + + users.at(0).create(); + users.at(1).create(); + //Install apps for both users + for(const auto &user : users) { + for(const auto &app : users2AppsMap.at(user.getUserName())) { + InstallRequest requestInst; + requestInst.setAppId(app.first.c_str()); + try { + requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).c_str()); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first); + }; + requestInst.setUid(user.getUid()); + + for (const auto &privilege : app.second) { + requestInst.addPrivilege(privilege.c_str()); + }; + + Api::install(requestInst); + }; + + //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str()); + }; + + //Start child + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno); + + //Wait for child to finish + int status; + wait(&status); + + for(auto &user : users) { + user.remove(); + }; + }; + + if (pid == 0) { //child process + errno = 0; + RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child failed, errno: " << errno); + + struct passwd *pw = getUserStruct(usernames.at(1)); + register_current_process_as_privilege_manager(pw->pw_uid, true); + + //change uid to normal user + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + std::vector policyEntries; + PolicyEntry filter; + //this call should succeed as the calling user is privileged + Api::getPolicy(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty"); + RUNNER_ASSERT_MSG(policyEntries.size() == privileges_count, "Number of policies doesn't match - should be: " << privileges_count << " and is " << policyEntries.size()); + + for (const auto &policyEntry : policyEntries) { + std::string user = policyEntry.getUser(); + std::string app = policyEntry.getAppId(); + std::string privilege = policyEntry.getPrivilege(); + + try { + struct passwd *pw_current = getUserStruct(static_cast(std::stoul(user))); + std::set::iterator tmp = users2AppsMap.at(pw_current->pw_name).at(app).find(privilege); + if (tmp == users2AppsMap.at(pw_current->pw_name).at(app).end()) + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected privilege: " << policyEntry); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Unexpected policy entry: unexpected user or app: " << policyEntry << ". Exception: " << e.what()); + } catch (const std::invalid_argument& e) { + RUNNER_FAIL_MSG("Incorrect UID: " << user << ". Exception: " << e.what()); + }; + }; + + exit(0); + }; +} + +RUNNER_TEST(security_manager_13_privacy_manager_fetch_policy_after_update_unprivileged) +{ + //TEST DATA + const std::vector usernames = {"sm_test_13_user_name_1", "sm_test_13_user_name_2"}; + + std::map>> users2AppsMap; + std::map> apps2PrivsMap; + + for (const auto &username : usernames) { + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + apps2PrivsMap.insert(std::pair>( + MANY_APPS.at(i), std::set( + MANY_APPS_PRIVILEGES.at(i).begin(), + MANY_APPS_PRIVILEGES.at(i).end()))); + }; + + users2AppsMap.insert(std::pair>>(username, apps2PrivsMap)); + }; + + users2AppsMap.at(usernames.at(1)).insert(std::pair>( + PRIVILEGE_MANAGER_APP, std::set{PRIVILEGE_MANAGER_SELF_PRIVILEGE})); + + //TEST DATA END + + pid_t pid[2]; + sem_t *mutex[2]; + errno = 0; + RUNNER_ASSERT_MSG(((mutex[0] = sem_open("mutex_1", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex #1, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(((mutex[1] = sem_open("mutex_2", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex #2, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex[0], 1, 0) == 0, "failed to setup mutex #1, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex[1], 1, 0) == 0, "failed to setup mutex #2, errno: " << errno); + std::vector policyEntries; + + pid[0] = fork(); + + if(pid[0] == 0) { //child #1 process + RUNNER_ASSERT_MSG(sem_wait(mutex[0]) == 0, "sem_wait in child #1 failed, errno: " << errno); + struct passwd *pw = getUserStruct(usernames.at(0)); + register_current_process_as_privilege_manager(pw->pw_uid); + + //change uid to normal user + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + PolicyEntry filter; + PolicyRequest policyRequest; + //this call should succeed as the calling user is privileged + Api::getPolicyForSelf(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty"); + + PolicyEntry policyEntry( + MANY_APPS[0], + std::to_string(pw->pw_uid), + "http://tizen.org/privilege/internet" + ); + policyEntry.setLevel("Deny"); + + policyRequest.addEntry(policyEntry); + policyEntry = PolicyEntry( + MANY_APPS[1], + std::to_string(pw->pw_uid), + "http://tizen.org/privilege/location" + ); + policyEntry.setLevel("Deny"); + + policyRequest.addEntry(policyEntry); + Api::sendPolicy(policyRequest); + Api::getPolicyForSelf(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() == 2, "Number of policies doesn't match - should be: 2 and is " << policyEntries.size()); + exit(0); + }; + + if (pid[0] != 0) {//parent process + pid[1] = fork(); + + if (pid[1] == 0) { //child #2 process + errno = 0; + RUNNER_ASSERT_MSG(sem_wait(mutex[1]) == 0, "sem_wait in child #2 failed, errno: " << errno); + struct passwd *pw_target = getUserStruct(usernames.at(0)); + struct passwd *pw = getUserStruct(usernames.at(1)); + register_current_process_as_privilege_manager(pw->pw_uid); + + //change uid to normal user + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + PolicyEntry filter = PolicyEntry( + SECURITY_MANAGER_ANY, + std::to_string(pw_target->pw_uid), + SECURITY_MANAGER_ANY + ); + + //U2 requests contents of U1 privacy manager - should fail + Api::getPolicyForSelf(filter, policyEntries); + RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty"); + + filter = PolicyEntry( + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY + ); + + policyEntries.clear(); + + //U2 requests contents of ADMIN bucket - should fail + Api::getPolicyForAdmin(filter, policyEntries, SECURITY_MANAGER_ERROR_ACCESS_DENIED); + RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty"); + exit(0); + }; + + if (pid[1] != 0) { //parent + + std::vector users = { + TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false), + TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false) + }; + + users.at(0).create(); + users.at(1).create(); + + //Install apps for both users + for(const auto &user : users2AppsMap) { + + for(const auto &app : user.second) { + InstallRequest requestInst; + requestInst.setAppId(app.first.c_str()); + try { + requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).c_str()); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first); + }; + requestInst.setUid(users.at(0).getUid()); + + for (const auto &privilege : app.second) { + requestInst.addPrivilege(privilege.c_str()); + }; + + Api::install(requestInst); + }; + + //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str()); + }; + + int status; + //Start child #1 + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex[0]) == 0, "Error while opening mutex #1, errno: " << errno); + + //Wait until child #1 finishes + pid_t ret = wait(&status); + RUNNER_ASSERT_MSG((ret != -1) && WIFEXITED(status), "Updating privileges failed"); + + //Start child #2 + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex[1]) == 0, "Error while opening mutex #2, errno: " << errno); + //Wait until child #2 finishes + ret = wait(&status); + RUNNER_ASSERT_MSG((ret =-1) && WIFEXITED(status), "Listing privileges failed"); + + for(auto &user : users) { + user.remove(); + }; + + sem_close(mutex[0]); + sem_close(mutex[1]); + }; + }; +} + +RUNNER_TEST(security_manager_14_privacy_manager_fetch_and_update_policy_for_admin) +{ + //TEST DATA + const std::vector usernames = {"sm_test_14_user_name_1", "sm_test_14_user_name_2"}; + unsigned int privileges_count = 0; + + std::map>> users2AppsMap; + std::map> apps2PrivsMap; + + for (const auto &username : usernames) { + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + apps2PrivsMap.insert(std::pair>( + MANY_APPS.at(i), std::set( + MANY_APPS_PRIVILEGES.at(i).begin(), + MANY_APPS_PRIVILEGES.at(i).end()))); + privileges_count+=MANY_APPS_PRIVILEGES.at(i).size(); + }; + + users2AppsMap.insert(std::pair>>(username, apps2PrivsMap)); + }; + + users2AppsMap.at(usernames.at(1)).insert(std::pair>( + PRIVILEGE_MANAGER_APP, std::set{PRIVILEGE_MANAGER_SELF_PRIVILEGE})); + + privileges_count += 2; + //TEST DATA END + sem_t *mutex; + errno = 0; + RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno); + errno = 0; + RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno); + + pid_t pid = fork(); + if (pid != 0) { + std::vector users = { + TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false), + TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false) + }; + + users.at(0).create(); + users.at(1).create(); + + //Install apps for both users + for(const auto &user : users) { + + for(const auto &app : users2AppsMap.at(user.getUserName())) { + InstallRequest requestInst; + requestInst.setAppId(app.first.c_str()); + try { + requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).c_str()); + } catch (const std::out_of_range &e) { + RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first); + }; + requestInst.setUid(user.getUid()); + + for (const auto &privilege : app.second) { + requestInst.addPrivilege(privilege.c_str()); + }; + + Api::install(requestInst); + }; + }; + //Start child process + errno = 0; + RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno); + int status; + //Wait for child process to finish + wait(&status); + + //switch back to root + for(auto &user : users) { + user.remove(); + }; + + sem_close(mutex); + } + + if (pid == 0) { //child process + errno = 0; + RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child process failed, errno: " << errno); + + struct passwd *pw = getUserStruct(usernames.at(0)); + register_current_process_as_privilege_manager(pw->pw_uid, true); + + //change uid to normal user + int result = drop_root_privileges(pw->pw_uid, pw->pw_gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + PolicyRequest *policyRequest = new PolicyRequest(); + PolicyEntry filter; + std::vector policyEntries; + //this call should succeed as the calling user is privileged + Api::getPolicyForSelf(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty"); + + PolicyEntry policyEntry( + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY, + "http://tizen.org/privilege/internet" + ); + policyEntry.setMaxLevel("Deny"); + + policyRequest->addEntry(policyEntry); + policyEntry = PolicyEntry( + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY, + "http://tizen.org/privilege/location" + ); + policyEntry.setMaxLevel("Deny"); + + policyRequest->addEntry(policyEntry); + Api::sendPolicy(*policyRequest); + Api::getPolicyForAdmin(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() == 2, "Number of policies doesn't match - should be: 2 and is " << policyEntries.size()); + + delete policyRequest; + policyRequest = new PolicyRequest(); + policyEntry = PolicyEntry( + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY, + "http://tizen.org/privilege/internet" + ); + policyEntry.setMaxLevel(SECURITY_MANAGER_DELETE); + policyRequest->addEntry(policyEntry); + + policyEntry = PolicyEntry( + SECURITY_MANAGER_ANY, + SECURITY_MANAGER_ANY, + "http://tizen.org/privilege/location" + ); + policyEntry.setMaxLevel(SECURITY_MANAGER_DELETE); + + policyRequest->addEntry(policyEntry); + Api::sendPolicy(*policyRequest); + + policyEntries.clear(); + Api::getPolicyForAdmin(filter, policyEntries); + RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Number of policies doesn't match - should be: 0 and is " << policyEntries.size()); + + delete policyRequest; + + exit(0); + }; + +} + +RUNNER_MULTIPROCESS_TEST(security_manager_15_privacy_manager_send_policy_update_for_admin) +{ + const char *const update_app_id = "security_manager_15_update_app_id"; + const char *const update_privilege = "http://tizen.org/privilege/led"; + const char *const check_start_bucket = "ADMIN"; + const std::string username("sm_test_15_username"); + PolicyRequest addPolicyRequest; + CynaraTestAdmin::Admin admin; + + std::string smackLabel; + generateAppLabel(update_app_id, smackLabel); + + struct message { + uid_t uid; + gid_t gid; + } msg; + + int pipefd[2]; + pid_t pid; + int result = 0; + + RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed"); + + TemporaryTestUser user(username, GUM_USERTYPE_ADMIN, false); + user.create(); + + pid = fork(); + RUNNER_ASSERT_MSG(pid >= 0, "fork failed"); + if (pid != 0)//parent process + { + FdUniquePtr pipeptr(pipefd+1); + close(pipefd[0]); + + register_current_process_as_privilege_manager(user.getUid(), true); + + //send info to child + msg.uid = user.getUid(); + msg.gid = user.getGid(); + + ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed"); + + //wait for child + RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed"); + + admin.adminCheck(check_start_bucket, false, smackLabel.c_str(), + std::to_string(static_cast(msg.uid)).c_str(), update_privilege, CYNARA_ADMIN_ALLOW, nullptr); + } + if(pid == 0) + { + FdUniquePtr pipeptr(pipefd); + close(pipefd[1]); + + ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed"); + + //become admin privacy manager manager + Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str()); + result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + PolicyEntry entry(update_app_id, std::to_string(static_cast(msg.uid)), update_privilege); + entry.setMaxLevel("Allow"); + + addPolicyRequest.addEntry(entry); + Api::sendPolicy(addPolicyRequest); + exit(0); + } +} + +RUNNER_MULTIPROCESS_TEST(security_manager_15_privacy_manager_send_policy_update_for_admin_wildcard) +{ + const char *const update_other_app_id = "security_manager_15_update_other_app_id"; + const char *const update_privilege = "http://tizen.org/privilege/led"; + const char *const check_start_bucket = "ADMIN"; + const std::string username("sm_test_15_username"); + PolicyRequest addPolicyRequest; + CynaraTestAdmin::Admin admin; + + std::string smackLabel; + generateAppLabel(update_other_app_id, smackLabel); + + struct message { + uid_t uid; + gid_t gid; + } msg; + + int pipefd[2]; + pid_t pid; + int result = 0; + + RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed"); + + TemporaryTestUser user(username, GUM_USERTYPE_ADMIN, false); + user.create(); + + pid = fork(); + RUNNER_ASSERT_MSG(pid >= 0, "fork failed"); + if (pid != 0)//parent process + { + FdUniquePtr pipeptr(pipefd+1); + close(pipefd[0]); + + register_current_process_as_privilege_manager(user.getUid(), true); + + //send info to child + msg.uid = user.getUid(); + msg.gid = user.getGid(); + + ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed"); + + //wait for child + RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed"); + + admin.adminCheck(check_start_bucket, false, smackLabel.c_str(), + std::to_string(static_cast(msg.uid)).c_str(), update_privilege, CYNARA_ADMIN_ALLOW, nullptr); + } + if(pid == 0) + { + FdUniquePtr pipeptr(pipefd); + close(pipefd[1]); + + ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed"); + + //become admin privacy manager manager + Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str()); + result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + // use wildcard as appId + PolicyEntry entry(SECURITY_MANAGER_ANY, std::to_string(static_cast(msg.uid)), update_privilege); + entry.setMaxLevel("Allow"); + + addPolicyRequest.addEntry(entry); + Api::sendPolicy(addPolicyRequest); + exit(0); + } +} + +RUNNER_MULTIPROCESS_TEST(security_manager_15_privacy_manager_send_policy_update_for_self) +{ + const char *const update_app_id = "security_manager_15_update_app_id"; + const char *const update_privilege = "http://tizen.org/privilege/led"; + const char *const check_start_bucket = ""; + const std::string username("sm_test_15_username"); + PolicyRequest addPolicyRequest; + CynaraTestAdmin::Admin admin; + + std::string smackLabel; + generateAppLabel(update_app_id, smackLabel); + + struct message { + uid_t uid; + gid_t gid; + } msg; + + int pipefd[2]; + pid_t pid; + int result = 0; + + RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed"); + + TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, false); + user.create(); + + pid = fork(); + RUNNER_ASSERT_MSG(pid >= 0, "fork failed"); + if (pid != 0)//parent process + { + FdUniquePtr pipeptr(pipefd+1); + close(pipefd[0]); + + register_current_process_as_privilege_manager(user.getUid(), false); + + //send info to child + msg.uid = user.getUid(); + msg.gid = user.getGid(); + + ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed"); + + //wait for child + RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed"); + + admin.adminCheck(check_start_bucket, false, smackLabel.c_str(), + std::to_string(static_cast(msg.uid)).c_str(), update_privilege, CYNARA_ADMIN_ALLOW, nullptr); + } + if(pid == 0) + { + FdUniquePtr pipeptr(pipefd); + close(pipefd[1]); + + ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed"); + + //become admin privacy manager manager + Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str()); + result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + PolicyEntry entry(update_app_id, std::to_string(static_cast(msg.uid)), update_privilege); + entry.setLevel("Allow"); + + addPolicyRequest.addEntry(entry); + Api::sendPolicy(addPolicyRequest); + exit(0); + } +} + +RUNNER_MULTIPROCESS_TEST(security_manager_16_policy_levels_get) +{ + const std::string username("sm_test_16_user_cynara_policy"); + CynaraTestAdmin::Admin admin; + int pipefd[2]; + pid_t pid; + int result = 0; + + struct message { + uid_t uid; + gid_t gid; + } msg; + + RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed"); + + TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, false); + user.create(); + + pid = fork(); + RUNNER_ASSERT_MSG(pid >= 0, "fork failed"); + if (pid != 0)//parent process + { + FdUniquePtr pipeptr(pipefd+1); + close(pipefd[0]); + + //send info to child + msg.uid = user.getUid(); + msg.gid = user.getGid(); + + ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed"); + + //wait for child + RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed"); + } + if(pid == 0) + { + int ret; + char** levels; + std::string allow_policy, deny_policy; + size_t count; + FdUniquePtr pipeptr(pipefd); + close(pipefd[1]); + + ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed"); + + //become admin privacy manager manager + result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + // without plugins there should only be 2 policies - Allow and Deny + ret = security_manager_policy_levels_get(&levels, &count); + + RUNNER_ASSERT_MSG((lib_retcode)ret == SECURITY_MANAGER_SUCCESS, + "Invlid return code: " << ret); + + RUNNER_ASSERT_MSG(count == 2, "Invalid number of policy levels. Should be 2, instead there is: " << static_cast(count)); + + deny_policy = std::string(levels[0]); + allow_policy = std::string(levels[count-1]); + + // first should always be Deny + RUNNER_ASSERT_MSG(deny_policy.compare("Deny") == 0, + "Invalid first policy level. Should be Deny, instead there is: " << levels[0]); + + // last should always be Allow + RUNNER_ASSERT_MSG(allow_policy.compare("Allow") == 0, + "Invalid last policy level. Should be Allow, instead there is: " << levels[count-1]); + + security_manager_policy_levels_free(levels, count); + exit(0); + } +} + +RUNNER_CHILD_TEST(security_manager_17_privacy_manager_delete_policy_for_self) +{ + const char *const update_app_id = "security_manager_17_update_app_id"; + const char *const update_privilege = "http://tizen.org/privilege/led"; + const char *const check_start_bucket = ""; + const std::string username("sm_test_17_username"); + PolicyRequest addPolicyRequest; + CynaraTestAdmin::Admin admin; + + std::string smackLabel; + generateAppLabel(update_app_id, smackLabel); + + struct message { + uid_t uid; + gid_t gid; + } msg; + + int pipefd[2]; + int pipefd2[2]; + pid_t pid; + int result = 0; + + RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed"); + RUNNER_ASSERT_MSG((pipe(pipefd2) != -1),"second pipe failed"); + + TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, false); + user.create(); + + pid = fork(); + RUNNER_ASSERT_MSG(pid >= 0, "fork failed"); + if (pid != 0)//parent process + { + FdUniquePtr pipeptr(pipefd+1); + close(pipefd[0]); + + register_current_process_as_privilege_manager(user.getUid(), false); + + //send info to child + msg.uid = user.getUid(); + msg.gid = user.getGid(); + + ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed"); + + //wait for child + RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed"); + + admin.adminCheck(check_start_bucket, false, smackLabel.c_str(), + std::to_string(static_cast(msg.uid)).c_str(), update_privilege, CYNARA_ADMIN_ALLOW, nullptr); + + pid = fork(); + if (pid != 0)//parent process + { + FdUniquePtr pipeptr(pipefd2+1); + close(pipefd2[0]); + + //send info to child + msg.uid = user.getUid(); + msg.gid = user.getGid(); + + ssize_t written = TEMP_FAILURE_RETRY(write(pipefd2[1], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed"); + + //wait for child + RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed"); + + //wait for child + waitpid(-1, &result, 0); + + admin.adminCheck(check_start_bucket, false, smackLabel.c_str(), + std::to_string(static_cast(msg.uid)).c_str(), update_privilege, CYNARA_ADMIN_DENY, nullptr); + } + if(pid == 0) + { + FdUniquePtr pipeptr(pipefd2); + close(pipefd2[1]); + + ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd2[0], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed"); + + //become admin privacy manager manager + Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str()); + result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + // delete this entry + PolicyRequest deletePolicyRequest; + PolicyEntry deleteEntry(update_app_id, std::to_string(static_cast(msg.uid)), update_privilege); + deleteEntry.setLevel(SECURITY_MANAGER_DELETE); + + deletePolicyRequest.addEntry(deleteEntry); + Api::sendPolicy(deletePolicyRequest); + exit(0); + } + } + if(pid == 0) + { + FdUniquePtr pipeptr(pipefd); + close(pipefd[1]); + + ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed"); + + //become admin privacy manager manager + Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str()); + result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + PolicyEntry entry(update_app_id, std::to_string(static_cast(msg.uid)), update_privilege); + entry.setLevel("Allow"); + + addPolicyRequest.addEntry(entry); + Api::sendPolicy(addPolicyRequest); + exit(0); + } +} + +RUNNER_CHILD_TEST(security_manager_17_privacy_manager_fetch_whole_policy_for_self_filtered) +{ + const std::string username("sm_test_17_user_name"); + + struct message { + uid_t uid; + gid_t gid; + unsigned int privileges_count; + } msg; + + int pipefd[2]; + pid_t pid; + int result = 0; + + RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed"); + + pid = fork(); + RUNNER_ASSERT_MSG(pid >= 0, "fork failed"); + if (pid != 0)//parent process + { + FdUniquePtr pipeptr(pipefd+1); + close(pipefd[0]); + + TemporaryTestUser user(username, static_cast(GUM_USERTYPE_NORMAL), false); + user.create(); + + unsigned int privileges_count = 0; + + register_current_process_as_privilege_manager(user.getUid(), false); + //the above call, registers 1 new privilege for the given user, hence the incrementation of below variable + ++privileges_count; + + for(unsigned int i = 0; i < MANY_APPS.size(); ++i) { + InstallRequest requestInst; + requestInst.setAppId(MANY_APPS[i].c_str()); + requestInst.setPkgId(MANY_APPS_PKGS.at(MANY_APPS[i]).c_str()); + requestInst.setUid(user.getUid()); + + for (auto &priv : MANY_APPS_PRIVILEGES.at(i)) { + requestInst.addPrivilege(priv.c_str()); + }; + + Api::install(requestInst); + privileges_count += MANY_APPS_PRIVILEGES.at(i).size(); + }; + + //send info to child + msg.uid = user.getUid(); + msg.gid = user.getGid(); + msg.privileges_count = privileges_count; + + ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed"); + + //wait for child + RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed"); + } + if(pid == 0) + { + FdUniquePtr pipeptr(pipefd); + close(pipefd[1]); + + ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message))); + RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed"); + + //become admin privacy manager manager + Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str()); + result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + // filter by privilege + std::vector policyEntries; + PolicyEntry filter(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, "http://tizen.org/privilege/internet"); + Api::getPolicy(filter, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty"); + RUNNER_ASSERT_MSG(policyEntries.size() == 2, "Number of policies doesn't match - should be: 2 and is " << policyEntries.size()); + + // filter by other privilege + policyEntries.clear(); + PolicyEntry filter2(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, "http://tizen.org/privilege/email"); + Api::getPolicy(filter2, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty"); + RUNNER_ASSERT_MSG(policyEntries.size() == 3, "Number of policies doesn't match - should be: 3 and is " << policyEntries.size()); + + // filter by appId + policyEntries.clear(); + PolicyEntry filter3(MANY_APPS[4].c_str(), SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY); + Api::getPolicy(filter3, policyEntries); + + RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty"); + RUNNER_ASSERT_MSG(policyEntries.size() == 4, "Number of policies doesn't match - should be: 4 and is " << policyEntries.size()); + } +} + int main(int argc, char *argv[]) { return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);