Same as RUNNER_TEST_CHILD but run only with smack disabled.
RUNNER_MULTIPROCESS_TEST_SMACK
Same as RUNNER_TEST_MULTIPROCESS but run only with smack enabled.
- RUNNER_MULTIPROCESS_TEST_NOSMACK
- Same as RUNNER_TEST_MULTIPROCESS but run only with smack disabled.
--Assert macros----------------------------------------------------------------
Used within test registering macros.
BuildRequires: libcynara-creds-gdbus-devel
BuildRequires: libcynara-creds-sd-bus-devel
BuildRequires: pkgconfig(libtzplatform-config)
-BuildRequires: boost-devel
+BuildRequires: pkgconfig(boost)
BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(libgum) >= 1.0.5
BuildRequires: pkgconfig(security-privilege-manager)
%global ckm_test_dir %{?TZ_SYS_SHARE:%TZ_SYS_SHARE/ckm-test/}%{!?TZ_SYS_SHARE:/usr/share/ckm-test/}
%global ckm_rw_data_dir %{?TZ_SYS_DATA:%TZ_SYS_DATA/ckm/}%{!?TZ_SYS_DATA:/opt/data/ckm/}
%global tz_backend_enabled %{?tz_backend:%tz_backend}%{!?tz_backend:OFF}
+%global sm_test_dir %{?TZ_SYS_SHARE:%TZ_SYS_SHARE/security-manager-test}%{!?TZ_SYS_SHARE:/usr/share/security-manager-test}
%description
Security tests repository - for tests that can't be kept together with code.
-DCKM_TEST_DIR=%{ckm_test_dir} \
-DCKM_RW_DATA_DIR=%{ckm_rw_data_dir} \
-DGLOBAL_APP_DIR=%{TZ_SYS_RW_APP} \
- -DLOCAL_APP_DIR="%{TZ_SYS_HOME}/security_test_user/apps_rw"
+ -DLOCAL_APP_DIR="%{TZ_SYS_HOME}/security_test_user/apps_rw" \
+ -DSM_TEST_DIR="%{sm_test_dir}"
make %{?jobs:-j%jobs}
%pre
%{_prefix}/share/yaca-test
%dir %{_prefix}/share/security-tests-cleanup-test
%{_prefix}/share/security-tests-cleanup-test/*
+%{sm_test_dir}
%postun
id -u security_test_user 1>/dev/null 2>&1 && gum-utils -o -d --uid=`id -u security_test_user`
/*
- * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000-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.
}
void check_alias_info_list_helper(const CKM::AliasPwdVector& expected, const CKM::AliasPwdVector& actual,
- const std::string userSmackLabel)
+ const std::string &userSmackLabel)
{
std::string errorLogMsg;
std::unordered_map<std::string, bool> aliasPwdMap;
}
}
-void check_alias_info_list(const CKM::AliasPwdVector& expected, const std::string& userSmackLabel)
+void check_alias_info_list(const CKM::AliasPwdVector& expected)
{
ckmc_alias_info_list_s *aliasInfoList = NULL;
int ret = ckmc_get_data_alias_info_list(&aliasInfoList);
it++;
}
ckmc_alias_info_list_all_free(aliasInfoList);
- check_alias_info_list_helper(expected, actual, userSmackLabel);
+ check_alias_info_list_helper(expected, actual);
}
size_t count_aliases(alias_type_ type, size_t minimum_initial_element_count)
/*
- * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000-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.
ckmc_raw_buffer_s prepare_message_buffer(const char * input);
void check_alias_list(const CKM::AliasVector& expected);
void check_alias_info_list_helper(const CKM::AliasPwdVector& expected, const CKM::AliasPwdVector& actual,
- const std::string userSmackLabel = "");
-void check_alias_info_list(const CKM::AliasPwdVector& expected,
- const std::string& userSmackLabel = "");
+ const std::string &userSmackLabel = {});
+void check_alias_info_list(const CKM::AliasPwdVector& expected);
typedef enum {
ALIAS_KEY,
/*
- * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact: Bumjin Im <bj.im@samsung.com>
+ * 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.
{
public:
MyObserver() :
- m_finished(false), m_error(0)
+ m_finished(false), m_error(0), m_ocspStatus(0)
{
}
m_cv.notify_one();
}
- void ReceivedSaveKey() { Succeeded(); }
- void ReceivedSaveCertificate() { Succeeded(); }
- void ReceivedSaveData() { Succeeded(); }
- void ReceivedSavePKCS12() { Succeeded(); }
-
- void ReceivedRemovedAlias() { Succeeded(); }
-
- void ReceivedKey(Key &&) { Succeeded(); }
- void ReceivedCertificate(Certificate &&) { Succeeded(); }
- void ReceivedData(RawBuffer &&) { Succeeded(); }
- void ReceivedPKCS12(PKCS12ShPtr && pkcs) { m_pkcs = pkcs; Succeeded(); }
-
- void ReceivedKeyAliasVector(AliasVector && av) { m_aliases = move(av); Succeeded(); }
- void ReceivedCertificateAliasVector(AliasVector && av) { m_aliases = move(av); Succeeded(); }
- void ReceivedDataAliasVector(AliasVector && av) { m_aliases = move(av); Succeeded(); }
+ void ReceivedSaveKey()
+ {
+ Succeeded();
+ }
+ void ReceivedSaveCertificate()
+ {
+ Succeeded();
+ }
+ void ReceivedSaveData()
+ {
+ Succeeded();
+ }
+ void ReceivedSavePKCS12()
+ {
+ Succeeded();
+ }
+ void ReceivedRemovedAlias()
+ {
+ Succeeded();
+ }
+ void ReceivedKey(Key && key)
+ {
+ m_data = move(key.getDER());
+ Succeeded();
+ }
+ void ReceivedCertificate(Certificate && cert)
+ {
+ m_data = move(cert.getDER());
+ Succeeded();
+ }
+ void ReceivedData(RawBuffer && data)
+ {
+ m_data = move(data);
+ Succeeded();
+ }
+ void ReceivedPKCS12(PKCS12ShPtr && pkcs)
+ {
+ m_pkcs = move(pkcs);
+ Succeeded();
+ }
+ void ReceivedKeyAliasVector(AliasVector && av)
+ {
+ m_aliases = move(av);
+ Succeeded();
+ }
+ void ReceivedCertificateAliasVector(AliasVector && av)
+ {
+ m_aliases = move(av);
+ Succeeded();
+ }
+ void ReceivedDataAliasVector(AliasVector && av)
+ {
+ m_aliases = move(av);
+ Succeeded();
+ }
+ void ReceivedCreateKeyAES()
+ {
+ Succeeded();
+ }
+ void ReceivedCreateKeyPair()
+ {
+ Succeeded();
+ }
+ void ReceivedGetCertificateChain(CertificateShPtrVector && chain)
+ {
+ m_certChain = move(chain);
+ Succeeded();
+ }
+ void ReceivedCreateSignature(RawBuffer && buffer)
+ {
+ m_signed = move(buffer);
+ Succeeded();
+ }
+ void ReceivedVerifySignature()
+ {
+ Succeeded();
+ }
+ void ReceivedOCSPCheck(int status)
+ {
+ m_ocspStatus = status;
+ Succeeded();
+ }
+ void ReceivedSetPermission()
+ {
+ Succeeded();
+ }
- void ReceivedCreateKeyAES() { Succeeded(); }
- void ReceivedCreateKeyPair() { Succeeded(); }
+ void WaitForResponse()
+ {
+ unique_lock < mutex > lock(m_mutex);
- void ReceivedGetCertificateChain(CertificateShPtrVector && chain)
- { m_certChain = move(chain); Succeeded(); }
+ m_cv.wait(lock, [this] {return m_finished;});
- void ReceivedCreateSignature(RawBuffer && buffer) { m_signed = move(buffer); Succeeded(); }
- void ReceivedVerifySignature() { Succeeded(); }
+ RUNNER_ASSERT_MSG(m_finished, "Request is not finished!");
+ m_finished = false;
+ }
- void ReceivedOCSPCheck(int status) { m_ocspStatus = status; Succeeded(); }
+ void WaitForSuccess()
+ {
+ WaitForResponse();
- void ReceivedSetPermission() { Succeeded(); }
+ RUNNER_ASSERT_MSG(m_error == 0,
+ "Request failed " << m_error << "/" << APICodeToString(m_error));
+ }
- void WaitForResponse()
+ void WaitFor(int expected)
{
- unique_lock < mutex > lock(m_mutex);
+ WaitForResponse();
- m_cv.wait(lock, [this] {return m_finished;});
+ RUNNER_ASSERT_MSG(m_error == expected,
+ "Expected " << expected << "/" << APICodeToString(expected) <<
+ " got: " << m_error << "/" << APICodeToString(m_error));
}
bool m_finished;
PKCS12ShPtr m_pkcs;
RawBuffer m_signed;
int m_ocspStatus;
+ RawBuffer m_data;
protected:
void Succeeded()
ManagerAsync mgr;
(mgr.*func)(static_pointer_cast < ManagerAsync::Observer > (obs), args...);
- obs->WaitForResponse();
-
- RUNNER_ASSERT_MSG(obs->m_finished, "Request is not finished!");
- RUNNER_ASSERT_MSG(
- obs->m_error == expected,
- "Expected " << expected << "/" << APICodeToString(expected) <<
- " got: " << obs->m_error << "/" << APICodeToString(obs->m_error));
+ obs->WaitFor(expected);
}
template <typename F, typename... Args>
ManagerAsync mgr;
(mgr.*func)(static_pointer_cast < ManagerAsync::Observer > (obs), args...);
- obs->WaitForResponse();
-
- RUNNER_ASSERT_MSG(obs->m_finished, "Request is not finished!");
- RUNNER_ASSERT_MSG(obs->m_error == 0,
- "Request failed " << obs->m_error << "/" << APICodeToString(obs->m_error));
+ obs->WaitForSuccess();
return obs;
}
RUNNER_TEST(TA0650_get_key_positive, UserEnv)
{
- test_positive(&ManagerAsync::saveKey, "alias_RSA", keys[RSA][0].prv, Policy("password"));
- test_positive(&ManagerAsync::getKey, "alias_RSA", "password");
- test_positive(&ManagerAsync::saveKey, "alias_DSA", keys[DSA][0].prv, Policy("password"));
- test_positive(&ManagerAsync::getKey, "alias_DSA", "password");
- test_positive(&ManagerAsync::saveKey, "alias_AES", keys[AES][0].prv, Policy("password"));
- test_positive(&ManagerAsync::getKey, "alias_AES", "password");
+ MyObserverPtr obs = make_shared<MyObserver>();
+ ManagerAsync mgr;
+
+ auto saveGetKey = [&](const string& alias, const KeyShPtr& key){
+ static constexpr char PASS[] = "password";
+ mgr.saveKey(obs, alias, key, Policy(PASS));
+ obs->WaitForSuccess();
+ mgr.getKey(obs, alias, PASS);
+ obs->WaitForSuccess();
+ RUNNER_ASSERT_MSG(obs->m_data == key->getDER(), "Received key does not match");
+ };
+
+ saveGetKey("alias_RSA_prv", keys[RSA][0].prv);
+ saveGetKey("alias_RSA_pub", keys[RSA][0].pub);
+ saveGetKey("alias_DSA_prv", keys[DSA][0].prv);
+ saveGetKey("alias_DSA_pub", keys[DSA][0].pub);
+ saveGetKey("alias_ECDSA_prv", keys[ECDSA][0].prv);
+ saveGetKey("alias_ECDSA_pub", keys[ECDSA][0].pub);
+ saveGetKey("alias_AES", keys[AES][0].prv);
}
RUNNER_TEST(TA0750_get_cert_positive, UserEnv)
{
- test_positive(&ManagerAsync::saveCertificate, "alias", getTestCertificate(OCSP_AVAILABLE_LEAF), Policy("password"));
- test_positive(&ManagerAsync::getCertificate, "alias", "password");
+ MyObserverPtr obs = make_shared<MyObserver>();
+ ManagerAsync mgr;
+
+ static constexpr char PASS[] = "password";
+ static constexpr char ALIAS[] = "alias";
+
+ const auto cert = getTestCertificate(OCSP_AVAILABLE_LEAF);
+
+ mgr.saveCertificate(obs, ALIAS, cert, Policy(PASS));
+ obs->WaitForSuccess();
+ mgr.getCertificate(obs, ALIAS, PASS);
+ obs->WaitForSuccess();
+ RUNNER_ASSERT_MSG(obs->m_data == cert->getDER(), "Received cert does not match");
}
RUNNER_TEST(TA0850_get_data_positive, UserEnv)
{
- test_positive(&ManagerAsync::saveData, "alias", test_buffer, Policy("password"));
- test_positive(&ManagerAsync::getData, "alias", "password");
+ MyObserverPtr obs = make_shared<MyObserver>();
+ ManagerAsync mgr;
+
+ static constexpr char PASS[] = "password";
+ static constexpr char ALIAS[] = "alias";
+
+ mgr.saveData(obs, ALIAS, test_buffer, Policy(PASS));
+ obs->WaitForSuccess();
+ mgr.getData(obs, ALIAS, PASS);
+ obs->WaitForSuccess();
+ RUNNER_ASSERT_MSG(obs->m_data == test_buffer, "Received data does not match");
}
/*
- * Copyright (c) 2014-2018 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.
PRIVACY,
};
+ Privilege(const char* systemPrivilege, Type type = UNSET, std::string license = std::string())
+ : m_name(systemPrivilege)
+ , m_type(type)
+ , m_license(std::move(license))
+ {}
+
Privilege(std::string systemPrivilege, Type type = UNSET, std::string license = std::string())
: m_name(std::move(systemPrivilege))
, m_type(type)
operator std::string() const { return m_name; }
+ bool operator==(const std::string& other) const { return m_name == other; }
+
private:
std::string m_name;
Type m_type;
/*
- * Copyright (c) 2014-2019 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.
return getPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::FILE, i, type);
}
-std::string AppInstallHelper::getAppId() const {
- return m_appName + "_app_id";
+const std::string& AppInstallHelper::getAppId() const {
+ return m_appName;
}
-std::string AppInstallHelper::getPkgId() const {
- return m_pkgName + "_pkg_id";
+const std::string& AppInstallHelper::getPkgId() const {
+ return m_pkgName;
}
void AppInstallHelper::setVersion(const std::string &version) {
return m_version;
}
+void AppInstallHelper::setUidGid(int uidGid) {
+ m_uidGid = uidGid;
+}
+
int AppInstallHelper::getUID() const {
return m_uidGid;
}
return m_isHybrid;
}
-void AppInstallHelper::addPrivileges(const std::vector<std::string> &privileges) {
- for (auto &p : privileges) {
- addPrivilege(Privilege(p));
- }
-}
-
-std::vector<std::string> AppInstallHelper::getPrivilegesNames() const {
- std::vector<std::string> privileges;
- for (auto &p : m_privileges) {
- privileges.push_back(p.getName());
- }
- return privileges;
-}
-
void AppInstallHelper::addPrivilege(Privilege privilege) {
m_privileges.push_back(std::move(privilege));
}
app_install_type AppInstallHelper::getInstallType() const {
return m_installType;
}
-
/*
- * Copyright (c) 2014-2019 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.
bool isLocal,
uid_t uid,
std::string version = std::string())
- : m_appName(appNamePrefix), m_pkgName(pkgNamePrefix), m_isLocal(isLocal), m_uidGid(uid), m_version(version),
+ : m_appName(appNamePrefix + "_app_id"), m_pkgName(pkgNamePrefix + "_pkg_id"), m_isLocal(isLocal), m_uidGid(uid), m_version(version),
m_installType(SM_APP_INSTALL_NONE), m_isHybrid(false), m_creatorPid(getpid())
{}
AppInstallHelper(AppInstallHelper &&other);
// App info getters and setters
- std::string getAppId() const;
- std::string getPkgId() const;
+ const std::string& getAppId() const;
+ const std::string& getPkgId() const;
+ void setUidGid(int uidGid);
int getUID() const;
int getGID() const;
void setVersion(const std::string &version);
const TypePathsMap& getFilesMap() const;
// Privileges
- std::vector<std::string> getPrivilegesNames() const; // deprecated
- void addPrivileges(const std::vector<std::string> &privileges); // deprecated
void addPrivilege(Privilege privilege);
void addPrivileges(const PrivilegeVector &privileges);
const PrivilegeVector& getPrivileges() const;
RootType rType = RootType::BASE);
void createInstallDir(RootType type);
- std::string m_appName;
- std::string m_pkgName;
+ const std::string m_appName;
+ const std::string m_pkgName;
bool m_isLocal;
int m_uidGid;
std::string m_version;
/*
- * 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.
class ScopedInstaller {
public:
- ScopedInstaller(const AppInstallHelper &app, bool requestUid = true)
+ ScopedInstaller(const AppInstallHelper &app,
+ bool requestUid = true,
+ lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS)
: m_appIds({app.getAppId()}),
m_uid(app.getUID()),
m_installType(app.getInstallType()),
- m_shouldUninstall(true),
+ m_shouldUninstall(expectedResult == SECURITY_MANAGER_SUCCESS),
m_requestUid(requestUid),
m_creatorPid(getpid())
{
for (const auto &priv : app.getAppDefinedPrivileges())
instReq.addAppDefinedPrivilege(priv);
- SecurityManagerTest::Api::install(instReq);
+ SecurityManagerTest::Api::install(instReq, expectedResult);
}
ScopedInstaller(const std::vector<std::string> &appIds, const std::string &pkgId)
/*
- * Copyright (c) 2013-2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2013-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.
DBus::MessageOut ServiceManager::newMethodCall(const std::string &method)
{
- return DBus::MessageOut(SYSTEMD_DESTINATION.c_str(),
- SYSTEMD_PATH.c_str(),
- SYSTEMD_MANAGER_INTERFACE.c_str(),
- method.c_str());
+ return DBus::MessageOut(SYSTEMD_DESTINATION,
+ SYSTEMD_PATH,
+ SYSTEMD_MANAGER_INTERFACE,
+ method);
}
std::string ServiceManager::handleObjectPathMsgReply(DBus::MessageIn &messageIn)
/*
- * Copyright (c) 2014-2019 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.
void install(const InstallRequest &request, lib_retcode expectedResult)
{
- uid_t uid = getuid();
- std::string dbPath = uid == 0 ? "/opt/dbspace/" : "/opt/dbspace/user/" + std::to_string(uid) + "/";
-
- std::ostringstream command;
- command << "/usr/bin/sqlite3 "
- << dbPath << ".pkgmgr_parser.db "
- << " \"insert into package_info (package, package_type, package_api_version,"
- << " install_location, mainapp_id, root_path, installed_storage)"
- << " values ('" << request.getPkgId() << "', 'tpk', '" << request.getAppTizenVersion()
- << "', 'auto', '" << request.getPkgId() << "', '/opt/usr/globallapps/"
- << request.getPkgId() << "', 'installed_internal')\"";
- int result = system(command.str().c_str());
- RUNNER_ASSERT_MSG(result == 0, "failed to set package_info: " << result);
-
- result = security_manager_app_install(request.get());
+ int result = security_manager_app_install(request.get());
+
RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
"installing app returned wrong value."
- << " InstallRequest: [ " << request << "];"
- << " Result: " << result << ";"
- << " Expected result: " << expectedResult);
-
- command = std::ostringstream();
- command << "/usr/bin/sqlite3 "
- << dbPath << ".pkgmgr_parser.db "
- << " \"delete from package_info where package='" << request.getPkgId() << "'\"";
- result = system(command.str().c_str());
- RUNNER_ASSERT_MSG(result == 0, "failed to unset package_info: " << result);
+ << " InstallRequest: [ " << request << "];"
+ << " Result: " << result << ";"
+ << " Expected result: " << expectedResult);
}
void update(const InstallRequest &request, lib_retcode expectedResult)
namespace SecurityManagerTest {
+constexpr char PolicyEntry::LEVEL_ALLOW[];
+constexpr char PolicyEntry::LEVEL_DENY[];
+constexpr char PolicyEntry::LEVEL_ASK_USER[];
+
PolicyEntry::PolicyEntry()
: m_appId(true, std::string(SECURITY_MANAGER_ANY))
, m_user(true, std::string(SECURITY_MANAGER_ANY))
class PolicyEntry
{
public:
+ static constexpr char LEVEL_ALLOW[] = "Allow";
+ static constexpr char LEVEL_DENY[] = "Deny";
+ static constexpr char LEVEL_ASK_USER[] = "Ask user";
+
PolicyEntry();
PolicyEntry(const std::string &appId,
/*
- * Copyright (c) 2014-2019 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.
RUNNER_ASSERT_MSG((lib_retcode)result == SECURITY_MANAGER_SUCCESS,
"creation of new request failed. Result: " << result);
RUNNER_ASSERT_MSG(m_req != nullptr, "creation of new request did not allocate memory");
+ // platform level has the widest possible privilege spectrum available, hence using it for all apps
+ result = security_manager_app_inst_req_set_pkg_privilege_level(m_req, SM_PKG_PRIVILEGE_LEVEL_PLATFORM);
+ RUNNER_ASSERT_MSG((lib_retcode)result == SECURITY_MANAGER_SUCCESS,
+ "setting privilege level failed. Result: " << result);
+ // core seems to map to TPK, which is what we're mimicking
+ result = security_manager_app_inst_req_set_pkg_type(m_req, SM_PKG_TYPE_CORE);
+ RUNNER_ASSERT_MSG((lib_retcode)result == SECURITY_MANAGER_SUCCESS,
+ "setting package type. Result: " << result);
}
InstallRequest::~InstallRequest()
/*
- * Copyright (c) 2013 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2013-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 "tests_common.h"
-#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
-#include <grp.h>
#include <errno.h>
-#include <vector>
-#include <algorithm>
bool smack_check(void)
{
return 1;
}
-/*
- * Add a new group to the current process groups.
- */
-void add_process_group(const char* group_name)
-{
- // get group ID by group name
- group *gr = getgrnam(group_name);
- RUNNER_ASSERT_ERRNO_MSG(gr != nullptr, "getgrnam failed on '" << group_name << "' group");
- const gid_t new_group_id = gr->gr_gid;
-
- // get number of groups that the current process belongs to
- int ngroups = getgroups(0, nullptr);
-
- //allocate groups table + space for new group entry
- std::vector<gid_t> groups(ngroups + 1);
- getgroups(ngroups, groups.data());
-
- // check if the process already belongs to the group
- if (std::find(groups.begin(), groups.end(), new_group_id) != groups.end()) return;
-
- // add new group & apply change
- groups[ngroups] = new_group_id;
- int ret = setgroups(groups.size(), groups.data());
- RUNNER_ASSERT_ERRNO_MSG(ret == 0, "setgroups() failed");
-}
-
-/*
- * Remove specific group from the current process groups.
- */
-void remove_process_group(const char* group_name)
-{
- // get group ID by group name
- group *gr = getgrnam(group_name);
- RUNNER_ASSERT_ERRNO_MSG(gr != nullptr, "getgrnam failed on '" << group_name << "' group");
- const gid_t new_group_id = gr->gr_gid;
-
- int ngroups = getgroups(0, nullptr);
- std::vector<gid_t> groups(ngroups);
- getgroups(ngroups, groups.data());
-
- // remove group from the list
- groups.erase(std::remove(groups.begin(), groups.end(), new_group_id), groups.end());
-
- if (groups.size() != (size_t)ngroups) {
- // apply change
- int ret = setgroups(groups.size(), groups.data());
- RUNNER_ASSERT_ERRNO_MSG(ret == 0, "setgroups() failed");
- }
-}
-
std::string formatCstr(const char *cstr)
{
if (!cstr)
return result;
}
-void mkdirSafe(const std::string &path, mode_t mode)
+static void mkdirSafe(const std::string &path, mode_t mode)
{
RUNNER_ASSERT_ERRNO_MSG(0 == mkdir(path.c_str(), mode) || errno == EEXIST,
"mkdir for <" << path << "> with mode <" << mode << "> failed");
mkdirSafe(path, mode);
}
-void creatSafe(const std::string &path, mode_t mode)
-{
- RUNNER_ASSERT_ERRNO_MSG(-1 != creat(path.c_str(), mode),
- "creat for <" << path << "> with mode <" << mode << "> failed");
-}
-
-void symlinkSafe(const std::string &targetPath, const std::string &linkPath)
-{
- RUNNER_ASSERT_ERRNO_MSG(0 == symlink(targetPath.c_str(), linkPath.c_str()),
- "symlink for <" << linkPath << "> to <" << targetPath << "> failed");
-}
-
-void removeDir(const std::string &path)
-{
- DIR *d = opendir(path.c_str());
-
- if (nullptr == d) {
- RUNNER_ASSERT_ERRNO_MSG(errno == ENOENT, "opendir of <" << path << "> failed");
- return;
- }
-
- struct dirent *dirEntry;
- while (nullptr != (dirEntry = readdir(d))) {
- std::string entryName(dirEntry->d_name);
- if (entryName == "." || entryName == "..")
- continue;
-
- std::string entryPath(path + "/" + entryName);
- struct stat st;
-
- RUNNER_ASSERT_ERRNO_MSG(0 == lstat(entryPath.c_str(), &st),
- "stat for <" << entryPath << "> failed");
- if (S_ISDIR(st.st_mode))
- removeDir(entryPath);
- else
- RUNNER_ASSERT_ERRNO_MSG(0 == unlink(entryPath.c_str()),
- "unlink for <" << entryPath << "> failed");
- }
-
- closedir(d);
-
- RUNNER_ASSERT_ERRNO_MSG(0 == rmdir(path.c_str()), "rmdir for <" << path << "> failed");
-}
-
void waitPid(pid_t pid)
{
int status;
#include <sys/types.h>
#include <string>
#include <tuple>
-#include <errno.h>
#include <string.h>
const uid_t APP_UID = 5001;
const gid_t APP_GID = 100;
-const uid_t APP_UID_2 = 5200;
-const gid_t APP_GID_2 = 5200;
-const uid_t DB_ALARM_UID = 6001;
-const gid_t DB_ALARM_GID = 6001;
-const std::string TMP_DIR("/tmp");
bool smack_check(void);
int drop_root_privileges(uid_t appUid = APP_UID, gid_t appGid = APP_GID);
-void add_process_group(const char* group_name);
-void remove_process_group(const char* group_name);
std::string formatCstr(const char *cstr);
int files_compare(int fd1, int fd2);
-void mkdirSafe(const std::string &path, mode_t mode);
void mktreeSafe(const std::string &path, mode_t mode);
-void creatSafe(const std::string &path, mode_t mode);
-void symlinkSafe(const std::string &targetPath, const std::string &linkPath);
-void removeDir(const std::string &path);
void waitPid(pid_t pid);
pid_t runInChild(const std::function<void(void)> &process);
} \
void Proc##Multi(std::tuple<__VA_ARGS__> &optionalArgsTuple DPL_UNUSED)
-#define RUNNER_MULTIPROCESS_TEST_NOSMACK(Proc, ...) \
- void Proc(std::tuple<__VA_ARGS__> &optionalArgsTuple); \
- void Proc##Multi(std::tuple<__VA_ARGS__> &optionalArgsTuple); \
- static int Static##Proc##Init() \
- { \
- if (!smack_check()) \
- DPL::Test::TestRunnerSingleton::Instance().RegisterTest( \
- new DPL::Test::TestCaseExtended<__VA_ARGS__>(#Proc, &Proc)); \
- return 0; \
- } \
- const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init(); \
- void Proc(std::tuple<__VA_ARGS__> &optionalArgsTuple) { \
- DPL::Test::RunMultiProc(std::bind(Proc##Multi, optionalArgsTuple)); \
- } \
- void Proc##Multi(std::tuple<__VA_ARGS__> &optionalArgsTuple DPL_UNUSED)
-
#endif
/*
- * Copyright (c) 2014-2015 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.
FileOperations::removeDirFiles(CynaraTestConsts::SERVICE_PLUGINS_DIR);
for (const auto &dir : pluginDirectories)
- FileOperations::copyCynaraFiles(dir.c_str(), CynaraTestConsts::SERVICE_PLUGINS_DIR);
+ FileOperations::copyCynaraFiles(dir, CynaraTestConsts::SERVICE_PLUGINS_DIR);
}
void restartCynaraService()
/*
- * Copyright (c) 2014-2015 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.
void CynaraTestEnv::init(const std::string &testName)
{
- m_saveDir = TMP_DIR + "/" + testName;
+ m_saveDir = "/tmp/" + testName;
m_dbSaveDir = m_saveDir + "/db";
m_defaultDir = "/etc/security-tests/db_patterns/default";
m_pluginsToInstallDir = "/opt/plugins_to_install";
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-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.
namespace FileOperations
{
-static int removeFile(const char *fpath, const struct stat * /*sb*/,
+namespace {
+
+int removeFile(const char *fpath, const struct stat * /*sb*/,
int tflag, struct FTW * /*ftwbuf*/)
{
if (tflag == FTW_F)
return 0;
}
-bool dirExists(const std::string &directory)
+void syncElem(const std::string &filename, int flags, mode_t mode)
{
- struct stat st;
- int ret = stat(directory.c_str(), &st);
- if (ret == -1 && errno == ENOENT) {
- return false;
- } else if (ret == -1) {
- RUNNER_ASSERT_ERRNO_MSG(false, "Cannot stat " << directory
- << " not due to its nonexistence");
- }
- RUNNER_ASSERT_MSG(st.st_mode & S_IFDIR, directory << " is not a directory");
- return true;
+ int fileFd = TEMP_FAILURE_RETRY(open(filename.c_str(), flags, mode));
+ RUNNER_ASSERT_ERRNO_MSG(fileFd != -1, "open failed name=" << filename);
+ FdUniquePtr fdPtr(&fileFd);
+
+ int ret = fsync(fileFd);
+ RUNNER_ASSERT_ERRNO_MSG(ret != -1, "fsync failed name=" << filename);
+}
+
+void syncDir(const std::string &dirname, mode_t mode = S_IRUSR | S_IWUSR) {
+ syncElem(dirname, O_DIRECTORY, mode);
}
void copyCynaraFile(const std::string &src, const std::string &dst)
RUNNER_ASSERT_ERRNO_MSG(ret != -1, "fsync failed");
}
+} // namespace
+
+bool dirExists(const std::string &directory)
+{
+ struct stat st;
+ int ret = stat(directory.c_str(), &st);
+ if (ret == -1 && errno == ENOENT) {
+ return false;
+ } else if (ret == -1) {
+ RUNNER_ASSERT_ERRNO_MSG(false, "Cannot stat " << directory
+ << " not due to its nonexistence");
+ }
+ RUNNER_ASSERT_MSG(st.st_mode & S_IFDIR, directory << " is not a directory");
+ return true;
+}
+
void copyCynaraFiles(const std::string &source, const std::string &destination)
{
DIR *dirPtr = nullptr;
syncDir(destination);
}
-void syncElem(const std::string &filename, int flags, mode_t mode)
-{
- int fileFd = TEMP_FAILURE_RETRY(open(filename.c_str(), flags, mode));
- RUNNER_ASSERT_ERRNO_MSG(fileFd != -1, "open failed name=" << filename);
- FdUniquePtr fdPtr(&fileFd);
-
- int ret = fsync(fileFd);
- RUNNER_ASSERT_ERRNO_MSG(ret != -1, "fsync failed name=" << filename);
-}
-
-void syncDir(const std::string &dirname, mode_t mode) {
- syncElem(dirname, O_DIRECTORY, mode);
-}
-
void makeDir(const std::string &directory)
{
RUNNER_ASSERT_ERRNO_MSG(!mkdir(directory.c_str(), S_IRWXU | S_IRWXG | S_IRWXO),
#ifndef CYNARA_TEST_FILE_OPERATIONS_H
#define CYNARA_TEST_FILE_OPERATIONS_H
-#include <fcntl.h>
#include <string>
namespace FileOperations
{
bool dirExists(const std::string &directory);
-void copyCynaraFile(const std::string &src, const std::string &dst);
void copyCynaraFiles(const std::string &source, const std::string &destination);
-void syncElem(const std::string &filename, int flags = O_RDONLY, mode_t mode = S_IRUSR | S_IWUSR);
-void syncDir(const std::string &dirname, mode_t mode = S_IRUSR | S_IWUSR);
void makeDir(const std::string &directory);
void removeDirFiles(const std::string &dir);
void removeDirIfExists(const std::string &dir);
/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011-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.
static void DisplayKnownException(const Exception& e)
{
- LogUnhandledException(KnownExceptionToString(e).c_str());
+ LogUnhandledException(KnownExceptionToString(e));
}
static void DisplayUnknownException()
{
- LogUnhandledException(UnknownExceptionToString().c_str());
+ LogUnhandledException(UnknownExceptionToString());
}
Exception(const Exception &other)
/*
- * Copyright (c) 2014-2015 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.
void SummaryCollector::writeStats(bool segfault)
{
- m_output.open(m_filename.c_str(), std::ofstream::out | std::ofstream::trunc);
+ m_output.open(m_filename, std::ofstream::out | std::ofstream::trunc);
if (!m_output) {
LogPedantic("Could not open file " << m_filename << " for writing");
return;
-# 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.
# @brief
#
+IF(NOT DEFINED SM_TEST_DIR)
+ SET(SM_TEST_DIR "${SHARE_INSTALL_PREFIX}/security-manager-test")
+ENDIF(NOT DEFINED SM_TEST_DIR)
+ADD_DEFINITIONS("-DSM_TEST_DIR=\"${SM_TEST_DIR}\"")
+
INCLUDE(FindPkgConfig)
# Dependencies
sqlite3
libcap
dbus-1
- libgum)
+ libgum
+ boost)
SET(TARGET_SEC_MGR_TESTS "security-manager-tests")
${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_public_sharing.cpp
${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_register_paths.cpp
${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_shm.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_smack_privileges.cpp
${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_trusted_sharing.cpp
${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_prepare_app.cpp
${PROJECT_SOURCE_DIR}/src/security-manager-tests/security_manager_tests.cpp
${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/policy_configuration.cpp
${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
INSTALL(DIRECTORY
${PROJECT_SOURCE_DIR}/src/security-manager-tests/app_files/
DESTINATION ${LOCAL_APP_DIR}
+)
+
+INSTALL(DIRECTORY
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/smack-privileges
+ DESTINATION ${SM_TEST_DIR}
)
\ No newline at end of file
--- /dev/null
+/*
+ * 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>
+#include <policy_configuration.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 PrivilegeVector &allowedPrivs,
+ const PrivilegeVector &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, "", user, priv.getName(), 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, "", user, priv.getName(), 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 PrivilegeVector &deniedPrivs) const
+{
+ checkPrivileges({}, deniedPrivs);
+}
+
+void AppInstallHelperExt::checkGroupPrivileges(const PrivilegeVector &expectedPrivs) const
+{
+ static PolicyConfiguration policy;
+
+ // get expected groups
+ auto expectedGids = policy.groupToGid(policy.privToGroup(expectedPrivs));
+ RUNNER_ASSERT_MSG(expectedGids.size() == expectedPrivs.size(),
+ "Some privileges given were not found in the policy");
+ std::sort(expectedGids.begin(), expectedGids.end());
+
+ // get current process groups
+ int 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");
+
+ // remove groups unrelated to privileges
+ const auto allPrivGids = policy.getGid();
+ auto notPrivGid = [&](gid_t gid){
+ return std::find(allPrivGids.begin(), allPrivGids.end(), gid) == allPrivGids.end();
+ };
+ actualGids.erase(std::remove_if(actualGids.begin(), actualGids.end(), notPrivGid),
+ actualGids.end());
+ std::sort(actualGids.begin(), actualGids.end());
+
+ // expected but not allowed
+ std::vector<gid_t> notAllowedGids;
+ std::set_difference(expectedGids.begin(), expectedGids.end(),
+ actualGids.begin(), actualGids.end(),
+ std::back_inserter(notAllowedGids));
+
+ RUNNER_ASSERT_MSG(notAllowedGids.empty(),
+ notAllowedGids.size() << " expected groups were not assigned");
+
+ // allowed but not expected
+ std::vector<gid_t> notDeniedGids;
+ std::set_difference(actualGids.begin(), actualGids.end(),
+ expectedGids.begin(), expectedGids.end(),
+ std::back_inserter(notDeniedGids));
+
+ RUNNER_ASSERT_MSG(notDeniedGids.empty(),
+ notDeniedGids.size() << " unexpected groups were assigned");
+}
+
+void AppInstallHelperExt:: checkSmackPrivileges(const PrivilegeVector &allowedPrivs,
+ const PrivilegeVector &deniedPrivs) const
+{
+ auto& smackPrivilegeRules = PolicyConfiguration::getSmackPrivRulesMap();
+
+ auto getPrivilegeRules = [&](const PrivilegeVector &privs) {
+ std::vector<AccessRequest> rules;
+
+ for (auto &priv : privs) {
+ auto it = smackPrivilegeRules.find(priv);
+ RUNNER_ASSERT_MSG(it != smackPrivilegeRules.end(), priv << " is not a smack privilege");
+
+ rules.insert(rules.end(), it->second.begin(), it->second.end());
+ }
+ return rules;
+ };
+
+ checkSmackAccesses(getPrivilegeRules(allowedPrivs));
+ checkSmackAccesses(getPrivilegeRules(deniedPrivs), false);
+}
+
+void AppInstallHelperExt::checkAfterInstall() const
+{
+ static const std::vector<AccessRequest> staticRules[] =
+ {parseSmackRulesFile(PolicyConfiguration::getPkgRulesFilePath()),
+ parseSmackRulesFile(PolicyConfiguration::getAppRulesFilePath())};
+
+ checkAppIdExistence(true);
+
+ checkSmackAccesses(staticRules[m_isHybrid]);
+
+ checkPrivileges(m_privileges, {});
+}
+
+void AppInstallHelperExt::checkAfterUninstall(bool removePkg) const
+{
+ checkAppIdExistence(false);
+
+ if (removePkg) {
+ checkPkgSmackRulesAfterUninstall();
+ }
+ // there should be no hybrid rules regardless of the app type
+ checkHybridAppSmackRulesAterUninstall();
+
+ checkDeniedPrivileges(m_privileges);
+}
+
+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.");
+ }
+}
+
+} // namespace SecurityManagerTest
--- /dev/null
+/*
+ * 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 <app_def_privilege.h>
+
+namespace SecurityManagerTest {
+
+class AppInstallHelperExt : public AppInstallHelper {
+public:
+ using AppInstallHelper::AppInstallHelper;
+
+ void checkPrivileges(const PrivilegeVector &allowedPrivs,
+ const PrivilegeVector &deniedPrivs) const;
+ void checkDeniedPrivileges(const PrivilegeVector &deniedPrivs) const;
+ void checkGroupPrivileges(const PrivilegeVector &allowedPrivs) const;
+ void checkSmackPrivileges(const PrivilegeVector &allowedPrivs,
+ const PrivilegeVector &deniedPrivs = {}) 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;
+};
+
+} // namespace SecurityManagerTest
/*
- * Copyright (c) 2016 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 <regex>
#include <string>
#include <vector>
+#include <stdexcept>
#include <grp.h>
#include <sys/types.h>
#define CONF_DIR "/usr/share/security-manager/policy/"
#define CONF_GROUP_FILE "privilege-group.list"
+#define CONF_SYSTEMD_PRIVS_FILE "privilege-managed-by-systemd-for-daemons.list"
#define CONF_USER_TEMPLATE_FILE "usertype-%s.profile"
namespace SecurityManagerTest {
+namespace {
+
+PolicyConfiguration::SmackPrivRulesMap parsePrivilegeSmackList() {
+ constexpr char PRIVILEGE[] = "~PRIVILEGE~";
+ PolicyConfiguration::SmackPrivRulesMap privilegeRules;
+
+ std::ifstream templateFile(CONF_DIR "privilege-smack.list");
+
+ if (templateFile.fail())
+ return privilegeRules;
+
+ try {
+ std::string line;
+ while (getline(templateFile, line)) {
+ if (line.empty() || line[0] == '#')
+ continue;
+
+ std::string privilege, label, rulesFileName;
+ std::istringstream stream(line);
+ stream >> privilege >> label >> rulesFileName;
+
+ if (rulesFileName == "default")
+ rulesFileName = "priv-rules-default-template.smack";
+
+ std::ifstream rulesFile(std::string(CONF_DIR) + "privilege-mapping/" + rulesFileName);
+ std::string object, subject, access;
+ while (rulesFile >> subject >> object >> access) {
+ if (object.empty() || subject.empty())
+ throw std::runtime_error("Malformed rule");
+
+ // ignore
+ if (object.front() != '~' || subject.front() != '~')
+ continue;
+
+ if (object == PRIVILEGE)
+ object = label;
+ if (subject == PRIVILEGE)
+ subject = label;
+ privilegeRules[privilege].emplace_back(std::move(subject),
+ std::move(object),
+ std::move(access));
+ }
+ }
+ } catch (const std::exception&) {
+ privilegeRules.clear();
+ }
+ return privilegeRules;
+}
+
+} // namespace anonymous
+
gid_t nameToGid(const char *name) {
struct group entry, *gresult;
char buffer[1024];
return result;
}
-PolicyConfiguration::GroupVector PolicyConfiguration::privToGroup(const PolicyConfiguration::PrivVector &privVector) {
- GroupVector result;
- if (m_privGroupMap.empty())
- loadPrivGroupMap();
- for (auto &e : privVector) {
- auto it = m_privGroupMap.find(e);
- if (it == m_privGroupMap.end())
- continue;
- result.push_back(it->second);
+PolicyConfiguration::PrivVector PolicyConfiguration::getSystemdManagedPrivs()
+{
+ PolicyConfiguration::PrivVector result;
+ std::ifstream file(CONF_DIR CONF_SYSTEMD_PRIVS_FILE);
+ if (!file.is_open()) {
+ RUNNER_ASSERT_MSG(file.is_open(),
+ "Unable to read config file " << CONF_DIR CONF_SYSTEMD_PRIVS_FILE);
+ }
+ std::string line;
+ std::regex r("^(http(.*))");
+ while (std::getline(file, line)) {
+ std::smatch m;
+ if (std::regex_search(line, m, r))
+ result.emplace_back(m[1]);
}
return result;
}
}
}
+std::string PolicyConfiguration::getPkgRulesFilePath() {
+ return CONF_DIR "pkg-rules-template.smack";
+}
+std::string PolicyConfiguration::getAppRulesFilePath() {
+ return CONF_DIR "app-rules-template.smack";
+}
+
+const PolicyConfiguration::SmackPrivRulesMap& PolicyConfiguration::getSmackPrivRulesMap() {
+ const static auto smackPrivRulesMap = parsePrivilegeSmackList();
+ return smackPrivRulesMap;
+}
+
} // namespace SecurityManagerTest
/*
- * Copyright (c) 2016 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 <map>
#include <string>
#include <vector>
+#include <unordered_map>
#include <sys/types.h>
+#include <template_parser.h>
+
namespace SecurityManagerTest {
gid_t nameToGid(const char *name);
typedef std::vector<std::string> GroupVector;
typedef std::vector<std::string> PrivVector;
typedef std::map<std::string, std::string> PrivGroupMap;
+ typedef std::unordered_map<std::string, std::vector<AccessRequest>> SmackPrivRulesMap;
struct UserDescription {
PrivVector privVector;
UserDescription& getUserDescription(UserType userType);
gid_t groupToGid(const std::string &gname);
PrivGroupMap getPrivGroupMap();
- GroupVector privToGroup(const PrivVector &privVector);
+ PrivVector getSystemdManagedPrivs();
+
+ template <typename T>
+ GroupVector privToGroup(const T &privVector);
+ GidVector groupToGid(const GroupVector &groupVector);
-static bool getIsAskuserEnabled();
+ static bool getIsAskuserEnabled();
+ static std::string getPkgRulesFilePath();
+ static std::string getAppRulesFilePath();
+ static const SmackPrivRulesMap& getSmackPrivRulesMap();
private:
- GidVector groupToGid(const GroupVector &groupVector);
UserDescription loadUserDescription(UserType userType);
PrivVector loadPrivFile(const std::string &path);
void loadPrivGroupMap(void);
std::map<UserType, UserDescription> m_userDescriptionMap;
};
+template <typename T>
+PolicyConfiguration::GroupVector PolicyConfiguration::privToGroup(const T &privVector) {
+ GroupVector result;
+ if (m_privGroupMap.empty())
+ loadPrivGroupMap();
+ for (auto &e : privVector) {
+ auto it = m_privGroupMap.find(e);
+ if (it == m_privGroupMap.end())
+ continue;
+ result.push_back(it->second);
+ }
+ return result;
+}
+
+
} // namespace SecurityManagerTest
#endif
--- /dev/null
+/*
+ * 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
+
+namespace PrivilegeNames {
+
+constexpr char PRIV_INTERNAL_AUDIO[] = "http://tizen.org/privilege/internal/device/audio";
+constexpr char PRIV_INTERNAL_DISPLAY[] = "http://tizen.org/privilege/internal/device/display";
+constexpr char PRIV_INTERNAL_USERMANAGEMENT[] = "http://tizen.org/privilege/internal/usermanagement";
+constexpr char PRIV_INTERNAL_VIDEO[] = "http://tizen.org/privilege/internal/device/video";
+
+constexpr char PRIV_ACCOUNT_READ[] = "http://tizen.org/privilege/account.read";
+constexpr char PRIV_BLUETOOTH[] = "http://tizen.org/privilege/bluetooth";
+constexpr char PRIV_CALENDAR_READ[] = "http://tizen.org/privilege/calendar.read";
+constexpr char PRIV_CALENDAR_WRITE[] = "http://tizen.org/privilege/calendar.write";
+constexpr char PRIV_CALLHISTORY_READ[] = "http://tizen.org/privilege/callhistory.read";
+constexpr char PRIV_CAMERA[] = "http://tizen.org/privilege/camera";
+constexpr char PRIV_CONTACTS_READ[] = "http://tizen.org/privilege/contacts.read";
+constexpr char PRIV_CONTENT_WRITE[] = "http://tizen.org/privilege/content.write";
+constexpr char PRIV_DATASHARING[] = "http://tizen.org/privilege/datasharing";
+constexpr char PRIV_DISPLAY[] = "http://tizen.org/privilege/display";
+constexpr char PRIV_EMAIL[] = "http://tizen.org/privilege/email";
+constexpr char PRIV_EXTERNALSTORAGE[] = "http://tizen.org/privilege/externalstorage";
+constexpr char PRIV_HEALTHINFO[] = "http://tizen.org/privilege/healthinfo";
+constexpr char PRIV_INTERNET[] = "http://tizen.org/privilege/internet";
+constexpr char PRIV_LED[] = "http://tizen.org/privilege/led";
+constexpr char PRIV_LOCATION[] = "http://tizen.org/privilege/location";
+constexpr char PRIV_MEDIASTORAGE[] = "http://tizen.org/privilege/mediastorage";
+constexpr char PRIV_NFC[] = "http://tizen.org/privilege/nfc";
+constexpr char PRIV_NOTEXIST[] = "http://tizen.org/privilege/notexist";
+constexpr char PRIV_NOTIFICATION[] = "http://tizen.org/privilege/notification";
+constexpr char PRIV_POWER[] = "http://tizen.org/privilege/power";
+constexpr char PRIV_PUSH[] = "http://tizen.org/privilege/push";
+constexpr char PRIV_SYSTEMMONITOR[] = "http://tizen.org/privilege/systemmonitor";
+constexpr char PRIV_TELEPHONY[] = "http://tizen.org/privilege/telephony";
+constexpr char PRIV_VOLUME_SET[] = "http://tizen.org/privilege/volume.set";
+constexpr char PRIV_VPNSERVICE[] = "http://tizen.org/privilege/vpnservice";
+constexpr char PRIV_WIFIDIRECT[] = "http://tizen.org/privilege/wifidirect";
+
+}
--- /dev/null
+/*
+ * 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 <scoped_app_launcher.h>
+#include <sm_api.h>
+#include <sm_commons.h>
+#include <tests_common.h>
+#include <dpl/test/safe_cleanup.h>
+
+using namespace SecurityManagerTest;
+
+ScopedAppLauncher::ScopedAppLauncher(const AppInstallHelper& app,
+ const std::function<void(void)>& runInAppContext) :
+ m_uid(app.getUID()),
+ m_appId(app.getAppId())
+{
+ m_pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(m_pid >= 0, "Fork failed");
+ if (m_pid != 0) {
+ m_syncPipe.claimParentEp();
+ m_syncPipe.wait();
+ } else {
+ m_syncPipe.claimChildEp();
+
+ try {
+ RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(app.getUID(), app.getGID()) == 0,
+ "launcher failed");
+ Api::prepareAppCandidate();
+ Api::prepareApp(app.getAppId());
+ runInAppContext();
+ } catch (...) {
+ m_syncPipe.post();
+ throw;
+ }
+ m_syncPipe.post();
+ m_syncPipe.wait();
+ exit(0);
+ }
+}
+
+ScopedAppLauncher::~ScopedAppLauncher()
+{
+ SafeCleanup::run([this]{
+ m_syncPipe.post();
+ waitPid(m_pid);
+ Api::cleanupApp(m_appId, m_uid, m_pid);
+ });
+}
--- /dev/null
+/*
+ * 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 <functional>
+
+#include <app_install_helper.h>
+#include <synchronization_pipe.h>
+
+class ScopedAppLauncher final {
+public:
+ explicit ScopedAppLauncher(const AppInstallHelper& app,
+ const std::function<void(void)>& runInAppContext = []{});
+ ~ScopedAppLauncher();
+
+ ScopedAppLauncher(const ScopedAppLauncher&) = delete;
+ ScopedAppLauncher& operator=(const ScopedAppLauncher&) = delete;
+
+private:
+ SynchronizationPipe m_syncPipe;
+ pid_t m_pid;
+ const uid_t m_uid;
+ const std::string m_appId;
+};
/*
- * 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 CONF_DIR "/usr/share/security-manager/policy/"
-#define SMACK_RULES_PATH "/sys/fs/smackfs/load2"
-
#define ALLOW 0
#define DENY -1
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(CONF_DIR "pkg-rules-template.smack"),
- parseSmackRulesFile(CONF_DIR "app-rules-template.smack")};
-
- 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("~PATH_SHARED_RO~", getSharedROPathLabel()),
- 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;
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());
/*
- * 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);
* @author Alicja Kluczek <a.kluczek@samsung.com>
* @brief Parsing function for smack rules templates
*/
+#pragma once
+
#include <vector>
#include <string>
--- /dev/null
+~PROCESS~ ~PRIVILEGE~ w
+~PRIVILEGE~ ~PROCESS~ w
--- /dev/null
+http://tizen.org/privilege/internet System::Privilege::Internet default
\ No newline at end of file
--- /dev/null
+~PROCESS~ ~PRIVILEGE~ w
+~PRIVILEGE~ ~PROCESS~ w
--- /dev/null
+http://tizen.org/privilege/internet System::Privilege::Internet default
+http://tizen.org/privilege/camera System::Privilege::Camera the-fault
+http://tizen.org/privilege/camera System::Privilege::Camera
--- /dev/null
+~PROCESS~ System::TEF r
+~PROCESS~ ~PRIVILEGE~ w
+~PRIVILEGE~ ~PROCESS~ w
--- /dev/null
+~PROCESS~ ~PRIVILEGE~ w
+~PRIVILEGE~ ~PROCESS~ w
--- /dev/null
+http://tizen.org/privilege/internet System::Privilege::Internet default
+http://tizen.org/privilege/camera System::Privilege::Camera flawed-camera-template.smack
/*
- * 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 <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>
+#include <app_def_privilege.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);
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());
check_path(sharedRODir, getSharedROPathLabel());
}
-RUNNER_TEST(security_manager_02_app_install_uninstall_full)
+RUNNER_CHILD_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 PrivilegeVector defaultPrivs = {
+ PRIV_INTERNAL_AUDIO,
+ PRIV_INTERNAL_DISPLAY,
+ PRIV_INTERNAL_VIDEO,
};
+ const PrivilegeVector allowedPrivs = {PRIV_CAMERA, PRIV_MEDIASTORAGE};
+ const PrivilegeVector someDeniedPrivs = {PRIV_INTERNET, PRIV_EXTERNALSTORAGE};
- privileges_t defaultAllowedPrivs = defaultPrivs;
+ PrivilegeVector 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();
{
ScopedInstaller appInstall(app);
- check_app_after_install(app.getAppId(), app.getPkgId(),
- defaultAllowedPrivs, someDeniedPrivs);
+ app.checkAfterInstall();
+ app.checkDeniedPrivileges(someDeniedPrivs);
+ {
+ ScopedAppLauncher launcher(app, [&]{ app.checkGroupPrivileges(defaultAllowedPrivs); });
+ }
check_path(app.getPrivateDir(), generatePathRWLabel(app.getPkgId()));
check_path(app.getPrivateRODir(), generatePathROLabel(app.getPkgId()), false);
check_path(app.getSharedRODir(), getSharedROPathLabel());
}
- check_app_after_uninstall(app.getAppId(), app.getPkgId(), app.getPrivilegesNames());
+ 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)
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 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();
- 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 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();
- 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)
// 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 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();
- AppInstallHelper app("sm_test_07a", testUser.getUid());
+ AppInstallHelperExt app("sm_test_07a", testUser.getUid());
app.addPrivileges(allowedPrivs);
InstallRequest req;
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)
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 PrivilegeVector somePrivs = {PRIV_LED, PRIV_NOTIFICATION};
+
// gumd
TemporaryTestUser testUser("sm_test_08_user_name", GUM_USERTYPE_NORMAL);
testUser.create();
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;
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);
};
- 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"};
- 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)
{
- 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();
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 PrivilegeVector allowedPrivs = {PRIV_WIFIDIRECT, PRIV_TELEPHONY};
+ const PrivilegeVector 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)
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 privileges_t allowedPrivsAfterChange = {"http://tizen.org/privilege/datasharing"};
- const privileges_t deniedPrivsAfterChange = {"http://tizen.org/privilege/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);
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,
PolicyRequest addPolicyReq;
for (auto &deniedPriv : deniedPrivsAfterChange) {
PolicyEntry entry(SECURITY_MANAGER_ANY, normalUser.getUidString(), deniedPriv);
- entry.setMaxLevel("Deny");
+ entry.setMaxLevel(PolicyEntry::LEVEL_DENY);
addPolicyReq.addEntry(entry);
}
Api::sendPolicy(addPolicyReq);
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;
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)
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)
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"
- };
- std::vector<std::string> someDeniedPrivs = {
- "http://tizen.org/privilege/push",
- "http://tizen.org/privilege/power",
- "http://tizen.org/privilege/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();
- 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);
"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)
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 PrivilegeVector 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();
}
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017 - 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 <tzplatform.h>
#include <app_install_helper.h>
#include <scoped_installer.h>
+#include <privilege_names.h>
RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_APP_DEFINED_PRIVILEGE)
using namespace SecurityManagerTest;
+using namespace PrivilegeNames;
RUNNER_CHILD_TEST(app_defined_01_global_install_untrusted)
{
RUNNER_CHILD_TEST(app_defined_10_check_system_privileges)
{
const std::string providerAppId = "app_def_09_provider";
- const Privilege privilege("http://tizen.org/privilege/internet", Privilege::UNTRUSTED);
+ const Privilege privilege(PRIV_INTERNET, Privilege::UNTRUSTED);
InstallRequest requestInst;
requestInst.setAppId(providerAppId);
CynaraTestClient::Client cynara;
cynara.check(clientLabel, session, ownerId, clientPrivilegeLicense, CYNARA_API_ACCESS_DENIED);
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2016-2018 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 <dpl/test/test_runner.h>
#include <dpl/test/test_runner_child.h>
+#include <privilege_names.h>
+
+using namespace PrivilegeNames;
const PrivilegeVector TEST_PRIVACY_PRIVILEGES = {
- Privilege("http://tizen.org/privilege/callhistory.read", Privilege::PRIVACY),
- Privilege("http://tizen.org/privilege/account.read", Privilege::PRIVACY),
- Privilege("http://tizen.org/privilege/healthinfo", Privilege::PRIVACY) };
+ Privilege(PRIV_CALLHISTORY_READ, Privilege::PRIVACY),
+ Privilege(PRIV_ACCOUNT_READ, Privilege::PRIVACY),
+ Privilege(PRIV_HEALTHINFO, Privilege::PRIVACY) };
using namespace SecurityManagerTest;
/*
- * Copyright (c) 2016 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 <sm_policy_request.h>
#include <sm_user_request.h>
#include <temp_test_user.h>
+#include <privilege_names.h>
#include <security-manager.h>
using namespace SecurityManagerTest;
+using namespace PrivilegeNames;
RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_NSS_PLUGIN)
-RUNNER_CHILD_TEST(nss_01_unknown_user) {
+RUNNER_CHILD_TEST(nss_01_normal_user_without_inter_daemon_groups) {
const std::string newUserName = "nss_01_user";
- PolicyConfiguration pc;
- TemporaryTestUser testUser(newUserName, GUM_USERTYPE_NORMAL, false);
- testUser.create();
-
- auto gidVector = pc.getGid();
-
- RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
-
- gid_t list[64];
- int grsize = getgroups(64, list);
- size_t counter = 0;
-
- for (size_t i=0; i<gidVector.size(); ++i) {
- for (int j=0; j<grsize; ++j)
- if(list[j] == gidVector[i]) {
- counter++;
- break;
- }
- }
-
- RUNNER_ASSERT_MSG(gidVector.size() == counter,
- "Process should have all groups related with privileges but it have only " <<
- counter << " of " << gidVector.size() << " required groups");
-}
-
-RUNNER_CHILD_TEST(nss_02_normal_user_all_priv) {
- const std::string newUserName = "nss_02_user";
- PolicyConfiguration pc;
TemporaryTestUser testUser(newUserName, GUM_USERTYPE_NORMAL, false);
testUser.create();
- auto gidVector = pc.getUserGid(PolicyConfiguration::NORMAL);
-
UserRequest addUserRequest;
addUserRequest.setUid(testUser.getUid());
addUserRequest.setUserType(SM_USER_TYPE_NORMAL);
RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
- gid_t list[64];
- int grsize = getgroups(64, list);
- size_t counter = 0;
+ gid_t list[NGROUPS_MAX + 1];
+ int grsize = getgroups(NGROUPS_MAX + 1, list);
- for (size_t i=0; i<gidVector.size(); ++i) {
- for (int j=0; j<grsize; ++j)
- if(list[j] == gidVector[i]) {
- counter++;
- break;
- }
+ PolicyConfiguration pc;
+ auto sysdGidVec = pc.groupToGid(pc.privToGroup(pc.getSystemdManagedPrivs()));
+ auto allPrivGids = pc.getGid();
+ unsigned int privGidsOther = 0;
+ for (int i = 0; i < grsize; ++i) {
+ RUNNER_ASSERT_MSG(std::find(sysdGidVec.begin(), sysdGidVec.end(), list[i]) == sysdGidVec.end() , "Process should not get gid " << list[i]);
+ if (std::find(allPrivGids.begin(), allPrivGids.end(), list[i]) != allPrivGids.end())
+ ++privGidsOther;
}
- RUNNER_ASSERT_MSG(gidVector.size() == counter,
- "Process should have all groups related with privileges but it have only " <<
- counter << " of " << gidVector.size() << " required groups");
+ RUNNER_ASSERT_MSG(privGidsOther + sysdGidVec.size() == allPrivGids.size(), "Improper GID setup for process, has priv_*: " <<
+ privGidsOther << ", systemd managed all: " << sysdGidVec.size() << " , all: " << allPrivGids.size() );
}
-RUNNER_CHILD_TEST(nss_03_normal_user_without_camera) {
- const std::string newUserName = "nss_03_user";
- TemporaryTestUser testUser(newUserName, GUM_USERTYPE_NORMAL, false);
+RUNNER_CHILD_TEST(nss_02_guest_user_without_inter_daemon_groups) {
+ const std::string newUserName = "nss_02_user";
+ TemporaryTestUser testUser(newUserName, GUM_USERTYPE_GUEST, false);
testUser.create();
- gid_t cameraPrivId = nameToGid("priv_camera");
UserRequest addUserRequest;
addUserRequest.setUid(testUser.getUid());
- addUserRequest.setUserType(SM_USER_TYPE_NORMAL);
+ addUserRequest.setUserType(SM_USER_TYPE_GUEST);
Api::addUser(addUserRequest);
- PolicyRequest policyRequest;
- PolicyEntry entry(
- SECURITY_MANAGER_ANY,
- std::to_string(static_cast<int>(testUser.getUid())),
- "http://tizen.org/privilege/camera");
- entry.setMaxLevel("Deny");
- policyRequest.addEntry(entry);
- Api::sendPolicy(policyRequest);
-
RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
- gid_t list[64];
- int grsize = getgroups(64, list);
- size_t counter = 0;
-
- for (int i=0; i<grsize; ++i) {
- if (list[i] == cameraPrivId) {
- counter++;
- break;
- }
- }
-
- RUNNER_ASSERT_MSG(0 == counter, "Process should not have priv_camera group");
+ gid_t list[NGROUPS_MAX + 1];
+ int grsize = getgroups(NGROUPS_MAX + 1, list);
PolicyConfiguration pc;
- auto gidVector = pc.getUserGid(PolicyConfiguration::NORMAL);
- gidVector.erase(
- std::remove_if(gidVector.begin(), gidVector.end(), [=](gid_t g) { return g == cameraPrivId; }),
- gidVector.end());
-
- for (size_t i=0; i<gidVector.size(); ++i) {
- for (int j=0; j<grsize; ++j)
- if(list[j] == gidVector[i]) {
- counter++;
- break;
- }
+ auto sysdGidVec = pc.groupToGid(pc.privToGroup(pc.getSystemdManagedPrivs()));
+ auto allPrivGids = pc.getGid();
+ unsigned int privGidsOther = 0;
+ for (int i = 0; i < grsize; ++i) {
+ RUNNER_ASSERT_MSG(std::find(sysdGidVec.begin(), sysdGidVec.end(), list[i]) == sysdGidVec.end() , "Process should not get gid " << list[i]);
+ if (std::find(allPrivGids.begin(), allPrivGids.end(), list[i]) != allPrivGids.end())
+ ++privGidsOther;
}
- RUNNER_ASSERT_MSG(gidVector.size() == counter,
- "Process should have all groups related with privileges but it have only " <<
- counter << " of " << gidVector.size() << " required groups");
+ RUNNER_ASSERT_MSG(privGidsOther + sysdGidVec.size() == allPrivGids.size(), "Improper GID setup for process, has priv_*: " <<
+ privGidsOther << ", systemd managed all: " << sysdGidVec.size() << " , all: " << allPrivGids.size() );
}
-RUNNER_CHILD_TEST(nss_04_guest_user) {
- const std::string newUserName = "nss_04_user";
+
+RUNNER_CHILD_TEST(nss_03_guest_user_without_inter_daemon_groups_unaffected_by_cynara) {
+ const std::string newUserName = "nss_03_user";
TemporaryTestUser testUser(newUserName, GUM_USERTYPE_GUEST, false);
testUser.create();
addUserRequest.setUserType(SM_USER_TYPE_GUEST);
Api::addUser(addUserRequest);
+ // Removing one more privilege from policy (that has GID associated), which should not affect nss daemon groups
+ PolicyRequest policyRequest;
+
+ PolicyEntry entry(SECURITY_MANAGER_ANY, testUser.getUidString(), PRIV_CAMERA);
+ entry.setMaxLevel(PolicyEntry::LEVEL_DENY);
+
+ policyRequest.addEntry(entry);
+ Api::sendPolicy(policyRequest);
+
RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
- gid_t list[64];
- int grsize = getgroups(64, list);
- size_t counter = 0;
+ gid_t list[NGROUPS_MAX + 1];
+ int grsize = getgroups(NGROUPS_MAX + 1, list);
PolicyConfiguration pc;
- auto gidVector = pc.getUserGid(PolicyConfiguration::GUEST);
-
- for (size_t i=0; i<gidVector.size(); ++i) {
- for (int j=0; j<grsize; ++j)
- if(list[j] == gidVector[i]) {
- counter++;
- break;
- }
+ auto sysdGidVec = pc.groupToGid(pc.privToGroup(pc.getSystemdManagedPrivs()));
+ auto allPrivGids = pc.getGid();
+ unsigned int privGidsOther = 0;
+ for (int i = 0; i < grsize; ++i) {
+ RUNNER_ASSERT_MSG(std::find(sysdGidVec.begin(), sysdGidVec.end(), list[i]) == sysdGidVec.end() , "Process should not get gid " << list[i]);
+ if (std::find(allPrivGids.begin(), allPrivGids.end(), list[i]) != allPrivGids.end())
+ ++privGidsOther;
}
- RUNNER_ASSERT_MSG(gidVector.size() == counter,
- "Process should have all groups related with privileges but it have only " <<
- counter << " of " << gidVector.size() << " required groups");
+ RUNNER_ASSERT_MSG(privGidsOther + sysdGidVec.size() == allPrivGids.size(), "Improper GID setup for process, has priv_*: " <<
+ privGidsOther << ", systemd managed all: " << sysdGidVec.size() << " , all: " << allPrivGids.size() );
}
-
-
#include <sm_commons.h>
#include <memory.h>
#include <tests_common.h>
+#include <privilege_names.h>
using namespace SecurityManagerTest;
+using namespace PrivilegeNames;
namespace {
bool finish = false;
const std::string APP_TEST_USER = "app_test_user";
-const std::string EXTERNAL_STORAGE_PRIVILEGE = "http://tizen.org/privilege/externalstorage";
-const std::string MEDIA_STORAGE_PRIVILEGE = "http://tizen.org/privilege/mediastorage";
-
const std::string ACCESS_DENIED_DIR_PATH = "/usr/share/security-manager/dummy";
const std::string EXTERNAL_STORAGE_DIR_PATH = "/opt/media";
const std::string MEDIA_STORAGE_RW_DIR_PATH = "/opt/usr/media";
std::string getTextFileContents(const std::string &path)
{
- std::ifstream in(path.c_str());
+ std::ifstream in(path);
if (in.fail())
return std::string();
std::stringstream ss;
for (size_t i = 0; i < THREADS; i++)
threads[i].run(i, expectedLabel);
- Api::prepareApp(app.getAppId().c_str());
+ Api::prepareApp(app.getAppId());
}
RUNNER_ASSERT_MSG(thread_errors.empty(), std::endl << thread_errors);
exit(0);
} else {
waitPid(pid);
- Api::cleanupApp(app.getAppId().c_str(), tmpUser.getUid(), pid);
+ Api::cleanupApp(app.getAppId(), tmpUser.getUid(), pid);
}
}
synchPipe.claimParentEp();
RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
Api::prepareAppCandidate();
- Api::prepareApp(app.getAppId().c_str());
+ Api::prepareApp(app.getAppId());
synchPipe.post();
synchPipe.wait();
synchPipe.claimChildEp();
synchPipe.wait();
- std::string appBindPath = std::string("/var/run/user/") + std::to_string(tmpUser.getUid())
+ std::string appBindPath = std::string("/var/run/user/") + tmpUser.getUidString()
+ "/apps/" + app.generateAppLabel() + "/" + std::to_string(pid);
std::string appProcPath = std::string("/proc/") + std::to_string(pid) + "/ns/mnt";
std::string launcherProcPath = std::string("/proc/") + std::to_string(getpid()) + "/ns/mnt";
synchPipe.post();
waitPid(pid);
- Api::cleanupApp(app.getAppId().c_str(), tmpUser.getUid(), pid);
+ Api::cleanupApp(app.getAppId(), tmpUser.getUid(), pid);
}
}
synchPipe.claimParentEp();
RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
Api::prepareAppCandidate();
- Api::prepareApp(app.getAppId().c_str());
+ Api::prepareApp(app.getAppId());
synchPipe.post();
synchPipe.wait();
synchPipe.post();
waitPid(pid);
- Api::cleanupApp(app.getAppId().c_str(), tmpUser.getUid(), pid);
+ Api::cleanupApp(app.getAppId(), tmpUser.getUid(), pid);
}
}
tmpUser.create();
AppInstallHelper app("app103", tmpUser.getUid());
- app.addPrivilege(EXTERNAL_STORAGE_PRIVILEGE);
- app.addPrivilege(MEDIA_STORAGE_PRIVILEGE);
+ app.addPrivileges({PRIV_EXTERNALSTORAGE, PRIV_MEDIASTORAGE});
ScopedInstaller appInstall(app);
SynchronizationPipe synchPipe;
synchPipe.claimParentEp();
RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
Api::prepareAppCandidate();
- Api::prepareApp(app.getAppId().c_str());
+ Api::prepareApp(app.getAppId());
synchPipe.post();
synchPipe.wait();
RUNNER_ASSERT_ERRNO_MSG(result == false, "path is bound");
PolicyRequest policyRequest;
- PolicyEntry policyEntry(app.getAppId(), std::to_string(tmpUser.getUid()), EXTERNAL_STORAGE_PRIVILEGE);
- policyEntry.setLevel("Deny");
+ PolicyEntry policyEntry(app.getAppId(), tmpUser.getUidString(), PRIV_EXTERNALSTORAGE);
+ policyEntry.setLevel(PolicyEntry::LEVEL_DENY);
policyRequest.addEntry(policyEntry);
- policyEntry = PolicyEntry(app.getAppId(), std::to_string(tmpUser.getUid()), MEDIA_STORAGE_PRIVILEGE);
- policyEntry.setLevel("Deny");
+ policyEntry = PolicyEntry(app.getAppId(), tmpUser.getUidString(), PRIV_MEDIASTORAGE);
+ policyEntry.setLevel(PolicyEntry::LEVEL_DENY);
policyRequest.addEntry(policyEntry);
Api::sendPolicy(policyRequest);
result = isPathBound(ACCESS_DENIED_DIR_PATH, MEDIA_STORAGE_RO_DIR_PATH, pid);
RUNNER_ASSERT_ERRNO_MSG(result == true, "path is not bound");
- policyEntry = PolicyEntry(app.getAppId(), std::to_string(tmpUser.getUid()), EXTERNAL_STORAGE_PRIVILEGE);
- policyEntry.setLevel("Allow");
+ policyEntry = PolicyEntry(app.getAppId(), tmpUser.getUidString(), PRIV_EXTERNALSTORAGE);
+ policyEntry.setLevel(PolicyEntry::LEVEL_ALLOW);
policyRequest.addEntry(policyEntry);
- policyEntry = PolicyEntry(app.getAppId(), std::to_string(tmpUser.getUid()), MEDIA_STORAGE_PRIVILEGE);
- policyEntry.setLevel("Allow");
+ policyEntry = PolicyEntry(app.getAppId(), tmpUser.getUidString(), PRIV_MEDIASTORAGE);
+ policyEntry.setLevel(PolicyEntry::LEVEL_ALLOW);
policyRequest.addEntry(policyEntry);
Api::sendPolicy(policyRequest);
synchPipe.post();
waitPid(pid);
- Api::cleanupApp(app.getAppId().c_str(), tmpUser.getUid(), pid);
+ Api::cleanupApp(app.getAppId(), tmpUser.getUid(), pid);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_104_policy_change_kill_app_test)
+{
+ TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false);
+ tmpUser.create();
+
+ AppInstallHelper app("app104", tmpUser.getUid());
+ app.addPrivileges({PRIV_EXTERNALSTORAGE, PRIV_MEDIASTORAGE});
+ ScopedInstaller appInstall(app);
+
+ SynchronizationPipe synchPipe;
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+ if (pid == 0) {
+ synchPipe.claimParentEp();
+ try {
+ RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
+ Api::prepareAppCandidate();
+ Api::prepareApp(app.getAppId());
+ } catch (...) {
+ synchPipe.post();
+ throw;
+ }
+ synchPipe.post();
+ exit(0);
+ } else {
+ synchPipe.claimChildEp();
+ synchPipe.wait();
+
+ PolicyRequest policyRequest;
+ PolicyEntry policyEntry(app.getAppId(), tmpUser.getUidString(), PRIV_EXTERNALSTORAGE);
+ policyEntry.setLevel(PolicyEntry::LEVEL_DENY);
+ policyRequest.addEntry(policyEntry);
+ Api::sendPolicy(policyRequest);
+
+ waitPid(pid);
+ Api::cleanupApp(app.getAppId(), tmpUser.getUid(), pid);
}
}
for (int i = 0; i < nAppsMax; i++) {
apps.emplace_back(App{AppInstallHelper("app200_" + std::to_string(i), uid), 0});
auto &hlp = apps.back().hlp;
- for (const auto &p : { EXTERNAL_STORAGE_PRIVILEGE, MEDIA_STORAGE_PRIVILEGE,
- std::string("http://tizen.org/privilege/camera"),
- std::string("http://tizen.org/privilege/internet") })
- hlp.addPrivilege(p);
+ hlp.addPrivileges({PRIV_EXTERNALSTORAGE, PRIV_MEDIASTORAGE, PRIV_CAMERA, PRIV_INTERNET});
hlp.createSharedRODir();
appInstalls.emplace_back(ScopedInstaller(hlp));
}
/*
- * Copyright (c) 2016-2018 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 <synchronization_pipe.h>
#include <temp_test_user.h>
#include <tests_common.h>
+#include <privilege_names.h>
+#include <app_def_privilege.h>
using namespace SecurityManagerTest;
+using namespace PrivilegeNames;
namespace {
struct UserInfo {
std::string userName;
};
// Privileges required for having permission to self/admin get/set policies.
-const std::string SELF_PRIVILEGE = "http://tizen.org/privilege/notexist";
-const std::string ADMIN_PRIVILEGE = "http://tizen.org/privilege/internal/usermanagement";
-
-typedef std::vector<std::string> Privileges;
-const std::vector<Privileges> TEST_PRIVILEGES = {
- {
- "http://tizen.org/privilege/internet",
- "http://tizen.org/privilege/display"
- },
- {
- "http://tizen.org/privilege/telephony",
- "http://tizen.org/privilege/datasharing"
- },
- {
- "http://tizen.org/privilege/content.write",
- "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/datasharing"
- },
- {
- "http://tizen.org/privilege/internet",
- "http://tizen.org/privilege/display",
- "http://tizen.org/privilege/led",
- "http://tizen.org/privilege/email"
- }
+const std::string& SELF_PRIVILEGE = PRIV_NOTEXIST;
+const std::string& ADMIN_PRIVILEGE = PRIV_INTERNAL_USERMANAGEMENT;
+
+const std::vector<PrivilegeVector> TEST_PRIVILEGES = {
+ {PRIV_INTERNET, PRIV_DISPLAY},
+ {PRIV_TELEPHONY, PRIV_DATASHARING},
+ {PRIV_CONTENT_WRITE, PRIV_LED, PRIV_EMAIL},
+ {PRIV_LED, PRIV_EMAIL, PRIV_TELEPHONY, PRIV_DATASHARING},
+ {PRIV_INTERNET, PRIV_DISPLAY, PRIV_LED, PRIV_EMAIL}
};
const PrivilegeVector TEST_PRIVACY_PRIVILEGES[] = {
{
- Privilege("http://tizen.org/privilege/telephony"),
- Privilege("http://tizen.org/privilege/led"),
- Privilege("http://tizen.org/privilege/callhistory.read", Privilege::PRIVACY),
- Privilege("http://tizen.org/privilege/account.read", Privilege::PRIVACY),
- Privilege("http://tizen.org/privilege/healthinfo", Privilege::PRIVACY),
+ Privilege(PRIV_TELEPHONY),
+ Privilege(PRIV_LED),
+ Privilege(PRIV_CALLHISTORY_READ, Privilege::PRIVACY),
+ Privilege(PRIV_ACCOUNT_READ, Privilege::PRIVACY),
+ Privilege(PRIV_HEALTHINFO, Privilege::PRIVACY),
},
{
- Privilege("http://tizen.org/privilege/telephony"),
- Privilege("http://tizen.org/privilege/led"),
- Privilege("http://tizen.org/privilege/callhistory.read", Privilege::PRIVACY),
+ Privilege(PRIV_TELEPHONY),
+ Privilege(PRIV_LED),
+ Privilege(PRIV_CALLHISTORY_READ, Privilege::PRIVACY),
}
};
RUNNER_ASSERT_MSG(appIt != appIdToAIH.end(), "Policy returned unexpected app: " << app);
AppInstallHelper &aih = appIt->second;
- auto appPrivileges = aih.getPrivilegesNames();
+ auto& appPrivileges = aih.getPrivileges();
auto privIt = std::find(appPrivileges.begin(), appPrivileges.end(), privilege);
RUNNER_ASSERT_MSG(privIt != appPrivileges.end(),
"Unexpected privilege " << privilege << " for app " << app);
AppInstallHelper &aih = userAppIdToAIHIt->second;
auto privs = aih.getPrivileges();
- auto appPrivileges = aih.getPrivilegesNames();
+ auto& appPrivileges = aih.getPrivileges();
auto privIt = std::find(appPrivileges.begin(), appPrivileges.end(), privilege);
RUNNER_ASSERT_MSG(privIt != appPrivileges.end(),
"Unexpected privilege " << privilege << " for app " << app);
AppInstallHelper &aih = userAppIdToAIHIt->second;
auto privs = aih.getPrivileges();
- auto appPrivileges = aih.getPrivilegesNames();
+ auto& appPrivileges = aih.getPrivileges();
auto privIt = std::find(appPrivileges.begin(), appPrivileges.end(), privilege);
RUNNER_ASSERT_MSG(privIt != appPrivileges.end(),
"Unexpected privilege " << privilege << " for app " << app);
normalUser.getUidString(),
app1.getPrivileges()[0]
);
- policyEntry.setLevel("Deny");
+ policyEntry.setLevel(PolicyEntry::LEVEL_DENY);
policyRequest.addEntry(policyEntry);
policyEntry = PolicyEntry(
normalUser.getUidString(),
app1.getPrivileges()[1]
);
- policyEntry.setLevel("Deny");
+ policyEntry.setLevel(PolicyEntry::LEVEL_DENY);
policyRequest.addEntry(policyEntry);
Api::sendPolicy(policyRequest);
PolicyRequest setPolicyRequest;
std::vector<PolicyEntry> policyEntries;
- const std::string internetPriv = "http://tizen.org/privilege/internet";
- const std::string displayPriv = "http://tizen.org/privilege/display";
-
- PolicyEntry internetPolicyEntry(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, internetPriv);
- internetPolicyEntry.setMaxLevel("Deny");
+ PolicyEntry internetPolicyEntry(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, PRIV_INTERNET);
+ internetPolicyEntry.setMaxLevel(PolicyEntry::LEVEL_DENY);
setPolicyRequest.addEntry(internetPolicyEntry);
- PolicyEntry displayPolicyEntry(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, displayPriv);
- displayPolicyEntry.setMaxLevel("Deny");
+ PolicyEntry displayPolicyEntry(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, PRIV_DISPLAY);
+ displayPolicyEntry.setMaxLevel(PolicyEntry::LEVEL_DENY);
setPolicyRequest.addEntry(displayPolicyEntry);
Api::sendPolicy(setPolicyRequest);
RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_admin)
{
- const std::string updatePriv = "http://tizen.org/privilege/led";
+ const std::string& updatePriv = PRIV_LED;
TemporaryTestUser adminUser("sm_test_15_username", GUM_USERTYPE_ADMIN);
adminUser.create();
"drop_root_privileges failed");
PolicyEntry entry(updatedApp.getAppId(), adminUser.getUidString(), updatePriv);
- entry.setMaxLevel("Allow");
+ entry.setMaxLevel(PolicyEntry::LEVEL_ALLOW);
PolicyRequest addPolicyRequest;
addPolicyRequest.addEntry(entry);
Api::sendPolicy(addPolicyRequest);
RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_admin_wildcard)
{
- const std::string updatePriv = "http://tizen.org/privilege/led";
+ const std::string& updatePriv = PRIV_LED;
TemporaryTestUser adminUser("sm_test_15_username", GUM_USERTYPE_ADMIN);
adminUser.create();
"drop_root_privileges failed");
PolicyEntry entry(SECURITY_MANAGER_ANY, adminUser.getUidString(), updatePriv);
- entry.setMaxLevel("Allow");
+ entry.setMaxLevel(PolicyEntry::LEVEL_ALLOW);
PolicyRequest addPolicyRequest;
addPolicyRequest.addEntry(entry);
RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_self)
{
- const std::string updatePriv = "http://tizen.org/privilege/led";
+ const std::string& updatePriv = PRIV_LED;
TemporaryTestUser user("sm_test_15_username", GUM_USERTYPE_NORMAL);
user.create();
"drop_root_privileges failed");
PolicyEntry entry(app.getAppId(), user.getUidString(), updatePriv);
- entry.setLevel("Allow");
+ entry.setLevel(PolicyEntry::LEVEL_ALLOW);
PolicyRequest addPolicyRequest;
addPolicyRequest.addEntry(entry);
std::string allowPolicy = std::string(levels[count-1]);
// first should always be Deny
- RUNNER_ASSERT_MSG(denyPolicy.compare("Deny") == 0,
+ RUNNER_ASSERT_MSG(denyPolicy.compare(PolicyEntry::LEVEL_DENY) == 0,
"Invalid first policy level. Should be Deny, instead there is: " << levels[0]);
// last should always be Allow
- RUNNER_ASSERT_MSG(allowPolicy.compare("Allow") == 0,
+ RUNNER_ASSERT_MSG(allowPolicy.compare(PolicyEntry::LEVEL_ALLOW) == 0,
"Invalid last policy level. Should be Allow, instead there is: " << levels[count-1]);
exit(0);
}
RUNNER_CHILD_TEST(security_manager_17a_privacy_manager_delete_policy_for_self)
{
- const std::string updatePriv = "http://tizen.org/privilege/led";
+ const std::string& updatePriv = PRIV_LED;
TemporaryTestUser user("sm_test_17a_username", GUM_USERTYPE_NORMAL);
user.create();
"drop_root_privileges failed");
PolicyEntry entry(app.getAppId(), user.getUidString(), updatePriv);
- entry.setLevel("Allow");
+ entry.setLevel(PolicyEntry::LEVEL_ALLOW);
PolicyRequest addPolicyRequest;
addPolicyRequest.addEntry(entry);
Api::sendPolicy(addPolicyRequest);
RUNNER_CHILD_TEST(security_manager_17b_privacy_manager_delete_policy_for_self)
{
- const std::string updatePriv = "http://tizen.org/privilege/led";
+ const std::string& updatePriv = PRIV_LED;
TemporaryTestUser user("sm_test_17b_username", GUM_USERTYPE_NORMAL);
user.create();
"drop_root_privileges failed");
PolicyEntry entry(app.getAppId(), user.getUidString(), updatePriv);
- entry.setLevel("Allow");
+ entry.setLevel(PolicyEntry::LEVEL_ALLOW);
PolicyRequest addPolicyRequest;
addPolicyRequest.addEntry(entry);
Api::sendPolicy(addPolicyRequest);
RUNNER_CHILD_TEST(security_manager_18_privacy_manager_privacy_related_privileges_policy_install_remove)
{
- const std::string askUserDescription = "Ask user";
TemporaryTestUser user("sm_test_18_username", GUM_USERTYPE_NORMAL);
user.create();
unsigned int privacyActNum = 0;
for (auto &entry : policyEntries)
if (isPrivilegePrivacy(entry.getPrivilege())) {
- RUNNER_ASSERT_MSG(entry.getCurrentLevel() == askUserDescription,
+ RUNNER_ASSERT_MSG(entry.getCurrentLevel() == PolicyEntry::LEVEL_ASK_USER,
"Invalid policy setup; policy should be \"Ask user\" but is "
<< entry.getCurrentLevel());
++privacyActNum;
}
void test_privacy_related_privileges(bool isHybrid) {
- const std::string askUserDescription = "Ask user";
TemporaryTestUser user("sm_test_19_username", GUM_USERTYPE_NORMAL);
user.create();
"Invalid appId: should be either " << app1.getAppId() << " or "
<< app2.getAppId() << " but is " << entry.getAppId());
if (PolicyConfiguration::getIsAskuserEnabled() && isPrivilegePrivacy(entry.getPrivilege())) {
- RUNNER_ASSERT_MSG(entry.getCurrentLevel() == askUserDescription,
+ RUNNER_ASSERT_MSG(entry.getCurrentLevel() == PolicyEntry::LEVEL_ASK_USER,
"Invalid policy setup; policy should be \"Ask user\" but is "
<< entry.getCurrentLevel());
if (entry.getAppId() == app1.getAppId())
RUNNER_CHILD_TEST(security_manager_20_privacy_manager_privacy_related_privileges_policy_admin_check)
{
- const std::string askUserDescription = "Ask user";
TemporaryTestUser user("sm_test_20_username", GUM_USERTYPE_NORMAL);
user.create();
int policyType = CYNARA_ADMIN_ALLOW;
int privacyPolicyType = -1;
if (PolicyConfiguration::getIsAskuserEnabled())
- admin.getPolicyTypeForDescription(askUserDescription, privacyPolicyType);
+ admin.getPolicyTypeForDescription(PolicyEntry::LEVEL_ASK_USER, privacyPolicyType);
for (auto &priv : app.getPrivileges()) {
if (PolicyConfiguration::getIsAskuserEnabled() && isPrivilegePrivacy(priv)) {
static void check_privileges_from_manifest(const AppInstallHelper &aih, char **privileges, size_t nPrivs)
{
- std::vector<std::string> aihPrivs = aih.getPrivilegesNames();
+ auto& aihPrivs = aih.getPrivileges();
RUNNER_ASSERT_MSG(nPrivs == aihPrivs.size(), "Expected privileges number: " << aihPrivs.size() << ", got " << nPrivs);
for (size_t i = 0; i < nPrivs; ++i) {
RUNNER_ASSERT_MSG(std::find(aihPrivs.begin(), aihPrivs.end(), std::string(privileges[i])) != aihPrivs.end(),
AppInstallHelper app("security_manager_24_fetch");
app.setInstallType(SM_APP_INSTALL_GLOBAL);
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
+ app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
ScopedInstaller appInstall(app);
char **privileges;
AppInstallHelper app("security_manager_25_fetch", user.getUid());
app.setInstallType(SM_APP_INSTALL_LOCAL);
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
+ app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
ScopedInstaller appInstall(app);
char **privileges;
AppInstallHelper appGlobal("security_manager_26_fetch");
appGlobal.setInstallType(SM_APP_INSTALL_GLOBAL);
- appGlobal.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- appGlobal.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
- appGlobal.addPrivilege(std::string("http://tizen.org/privielge/contacts.read"));
+ appGlobal.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE, PRIV_CONTACTS_READ});
ScopedInstaller appGlobalInstall(appGlobal);
AppInstallHelper appLocal("security_manager_26_fetch", user.getUid());
appLocal.setInstallType(SM_APP_INSTALL_LOCAL);
- appLocal.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- appLocal.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
+ appLocal.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
ScopedInstaller appLocalInstall(appLocal);
AppInstallHelper app("security_manager_27_fetch", user.getUid());
app.setInstallType(SM_APP_INSTALL_LOCAL);
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
+ app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
ScopedInstaller appInstall(app);
pid_t pid = fork();
AppInstallHelper app("security_manager_28_fetch");
app.setInstallType(SM_APP_INSTALL_GLOBAL);
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
+ app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
ScopedInstaller appInstall(app);
pid_t pid = fork();
AppInstallHelper app("security_manager_29_fetch", user.getUid());
app.setInstallType(SM_APP_INSTALL_LOCAL);
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
+ app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
ScopedInstaller appInstall(app);
AppInstallHelper app1("security_manager_29_fetch", user1.getUid());
app1.setInstallType(SM_APP_INSTALL_LOCAL);
- app1.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- app1.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
- app1.addPrivilege(std::string("http://tizen.org/privilege/contacts.read"));
+ app1.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE, PRIV_CONTACTS_READ});
ScopedInstaller appInstall1(app1);
AppInstallHelper app("security_manager_30_fetch", user.getUid());
app.setInstallType(SM_APP_INSTALL_LOCAL);
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
+ app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
ScopedInstaller appInstall(app);
AppInstallHelper app1("security_manager_30_fetch_1", user.getUid());
app1.setInstallType(SM_APP_INSTALL_LOCAL);
- app1.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- app1.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
- app1.addPrivilege(std::string("http://tizen.org/privilege/contacts.read"));
+ app1.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE, PRIV_CONTACTS_READ});
ScopedInstaller appInstall1(app1);
AppInstallHelper app("security_manager_31_fetch", user.getUid());
app.setInstallType(SM_APP_INSTALL_LOCAL);
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- app.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
+ app.addPrivileges({PRIV_CALENDAR_READ, PRIV_CALENDAR_WRITE});
ScopedInstaller appInstall(app);
AppInstallHelper app1("security_manager_31_fetch_1", user.getUid());
app1.setInstallType(SM_APP_INSTALL_LOCAL);
- app1.addPrivilege(std::string("http://tizen.org/privilege/calendar.read"));
- app1.addPrivilege(std::string("http://tizen.org/privilege/calendar.write"));
- app1.addPrivilege(std::string("http://tizen.org/privilege/contacts.read"));
- app1.addPrivilege(std::string("http://tizen.org/privilege/internal/usermanagement"));
+ app1.addPrivileges({PRIV_CALENDAR_READ,
+ PRIV_CALENDAR_WRITE,
+ PRIV_CONTACTS_READ,
+ PRIV_INTERNAL_USERMANAGEMENT});
ScopedInstaller appInstall1(app1);
/*
- * 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.
if (pid == 0) {
setLauncherSecurityAttributes(uid, gid);
Api::prepareAppCandidate();
- Api::prepareApp(appId.c_str());
+ Api::prepareApp(appId);
f();
exit(0);
} else {
waitPid(pid);
- Api::cleanupApp(appId.c_str(), uid, pid);
+ Api::cleanupApp(appId, uid, pid);
}
}
--- /dev/null
+/*
+ * 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 <memory>
+#include <map>
+#include <cassert>
+
+#include <boost/filesystem.hpp>
+
+#include <tzplatform_config.h>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+
+#include <scoped_installer.h>
+#include <scoped_app_launcher.h>
+#include <temp_test_user.h>
+#include <app_install_helper_ext.h>
+#include <sm_policy_request.h>
+#include <privilege_names.h>
+#include <sm_commons.h>
+#include <service_manager.h>
+
+using namespace SecurityManagerTest;
+using namespace PrivilegeNames;
+
+namespace {
+
+namespace fs = boost::filesystem;
+
+const uid_t OWNER_ID = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+
+const fs::path TEST_SETUP_PATH = SM_TEST_DIR "/smack-privileges";
+const fs::path BACKUP_SETUP_PATH = TEST_SETUP_PATH / "backup";
+
+constexpr char SM_POLICY_PATH[] = "/usr/share/security-manager/policy";
+constexpr char SM_SMACK_PRIV_MAPPING_SUBDIR[] = "/privilege-mapping";
+constexpr char SM_SMACK_PRIV_CONFIG[] = "privilege-smack.list";
+
+void changePolicy(const AppInstallHelper& app, const std::string& priv, const std::string &level) {
+ PolicyRequest policyRequest;
+ PolicyEntry entry(app.getAppId(), std::to_string(app.getUID()), priv);
+ entry.setLevel(level);
+ policyRequest.addEntry(entry);
+ Api::sendPolicy(policyRequest);
+}
+
+const std::vector<AccessRequest> INTERNET_RULES = {
+ {"~PROCESS~", "System::Privilege::Internet", "w"},
+ {"System::Privilege::Internet", "~PROCESS~", "w"}
+};
+const std::vector<AccessRequest> CAMERA_RULES = {
+ {"~PROCESS~", "System::Privilege::Camera", "w"},
+ {"System::Privilege::Camera", "~PROCESS~", "w"}
+};
+const std::vector<AccessRequest> CAMERA_IGNORED_RULES = {
+ {"~PROCESS~", "System::TEF", "r"}
+};
+
+enum class SmackPrivSetup {
+ ORIGINAL,
+ EMPTY,
+ INTERNET_ONLY,
+ MULTIPLE_PRIVS,
+ MALFORMED
+};
+
+// This is to ensure that original security-manager policy is restored after the group is finished
+class SmackPrivGroupEnv final : public DPL::Test::TestGroup {
+private:
+ class SmackPrivSetupMgr final {
+ public:
+ SmackPrivSetupMgr() :
+ m_currentSetup(SmackPrivSetup::ORIGINAL),
+ m_serviceManager("security-manager.service"),
+ m_setupMap({{ SmackPrivSetup::EMPTY, "empty" },
+ { SmackPrivSetup::INTERNET_ONLY, "internet-only" },
+ { SmackPrivSetup::MULTIPLE_PRIVS, "multiple-privs" },
+ { SmackPrivSetup::MALFORMED, "malformed" }})
+ {
+ }
+ SmackPrivSetupMgr(const SmackPrivSetupMgr&) = delete;
+ SmackPrivSetupMgr& operator=(const SmackPrivSetupMgr&) = delete;
+ ~SmackPrivSetupMgr()
+ {
+ // restore setup
+ if (m_currentSetup != SmackPrivSetup::ORIGINAL) {
+ try {
+ copySetup(BACKUP_SETUP_PATH, SM_POLICY_PATH);
+
+ m_serviceManager.restartService();
+ } catch (...) {
+ RUNNER_ERROR_MSG("Unknown exception occurred during backup restore.");
+ }
+ }
+ }
+
+ void install(SmackPrivSetup setup)
+ {
+ if (setup == m_currentSetup)
+ return;
+
+ // backup setup
+ if (m_currentSetup == SmackPrivSetup::ORIGINAL)
+ copySetup(SM_POLICY_PATH, BACKUP_SETUP_PATH);
+
+ copySetup(TEST_SETUP_PATH / m_setupMap.at(setup), SM_POLICY_PATH);
+ m_currentSetup = setup;
+
+ // restart SM
+ m_serviceManager.restartService();
+ }
+
+ private:
+ void copySetup(const boost::filesystem::path& src, const boost::filesystem::path& dst)
+ {
+ const auto srcConfig = src / SM_SMACK_PRIV_CONFIG;
+ const auto dstConfig = dst / SM_SMACK_PRIV_CONFIG;
+ const auto srcMappingSubdir = src / SM_SMACK_PRIV_MAPPING_SUBDIR;
+ const auto dstMappingSubdir = dst / SM_SMACK_PRIV_MAPPING_SUBDIR;
+
+ // remove dst
+ fs::remove(dstConfig);
+ fs::remove_all(dstMappingSubdir);
+
+ // copy
+ if (fs::exists(srcConfig))
+ fs::copy_file(srcConfig, dstConfig);
+
+ if (fs::exists(srcMappingSubdir)) {
+ fs::create_directory(dstMappingSubdir);
+ for (const auto& e: fs::recursive_directory_iterator(srcMappingSubdir))
+ fs::copy(e.path(), dstMappingSubdir / fs::relative(e.path(), srcMappingSubdir));
+ }
+ }
+
+ SmackPrivSetup m_currentSetup;
+ ServiceManager m_serviceManager;
+ const std::map<SmackPrivSetup, std::string> m_setupMap;
+ };
+
+ static SmackPrivSetupMgr* m_setupMgr;
+
+public:
+ void Init() override {
+ assert(!m_setupMgr);
+
+ m_setupMgr = new SmackPrivSetupMgr();
+ }
+
+ static void Install(SmackPrivSetup setup)
+ {
+ assert(m_setupMgr);
+
+ m_setupMgr->install(setup);
+ }
+
+ void Finish() override {
+ assert(m_setupMgr);
+
+ delete(m_setupMgr);
+ m_setupMgr = nullptr;
+ }
+};
+
+SmackPrivGroupEnv::SmackPrivSetupMgr* SmackPrivGroupEnv::m_setupMgr = nullptr;
+
+template<SmackPrivSetup T>
+class TestSetup
+{
+public:
+ void init(const std::string &) {
+ SmackPrivGroupEnv::Install(T);
+ }
+ void finish() {}
+};
+
+typedef TestSetup<SmackPrivSetup::EMPTY> EmptySetup;
+typedef TestSetup<SmackPrivSetup::INTERNET_ONLY> InternetOnlySetup;
+typedef TestSetup<SmackPrivSetup::MULTIPLE_PRIVS> MultiplePrivsSetup;
+typedef TestSetup<SmackPrivSetup::MALFORMED> MalformedSetup;
+
+} // namespace anonymous
+
+RUNNER_TEST_GROUP_INIT_ENV(SECURITY_MANAGER_SMACK_PRIVILEGES, SmackPrivGroupEnv)
+
+RUNNER_CHILD_TEST(smack_privileges_10_no_privileges, InternetOnlySetup)
+{
+ AppInstallHelperExt app("sm_test_sp_10_app");
+ {
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+ app.checkDeniedPrivileges({PRIV_INTERNET});
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app.checkSmackAccesses(CAMERA_RULES, false);
+ {
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app.checkSmackAccesses(CAMERA_RULES, false);
+ }
+ }
+ app.checkAfterUninstall();
+}
+
+RUNNER_CHILD_TEST(smack_privileges_20_internet_privilege, InternetOnlySetup)
+{
+ AppInstallHelperExt app("sm_test_sp_20_app");
+ app.addPrivileges({PRIV_INTERNET, PRIV_CAMERA});
+ {
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ // rules absent before app is launched
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app.checkSmackAccesses(CAMERA_RULES, false);
+ {
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ app.checkSmackAccesses(CAMERA_RULES, false);
+ }
+ // rules present after app is terminated
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkAfterUninstall();
+ // rules removed after app uninstallation
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_30_one_after_another, InternetOnlySetup)
+{
+ AppInstallHelperExt app("sm_test_sp_30_app");
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ // rules absent before app is launched
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ {
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ // rules present after app is terminated
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ {
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ // rules present after app is terminated
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkAfterUninstall();
+ // rules removed after app uninstallation
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_40_different_users_one_after_another, InternetOnlySetup)
+{
+ TemporaryTestUser testUser("sm_test_40_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ AppInstallHelperExt app("sm_test_sp_40_app");
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ // global install
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // owner launch
+ {
+ app.setUidGid(OWNER_ID);
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ // test user launch
+ {
+ app.setUidGid(testUser.getUid());
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_50_same_user_simultaneously, InternetOnlySetup)
+{
+ AppInstallHelperExt app("sm_test_sp_50_app", OWNER_ID);
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ {
+ ScopedAppLauncher appLaunch1(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ {
+ ScopedAppLauncher appLaunch2(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_60_same_user_interchangeably, InternetOnlySetup)
+{
+ AppInstallHelperExt app("sm_test_sp_60_app", OWNER_ID);
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ // local install
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // owner launch 1
+ auto appLaunch1 = std::make_unique<ScopedAppLauncher>(app);
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ // owner launch 2
+ auto appLaunch2 = std::make_unique<ScopedAppLauncher>(app);
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ // owner terminate 1
+ appLaunch1.reset();
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ // owner terminate 2
+ appLaunch2.reset();
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_70_different_users_simultaneously, InternetOnlySetup)
+{
+ TemporaryTestUser testUser("sm_test_70_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ AppInstallHelperExt app("sm_test_sp_70_app");
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ // global install
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // owner launch
+ {
+ app.setUidGid(OWNER_ID);
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ // test user launch
+ {
+ app.setUidGid(testUser.getUid());
+ ScopedAppLauncher appLaunch(app);
+
+ // multiuser detected -> rules removed
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ }
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ }
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // owner launch
+ {
+ app.setUidGid(OWNER_ID);
+ ScopedAppLauncher appLaunch(app);
+
+ // rules restored
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_80_uninstall_local_while_running, InternetOnlySetup)
+{
+ AppInstallHelperExt app("sm_test_sp_80_app");
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ // global install
+ ScopedInstaller appInstall1(app);
+ app.checkAfterInstall();
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // local install
+ AppInstallHelperExt app2("sm_test_sp_80_app", OWNER_ID);
+ auto appInstall2 = std::make_unique<ScopedInstaller>(app2);
+ app2.checkAfterInstall();
+
+ // global launch
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ // local uninstall
+ appInstall2.reset();
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_90_user_removal, InternetOnlySetup)
+{
+ TemporaryTestUser testUser("sm_test_90_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ AppInstallHelperExt app("sm_test_sp_90_app", testUser.getUid());
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ // local install
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // local launch
+ {
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ // user removal
+ testUser.remove();
+
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ }
+}
+
+RUNNER_CHILD_TEST(smack_privileges_100_hybrid_app, InternetOnlySetup)
+{
+ AppInstallHelperExt app("sm_test_sp_100_app");
+ app.addPrivileges({PRIV_INTERNET});
+ app.setHybrid();
+ {
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // launch
+ {
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_110_hybridity_change, InternetOnlySetup)
+{
+ AppInstallHelperExt app("sm_test_sp_110_app");
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // launch
+ {
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ app.setHybrid();
+
+ // make it hybrid
+ InstallRequest request;
+ request.setAppId(app.getAppId());
+ request.setPkgId(app.getPkgId());
+ request.setUid(app.getUID());
+ request.setHybrid();
+ for (const auto &priv: app.getPrivileges()) {
+ request.addPrivilege(priv);
+ }
+ Api::update(request);
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // launch
+ {
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_120_policy_change_while_running, InternetOnlySetup)
+{
+ TemporaryTestUser testUser("sm_test_120_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ AppInstallHelperExt app("sm_test_sp_120_app", testUser.getUid());
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // launch
+ {
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ // change policy
+ changePolicy(app, PRIV_INTERNET, PolicyEntry::LEVEL_DENY);
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // change policy
+ changePolicy(app, PRIV_INTERNET, PolicyEntry::LEVEL_ALLOW);
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_130_different_users_and_policies, InternetOnlySetup)
+{
+ TemporaryTestUser testUser("sm_test_130_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ AppInstallHelperExt app("sm_test_sp_130_app");
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ // global install
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // test user launch with denied policy
+ {
+ app.setUidGid(testUser.getUid());
+ changePolicy(app, PRIV_INTERNET, PolicyEntry::LEVEL_DENY);
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ }
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // owner launch
+ {
+ app.setUidGid(OWNER_ID);
+ ScopedAppLauncher appLaunch(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_140_two_users_sequence, InternetOnlySetup)
+{
+ TemporaryTestUser testUser("sm_test_140_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ AppInstallHelperExt app("sm_test_sp_140_app");
+ app.addPrivileges({PRIV_INTERNET});
+ {
+ // global install
+ ScopedInstaller appInstall(app);
+ app.checkAfterInstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ {
+ // owner launch -> allowed
+ app.setUidGid(OWNER_ID);
+ ScopedAppLauncher appLaunch1(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ {
+ // test user launch -> denied
+ app.setUidGid(testUser.getUid());
+ ScopedAppLauncher appLaunch2(app);
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // owner launch -> denied
+ app.setUidGid(OWNER_ID);
+ ScopedAppLauncher appLaunch3(app);
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ }
+ // test user launch -> still denied
+ app.setUidGid(testUser.getUid());
+ ScopedAppLauncher appLaunch4(app);
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+ }
+
+ // test user launch -> allowed
+ app.setUidGid(testUser.getUid());
+ ScopedAppLauncher appLaunch5(app);
+ app.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_150_independent_apps, InternetOnlySetup)
+{
+ TemporaryTestUser testUser("sm_test_150_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ AppInstallHelperExt app1("sm_test_sp_150_app1", testUser.getUid());
+ AppInstallHelperExt app2("sm_test_sp_150_app2", testUser.getUid());
+ app1.addPrivileges({PRIV_INTERNET});
+ {
+ ScopedInstaller appInstall1(app1);
+ ScopedInstaller appInstall2(app2);
+
+ app1.checkAfterInstall();
+ app2.checkAfterInstall();
+
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // launch
+ {
+ ScopedAppLauncher appLaunch1(app1);
+ ScopedAppLauncher appLaunch2(app2);
+
+ app1.checkSmackPrivileges({PRIV_INTERNET}, {});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+ }
+ }
+ app1.checkAfterUninstall();
+ app2.checkAfterUninstall();
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_160_nonhybrid_package, InternetOnlySetup)
+{
+ TemporaryTestUser testUser("sm_test_160_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ constexpr char pkgPrefix[] = "sm_test_sp_160_pkg";
+
+ AppInstallHelperExt app1("sm_test_sp_160_app1", pkgPrefix, testUser.getUid());
+ app1.addPrivileges({PRIV_INTERNET});
+
+ AppInstallHelperExt app2("sm_test_sp_160_app2", pkgPrefix, testUser.getUid());
+ app2.addPrivileges({PRIV_INTERNET});
+ {
+ ScopedInstaller appInstall1(app1);
+ ScopedInstaller appInstall2(app2);
+
+ app1.checkAfterInstall();
+ app2.checkAfterInstall();
+
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // launch
+ {
+ ScopedAppLauncher appLaunch1(app1);
+ ScopedAppLauncher appLaunch2(app2);
+
+ // both have access in non-hybrid package
+ app1.checkSmackPrivileges({PRIV_INTERNET}, {});
+ app2.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ // change policy of single app
+ changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_DENY);
+
+ // both should lose the access
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_ALLOW);
+
+ app1.checkSmackPrivileges({PRIV_INTERNET}, {});
+ app2.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ }
+ app1.checkAfterUninstall();
+ app2.checkAfterUninstall();
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+
+RUNNER_CHILD_TEST(smack_privileges_170_hybrid_package, InternetOnlySetup)
+{
+ TemporaryTestUser testUser("sm_test_170_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ constexpr char pkgPrefix[] = "sm_test_sp_170_pkg";
+
+ AppInstallHelperExt app1("sm_test_sp_170_app1", pkgPrefix, testUser.getUid());
+ app1.addPrivileges({PRIV_INTERNET});
+ app1.setHybrid();
+
+ AppInstallHelperExt app2("sm_test_sp_170_app2", pkgPrefix, testUser.getUid());
+ app2.setHybrid();
+ {
+ ScopedInstaller appInstall1(app1);
+ ScopedInstaller appInstall2(app2);
+
+ app1.checkAfterInstall();
+ app2.checkAfterInstall();
+
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // launch
+ {
+ ScopedAppLauncher appLaunch1(app1);
+ ScopedAppLauncher appLaunch2(app2);
+
+ // only one have access in a hybrid package
+ app1.checkSmackPrivileges({PRIV_INTERNET}, {});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // change policy of single app
+ changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_DENY);
+
+ // both should have no access
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_ALLOW);
+
+ app1.checkSmackPrivileges({PRIV_INTERNET}, {});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+ }
+ }
+ app1.checkAfterUninstall();
+ app2.checkAfterUninstall();
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_180_hybrid_package_both_apps_privileged, InternetOnlySetup)
+{
+ TemporaryTestUser testUser("sm_test_180_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ constexpr char pkgPrefix[] = "sm_test_sp_180_pkg";
+
+ AppInstallHelperExt app1("sm_test_sp_180_app1", pkgPrefix, testUser.getUid());
+ app1.addPrivileges({PRIV_INTERNET});
+ app1.setHybrid();
+
+ AppInstallHelperExt app2("sm_test_sp_180_app2", pkgPrefix, testUser.getUid());
+ app2.addPrivileges({PRIV_INTERNET});
+ app2.setHybrid();
+ {
+ ScopedInstaller appInstall1(app1);
+ ScopedInstaller appInstall2(app2);
+
+ app1.checkAfterInstall();
+ app2.checkAfterInstall();
+
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+
+ // launch
+ {
+ ScopedAppLauncher appLaunch1(app1);
+ ScopedAppLauncher appLaunch2(app2);
+
+ // only one have access in a hybrid package
+ app1.checkSmackPrivileges({PRIV_INTERNET}, {});
+ app2.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ // change policy of single app
+ changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_DENY);
+
+ // both should have no access
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({PRIV_INTERNET}, {});
+
+ changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_ALLOW);
+
+ app1.checkSmackPrivileges({PRIV_INTERNET}, {});
+ app2.checkSmackPrivileges({PRIV_INTERNET}, {});
+ }
+ }
+ app1.checkAfterUninstall();
+ app2.checkAfterUninstall();
+ app1.checkSmackPrivileges({}, {PRIV_INTERNET});
+ app2.checkSmackPrivileges({}, {PRIV_INTERNET});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_200_empty_policy, EmptySetup)
+{
+ AppInstallHelperExt app("sm_test_sp_200_app");
+ app.addPrivileges({PRIV_INTERNET, PRIV_CAMERA});
+ {
+ ScopedInstaller appInstall(app);
+
+ app.checkAfterInstall();
+
+ app.checkSmackAccesses(INTERNET_RULES, false);
+ app.checkSmackAccesses(CAMERA_RULES, false);
+ {
+ ScopedAppLauncher appLaunch(app);
+
+ // no config -> no access
+ app.checkSmackAccesses(INTERNET_RULES, false);
+ app.checkSmackAccesses(CAMERA_RULES, false);
+ }
+ }
+ app.checkAfterUninstall();
+ app.checkSmackAccesses(INTERNET_RULES, false);
+ app.checkSmackAccesses(CAMERA_RULES, false);
+}
+
+RUNNER_CHILD_TEST(smack_privileges_300_multi_policy_no_privs, MultiplePrivsSetup)
+{
+ AppInstallHelperExt app("sm_test_sp_300_app");
+ {
+ ScopedInstaller appInstall(app);
+
+ app.checkAfterInstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET, PRIV_CAMERA});
+ app.checkSmackAccesses(CAMERA_IGNORED_RULES, false);
+ {
+ ScopedAppLauncher appLaunch(app);
+
+ app.checkSmackPrivileges({}, {PRIV_INTERNET, PRIV_CAMERA});
+ app.checkSmackAccesses(CAMERA_IGNORED_RULES, false);
+ }
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET, PRIV_CAMERA});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_310_multi_policy_single_priv, MultiplePrivsSetup)
+{
+ AppInstallHelperExt app("sm_test_sp_310_app");
+ app.addPrivilege(PRIV_CAMERA);
+ {
+ ScopedInstaller appInstall(app);
+
+ app.checkAfterInstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET, PRIV_CAMERA});
+ app.checkSmackAccesses(CAMERA_IGNORED_RULES, false);
+ {
+ ScopedAppLauncher appLaunch(app);
+
+ app.checkSmackPrivileges({PRIV_CAMERA}, {PRIV_INTERNET});
+ app.checkSmackAccesses(CAMERA_IGNORED_RULES, false);
+ }
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET, PRIV_CAMERA});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_320_multi_policy_all_privs, MultiplePrivsSetup)
+{
+ TemporaryTestUser testUser("sm_test_320_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ AppInstallHelperExt app("sm_test_sp_320_app", testUser.getUid());
+ app.addPrivileges({PRIV_CAMERA, PRIV_INTERNET});
+ {
+ ScopedInstaller appInstall(app);
+
+ app.checkAfterInstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET, PRIV_CAMERA});
+ app.checkSmackAccesses(CAMERA_IGNORED_RULES, false);
+ {
+ ScopedAppLauncher appLaunch(app);
+
+ app.checkSmackPrivileges({PRIV_CAMERA, PRIV_INTERNET}, {});
+ app.checkSmackAccesses(CAMERA_IGNORED_RULES, false);
+
+ // change policy
+ changePolicy(app, PRIV_INTERNET, PolicyEntry::LEVEL_DENY);
+
+ app.checkSmackPrivileges({PRIV_CAMERA}, {PRIV_INTERNET});
+ app.checkSmackAccesses(CAMERA_IGNORED_RULES, false);
+
+ // change policy
+ changePolicy(app, PRIV_INTERNET, PolicyEntry::LEVEL_ALLOW);
+ changePolicy(app, PRIV_CAMERA, PolicyEntry::LEVEL_DENY);
+
+ app.checkSmackPrivileges({PRIV_INTERNET}, {PRIV_CAMERA});
+ app.checkSmackAccesses(CAMERA_IGNORED_RULES, false);
+ }
+ }
+ app.checkAfterUninstall();
+ app.checkSmackPrivileges({}, {PRIV_INTERNET, PRIV_CAMERA});
+}
+
+RUNNER_CHILD_TEST(smack_privileges_400_malformed, MalformedSetup)
+{
+ AppInstallHelperExt app("sm_test_sp_400_app");
+ app.addPrivileges({PRIV_INTERNET, PRIV_CAMERA});
+ {
+ ScopedInstaller appInstall(app);
+
+ app.checkAfterInstall();
+
+ app.checkSmackAccesses(INTERNET_RULES, false);
+ app.checkSmackAccesses(CAMERA_RULES, false);
+ {
+ ScopedAppLauncher appLaunch(app);
+
+ // malformed config -> no access
+ app.checkSmackAccesses(INTERNET_RULES, false);
+ app.checkSmackAccesses(CAMERA_RULES, false);
+ }
+ }
+ app.checkAfterUninstall();
+ app.checkSmackAccesses(INTERNET_RULES, false);
+ app.checkSmackAccesses(CAMERA_RULES, false);
+}