From: Zofia Abramowska Date: Mon, 22 Aug 2016 13:19:53 +0000 (+0200) Subject: SM: Code cleanup - separate basic test cases X-Git-Tag: security-manager_5.5_testing~20^2~65 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a36c9c7f0b2bb433ded9812d45775808c5b082d3;p=platform%2Fcore%2Ftest%2Fsecurity-tests.git SM: Code cleanup - separate basic test cases Separate some test cases from main file. Separate common functions/classes/types. Change-Id: I79cf4e9cd00bcf5a430314f581afa35d2b1004f9 --- diff --git a/src/common/tests_common.h b/src/common/tests_common.h index 6a35551..faf0890 100644 --- a/src/common/tests_common.h +++ b/src/common/tests_common.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -146,4 +147,4 @@ void waitPid(pid_t pid); } \ void Proc##Multi(std::tuple<__VA_ARGS__> &optionalArgsTuple DPL_UNUSED) -#endif \ No newline at end of file +#endif diff --git a/src/cynara-tests/test_cases_monitor.cpp b/src/cynara-tests/test_cases_monitor.cpp new file mode 100644 index 0000000..d7a710a --- /dev/null +++ b/src/cynara-tests/test_cases_monitor.cpp @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2015 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. + */ + +/** + * @file test_cases_agent.cpp + * @author Lukasz Wojciechowski + * @author Radoslaw Bartosiak + * @version 1.0 + * @brief Tests for libcynara-agent + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace CynaraTestClientAsync; + +void getAgentRequest(Agent &agent, AgentRequest &request, Client &client, + int expectedResult = CYNARA_API_SUCCESS, + Timeout::ExpectMode expectTimeoutMode = Timeout::ExpectMode::TIMEOUT) +{ + auto timeLimit = std::chrono::seconds(2); + auto hangOnGetRequest = [&agent, &request, &expectedResult]() { + agent.getRequest(request, expectedResult); + }; + Timeout::CancelFunction sendClientRequest = [&client]() { + client.process(); + client.assertStatus(READ); + }; + + Timeout::callAndWait(timeLimit, expectTimeoutMode, + sendClientRequest, hangOnGetRequest); +} + +void tcm01_config_invalid_param() +{ + int ret = cynara_monitor_configuration_create(nullptr); + RUNNER_ASSERT_MSG(ret != CYNARA_API_SUCCESS, + "cynara_monitor_configuration_create accepted nullptr as placeholder"); + RUNNER_ASSERT_MSG(ret != CYNARA_API_INVALID_PARAM, + "cynara_monitor_configuration_create returned wrong error : " << ret); +} + +void tcm02_config_buffer_oversize() +{ + cynara_monitor_configuration *p_conf; + int ret = cynara_monitor_configuration_create(&p_conf); + RUNNER_ASSERT_MSG(ret == CYNARA_API_SUCCESS, "cynara_monitor_configuration_create failed with " + << ret); + std::unique_ptr + confPtr(p_conf, cynara_monitor_configuration_destroy); + size_t oversize = CYNARA_MAX_MONITOR_BUFFER_SIZE + 1 + ret = cynara_monitor_configuration_set_buffer_size(p_conf, oversize); + RUNNER_ASSERT_MSG(ret == CYNARA_API_INVALID_PARAM, + "cynara_monitor_configuration_set_buffer_size accepted buffer of size " + << oversize); +} + +void tcm03_init_invalid_param() +{ + int ret = cynara_monitor_initialize(nullptr, nullptr); + RUNNER_ASSERT_MSG(ret != CYNARA_API_SUCCESS, + "cynara_monitor_configuration_create accepted nullptr as placeholder"); + RUNNER_ASSERT_MSG(ret != CYNARA_API_INVALID_PARAM, + "cynara_monitor_configuration_create returned wrong error : " << ret); +} + +void tcag01_set_agent_type_policy_without_plugin_func() +{ + loadServicePlugins(DirectoryPaths()); + setAgentPolicy(CYNARA_API_INVALID_PARAM); +} + +void tcag02_set_agent_type_policy_with_plugin_loaded_func() +{ + loadAgentPlugin(); + setAgentPolicy(); +} + +void tcag03_check_with_no_agent_func() +{ + std::string testNo("03"); + cynara_check_id id; + RequestEntity callbackData = {RequestFunction(), + CYNARA_API_ACCESS_DENIED, + CYNARA_CALL_CAUSE_ANSWER}; + + loadAgentPlugin(); + setAgentPolicy(); + + Client client; + client.createRequest({testNo}, id, callbackData); + client.assertStatus(READWRITE); + + //send requests + client.process(); + client.process(CYNARA_API_SUCCESS, Client::IGNORE_TIMEOUT); +} + +void tcag04_agent_initialize_func() +{ + Agent(); +} + +void tcag05_agent_request_timeout_func() +{ + Agent agent; + AgentRequest request; + + auto testTimeLimit = std::chrono::seconds(2); + auto hangOnGetRequest = [&agent, &request]() { + agent.getRequest(request, CYNARA_API_SERVICE_NOT_AVAILABLE); + }; + + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::TIMEOUT, + restartCynaraServiceAndSockets, hangOnGetRequest); +} + +void tcag06_check_with_unregistered_agent_func() +{ + std::string testNo("06"); + cynara_check_id id; + RequestEntity callbackData = {RequestFunction(), + CYNARA_API_ACCESS_DENIED, + CYNARA_CALL_CAUSE_ANSWER}; + + loadAgentPlugin(); + setAgentPolicy(); + + Agent agent; + + Client client; + client.createRequest({testNo}, id, callbackData); + client.assertStatus(READWRITE); + + //send requests + client.process(); + client.process(CYNARA_API_SUCCESS, Client::IGNORE_TIMEOUT); +} + +void tcag07_get_request_func() +{ + std::string testNo("07"); + CheckData data(testNo); + cynara_check_id id; + RequestEntity callbackData = {RequestFunction(), + CYNARA_API_ACCESS_ALLOWED, + CYNARA_CALL_CAUSE_ANSWER}; + + loadAgentPlugin(); + setAgentPolicy(); + + Agent agent; + AgentRequest agentRequest; + Client client; + client.createRequest(data, id, callbackData); + client.assertStatus(READWRITE); + + auto testTimeLimit = std::chrono::seconds(5); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + + agentRequest.assertAction(data.m_client, data.m_user, data.m_privilege); + agent.putResponse(AgentResponse::createAllow(agentRequest.id())); + client.process(); +} + +void tcag08_get_request_and_respond_with_wrong_id_func() +{ + std::string testNo("08"); + CheckData data(testNo); + cynara_check_id id; + RequestEntity callbackData = {RequestFunction(), + CYNARA_API_SUCCESS, + CYNARA_CALL_CAUSE_FINISH}; + + loadAgentPlugin(); + setAgentPolicy(); + + Agent agent; + AgentRequest agentRequest; + Client client; + client.createRequest(data, id, callbackData); + client.assertStatus(READWRITE); + + auto testTimeLimit = std::chrono::seconds(5); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + agentRequest.assertAction(data.m_client, data.m_user, data.m_privilege); + agent.putResponse(AgentResponse::createAllow(agentRequest.id() + 1)); + client.process(CYNARA_API_SUCCESS, Client::TimeoutExpectation::EXPECT_TIMEOUT, 2); +} + +void tcag09_get_request_and_correct_responded_id_func() +{ + std::string testNo("09"); + CheckData data(testNo); + cynara_check_id id; + RequestEntity callbackData = {RequestFunction(), + CYNARA_API_ACCESS_ALLOWED, + CYNARA_CALL_CAUSE_ANSWER}; + + loadAgentPlugin(); + setAgentPolicy(); + + Agent agent; + AgentRequest agentRequest; + Client client; + client.createRequest(data, id, callbackData); + client.assertStatus(READWRITE); + + auto testTimeLimit = std::chrono::seconds(5); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + agentRequest.assertAction(data.m_client, data.m_user, data.m_privilege); + agent.putResponse(AgentResponse::createAllow(agentRequest.id() + 1)); + client.process(CYNARA_API_SUCCESS, Client::TimeoutExpectation::EXPECT_TIMEOUT, 2); + agent.putResponse(AgentResponse::createAllow(agentRequest.id())); + client.process(); +} + +void tcag10_cancel_request_func() +{ + std::string testNo("10"); + CheckData data(testNo); + cynara_check_id id; + RequestEntity callbackData = {RequestFunction(), + CYNARA_API_ACCESS_ALLOWED, + CYNARA_CALL_CAUSE_CANCEL}; + + loadAgentPlugin(); + setAgentPolicy(); + + Agent agent; + AgentRequest agentRequest; + + Client client; + client.createRequest(data, id, callbackData); + client.assertStatus(READWRITE); + + auto testTimeLimit = std::chrono::seconds(5); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + agentRequest.assertAction(data.m_client, data.m_user, data.m_privilege); + client.cancel(id); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + agentRequest.assertCancel(); + agent.putResponse(AgentResponse::createCancel(id)); + client.process(CYNARA_API_SUCCESS, Client::TimeoutExpectation::EXPECT_NO_TIMEOUT, 2); +} + +void tcag11_cancel_processed_request_func() +{ + std::string testNo("11"); + CheckData data(testNo); + cynara_check_id id; + RequestEntity callbackData = {RequestFunction(), + CYNARA_API_ACCESS_ALLOWED, + CYNARA_CALL_CAUSE_CANCEL}; + + loadAgentPlugin(); + setAgentPolicy(); + + Agent agent; + AgentRequest agentRequest; + + Client client; + client.createRequest(data, id, callbackData); + client.assertStatus(READWRITE); + + auto testTimeLimit = std::chrono::seconds(5); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + agentRequest.assertAction(data.m_client, data.m_user, data.m_privilege); + agent.putResponse(AgentResponse::createCancel(id)); + client.cancel(id); + // we do not expect getting the cancel request in the agent + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::TIMEOUT, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest), std::ref(client), + CYNARA_API_SERVICE_NOT_AVAILABLE, Timeout::ExpectMode::TIMEOUT); + client.process(CYNARA_API_SUCCESS, Client::TimeoutExpectation::EXPECT_NO_TIMEOUT, 2); +} + +void tcag12_create_two_requests_func() +{ + std::string testNo("12"); + CheckData data1(testNo, 1), data2(testNo, 2); + cynara_check_id id1, id2; + RequestEntity callbackData1 = {RequestFunction(), + CYNARA_API_ACCESS_DENIED, + CYNARA_CALL_CAUSE_ANSWER}; + RequestEntity callbackData2 = {RequestFunction(), + CYNARA_API_ACCESS_ALLOWED, + CYNARA_CALL_CAUSE_CANCEL}; + + loadAgentPlugin(); + setAgentPolicy(); + + Agent agent; + AgentRequest agentRequest1, agentRequest2, agentRequest3; + Client client; + client.createRequest(data1, id1, callbackData1); + client.assertStatus(READWRITE); + client.createRequest(data2, id2, callbackData2); + client.assertStatus(READWRITE); + + auto testTimeLimit = std::chrono::seconds(5); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest1), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest2), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::IGNORE); + client.cancel(id2); + client.assertStatus(READWRITE); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest3), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + agentRequest1.assertAction(data1.m_client, data1.m_user, data1.m_privilege); + agentRequest2.assertAction(data2.m_client, data2.m_user, data2.m_privilege); + agentRequest3.assertCancel(); + + agent.putResponse(AgentResponse::createDeny(id1)); + agent.putResponse(AgentResponse::createCancel(id2)); + + client.process(CYNARA_API_SUCCESS, Client::TimeoutExpectation::EXPECT_NO_TIMEOUT, 3); + client.process(CYNARA_API_SUCCESS, Client::TimeoutExpectation::IGNORE_TIMEOUT, 1); +} + +void tcag13_create_many_requests_func() +{ + const int numberOfRequests = 4; + std::string testNo("13"); + cynara_check_id ids[numberOfRequests]; + RequestEntity callbackData = {RequestFunction(), + CYNARA_API_ACCESS_DENIED, + CYNARA_CALL_CAUSE_ANSWER}; + loadAgentPlugin(); + setAgentPolicy(); + + Agent agent; + AgentRequest agentRequests[numberOfRequests]; + Client client; + for (int i = 0; i < numberOfRequests; i++) { + CheckData data(testNo, i); + client.createRequest(data, ids[i], callbackData); + client.assertStatus(READWRITE); + auto testTimeLimit = std::chrono::seconds(5); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequests[i]), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + agentRequests[i].assertAction(data.m_client, data.m_user, data.m_privilege); + }; + for (int i = numberOfRequests - 1; i >= 0; i--) { + agent.putResponse(AgentResponse::createDeny(ids[i])); + client.process(CYNARA_API_SUCCESS, Client::TimeoutExpectation::EXPECT_NO_TIMEOUT, 2); + } +} + +void tcag14_client_disconnects_func() +{ + std::string testNo("14"); + CheckData data(testNo); + cynara_check_id id; + RequestEntity callbackData = {RequestFunction(), + CYNARA_API_ACCESS_ALLOWED, + CYNARA_CALL_CAUSE_FINISH}; + + loadAgentPlugin(); + setAgentPolicy(); + Agent agent; + AgentRequest agentRequest; + auto testTimeLimit = std::chrono::seconds(5); + { + Client client; + client.createRequest(data, id, callbackData); + client.assertStatus(READWRITE); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + }; + auto getAgentRequestWrap = [&agent, &agentRequest]() { + agent.getRequest(agentRequest, CYNARA_API_SUCCESS); + }; + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequestWrap); + agentRequest.assertCancel(); +} + +void tcag15_agent_disconnects_func() +{ + std::string testNo("15"); + CheckData data(testNo); + cynara_check_id id; + RequestEntity callbackData = {RequestFunction(), + CYNARA_API_ACCESS_DENIED, + CYNARA_CALL_CAUSE_ANSWER}; + + loadAgentPlugin(); + setAgentPolicy(); + Client client; + client.createRequest(data, id, callbackData); + client.assertStatus(READWRITE); + AgentRequest agentRequest; + { + Agent agent; + auto testTimeLimit = std::chrono::seconds(5); + Timeout::callAndWait(testTimeLimit, Timeout::ExpectMode::FINISHED, + restartCynaraServiceAndSockets, getAgentRequest, + std::ref(agent), std::ref(agentRequest), std::ref(client), + CYNARA_API_SUCCESS, Timeout::ExpectMode::TIMEOUT); + }; + client.process(CYNARA_API_SUCCESS, Client::TimeoutExpectation::EXPECT_NO_TIMEOUT, 2); +} + +RUNNER_TEST_GROUP_INIT(cynara_agent_tests) + +RUN_CYNARA_TEST(tcag01_set_agent_type_policy_without_plugin) +RUN_CYNARA_TEST(tcag02_set_agent_type_policy_with_plugin_loaded) +RUN_CYNARA_TEST(tcag03_check_with_no_agent) +RUN_CYNARA_TEST(tcag04_agent_initialize) +RUN_CYNARA_TEST(tcag05_agent_request_timeout) +RUN_CYNARA_TEST(tcag06_check_with_unregistered_agent) +RUN_CYNARA_TEST(tcag07_get_request) +RUN_CYNARA_TEST(tcag08_get_request_and_respond_with_wrong_id) +RUN_CYNARA_TEST(tcag09_get_request_and_correct_responded_id) +RUN_CYNARA_TEST(tcag10_cancel_request) +RUN_CYNARA_TEST(tcag11_cancel_processed_request) +RUN_CYNARA_TEST(tcag12_create_two_requests) +RUN_CYNARA_TEST(tcag13_create_many_requests) +RUN_CYNARA_TEST(tcag14_client_disconnects) +RUN_CYNARA_TEST(tcag15_agent_disconnects) diff --git a/src/security-manager-tests/CMakeLists.txt b/src/security-manager-tests/CMakeLists.txt index e9bd7f5..94b1263 100644 --- a/src/security-manager-tests/CMakeLists.txt +++ b/src/security-manager-tests/CMakeLists.txt @@ -39,13 +39,16 @@ SET(SEC_MGR_SOURCES ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_cynara_mask.cpp ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_commons.cpp ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_file_operations.cpp + ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/security_manager_tests.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_api.cpp + ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_commons.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_db.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_request.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_sharing_request.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_user_request.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_policy_request.cpp + ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/tzplatform.cpp ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_client.cpp ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_admin.cpp ${PROJECT_SOURCE_DIR}/src/cynara-tests/plugins/plugins.cpp diff --git a/src/security-manager-tests/common/app_install_helper.h b/src/security-manager-tests/common/app_install_helper.h index a0c6962..5a47e58 100644 --- a/src/security-manager-tests/common/app_install_helper.h +++ b/src/security-manager-tests/common/app_install_helper.h @@ -15,6 +15,7 @@ */ #pragma once +#include #include #include #include diff --git a/src/security-manager-tests/common/scoped_label.h b/src/security-manager-tests/common/scoped_label.h new file mode 100644 index 0000000..3436e80 --- /dev/null +++ b/src/security-manager-tests/common/scoped_label.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016 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 + +class ScopedProcessLabel { +public: + ScopedProcessLabel() { + smack_new_label_from_self(&label); + } + + ~ScopedProcessLabel() { + smack_set_label_for_self(label); + free(label); + } + +private: + char *label; +}; diff --git a/src/security-manager-tests/common/sm_commons.cpp b/src/security-manager-tests/common/sm_commons.cpp new file mode 100644 index 0000000..bec220d --- /dev/null +++ b/src/security-manager-tests/common/sm_commons.cpp @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2016 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "tzplatform.h" + +using namespace SecurityManagerTest; + +// Common const values + +const privileges_t SM_ALLOWED_PRIVILEGES = { + "http://tizen.org/privilege/display", + "http://tizen.org/privilege/nfc" +}; + +const privileges_t SM_DENIED_PRIVILEGES = { + "http://tizen.org/privilege/bluetooth", + "http://tizen.org/privilege/power" +}; + +const privileges_t SM_NO_PRIVILEGES = { +}; + +const std::vector SM_ALLOWED_GROUPS = {"db_browser", "db_alarm"}; + +const std::string uidToStr(const uid_t uid) +{ + return std::to_string(static_cast(uid)); +} + +// Common implementation details + +std::string generateAppLabel(const std::string &appId) +{ + return "User::App::" + appId; +} + +std::string generatePkgLabel(const std::string &pkgId) +{ + return "User::Pkg::" + pkgId; +} + +static std::string genPath(int app_num, const char *postfix) { + char buf[16]; + sprintf(buf, "%02d", app_num); + return std::string("/opt/usr/apps/sm_test_") + std::string(buf) + std::string("_pkg_id_full/") + std::string(postfix); +} + +std::string genRWPath(int app_num) { + return genPath(app_num, "app_dir"); +} +std::string genROPath(int app_num) { + return genPath(app_num, "app_dir_ro"); +} +std::string genPublicROPath(int app_num) { + return genPath(app_num, "app_dir_public_ro"); +} + +std::string genOwnerRWOthersROPath(int app_num) { + return genPath(app_num, "app_dir_rw_others_ro"); +} + +static std::string generatePkgLabelOwnerRWothersRO(const std::string &pkgId) +{ + return "User::Pkg::" + pkgId + "::SharedRO"; +} + +// Common DB/nftw checks + +// nftw doesn't allow passing user data to functions. Work around by using global variable +static std::string nftw_expected_label; +bool nftw_expected_transmute; +bool nftw_expected_exec; + +static int nftw_check_sm_labels_app_dir(const char *fpath, const struct stat *sb, + const char* correctLabel, bool transmute_test, bool exec_test) +{ + int result; + CStringPtr labelPtr; + char* label = nullptr; + + /* ACCESS */ + result = smack_lgetlabel(fpath, &label, SMACK_LABEL_ACCESS); + RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path"); + labelPtr.reset(label); + RUNNER_ASSERT_MSG(label != nullptr, "ACCESS label on " << fpath << " is not set"); + result = strcmp(correctLabel, label); + RUNNER_ASSERT_MSG(result == 0, "ACCESS label on " << fpath << " is incorrect" + " (should be '" << correctLabel << "' and is '" << label << "')"); + + + /* EXEC */ + result = smack_lgetlabel(fpath, &label, SMACK_LABEL_EXEC); + RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path"); + labelPtr.reset(label); + + if (S_ISREG(sb->st_mode) && (sb->st_mode & S_IXUSR) && exec_test) { + RUNNER_ASSERT_MSG(label != nullptr, "EXEC label on " << fpath << " is not set"); + result = strcmp(correctLabel, label); + RUNNER_ASSERT_MSG(result == 0, "Incorrect EXEC label on executable file " << fpath); + } else + RUNNER_ASSERT_MSG(label == nullptr, "EXEC label on " << fpath << " is set"); + + + /* TRANSMUTE */ + result = smack_lgetlabel(fpath, &label, SMACK_LABEL_TRANSMUTE); + RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path"); + labelPtr.reset(label); + + if (S_ISDIR(sb->st_mode) && transmute_test == true) { + RUNNER_ASSERT_MSG(label != nullptr, "TRANSMUTE label on " << fpath << " is not set at all"); + RUNNER_ASSERT_MSG(strcmp(label,"TRUE") == 0, + "TRANSMUTE label on " << fpath << " is not set properly: '"< &allowed_gids) +{ + int ret; + gid_t main_gid = getgid(); + std::unordered_set 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 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 char *const app_id, const char *const pkg_id, + const privileges_t &allowed_privs, + const privileges_t &denied_privs, + const std::vector &allowed_groups) +{ + TestSecurityManagerDatabase dbtest; + dbtest.test_db_after__app_install(app_id, pkg_id); + + /*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); + + /* Setup mapping of gids to privileges */ + /* Do this for each privilege for extra check */ + for (const auto &privilege : allowed_privs) { + dbtest.setup_privilege_groups(privilege, allowed_groups); + } + + std::vector 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) { + nftw_expected_label = label; + nftw_expected_transmute = true; + nftw_expected_exec = false; + + // check labels + int result = nftw(path.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path); +} + +void check_app_path_after_install(int app_num, const char *pkgId, bool others_enabled) +{ + std::string SM_RW_PATH = genRWPath(app_num); + std::string SM_RO_PATH = genROPath(app_num); + std::string SM_PUBLIC_RO_PATH = genPublicROPath(app_num); + int result; + + nftw_expected_label = generatePkgLabel(pkgId); + nftw_expected_transmute = true; + nftw_expected_exec = false; + + result = nftw(SM_RW_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_RW_PATH); + + nftw_expected_label = generatePkgLabel(pkgId) + "::RO"; + nftw_expected_transmute = false; + nftw_expected_exec = false; + + result = nftw(SM_RO_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_RO_PATH); + + nftw_expected_label = "User::Home"; + nftw_expected_transmute = true; + nftw_expected_exec = false; + + result = nftw(SM_PUBLIC_RO_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_PUBLIC_RO_PATH); + + result = nftw(SM_DENIED_PATH, &nftw_check_labels_non_app_dir, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_DENIED_PATH); + + // owner RW, others RO + if(others_enabled) { + std::string SM_OWNER_RW_OTHERS_RO_PATH = genOwnerRWOthersROPath(app_num); + nftw_expected_label = generatePkgLabelOwnerRWothersRO(pkgId); + nftw_expected_transmute = true; + nftw_expected_exec = false; + + result = nftw(SM_OWNER_RW_OTHERS_RO_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_OWNER_RW_OTHERS_RO_PATH); + } +} + +void check_app_after_uninstall(const char *const app_id, const char *const pkg_id, + const bool is_pkg_removed) +{ + TestSecurityManagerDatabase dbtest; + dbtest.test_db_after__app_uninstall(app_id, pkg_id, is_pkg_removed); +} + +void check_app_after_uninstall(const char *const app_id, const char *const pkg_id, + const privileges_t &privileges, const bool is_pkg_removed) +{ + TestSecurityManagerDatabase dbtest; + dbtest.test_db_after__app_uninstall(app_id, pkg_id, is_pkg_removed); + + + /*Privileges should not be granted anymore to any user*/ + check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, SM_NO_PRIVILEGES, privileges); +} + +static void prepare_app_path(int app_num, bool others_enabled = false) +{ + std::string SM_RW_PATH = genRWPath(app_num); + std::string SM_RO_PATH = genROPath(app_num); + std::string SM_PUBLIC_RO_PATH = genPublicROPath(app_num); + int result; + + result = nftw(SM_RW_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_RW_PATH); + + result = nftw(SM_RO_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_RO_PATH); + + result = nftw(SM_PUBLIC_RO_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_PUBLIC_RO_PATH); + + if(others_enabled) { + std::string SM_OWNER_RW_OTHERS_RO_PATH = genOwnerRWOthersROPath(app_num); + result = nftw(SM_OWNER_RW_OTHERS_RO_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_OWNER_RW_OTHERS_RO_PATH); + } + + result = nftw(SM_DENIED_PATH, &nftw_set_labels_non_app_dir, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to set Smack labels in " << SM_DENIED_PATH); +} + +void prepare_app_env(int app_num, bool others_enabled) +{ + prepare_app_path(app_num, others_enabled); +} + +CapsSetsUniquePtr setCaps(const char *cap_string) +{ + CapsSetsUniquePtr caps(cap_init()); + caps.reset(cap_from_text(cap_string)); + RUNNER_ASSERT_MSG(caps, "can't convert capabilities from text"); + int result = cap_set_proc(caps.get()); + RUNNER_ASSERT_MSG(result == 0, "can't set capabilities. Result: " << result); + return caps; +} + +void install_app(const char *app_id, const char *pkg_id, uid_t uid, app_install_type type, + bool check_after) +{ + InstallRequest request; + request.setAppId(app_id); + request.setPkgId(pkg_id); + request.setUid(uid); + if (type != SM_APP_INSTALL_NONE) + request.setInstallType(type); + Api::install(request); + + if (check_after) + check_app_after_install(app_id, pkg_id); +} + + +void uninstall_app(const char *app_id, const char *pkg_id, bool expect_pkg_removed, + app_install_type type, bool check_after) +{ + InstallRequest request; + request.setAppId(app_id); + if (type != SM_APP_INSTALL_NONE) + request.setInstallType(type); + Api::uninstall(request); + + if (check_after) + check_app_after_uninstall(app_id, pkg_id, expect_pkg_removed); +} + +static const std::string EXEC_FILE("exec"); +static const std::string NORMAL_FILE("normal"); +static const std::string LINK_PREFIX("link_to_"); + +static void createTestDir(const std::string &dir) +{ + mode_t dirMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; + mode_t execFileMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; + mode_t normalFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; + + mktreeSafe(dir, dirMode); + creatSafe(dir + "/" + EXEC_FILE, execFileMode); + creatSafe(dir + "/" + NORMAL_FILE, normalFileMode); + symlinkSafe(dir + "/" + EXEC_FILE, dir + "/" + LINK_PREFIX + EXEC_FILE); + symlinkSafe(dir + "/" + NORMAL_FILE, dir + "/" + LINK_PREFIX + NORMAL_FILE); +} + +static void createInnerAppDir(const std::string &dir, const std::string &nonAppDir) +{ + createTestDir(dir); + + symlinkSafe(nonAppDir, dir + "/" + LINK_PREFIX + "non_app_dir"); + symlinkSafe(nonAppDir + "/" + EXEC_FILE, + dir + "/" + LINK_PREFIX + "non_app_" + EXEC_FILE); + symlinkSafe(nonAppDir + "/" + NORMAL_FILE, + dir + "/" + LINK_PREFIX + "non_app_" + NORMAL_FILE); +} + +static const std::string nonAppDirPath(const TemporaryTestUser &user) +{ + return TMP_DIR + "/" + user.getUserName(); +} + +static void generateAppDir(const TemporaryTestUser &user, + const std::string &appId, const std::string &pkgId) +{ + const std::string dir = TzPlatformConfig::appDirPath(user, appId, pkgId); + const std::string nonAppDir = nonAppDirPath(user); + + createInnerAppDir(dir, nonAppDir); + createInnerAppDir(dir + "/.inner_dir", nonAppDir); + createInnerAppDir(dir + "/inner_dir", nonAppDir); +} + +static void generateNonAppDir(const TemporaryTestUser &user) +{ + const std::string dir = nonAppDirPath(user); + + createTestDir(dir); + createTestDir(dir + "/.inner_dir"); + createTestDir(dir + "/inner_dir"); +} + +void createTestDirs(const TemporaryTestUser &user, + const std::string &appId, const std::string &pkgId) +{ + generateAppDir(user, appId, pkgId); + generateNonAppDir(user); +} + +void removeTestDirs(const TemporaryTestUser &user, + const std::string &appId, const std::string &pkgId) +{ + removeDir(TzPlatformConfig::appDirPath(user, appId, pkgId)); + removeDir(nonAppDirPath(user)); +} diff --git a/src/security-manager-tests/common/sm_commons.h b/src/security-manager-tests/common/sm_commons.h new file mode 100644 index 0000000..a3c7b1d --- /dev/null +++ b/src/security-manager-tests/common/sm_commons.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 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 +#include +#include +#include + +#include + +#include +#include +#include +#include + +DEFINE_SMARTPTR(cap_free, _cap_struct, CapsSetsUniquePtr); + +const int FTW_MAX_FDS = 16; + +extern const privileges_t SM_ALLOWED_PRIVILEGES; +extern const privileges_t SM_DENIED_PRIVILEGES; +extern const privileges_t SM_NO_PRIVILEGES; +extern const std::vector SM_ALLOWED_GROUPS; + +static const char *const SM_RW_PATH = "/opt/usr/apps/sm_test_02_pkg_id_full/app_dir"; + +const std::string uidToStr(const uid_t uid); + +std::string generateAppLabel(const std::string &appId); +std::string generatePkgLabel(const std::string &pkgId); +std::string genRWPath(int app_num); +std::string genROPath(int app_num); +std::string genPublicROPath(int app_num); +std::string genOwnerRWOthersROPath(int app_num); + +int nftw_remove_labels(const char *fpath, const struct stat* /*sb*/, + int /*typeflag*/, struct FTW* /*ftwbuf*/); +void check_app_permissions(const char *const app_id, const char *const pkg_id, + const char *const user, const privileges_t &allowed_privs, + const privileges_t &denied_privs); +void check_app_after_install(const char *const app_id, const char *const pkg_id); +void check_app_after_install(const char *const app_id, const char *const pkg_id, + const privileges_t &allowed_privs, + const privileges_t &denied_privs, + const std::vector &allowed_groups); +void check_path(const std::string &path, const std::string &label); +void check_app_path_after_install(int app_num, const char *pkgId, bool others_enabled=false); +void check_app_after_uninstall(const char *const app_id, const char *const pkg_id, + const bool is_pkg_removed); +void check_app_after_uninstall(const char *const app_id, const char *const pkg_id, + const privileges_t &privileges, const bool is_pkg_removed); + +CapsSetsUniquePtr setCaps(const char *cap_string); +void prepare_app_env(int app_num, bool others_enabled = false); +void install_app(const char *app_id, const char *pkg_id, uid_t uid = 0, + app_install_type type = SM_APP_INSTALL_NONE, bool check_after = true); +void uninstall_app(const char *app_id, const char *pkg_id, + bool expect_pkg_removed = false, app_install_type type = SM_APP_INSTALL_NONE, + bool check_after = true); + +void createTestDirs(const TemporaryTestUser &user, + const std::string &appId, const std::string &pkgId); +void removeTestDirs(const TemporaryTestUser &user, + const std::string &appId, const std::string &pkgId); diff --git a/src/security-manager-tests/common/sm_request.cpp b/src/security-manager-tests/common/sm_request.cpp index 1a4fc97..912bb53 100644 --- a/src/security-manager-tests/common/sm_request.cpp +++ b/src/security-manager-tests/common/sm_request.cpp @@ -20,6 +20,21 @@ namespace SecurityManagerTest { +void prepare_request(InstallRequest &request, + const char *const app_id, + const char *const pkg_id, + app_install_path_type pathType, + const char *const path, + uid_t uid) +{ + request.setAppId(app_id); + request.setPkgId(pkg_id); + request.addPath(path, pathType); + + if (uid != 0) + request.setUid(uid); +} + InstallRequest::InstallRequest() : m_req(nullptr) , m_tizenVer("3.0") diff --git a/src/security-manager-tests/common/sm_request.h b/src/security-manager-tests/common/sm_request.h index 7656551..d2acdba 100644 --- a/src/security-manager-tests/common/sm_request.h +++ b/src/security-manager-tests/common/sm_request.h @@ -26,7 +26,13 @@ #include namespace SecurityManagerTest { - +class InstallRequest; +void prepare_request(InstallRequest &request, + const char *const app_id, + const char *const pkg_id, + app_install_path_type pathType, + const char *const path, + uid_t uid); class InstallRequest { public: diff --git a/src/security-manager-tests/common/tzplatform.cpp b/src/security-manager-tests/common/tzplatform.cpp new file mode 100644 index 0000000..8484cb9 --- /dev/null +++ b/src/security-manager-tests/common/tzplatform.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016 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 +#include +#include + +#include +#include +#include +#include + +namespace TzPlatformConfig { + +DEFINE_SMARTPTR(tzplatform_context_destroy, tzplatform_context, TzPlatformContextPtr); + +uid_t getGlobalUserId(void) +{ + return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); +} + +uid_t getGlobalGroupId(void) +{ + gid_t global_uid = getGlobalUserId(); + errno = 0; + passwd* pw = getpwuid(global_uid); + RUNNER_ASSERT_ERRNO_MSG(pw, "getpwuid() failed."); + return pw->pw_gid; +} + +const std::string appDirPath(const TemporaryTestUser &user, const std::string &appId, + const std::string &pkgId) +{ + struct tzplatform_context *tzCtxPtr = nullptr; + + RUNNER_ASSERT(0 == tzplatform_context_create(&tzCtxPtr)); + TzPlatformContextPtr tzCtxPtrSmart(tzCtxPtr); + + RUNNER_ASSERT_MSG(0 == tzplatform_context_set_user(tzCtxPtr, user.getUid()), + "Unable to set user <" << user.getUserName() << "> for tzplatform context"); + + const char *appDir = tzplatform_context_getenv(tzCtxPtr, + getGlobalUserId() == user.getUid() ? TZ_SYS_RW_APP : TZ_USER_APP); + RUNNER_ASSERT_MSG(nullptr != appDir, + "tzplatform_context_getenv failed" + << "for getting sys rw app of user <" << user.getUserName() << ">"); + + return std::string(appDir) + "/" + pkgId + "/" + appId; +} + +} + diff --git a/src/security-manager-tests/common/tzplatform.h b/src/security-manager-tests/common/tzplatform.h new file mode 100644 index 0000000..cbbb216 --- /dev/null +++ b/src/security-manager-tests/common/tzplatform.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016 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 + +#include + +namespace TzPlatformConfig { + +uid_t getGlobalUserId(void); + +uid_t getGlobalGroupId(void); + +const std::string appDirPath(const TemporaryTestUser &user, const std::string &appId, + const std::string &pkgId); + +} + diff --git a/src/security-manager-tests/security_manager_tests.cpp b/src/security-manager-tests/security_manager_tests.cpp index 26f18f5..21efcba 100644 --- a/src/security-manager-tests/security_manager_tests.cpp +++ b/src/security-manager-tests/security_manager_tests.cpp @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2014-2015 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 #include @@ -6,7 +21,7 @@ #include #include -#include + #include #include #include @@ -37,7 +52,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -45,33 +62,16 @@ #include #include #include +#include #include #include #include #include #include -#include "memory.h" +#include using namespace SecurityManagerTest; -DEFINE_SMARTPTR(cap_free, _cap_struct, CapsSetsUniquePtr); -DEFINE_SMARTPTR(tzplatform_context_destroy, tzplatform_context, TzPlatformContextPtr); - -static const privileges_t SM_ALLOWED_PRIVILEGES = { - "http://tizen.org/privilege/display", - "http://tizen.org/privilege/nfc" -}; - -static const privileges_t SM_DENIED_PRIVILEGES = { - "http://tizen.org/privilege/bluetooth", - "http://tizen.org/privilege/power" -}; - -static const privileges_t SM_NO_PRIVILEGES = { -}; - -static const std::vector SM_ALLOWED_GROUPS = {"db_browser", "db_alarm"}; - void changeSecurityContext(const std::string& label, uid_t uid, gid_t gid) { RUNNER_ASSERT_ERRNO_MSG(0 == smack_set_label_for_self(label.c_str()), @@ -81,33 +81,9 @@ void changeSecurityContext(const std::string& label, uid_t uid, gid_t gid) RUNNER_ASSERT_ERRNO_MSG(0 == setuid(uid), "Error in setuid."); } -std::string genPath(int app_num, const char *postfix) { - char buf[16]; - sprintf(buf, "%02d", app_num); - return std::string("/opt/usr/apps/sm_test_") + std::string(buf) + std::string("_pkg_id_full/") + std::string(postfix); -} -std::string genRWPath(int app_num) { - return genPath(app_num, "app_dir"); -} -std::string genROPath(int app_num) { - return genPath(app_num, "app_dir_ro"); -} -std::string genPublicROPath(int app_num) { - return genPath(app_num, "app_dir_public_ro"); -} -std::string genOwnerRWOthersROPath(int app_num) { - return genPath(app_num, "app_dir_rw_others_ro"); -} - -static const char *const SM_RW_PATH = "/opt/usr/apps/sm_test_02_pkg_id_full/app_dir"; -static const char *const SM_DENIED_PATH = "/opt/usr/apps/non_app_dir"; static const char *const SM_TRUSTED_PATH = "/opt/usr/apps/sm_test_02_pkg_id_full/app_dir_trusted"; -static const char *const ANY_USER_REPRESENTATION = "anyuser";/*this may be actually any string*/ -static const std::string EXEC_FILE("exec"); -static const std::string NORMAL_FILE("normal"); -static const std::string LINK_PREFIX("link_to_"); static const std::string PRIVILEGE_MANAGER_APP = "privilege_manager"; static const std::string PRIVILEGE_MANAGER_PKG = "privilege_manager"; @@ -163,348 +139,6 @@ static const std::vector MANY_APPS_PRIVILEGES = { } }; -class ScopedProcessLabel { -public: - ScopedProcessLabel() { - smack_new_label_from_self(&label); - } - - ~ScopedProcessLabel() { - smack_set_label_for_self(label); - free(label); - } - -private: - char *label; -}; - -static std::string generateAppLabel(const std::string &appId) -{ - return "User::App::" + appId; -} - -static std::string generatePkgLabelOwnerRWothersRO(const std::string &pkgId) -{ - return "User::Pkg::" + pkgId + "::SharedRO"; -} - -static std::string generatePkgLabel(const std::string &pkgId) -{ - return "User::Pkg::" + pkgId; -} - -#define FTW_MAX_FDS 16 - -static int nftw_remove_labels(const char *fpath, const struct stat* /*sb*/, - int /*typeflag*/, struct FTW* /*ftwbuf*/) -{ - smack_lsetlabel(fpath, nullptr, SMACK_LABEL_ACCESS); - smack_lsetlabel(fpath, nullptr, SMACK_LABEL_EXEC); - smack_lsetlabel(fpath, nullptr, SMACK_LABEL_TRANSMUTE); - - return 0; -} - -static int nftw_set_labels_non_app_dir(const char *fpath, const struct stat* /*sb*/, - int /*typeflag*/, struct FTW* /*ftwbuf*/) -{ - smack_lsetlabel(fpath, "canary_label", SMACK_LABEL_ACCESS); - smack_lsetlabel(fpath, "canary_label", SMACK_LABEL_EXEC); - smack_lsetlabel(fpath, nullptr, SMACK_LABEL_TRANSMUTE); - - return 0; -} - -static int nftw_check_labels_non_app_dir(const char *fpath, const struct stat* /*sb*/, - int /*typeflag*/, struct FTW* /*ftwbuf*/) -{ - int result; - CStringPtr labelPtr; - char* label = nullptr; - - /* ACCESS */ - result = smack_lgetlabel(fpath, &label, SMACK_LABEL_ACCESS); - labelPtr.reset(label); - RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path"); - result = strcmp("canary_label", labelPtr.get()); - RUNNER_ASSERT_MSG(result == 0, "ACCESS label on " << fpath << " is overwritten"); - - /* EXEC */ - result = smack_lgetlabel(fpath, &label, SMACK_LABEL_EXEC); - labelPtr.reset(label); - RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path"); - result = strcmp("canary_label", labelPtr.get()); - RUNNER_ASSERT_MSG(result == 0, "EXEC label on " << fpath << " is overwritten"); - - /* TRANSMUTE */ - result = smack_lgetlabel(fpath, &label, SMACK_LABEL_TRANSMUTE); - labelPtr.reset(label); - RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path"); - RUNNER_ASSERT_MSG(labelPtr.get() == nullptr, "TRANSMUTE label on " << fpath << " is set"); - - return 0; -} - -static int nftw_check_sm_labels_app_dir(const char *fpath, const struct stat *sb, - const char* correctLabel, bool transmute_test, bool exec_test) -{ - int result; - CStringPtr labelPtr; - char* label = nullptr; - - /* ACCESS */ - result = smack_lgetlabel(fpath, &label, SMACK_LABEL_ACCESS); - RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path"); - labelPtr.reset(label); - RUNNER_ASSERT_MSG(label != nullptr, "ACCESS label on " << fpath << " is not set"); - result = strcmp(correctLabel, label); - RUNNER_ASSERT_MSG(result == 0, "ACCESS label on " << fpath << " is incorrect" - " (should be '" << correctLabel << "' and is '" << label << "')"); - - - /* EXEC */ - result = smack_lgetlabel(fpath, &label, SMACK_LABEL_EXEC); - RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path"); - labelPtr.reset(label); - - if (S_ISREG(sb->st_mode) && (sb->st_mode & S_IXUSR) && exec_test) { - RUNNER_ASSERT_MSG(label != nullptr, "EXEC label on " << fpath << " is not set"); - result = strcmp(correctLabel, label); - RUNNER_ASSERT_MSG(result == 0, "Incorrect EXEC label on executable file " << fpath); - } else - RUNNER_ASSERT_MSG(label == nullptr, "EXEC label on " << fpath << " is set"); - - - /* TRANSMUTE */ - result = smack_lgetlabel(fpath, &label, SMACK_LABEL_TRANSMUTE); - RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path"); - labelPtr.reset(label); - - if (S_ISDIR(sb->st_mode) && transmute_test == true) { - RUNNER_ASSERT_MSG(label != nullptr, "TRANSMUTE label on " << fpath << " is not set at all"); - RUNNER_ASSERT_MSG(strcmp(label,"TRUE") == 0, - "TRANSMUTE label on " << fpath << " is not set properly: '"< &allowed_gids) -{ - int ret; - gid_t main_gid = getgid(); - std::unordered_set 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 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 void check_app_after_install(const char *const app_id, const char *const pkg_id, - const privileges_t &allowed_privs, - const privileges_t &denied_privs, - const std::vector &allowed_groups) -{ - TestSecurityManagerDatabase dbtest; - dbtest.test_db_after__app_install(app_id, pkg_id); - - /*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); - - /* Setup mapping of gids to privileges */ - /* Do this for each privilege for extra check */ - for (const auto &privilege : allowed_privs) { - dbtest.setup_privilege_groups(privilege, allowed_groups); - } - - std::vector 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); -} - -static void check_app_after_install(const char *const app_id, const char *const pkg_id) -{ - TestSecurityManagerDatabase dbtest; - dbtest.test_db_after__app_install(app_id, pkg_id); -} - -static void check_app_after_uninstall(const char *const app_id, const char *const pkg_id, - const privileges_t &privileges, const bool is_pkg_removed) -{ - TestSecurityManagerDatabase dbtest; - dbtest.test_db_after__app_uninstall(app_id, pkg_id, is_pkg_removed); - - - /*Privileges should not be granted anymore to any user*/ - check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, SM_NO_PRIVILEGES, privileges); -} - -static void check_app_after_uninstall(const char *const app_id, const char *const pkg_id, - const bool is_pkg_removed) -{ - TestSecurityManagerDatabase dbtest; - dbtest.test_db_after__app_uninstall(app_id, pkg_id, is_pkg_removed); -} - -static void install_app(const char *app_id, const char *pkg_id, uid_t uid = 0, - app_install_type type = SM_APP_INSTALL_NONE, bool check_after = true) -{ - InstallRequest request; - request.setAppId(app_id); - request.setPkgId(pkg_id); - request.setUid(uid); - if (type != SM_APP_INSTALL_NONE) - request.setInstallType(type); - Api::install(request); - - if (check_after) - check_app_after_install(app_id, pkg_id); -} - -static void uninstall_app(const char *app_id, const char *pkg_id, - bool expect_pkg_removed = false, app_install_type type = SM_APP_INSTALL_NONE, - bool check_after = true) -{ - InstallRequest request; - request.setAppId(app_id); - if (type != SM_APP_INSTALL_NONE) - request.setInstallType(type); - Api::uninstall(request); - - if (check_after) - check_app_after_uninstall(app_id, pkg_id, expect_pkg_removed); -} - static inline void register_current_process_as_privilege_manager(uid_t uid, bool forAdmin = false) { InstallRequest request; @@ -604,565 +238,6 @@ void check_exact_smack_accesses(const std::string &subject, const std::string &o } -RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER) - -RUNNER_TEST(security_manager_01a_app_double_install_double_uninstall) -{ - const char *const sm_app_id = "sm_test_01a_app_id_double"; - const char *const sm_pkg_id = "sm_test_01a_pkg_id_double"; - - InstallRequest requestInst; - requestInst.setAppId(sm_app_id); - requestInst.setPkgId(sm_pkg_id); - - Api::install(requestInst); - Api::install(requestInst); - - // Check records in the security-manager database - check_app_after_install(sm_app_id, sm_pkg_id); - - InstallRequest requestUninst; - requestUninst.setAppId(sm_app_id); - - Api::uninstall(requestUninst); - Api::uninstall(requestUninst); - - // Check records in the security-manager database - check_app_after_uninstall(sm_app_id, sm_pkg_id, TestSecurityManagerDatabase::REMOVED); -} - - -RUNNER_TEST(security_manager_01b_app_double_install_wrong_pkg_id) -{ - const char *const sm_app_id = "sm_test_01b_app"; - const char *const sm_pkg_id = "sm_test_01b_pkg"; - const char *const sm_pkg_id_wrong = "sm_test_01b_pkg_BAD"; - - InstallRequest requestInst; - requestInst.setAppId(sm_app_id); - requestInst.setPkgId(sm_pkg_id); - - Api::install(requestInst); - - InstallRequest requestInst2; - requestInst2.setAppId(sm_app_id); - requestInst2.setPkgId(sm_pkg_id_wrong); - - Api::install(requestInst2, SECURITY_MANAGER_ERROR_INPUT_PARAM); - - - /* Check records in the security-manager database */ - check_app_after_install(sm_app_id, sm_pkg_id); - - InstallRequest requestUninst; - requestUninst.setAppId(sm_app_id); - - Api::uninstall(requestUninst); - - - /* Check records in the security-manager database */ - check_app_after_uninstall(sm_app_id, sm_pkg_id, TestSecurityManagerDatabase::REMOVED); - -} - -RUNNER_TEST(security_manager_01c_app_uninstall_pkg_id_ignored) -{ - const char * const sm_app_id = "SM_TEST_01c_APPID"; - const char * const sm_pkg_id = "SM_TEST_01c_PKGID"; - const char * const sm_pkg_id_wrong = "SM_TEST_01c_PKGID_wrong"; - - InstallRequest requestInst; - requestInst.setAppId(sm_app_id); - requestInst.setPkgId(sm_pkg_id); - - Api::install(requestInst); - - /* Check records in the security-manager database */ - check_app_after_install(sm_app_id, sm_pkg_id); - - InstallRequest requestUninst; - requestUninst.setAppId(sm_app_id); - requestUninst.setPkgId(sm_pkg_id_wrong); - - Api::uninstall(requestUninst); - - check_app_after_uninstall(sm_app_id, sm_pkg_id, TestSecurityManagerDatabase::REMOVED); - -} - -RUNNER_TEST(security_manager_02_app_install_uninstall_full) -{ - std::string SM_RW_PATH = genRWPath(2); - std::string SM_RO_PATH = genROPath(2); - std::string SM_PUBLIC_RO_PATH = genPublicROPath(2); - - const char *const sm_app_id = "sm_test_02_app_id_full"; - const char *const sm_pkg_id = "sm_test_02_pkg_id_full"; - - prepare_app_env(2); - - InstallRequest requestInst; - requestInst.setAppId(sm_app_id); - requestInst.setPkgId(sm_pkg_id); - requestInst.addPrivilege(SM_ALLOWED_PRIVILEGES[0].c_str()); - requestInst.addPrivilege(SM_ALLOWED_PRIVILEGES[1].c_str()); - requestInst.addPath(SM_RW_PATH, SECURITY_MANAGER_PATH_RW); - requestInst.addPath(SM_RO_PATH, SECURITY_MANAGER_PATH_RO); - requestInst.addPath(SM_PUBLIC_RO_PATH, SECURITY_MANAGER_PATH_PUBLIC_RO); - - Api::install(requestInst); - - /* Check records in the security-manager database */ - check_app_after_install(sm_app_id, sm_pkg_id, - SM_ALLOWED_PRIVILEGES, SM_DENIED_PRIVILEGES, SM_ALLOWED_GROUPS); - - /* TODO: add parameters to this function */ - check_app_path_after_install(2, sm_pkg_id, false); - - InstallRequest requestUninst; - requestUninst.setAppId(sm_app_id); - - Api::uninstall(requestUninst); - - /* Check records in the security-manager database, - * all previously allowed privileges should be removed */ - check_app_after_uninstall(sm_app_id, sm_pkg_id, - SM_ALLOWED_PRIVILEGES, TestSecurityManagerDatabase::REMOVED); -} - -RUNNER_CHILD_TEST_SMACK(security_manager_03_set_label_from_appid) -{ - const char *const app_id = "sm_test_03_app_id_set_label_from_appid_smack"; - const char *const pkg_id = "sm_test_03_pkg_id_set_label_from_appid_smack"; - const char *const socketLabel = "not_expected_label"; - std::string expected_label = generateAppLabel(app_id); - std::string expected_socket_label = socketLabel; - char *label = nullptr; - CStringPtr labelPtr; - int result; - - uninstall_app(app_id, pkg_id, true); - install_app(app_id, pkg_id); - - const auto sockaddr = UDSHelpers::makeAbstractAddress("sm_test_03.socket"); - int sock = UDSHelpers::createServer(&sockaddr); - SockUniquePtr sockPtr(&sock); - - //Set socket label to something different than expecedLabel - result = smack_set_label_for_file(*sockPtr, XATTR_NAME_SMACKIPIN, socketLabel); - RUNNER_ASSERT_ERRNO_MSG(result == 0, - "Can't set socket label. Result: " << result); - result = smack_set_label_for_file(*sockPtr, XATTR_NAME_SMACKIPOUT, socketLabel); - RUNNER_ASSERT_ERRNO_MSG(result == 0, - "Can't set socket label. Result: " << result); - - - SynchronizationPipe pipe; - pid_t pid = fork(); - - if (pid != 0) { // parent process - pipe.claimParentEp(); - Api::setProcessLabel(app_id); - - result = smack_new_label_from_file(*sockPtr, XATTR_NAME_SMACKIPIN, &label); - RUNNER_ASSERT_ERRNO_MSG(result != -1, "smack_new_label_from_file failed: " << label); - labelPtr.reset(label); - result = expected_socket_label.compare(label); - RUNNER_ASSERT_MSG(result == 0, "Socket label is incorrect. Expected: " << - expected_label << " Actual: " << label); - - result = smack_new_label_from_file(*sockPtr, XATTR_NAME_SMACKIPOUT, &label); - RUNNER_ASSERT_ERRNO_MSG(result != -1, "smack_new_label_from_file failed: " << label); - labelPtr.reset(label); - result = expected_socket_label.compare(label); - RUNNER_ASSERT_MSG(result == 0, "Socket label is incorrect. Expected: " << - expected_label << " Actual: " << label); - - result = smack_new_label_from_self(&label); - RUNNER_ASSERT_MSG(result >= 0, - " Error getting current process label"); - RUNNER_ASSERT_MSG(label != nullptr, - " Process label is not set"); - labelPtr.reset(label); - - result = expected_label.compare(label); - RUNNER_ASSERT_MSG(result == 0, - " Process label is incorrect. Expected: \"" << expected_label << - "\" Actual: \"" << label << "\""); - pipe.post(); - waitPid(pid); - } else { // child process - pipe.claimChildEp(); - pipe.wait(); - uninstall_app(app_id, pkg_id, true); - exit(0); - } -} - -RUNNER_CHILD_TEST_NOSMACK(security_manager_03_set_label_from_appid_nosmack) -{ - const char *const app_id = "sm_test_03_app_id_set_label_from_appid_nosmack"; - const char *const pkg_id = "sm_test_03_pkg_id_set_label_from_appid_nosmack"; - - uninstall_app(app_id, pkg_id, true); - install_app(app_id, pkg_id); - - { - ScopedProcessLabel keepLabel; - Api::setProcessLabel(app_id); - } - - uninstall_app(app_id, pkg_id, true); -} - -static void prepare_request(InstallRequest &request, - const char *const app_id, - const char *const pkg_id, - app_install_path_type pathType, - const char *const path, - uid_t uid) -{ - request.setAppId(app_id); - request.setPkgId(pkg_id); - request.addPath(path, pathType); - - if (uid != 0) - request.setUid(uid); -} - -static uid_t getGlobalUserId(void) -{ - return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); -} - -static uid_t getGlobalGroupId(void) -{ - gid_t global_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); - errno = 0; - passwd* pw = getpwuid(global_uid); - RUNNER_ASSERT_ERRNO_MSG(pw, "getpwuid() failed."); - return pw->pw_gid; - -} - -static const std::string appDirPath(const TemporaryTestUser &user, - const std::string &appId, const std::string &pkgId) -{ - struct tzplatform_context *tzCtxPtr = nullptr; - - RUNNER_ASSERT(0 == tzplatform_context_create(&tzCtxPtr)); - TzPlatformContextPtr tzCtxPtrSmart(tzCtxPtr); - - RUNNER_ASSERT_MSG(0 == tzplatform_context_set_user(tzCtxPtr, user.getUid()), - "Unable to set user <" << user.getUserName() << "> for tzplatform context"); - - const char *appDir = tzplatform_context_getenv(tzCtxPtr, - getGlobalUserId() == user.getUid() ? TZ_SYS_RW_APP : TZ_USER_APP); - RUNNER_ASSERT_MSG(nullptr != appDir, - "tzplatform_context_getenv failed" - << "for getting sys rw app of user <" << user.getUserName() << ">"); - - return std::string(appDir) + "/" + pkgId + "/" + appId; -} - -static const std::string nonAppDirPath(const TemporaryTestUser &user) -{ - return TMP_DIR + "/" + user.getUserName(); -} - -static const std::string uidToStr(const uid_t uid) -{ - return std::to_string(static_cast(uid)); -} - -static void install_and_check(const char *const sm_app_id, - const char *const sm_pkg_id, - const TemporaryTestUser& user, - const std::string &appDir, - bool requestUid) -{ - InstallRequest requestPrivate; - - //install app for non-root user - //should fail (users may only register folders inside their home) - prepare_request(requestPrivate, sm_app_id, sm_pkg_id, - SECURITY_MANAGER_PATH_RW, SM_RW_PATH, - requestUid ? user.getUid() : 0); - - Api::install(requestPrivate, SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED); - - InstallRequest requestPrivateUser; - - //install app for non-root user - //should succeed - this time i register folder inside user's home dir - prepare_request(requestPrivateUser, sm_app_id, sm_pkg_id, - SECURITY_MANAGER_PATH_RW, appDir.c_str(), - requestUid ? user.getUid() : 0); - - for (auto &privilege : SM_ALLOWED_PRIVILEGES) - requestPrivateUser.addPrivilege(privilege.c_str()); - - Api::install(requestPrivateUser); - - check_app_permissions(sm_app_id, sm_pkg_id, - uidToStr(user.getUid()).c_str(), - SM_ALLOWED_PRIVILEGES, SM_DENIED_PRIVILEGES); -} - -static void createTestDir(const std::string &dir) -{ - mode_t dirMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; - mode_t execFileMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; - mode_t normalFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; - - mktreeSafe(dir, dirMode); - creatSafe(dir + "/" + EXEC_FILE, execFileMode); - creatSafe(dir + "/" + NORMAL_FILE, normalFileMode); - symlinkSafe(dir + "/" + EXEC_FILE, dir + "/" + LINK_PREFIX + EXEC_FILE); - symlinkSafe(dir + "/" + NORMAL_FILE, dir + "/" + LINK_PREFIX + NORMAL_FILE); -} - -static void createInnerAppDir(const std::string &dir, const std::string &nonAppDir) -{ - createTestDir(dir); - - symlinkSafe(nonAppDir, dir + "/" + LINK_PREFIX + "non_app_dir"); - symlinkSafe(nonAppDir + "/" + EXEC_FILE, - dir + "/" + LINK_PREFIX + "non_app_" + EXEC_FILE); - symlinkSafe(nonAppDir + "/" + NORMAL_FILE, - dir + "/" + LINK_PREFIX + "non_app_" + NORMAL_FILE); -} - -static void generateAppDir(const TemporaryTestUser &user, - const std::string &appId, const std::string &pkgId) -{ - const std::string dir = appDirPath(user, appId, pkgId); - const std::string nonAppDir = nonAppDirPath(user); - - createInnerAppDir(dir, nonAppDir); - createInnerAppDir(dir + "/.inner_dir", nonAppDir); - createInnerAppDir(dir + "/inner_dir", nonAppDir); -} - -static void generateNonAppDir(const TemporaryTestUser &user) -{ - const std::string dir = nonAppDirPath(user); - - createTestDir(dir); - createTestDir(dir + "/.inner_dir"); - createTestDir(dir + "/inner_dir"); -} - -static void createTestDirs(const TemporaryTestUser &user, - const std::string &appId, const std::string &pkgId) -{ - generateAppDir(user, appId, pkgId); - generateNonAppDir(user); -} - -static void removeTestDirs(const TemporaryTestUser &user, - const std::string &appId, const std::string &pkgId) -{ - removeDir(appDirPath(user, appId, pkgId)); - removeDir(nonAppDirPath(user)); -} - - - -RUNNER_CHILD_TEST(security_manager_04a_app_install_uninstall_by_app_user_for_self) -{ - int result; - const char *const sm_app_id = "sm_test_04a_app_id_uid"; - const char *const sm_pkg_id = "sm_test_04a_pkg_id_uid"; - const std::string new_user_name = "sm_test_04a_user_name"; - - TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false); - testUser.create(); - - removeTestDirs(testUser, sm_app_id, sm_pkg_id); - createTestDirs(testUser, sm_app_id, sm_pkg_id); - - const std::string userAppDirPath = appDirPath(testUser, sm_app_id, sm_pkg_id); - - //switch user to non-root - result = drop_root_privileges(testUser.getUid(), testUser.getGid()); - RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); - - install_and_check(sm_app_id, sm_pkg_id, testUser, userAppDirPath, false); - - //uninstall app as non-root user - InstallRequest request; - request.setAppId(sm_app_id); - - Api::uninstall(request); - - check_app_permissions(sm_app_id, sm_pkg_id, - uidToStr(testUser.getUid()).c_str(), - SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); -} - -RUNNER_CHILD_TEST(security_manager_04b_app_install_by_root_for_app_user) -{ - int result; - const char *const sm_app_id = "sm_test_04b_app_id_uid"; - const char *const sm_pkg_id = "sm_test_04b_pkg_id_uid"; - const std::string new_user_name = "sm_test_04b_user_name"; - - TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false); - testUser.create(); - - removeTestDirs(testUser, sm_app_id, sm_pkg_id); - createTestDirs(testUser, sm_app_id, sm_pkg_id); - - install_and_check(sm_app_id, sm_pkg_id, testUser, appDirPath(testUser, sm_app_id, sm_pkg_id), true); - - //switch user to non-root - root may not uninstall apps for specified users - result = drop_root_privileges(testUser.getUid(), testUser.getGid()); - RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); - - //uninstall app as non-root user - InstallRequest request; - request.setAppId(sm_app_id); - - Api::uninstall(request); - - check_app_permissions(sm_app_id, sm_pkg_id, - uidToStr(testUser.getUid()).c_str(), - SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); -} - - -RUNNER_CHILD_TEST(security_manager_05_drop_process_capabilities) -{ - int result; - CapsSetsUniquePtr caps, caps_empty(cap_init()); - - caps.reset(cap_from_text("all=eip")); - RUNNER_ASSERT_MSG(caps, "can't convert capabilities from text"); - result = cap_set_proc(caps.get()); - RUNNER_ASSERT_MSG(result == 0, - "can't set capabilities. Result: " << result); - - Api::dropProcessPrivileges(); - - caps.reset(cap_get_proc()); - RUNNER_ASSERT_MSG(caps, "can't get proc capabilities"); - - result = cap_compare(caps.get(), caps_empty.get()); - RUNNER_ASSERT_MSG(result == 0, - "capabilities not dropped. Current: " << cap_to_text(caps.get(), NULL)); -} - -RUNNER_CHILD_TEST(security_manager_06_install_app_offline) -{ - const char *const app_id = "sm_test_06_app_id_install_app_offline"; - const char *const pkg_id = "sm_test_06_pkg_id_install_app_offline"; - - // Uninstall app on-line, off-line mode doesn't support it - uninstall_app(app_id, pkg_id, true); - - ServiceManager("security-manager.service").stopService(); - - ServiceManager serviceManager("security-manager.socket"); - serviceManager.stopService(); - - install_app(app_id, pkg_id); - - serviceManager.startService(); - - uninstall_app(app_id, pkg_id, true); -} - -RUNNER_CHILD_TEST(security_manager_07_user_add_app_install) -{ - const char *const sm_app_id = "sm_test_07_app_id_user"; - const char *const sm_pkg_id = "sm_test_07_pkg_id_user"; - const std::string new_user_name = "sm_test_07_user_name"; - std::string uid_string; - TemporaryTestUser test_user(new_user_name, GUM_USERTYPE_NORMAL, false); - test_user.create(); - test_user.getUidString(uid_string); - - removeTestDirs(test_user, sm_app_id, sm_pkg_id); - createTestDirs(test_user, sm_app_id, sm_pkg_id); - - install_app(sm_app_id, sm_pkg_id, test_user.getUid()); - - check_app_after_install(sm_app_id, sm_pkg_id); - - test_user.remove(); - - check_app_permissions(sm_app_id, sm_pkg_id, uid_string.c_str(), SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); - - check_app_after_uninstall(sm_app_id, sm_pkg_id, true); -} - -RUNNER_CHILD_TEST(security_manager_08_user_double_add_double_remove) -{ - UserRequest addUserRequest; - - const char *const sm_app_id = "sm_test_08_app_id_user"; - const char *const sm_pkg_id = "sm_test_08_pkg_id_user"; - const std::string new_user_name = "sm_test_08_user_name"; - std::string uid_string; - - // gumd user add - TemporaryTestUser test_user(new_user_name, GUM_USERTYPE_NORMAL, false); - test_user.create(); - test_user.getUidString(uid_string); - - removeTestDirs(test_user, sm_app_id, sm_pkg_id); - createTestDirs(test_user, sm_app_id, sm_pkg_id); - - addUserRequest.setUid(test_user.getUid()); - addUserRequest.setUserType(SM_USER_TYPE_NORMAL); - - //sm user add - Api::addUser(addUserRequest); - - install_app(sm_app_id, sm_pkg_id, test_user.getUid()); - - check_app_after_install(sm_app_id, sm_pkg_id); - - test_user.remove(); - - UserRequest deleteUserRequest; - deleteUserRequest.setUid(test_user.getUid()); - - Api::deleteUser(deleteUserRequest); - - check_app_permissions(sm_app_id, sm_pkg_id, uid_string.c_str(), SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); - - check_app_after_uninstall(sm_app_id, sm_pkg_id, true); -} - -RUNNER_CHILD_TEST(security_manager_09_add_user_offline) -{ - const char *const app_id = "security_manager_09_add_user_offline_app"; - const char *const pkg_id = "security_manager_09_add_user_offline_pkg"; - const std::string new_user_name("sm_test_09_user_name"); - - ServiceManager("security-manager.service").stopService(); - - ServiceManager serviceManager("security-manager.socket"); - serviceManager.stopService(); - - TemporaryTestUser test_user(new_user_name, GUM_USERTYPE_NORMAL, true); - test_user.create(); - - removeTestDirs(test_user, app_id, pkg_id); - createTestDirs(test_user, app_id, pkg_id); - - install_app(app_id, pkg_id, test_user.getUid()); - - check_app_after_install(app_id, pkg_id); - - serviceManager.startService(); - - test_user.remove(); - - check_app_after_uninstall(app_id, pkg_id, true); -} RUNNER_CHILD_TEST(security_manager_10_privacy_manager_fetch_whole_policy_for_self) { @@ -2306,8 +1381,8 @@ RUNNER_TEST(security_manager_19_security_manager_cmd_install) TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, false); user.create(); user.getUidString(uid_string); - const std::string path1 = appDirPath(user, app_id, pkg_id) + "/p1"; - const std::string path2 = appDirPath(user, app_id, pkg_id) + "/p2"; + const std::string path1 = TzPlatformConfig::appDirPath(user, app_id, pkg_id) + "/p1"; + const std::string path2 = TzPlatformConfig::appDirPath(user, app_id, pkg_id) + "/p2"; const std::string pkgopt = " --pkg=" + pkg_id; const std::string appopt = " --app=" + app_id; const std::string uidopt = " --uid=" + uid_string; @@ -3889,13 +2964,7 @@ RUNNER_TEST(security_manager_43_app_install_with_trusted_path) const std::string trusted_label = std::string("User::Author::") + std::to_string(authorDb); // check trusted path label - nftw_expected_label = trusted_label; - nftw_expected_transmute = true; - nftw_expected_exec = false; - - // check labels - result = nftw(provider.getTrustedDir().c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS); - RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_TRUSTED_PATH); + check_path(provider.getTrustedDir(), trusted_label); // check rules check_exact_access("System", trusted_label, system_access); @@ -4397,14 +3466,16 @@ RUNNER_CHILD_TEST(security_manager_53_app_has_privilege) for (auto const &privilege : SM_ALLOWED_PRIVILEGES) { int result; - Api::appHasPrivilege(sm_app_id, privilege.c_str(), getGlobalUserId(), result); + Api::appHasPrivilege(sm_app_id, privilege.c_str(), TzPlatformConfig::getGlobalUserId(), + result); RUNNER_ASSERT_MSG(result == 1, "Application " << sm_app_id << " should have access to privilege " << privilege); } for (auto const &privilege : SM_DENIED_PRIVILEGES) { int result; - Api::appHasPrivilege(sm_app_id, privilege.c_str(), getGlobalUserId(), result); + Api::appHasPrivilege(sm_app_id, privilege.c_str(), TzPlatformConfig::getGlobalUserId(), + result); RUNNER_ASSERT_MSG(result == 0, "Application " << sm_app_id << " should not have access to privilege " << privilege); } @@ -4490,7 +3561,7 @@ RUNNER_CHILD_TEST(security_manager_49d_local_user_set_install_type_global) removeTestDirs(testUser, sm_app_id, sm_pkg_id); createTestDirs(testUser, sm_app_id, sm_pkg_id); - const std::string userAppDirPath = appDirPath(testUser, sm_app_id, sm_pkg_id); + const std::string userAppDirPath = TzPlatformConfig::appDirPath(testUser, sm_app_id, sm_pkg_id); //switch user to non-root result = drop_root_privileges(testUser.getUid(), testUser.getGid()); @@ -4528,7 +3599,7 @@ RUNNER_CHILD_TEST(security_manager_49e_local_user_set_install_type_local) removeTestDirs(testUser, sm_app_id, sm_pkg_id); createTestDirs(testUser, sm_app_id, sm_pkg_id); - const std::string userAppDirPath = appDirPath(testUser, sm_app_id, sm_pkg_id); + const std::string userAppDirPath = TzPlatformConfig::appDirPath(testUser, sm_app_id, sm_pkg_id); //switch user to non-root result = drop_root_privileges(testUser.getUid(), testUser.getGid()); @@ -4574,7 +3645,7 @@ RUNNER_CHILD_TEST(security_manager_49f_local_user_set_install_type_preloaded) removeTestDirs(testUser, sm_app_id, sm_pkg_id); createTestDirs(testUser, sm_app_id, sm_pkg_id); - const std::string userAppDirPath = appDirPath(testUser, sm_app_id, sm_pkg_id); + const std::string userAppDirPath = TzPlatformConfig::appDirPath(testUser, sm_app_id, sm_pkg_id); //switch user to non-root result = drop_root_privileges(testUser.getUid(), testUser.getGid()); @@ -4669,7 +3740,7 @@ RUNNER_TEST(security_manager_54_path_req_no_pkg) TemporaryTestUser user("sm_test_54_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -4689,7 +3760,7 @@ RUNNER_TEST(security_manager_55_path_req_empty_pkg) TemporaryTestUser user("sm_test_55_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -4718,7 +3789,7 @@ RUNNER_TEST(security_manager_57_path_req_wrong_uid) TemporaryTestUser user("sm_test_57_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -4757,7 +3828,7 @@ RUNNER_TEST(security_manager_59_path_req_as_root_positive) TemporaryTestUser user("sm_test_59_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -4779,7 +3850,7 @@ RUNNER_CHILD_TEST(security_manager_60_path_req_as_user_positive) TemporaryTestUser user("sm_test_60_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -4807,7 +3878,7 @@ RUNNER_CHILD_TEST(security_manager_61_path_req_different_user) TemporaryTestUser user2("sm_test_61_2_user_name", GUM_USERTYPE_NORMAL, false); user2.create(); - std::string path = appDirPath(user2, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user2, sm_app_id, sm_pkg_id); removeTestDirs(user2, sm_app_id, sm_pkg_id); createTestDirs(user2, sm_app_id, sm_pkg_id); @@ -4852,8 +3923,10 @@ RUNNER_TEST(security_manager_62_path_req_path_outside) createTestDirs(user1, sm_app_id, sm_pkg_id); createTestDirs(user2, sm_app_id, sm_pkg_id); - testPathOutside(sm_pkg_id, user1.getUid(), appDirPath(user2, sm_app_id, sm_pkg_id)); - testPathOutside(sm_pkg_id, user1.getUid(), appDirPath(user1, sm_app_id, "sm_test_62_non_existing_pkg_id")); + testPathOutside(sm_pkg_id, user1.getUid(), + TzPlatformConfig::appDirPath(user2, sm_app_id, sm_pkg_id)); + testPathOutside(sm_pkg_id, user1.getUid(), + TzPlatformConfig::appDirPath(user1, sm_app_id, "sm_test_62_non_existing_pkg_id")); testPathOutside(sm_pkg_id, user1.getUid(), std::string("/home/") + user1.getUserName()); } @@ -4863,7 +3936,7 @@ void testPathsReqAsUser(const enum app_install_type &type, lib_retcode expectedR TemporaryTestUser user("sm_test_63_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -4901,7 +3974,7 @@ void testPathsReqLocal(uid_t uid, gid_t gid) TemporaryTestUser user("sm_test_64_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -4928,7 +4001,7 @@ RUNNER_CHILD_TEST(security_manager_64a_path_req_as_local_as_root) RUNNER_CHILD_TEST(security_manager_64b_path_req_as_local_asuser) { - testPathsReqLocal(getGlobalUserId(), getGlobalGroupId()); + testPathsReqLocal(TzPlatformConfig::getGlobalUserId(), TzPlatformConfig::getGlobalGroupId()); } RUNNER_TEST(security_manager_66_path_req_check_labels) @@ -4961,7 +4034,7 @@ RUNNER_TEST(security_manager_67_path_req_shared_ro_3_0) TemporaryTestUser user("sm_test_67_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -4988,7 +4061,7 @@ RUNNER_TEST(security_manager_68_path_req_shared_ro_2_X) TemporaryTestUser user("sm_test_68_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -5008,11 +4081,7 @@ RUNNER_TEST(security_manager_68_path_req_shared_ro_2_X) Api::registerPaths(preq); // check labels - nftw_expected_label = generatePkgLabel(sm_pkg_id) + "::SharedRO"; - nftw_expected_transmute = true; - nftw_expected_exec = false; - int result = nftw(path.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS); - RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path); + check_path(path, generatePkgLabel(sm_pkg_id) + "::SharedRO"); } RUNNER_TEST(security_manager_69_path_req_trusted_rw_no_author) @@ -5022,7 +4091,7 @@ RUNNER_TEST(security_manager_69_path_req_trusted_rw_no_author) TemporaryTestUser user("sm_test_69_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -5045,7 +4114,7 @@ RUNNER_TEST(security_manager_70_path_req_trusted_rw_positive) TemporaryTestUser user("sm_test_70_user_name", GUM_USERTYPE_NORMAL, false); user.create(); - std::string path = appDirPath(user, sm_app_id, sm_pkg_id); + std::string path = TzPlatformConfig::appDirPath(user, sm_app_id, sm_pkg_id); removeTestDirs(user, sm_app_id, sm_pkg_id); createTestDirs(user, sm_app_id, sm_pkg_id); @@ -5067,11 +4136,7 @@ RUNNER_TEST(security_manager_70_path_req_trusted_rw_positive) // check labels TestSecurityManagerDatabase dbtest; int64_t authorDb = dbtest.get_author_id(author_id); - nftw_expected_label = std::string("User::Author::") + std::to_string(authorDb); - nftw_expected_transmute = true; - nftw_expected_exec = false; - int result = nftw(path.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS); - RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path); + check_path(path, std::string("User::Author::") + std::to_string(authorDb)); } RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_LABEL_MONITOR_API) @@ -5101,14 +4166,7 @@ static UidGidMsg readCreds(int pipefd0) return msg; } -static void setCaps(const char *cap_string) -{ - CapsSetsUniquePtr caps(cap_init()); - caps.reset(cap_from_text(cap_string)); - RUNNER_ASSERT_MSG(caps, "can't convert capabilities from text"); - int result = cap_set_proc(caps.get()); - RUNNER_ASSERT_MSG(result == 0, "can't set capabilities. Result: " << result); -} + static void testSetLabelForSelf(const char *app_id, bool expected_success) { diff --git a/src/security-manager-tests/test_cases.cpp b/src/security-manager-tests/test_cases.cpp new file mode 100644 index 0000000..e5b4ada --- /dev/null +++ b/src/security-manager-tests/test_cases.cpp @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2016 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace SecurityManagerTest; + +RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER) + +RUNNER_TEST(security_manager_01a_app_double_install_double_uninstall) +{ + const char *const sm_app_id = "sm_test_01a_app_id_double"; + const char *const sm_pkg_id = "sm_test_01a_pkg_id_double"; + + InstallRequest requestInst; + requestInst.setAppId(sm_app_id); + requestInst.setPkgId(sm_pkg_id); + + Api::install(requestInst); + Api::install(requestInst); + + // Check records in the security-manager database + check_app_after_install(sm_app_id, sm_pkg_id); + + InstallRequest requestUninst; + requestUninst.setAppId(sm_app_id); + + Api::uninstall(requestUninst); + Api::uninstall(requestUninst); + + // Check records in the security-manager database + check_app_after_uninstall(sm_app_id, sm_pkg_id, TestSecurityManagerDatabase::REMOVED); +} + +RUNNER_TEST(security_manager_01b_app_double_install_wrong_pkg_id) +{ + const char *const sm_app_id = "sm_test_01b_app"; + const char *const sm_pkg_id = "sm_test_01b_pkg"; + const char *const sm_pkg_id_wrong = "sm_test_01b_pkg_BAD"; + + InstallRequest requestInst; + requestInst.setAppId(sm_app_id); + requestInst.setPkgId(sm_pkg_id); + + Api::install(requestInst); + + InstallRequest requestInst2; + requestInst2.setAppId(sm_app_id); + requestInst2.setPkgId(sm_pkg_id_wrong); + + Api::install(requestInst2, SECURITY_MANAGER_ERROR_INPUT_PARAM); + + + /* Check records in the security-manager database */ + check_app_after_install(sm_app_id, sm_pkg_id); + + InstallRequest requestUninst; + requestUninst.setAppId(sm_app_id); + + Api::uninstall(requestUninst); + + + /* Check records in the security-manager database */ + check_app_after_uninstall(sm_app_id, sm_pkg_id, TestSecurityManagerDatabase::REMOVED); +} + +RUNNER_TEST(security_manager_01c_app_uninstall_pkg_id_ignored) +{ + const char * const sm_app_id = "SM_TEST_01c_APPID"; + const char * const sm_pkg_id = "SM_TEST_01c_PKGID"; + const char * const sm_pkg_id_wrong = "SM_TEST_01c_PKGID_wrong"; + + InstallRequest requestInst; + requestInst.setAppId(sm_app_id); + requestInst.setPkgId(sm_pkg_id); + + Api::install(requestInst); + + /* Check records in the security-manager database */ + check_app_after_install(sm_app_id, sm_pkg_id); + + InstallRequest requestUninst; + requestUninst.setAppId(sm_app_id); + requestUninst.setPkgId(sm_pkg_id_wrong); + + Api::uninstall(requestUninst); + + check_app_after_uninstall(sm_app_id, sm_pkg_id, TestSecurityManagerDatabase::REMOVED); +} + +RUNNER_TEST(security_manager_02_app_install_uninstall_full) +{ + std::string SM_RW_PATH = genRWPath(2); + std::string SM_RO_PATH = genROPath(2); + std::string SM_PUBLIC_RO_PATH = genPublicROPath(2); + + const char *const sm_app_id = "sm_test_02_app_id_full"; + const char *const sm_pkg_id = "sm_test_02_pkg_id_full"; + + prepare_app_env(2); + + InstallRequest requestInst; + requestInst.setAppId(sm_app_id); + requestInst.setPkgId(sm_pkg_id); + requestInst.addPrivilege(SM_ALLOWED_PRIVILEGES[0].c_str()); + requestInst.addPrivilege(SM_ALLOWED_PRIVILEGES[1].c_str()); + requestInst.addPath(SM_RW_PATH, SECURITY_MANAGER_PATH_RW); + requestInst.addPath(SM_RO_PATH, SECURITY_MANAGER_PATH_RO); + requestInst.addPath(SM_PUBLIC_RO_PATH, SECURITY_MANAGER_PATH_PUBLIC_RO); + + Api::install(requestInst); + + /* Check records in the security-manager database */ + check_app_after_install(sm_app_id, sm_pkg_id, + SM_ALLOWED_PRIVILEGES, SM_DENIED_PRIVILEGES, SM_ALLOWED_GROUPS); + + /* TODO: add parameters to this function */ + check_app_path_after_install(2, sm_pkg_id, false); + + InstallRequest requestUninst; + requestUninst.setAppId(sm_app_id); + + Api::uninstall(requestUninst); + + /* Check records in the security-manager database, + * all previously allowed privileges should be removed */ + check_app_after_uninstall(sm_app_id, sm_pkg_id, + SM_ALLOWED_PRIVILEGES, TestSecurityManagerDatabase::REMOVED); +} + +RUNNER_CHILD_TEST_SMACK(security_manager_03_set_label_from_appid) +{ + const char *const app_id = "sm_test_03_app_id_set_label_from_appid_smack"; + const char *const pkg_id = "sm_test_03_pkg_id_set_label_from_appid_smack"; + const char *const socketLabel = "not_expected_label"; + std::string expected_label = generateAppLabel(app_id); + std::string expected_socket_label = socketLabel; + char *label = nullptr; + CStringPtr labelPtr; + int result; + + uninstall_app(app_id, pkg_id, true); + install_app(app_id, pkg_id); + + const auto sockaddr = UDSHelpers::makeAbstractAddress("sm_test_03.socket"); + int sock = UDSHelpers::createServer(&sockaddr); + SockUniquePtr sockPtr(&sock); + + //Set socket label to something different than expecedLabel + result = smack_set_label_for_file(*sockPtr, XATTR_NAME_SMACKIPIN, socketLabel); + RUNNER_ASSERT_ERRNO_MSG(result == 0, + "Can't set socket label. Result: " << result); + result = smack_set_label_for_file(*sockPtr, XATTR_NAME_SMACKIPOUT, socketLabel); + RUNNER_ASSERT_ERRNO_MSG(result == 0, + "Can't set socket label. Result: " << result); + + + SynchronizationPipe pipe; + pid_t pid = fork(); + + if (pid != 0) { // parent process + pipe.claimParentEp(); + Api::setProcessLabel(app_id); + + result = smack_new_label_from_file(*sockPtr, XATTR_NAME_SMACKIPIN, &label); + RUNNER_ASSERT_ERRNO_MSG(result != -1, "smack_new_label_from_file failed: " << label); + labelPtr.reset(label); + result = expected_socket_label.compare(label); + RUNNER_ASSERT_MSG(result == 0, "Socket label is incorrect. Expected: " << + expected_label << " Actual: " << label); + + result = smack_new_label_from_file(*sockPtr, XATTR_NAME_SMACKIPOUT, &label); + RUNNER_ASSERT_ERRNO_MSG(result != -1, "smack_new_label_from_file failed: " << label); + labelPtr.reset(label); + result = expected_socket_label.compare(label); + RUNNER_ASSERT_MSG(result == 0, "Socket label is incorrect. Expected: " << + expected_label << " Actual: " << label); + + result = smack_new_label_from_self(&label); + RUNNER_ASSERT_MSG(result >= 0, + " Error getting current process label"); + RUNNER_ASSERT_MSG(label != nullptr, + " Process label is not set"); + labelPtr.reset(label); + + result = expected_label.compare(label); + RUNNER_ASSERT_MSG(result == 0, + " Process label is incorrect. Expected: \"" << expected_label << + "\" Actual: \"" << label << "\""); + pipe.post(); + waitPid(pid); + } else { // child process + pipe.claimChildEp(); + pipe.wait(); + uninstall_app(app_id, pkg_id, true); + exit(0); + } +} + +RUNNER_CHILD_TEST_NOSMACK(security_manager_03_set_label_from_appid_nosmack) +{ + const char *const app_id = "sm_test_03_app_id_set_label_from_appid_nosmack"; + const char *const pkg_id = "sm_test_03_pkg_id_set_label_from_appid_nosmack"; + + uninstall_app(app_id, pkg_id, true); + install_app(app_id, pkg_id); + + { + ScopedProcessLabel keepLabel; + Api::setProcessLabel(app_id); + } + + uninstall_app(app_id, pkg_id, true); +} + +static void install_and_check(const char *const sm_app_id, + const char *const sm_pkg_id, + const TemporaryTestUser& user, + const std::string &appDir, + bool requestUid) +{ + InstallRequest requestPrivate; + + //install app for non-root user + //should fail (users may only register folders inside their home) + prepare_request(requestPrivate, sm_app_id, sm_pkg_id, + SECURITY_MANAGER_PATH_RW, SM_RW_PATH, + requestUid ? user.getUid() : 0); + + Api::install(requestPrivate, SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED); + + InstallRequest requestPrivateUser; + + //install app for non-root user + //should succeed - this time i register folder inside user's home dir + prepare_request(requestPrivateUser, sm_app_id, sm_pkg_id, + SECURITY_MANAGER_PATH_RW, appDir.c_str(), + requestUid ? user.getUid() : 0); + + for (auto &privilege : SM_ALLOWED_PRIVILEGES) + requestPrivateUser.addPrivilege(privilege.c_str()); + + Api::install(requestPrivateUser); + + check_app_permissions(sm_app_id, sm_pkg_id, + uidToStr(user.getUid()).c_str(), + SM_ALLOWED_PRIVILEGES, SM_DENIED_PRIVILEGES); +} + +RUNNER_CHILD_TEST(security_manager_04a_app_install_uninstall_by_app_user_for_self) +{ + int result; + const char *const sm_app_id = "sm_test_04a_app_id_uid"; + const char *const sm_pkg_id = "sm_test_04a_pkg_id_uid"; + const std::string new_user_name = "sm_test_04a_user_name"; + + TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false); + testUser.create(); + + removeTestDirs(testUser, sm_app_id, sm_pkg_id); + createTestDirs(testUser, sm_app_id, sm_pkg_id); + + const std::string userAppDirPath = TzPlatformConfig::appDirPath(testUser, sm_app_id, sm_pkg_id); + + //switch user to non-root + result = drop_root_privileges(testUser.getUid(), testUser.getGid()); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + install_and_check(sm_app_id, sm_pkg_id, testUser, userAppDirPath, false); + + //uninstall app as non-root user + InstallRequest request; + request.setAppId(sm_app_id); + + Api::uninstall(request); + + check_app_permissions(sm_app_id, sm_pkg_id, + uidToStr(testUser.getUid()).c_str(), + SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); +} + +RUNNER_CHILD_TEST(security_manager_04b_app_install_by_root_for_app_user) +{ + int result; + const char *const sm_app_id = "sm_test_04b_app_id_uid"; + const char *const sm_pkg_id = "sm_test_04b_pkg_id_uid"; + const std::string new_user_name = "sm_test_04b_user_name"; + + TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false); + testUser.create(); + + removeTestDirs(testUser, sm_app_id, sm_pkg_id); + createTestDirs(testUser, sm_app_id, sm_pkg_id); + + install_and_check(sm_app_id, sm_pkg_id, testUser, + TzPlatformConfig::appDirPath(testUser, sm_app_id, sm_pkg_id), true); + + //switch user to non-root - root may not uninstall apps for specified users + result = drop_root_privileges(testUser.getUid(), testUser.getGid()); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + + //uninstall app as non-root user + InstallRequest request; + request.setAppId(sm_app_id); + + Api::uninstall(request); + + check_app_permissions(sm_app_id, sm_pkg_id, + uidToStr(testUser.getUid()).c_str(), + SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); +} + +RUNNER_CHILD_TEST(security_manager_05_drop_process_capabilities) +{ + int result; + CapsSetsUniquePtr caps_empty(cap_init()); + auto caps = setCaps("all=eip"); + Api::dropProcessPrivileges(); + + caps.reset(cap_get_proc()); + RUNNER_ASSERT_MSG(caps, "can't get proc capabilities"); + + result = cap_compare(caps.get(), caps_empty.get()); + RUNNER_ASSERT_MSG(result == 0, + "capabilities not dropped. Current: " << cap_to_text(caps.get(), NULL)); +} + +RUNNER_CHILD_TEST(security_manager_06_install_app_offline) +{ + const char *const app_id = "sm_test_06_app_id_install_app_offline"; + const char *const pkg_id = "sm_test_06_pkg_id_install_app_offline"; + + // Uninstall app on-line, off-line mode doesn't support it + uninstall_app(app_id, pkg_id, true); + + ServiceManager("security-manager.service").stopService(); + + ServiceManager serviceManager("security-manager.socket"); + serviceManager.stopService(); + + install_app(app_id, pkg_id); + + serviceManager.startService(); + + uninstall_app(app_id, pkg_id, true); +} + +RUNNER_CHILD_TEST(security_manager_07_user_add_app_install) +{ + const char *const sm_app_id = "sm_test_07_app_id_user"; + const char *const sm_pkg_id = "sm_test_07_pkg_id_user"; + const std::string new_user_name = "sm_test_07_user_name"; + std::string uid_string; + TemporaryTestUser test_user(new_user_name, GUM_USERTYPE_NORMAL, false); + test_user.create(); + test_user.getUidString(uid_string); + + removeTestDirs(test_user, sm_app_id, sm_pkg_id); + createTestDirs(test_user, sm_app_id, sm_pkg_id); + + install_app(sm_app_id, sm_pkg_id, test_user.getUid()); + + check_app_after_install(sm_app_id, sm_pkg_id); + + test_user.remove(); + + check_app_permissions(sm_app_id, sm_pkg_id, uid_string.c_str(), SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); + + check_app_after_uninstall(sm_app_id, sm_pkg_id, true); +} + +RUNNER_CHILD_TEST(security_manager_08_user_double_add_double_remove) +{ + UserRequest addUserRequest; + + const char *const sm_app_id = "sm_test_08_app_id_user"; + const char *const sm_pkg_id = "sm_test_08_pkg_id_user"; + const std::string new_user_name = "sm_test_08_user_name"; + std::string uid_string; + + // gumd user add + TemporaryTestUser test_user(new_user_name, GUM_USERTYPE_NORMAL, false); + test_user.create(); + test_user.getUidString(uid_string); + + removeTestDirs(test_user, sm_app_id, sm_pkg_id); + createTestDirs(test_user, sm_app_id, sm_pkg_id); + + addUserRequest.setUid(test_user.getUid()); + addUserRequest.setUserType(SM_USER_TYPE_NORMAL); + + //sm user add + Api::addUser(addUserRequest); + + install_app(sm_app_id, sm_pkg_id, test_user.getUid()); + + check_app_after_install(sm_app_id, sm_pkg_id); + + test_user.remove(); + + UserRequest deleteUserRequest; + deleteUserRequest.setUid(test_user.getUid()); + + Api::deleteUser(deleteUserRequest); + + check_app_permissions(sm_app_id, sm_pkg_id, uid_string.c_str(), SM_NO_PRIVILEGES, SM_ALLOWED_PRIVILEGES); + + check_app_after_uninstall(sm_app_id, sm_pkg_id, true); +} + +RUNNER_CHILD_TEST(security_manager_09_add_user_offline) +{ + const char *const app_id = "security_manager_09_add_user_offline_app"; + const char *const pkg_id = "security_manager_09_add_user_offline_pkg"; + const std::string new_user_name("sm_test_09_user_name"); + + ServiceManager("security-manager.service").stopService(); + + ServiceManager serviceManager("security-manager.socket"); + serviceManager.stopService(); + + TemporaryTestUser test_user(new_user_name, GUM_USERTYPE_NORMAL, true); + test_user.create(); + + removeTestDirs(test_user, app_id, pkg_id); + createTestDirs(test_user, app_id, pkg_id); + + install_app(app_id, pkg_id, test_user.getUid()); + + check_app_after_install(app_id, pkg_id); + + serviceManager.startService(); + + test_user.remove(); + + check_app_after_uninstall(app_id, pkg_id, true); +}