*/
#include <memory>
+#include <map>
+#include <cassert>
+
+#include <boost/filesystem.hpp>
#include <tzplatform_config.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);
Api::sendPolicy(policyRequest);
}
+enum class SmackPrivSetup {
+ ORIGINAL,
+ EMPTY,
+ INTERNET_ONLY,
+ // TODO test other configurations
+};
+
+// 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" }})
+ {
+ }
+ 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 std::unique_ptr<SmackPrivSetupMgr> m_setupMgr;
+
+public:
+ void Init() override {
+ assert(!m_setupMgr);
+
+ m_setupMgr.reset(new SmackPrivSetupMgr());
+ }
+
+ static void Install(SmackPrivSetup setup)
+ {
+ assert(m_setupMgr);
+
+ m_setupMgr->install(setup);
+ }
+
+ void Finish() override {
+ assert(m_setupMgr);
+
+ m_setupMgr.reset();
+ }
+};
+
+std::unique_ptr<SmackPrivGroupEnv::SmackPrivSetupMgr> SmackPrivGroupEnv::m_setupMgr;
+
} // namespace anonymous
-RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_SMACK_PRIVILEGES)
+RUNNER_TEST_GROUP_INIT_ENV(SECURITY_MANAGER_SMACK_PRIVILEGES, SmackPrivGroupEnv)
RUNNER_CHILD_TEST(smack_privileges_10_no_privileges)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
AppInstallHelperExt app("sm_test_sp_10_app");
{
ScopedInstaller appInstall(app);
RUNNER_CHILD_TEST(smack_privileges_20_internet_privilege)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
AppInstallHelperExt app("sm_test_sp_20_app");
app.addPrivileges({PRIV_INTERNET});
{
RUNNER_CHILD_TEST(smack_privileges_30_one_after_another)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
AppInstallHelperExt app("sm_test_sp_30_app");
app.addPrivileges({PRIV_INTERNET});
{
RUNNER_CHILD_TEST(smack_privileges_40_different_users_one_after_another)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
TemporaryTestUser testUser("sm_test_40_user_name", GUM_USERTYPE_NORMAL, true);
testUser.create();
RUNNER_CHILD_TEST(smack_privileges_50_same_user_simultaneously)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
AppInstallHelperExt app("sm_test_sp_50_app", OWNER_ID);
app.addPrivileges({PRIV_INTERNET});
{
RUNNER_CHILD_TEST(smack_privileges_60_same_user_interchangeably)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
AppInstallHelperExt app("sm_test_sp_60_app", OWNER_ID);
app.addPrivileges({PRIV_INTERNET});
{
RUNNER_CHILD_TEST(smack_privileges_70_different_users_simultaneously)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
TemporaryTestUser testUser("sm_test_70_user_name", GUM_USERTYPE_NORMAL, true);
testUser.create();
RUNNER_CHILD_TEST(smack_privileges_80_uninstall_local_while_running)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
AppInstallHelperExt app("sm_test_sp_80_app");
app.addPrivileges({PRIV_INTERNET});
{
RUNNER_CHILD_TEST(smack_privileges_90_user_removal)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
TemporaryTestUser testUser("sm_test_90_user_name", GUM_USERTYPE_NORMAL, true);
testUser.create();
RUNNER_CHILD_TEST(smack_privileges_100_hybrid_app)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
AppInstallHelperExt app("sm_test_sp_100_app");
app.addPrivileges({PRIV_INTERNET});
app.setHybrid();
RUNNER_CHILD_TEST(smack_privileges_110_hybridity_change)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
AppInstallHelperExt app("sm_test_sp_110_app");
app.addPrivileges({PRIV_INTERNET});
{
RUNNER_CHILD_TEST(smack_privileges_120_policy_change_while_running)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
TemporaryTestUser testUser("sm_test_120_user_name", GUM_USERTYPE_NORMAL, true);
testUser.create();
RUNNER_CHILD_TEST(smack_privileges_130_different_users_and_policies)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
TemporaryTestUser testUser("sm_test_130_user_name", GUM_USERTYPE_NORMAL, true);
testUser.create();
RUNNER_CHILD_TEST(smack_privileges_140_two_users_sequence)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
TemporaryTestUser testUser("sm_test_140_user_name", GUM_USERTYPE_NORMAL, true);
testUser.create();
RUNNER_CHILD_TEST(smack_privileges_150_independent_apps)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
TemporaryTestUser testUser("sm_test_150_user_name", GUM_USERTYPE_NORMAL, true);
testUser.create();
RUNNER_CHILD_TEST(smack_privileges_160_nonhybrid_package)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
TemporaryTestUser testUser("sm_test_160_user_name", GUM_USERTYPE_NORMAL, true);
testUser.create();
RUNNER_CHILD_TEST(smack_privileges_170_hybrid_package)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
TemporaryTestUser testUser("sm_test_170_user_name", GUM_USERTYPE_NORMAL, true);
testUser.create();
RUNNER_CHILD_TEST(smack_privileges_180_hybrid_package_both_apps_privileged)
{
+ SmackPrivGroupEnv::Install(SmackPrivSetup::INTERNET_ONLY);
+
TemporaryTestUser testUser("sm_test_180_user_name", GUM_USERTYPE_NORMAL, true);
testUser.create();