Separate some test cases from main file.
Separate common functions/classes/types.
Change-Id: I79cf4e9cd00bcf5a430314f581afa35d2b1004f9
#include <dpl/test/test_runner_child.h>
#include <dpl/test/test_runner_multiprocess.h>
#include <sys/smack.h>
+#include <sys/types.h>
#include <string>
#include <tuple>
#include <errno.h>
} \
void Proc##Multi(std::tuple<__VA_ARGS__> &optionalArgsTuple DPL_UNUSED)
-#endif
\ No newline at end of file
+#endif
--- /dev/null
+/*
+ * 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 <l.wojciechow@partner.samsung.com>
+ * @author Radoslaw Bartosiak <r.bartosiak@samsung.com>
+ * @version 1.0
+ * @brief Tests for libcynara-agent
+ */
+
+#include <chrono>
+#include <string>
+
+#include <cynara-client-async.h>
+#include <cynara-monitor.h>
+
+#include <dpl/test/test_runner.h>
+#include <cynara_test_client_async_client.h>
+#include <cynara_test_commons.h>
+#include <cynara_test_env.h>
+#include <service_manager.h>
+#include <timeout.h>
+
+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<cynara_monitor_configuration, void(cynara_monitor_configuration*)>
+ 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)
${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
*/
#pragma once
+#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
--- /dev/null
+/*
+ * 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 <sys/smack.h>
+
+class ScopedProcessLabel {
+public:
+ ScopedProcessLabel() {
+ smack_new_label_from_self(&label);
+ }
+
+ ~ScopedProcessLabel() {
+ smack_set_label_for_self(label);
+ free(label);
+ }
+
+private:
+ char *label;
+};
--- /dev/null
+/*
+ * 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 <cstring>
+#include <ftw.h>
+#include <grp.h>
+#include <string>
+#include <sys/capability.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <unordered_set>
+#include <vector>
+
+#include <security-manager-types.h>
+#include <sys/smack.h>
+
+#include <cynara_test_client.h>
+#include <dpl/test/test_runner.h>
+#include <memory.h>
+#include <sm_api.h>
+#include <sm_commons.h>
+#include <sm_db.h>
+#include <sm_request.h>
+#include <tests_common.h>
+#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<std::string> SM_ALLOWED_GROUPS = {"db_browser", "db_alarm"};
+
+const std::string uidToStr(const uid_t uid)
+{
+ return std::to_string(static_cast<unsigned int>(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: '"<<label<<"'");
+ } else {
+ RUNNER_ASSERT_MSG(label == nullptr, "TRANSMUTE label on " << fpath << " is set");
+ }
+
+ return 0;
+}
+
+static int nftw_check_sm_labels(const char *fpath, const struct stat *sb,
+ int /*typeflag*/, struct FTW* /*ftwbuf*/)
+{
+ return nftw_check_sm_labels_app_dir(fpath, sb,
+ nftw_expected_label.c_str(), nftw_expected_transmute, nftw_expected_exec);
+}
+
+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_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;
+}
+
+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 const char *const SM_DENIED_PATH = "/opt/usr/apps/non_app_dir";
+
+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) pkg_id;
+ std::string smackLabel = generateAppLabel(app_id);
+
+ CynaraTestClient::Client ctc;
+
+ for (auto &priv : allowed_privs) {
+ ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_ALLOWED);
+ }
+
+ for (auto &priv : denied_privs) {
+ ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_DENIED);
+ }
+}
+
+
+void 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_gids(const char *const app_id, const std::vector<gid_t> &allowed_gids)
+{
+ int ret;
+ gid_t main_gid = getgid();
+ std::unordered_set<gid_t> reference_gids(allowed_gids.begin(), allowed_gids.end());
+
+ // Reset supplementary groups
+ ret = setgroups(0, NULL);
+ RUNNER_ASSERT_MSG(ret != -1, "Unable to set supplementary groups");
+
+ Api::setProcessGroups(app_id);
+
+ ret = getgroups(0, nullptr);
+ RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
+
+ std::vector<gid_t> actual_gids(ret);
+ ret = getgroups(ret, actual_gids.data());
+ RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
+
+ for (const auto &gid : actual_gids) {
+ RUNNER_ASSERT_MSG(gid == main_gid || reference_gids.count(gid) > 0,
+ "Application shouldn't get access to group " << gid);
+ reference_gids.erase(gid);
+ }
+
+ RUNNER_ASSERT_MSG(reference_gids.empty(), "Application didn't get access to some groups");
+}
+
+static const char *const ANY_USER_REPRESENTATION = "anyuser";/*this may be actually any string*/
+
+void check_app_after_install(const char *const app_id, const char *const pkg_id,
+ const privileges_t &allowed_privs,
+ const privileges_t &denied_privs,
+ const std::vector<std::string> &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<gid_t> allowed_gids;
+
+ for (const auto &groupName : allowed_groups) {
+ errno = 0;
+ struct group* grp = getgrnam(groupName.c_str());
+ RUNNER_ASSERT_ERRNO_MSG(grp, "Group: " << groupName << " not found");
+ allowed_gids.push_back(grp->gr_gid);
+ }
+
+ check_app_gids(app_id, allowed_gids);
+}
+
+void check_path(const std::string &path, const std::string &label) {
+ 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));
+}
--- /dev/null
+/*
+ * 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 <string>
+#include <sys/capability.h>
+#include <sys/types.h>
+#include <vector>
+
+#include <security-manager-types.h>
+
+#include <app_install_helper.h>
+#include <memory.h>
+#include <sm_db.h>
+#include <temp_test_user.h>
+
+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<std::string> 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<std::string> &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);
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")
#include <security-manager.h>
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:
--- /dev/null
+/*
+ * 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 <pwd.h>
+#include <sys/types.h>
+#include <tzplatform_config.h>
+
+#include <dpl/test/test_runner.h>
+#include <memory.h>
+#include <temp_test_user.h>
+#include <tzplatform.h>
+
+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;
+}
+
+}
+
--- /dev/null
+/*
+ * 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 <string>
+
+#include <temp_test_user.h>
+
+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);
+
+}
+
+/*
+ * 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 <fcntl.h>
#include <stdio.h>
#include <attr/xattr.h>
#include <linux/xattr.h>
-#include <sys/capability.h>
+
#include <sys/inotify.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <dpl/test/test_runner.h>
#include <passwd_access.h>
#include <tests_common.h>
+#include <scoped_label.h>
#include <sm_api.h>
+#include <sm_commons.h>
#include <sm_db.h>
#include <sm_request.h>
#include <sm_sharing_request.h>
#include <app_install_helper.h>
#include <synchronization_pipe.h>
#include <temp_test_user.h>
+#include <tzplatform.h>
#include <uds.h>
#include <cynara_test_client.h>
#include <cynara_test_admin.h>
#include <service_manager.h>
#include <cynara_test_admin.h>
-#include "memory.h"
+#include <memory.h>
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<std::string> 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()),
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";
}
};
-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: '"<<label<<"'");
- } else {
- RUNNER_ASSERT_MSG(label == nullptr, "TRANSMUTE label on " << fpath << " is set");
- }
-
- return 0;
-}
-
-// 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(const char *fpath, const struct stat *sb,
- int /*typeflag*/, struct FTW* /*ftwbuf*/)
-{
- return nftw_check_sm_labels_app_dir(fpath, sb,
- nftw_expected_label.c_str(), nftw_expected_transmute, nftw_expected_exec);
-}
-
-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);
-}
-
-static void prepare_app_env(int app_num, bool others_enabled = false)
-{
- prepare_app_path(app_num, others_enabled);
-}
-
-static void check_app_path_after_install(int app_num, const char *pkgId, 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;
-
- 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);
- }
-}
-
-
-static 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) pkg_id;
- std::string smackLabel = generateAppLabel(app_id);
-
- CynaraTestClient::Client ctc;
-
- for (auto &priv : allowed_privs) {
- ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_ALLOWED);
- }
-
- for (auto &priv : denied_privs) {
- ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_DENIED);
- }
-}
-
-static void check_app_gids(const char *const app_id, const std::vector<gid_t> &allowed_gids)
-{
- int ret;
- gid_t main_gid = getgid();
- std::unordered_set<gid_t> reference_gids(allowed_gids.begin(), allowed_gids.end());
-
- // Reset supplementary groups
- ret = setgroups(0, NULL);
- RUNNER_ASSERT_MSG(ret != -1, "Unable to set supplementary groups");
-
- Api::setProcessGroups(app_id);
-
- ret = getgroups(0, nullptr);
- RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
-
- std::vector<gid_t> actual_gids(ret);
- ret = getgroups(ret, actual_gids.data());
- RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
-
- for (const auto &gid : actual_gids) {
- RUNNER_ASSERT_MSG(gid == main_gid || reference_gids.count(gid) > 0,
- "Application shouldn't get access to group " << gid);
- reference_gids.erase(gid);
- }
-
- RUNNER_ASSERT_MSG(reference_gids.empty(), "Application didn't get access to some groups");
-}
-
-static 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<std::string> &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<gid_t> allowed_gids;
-
- for (const auto &groupName : allowed_groups) {
- errno = 0;
- struct group* grp = getgrnam(groupName.c_str());
- RUNNER_ASSERT_ERRNO_MSG(grp, "Group: " << groupName << " not found");
- allowed_gids.push_back(grp->gr_gid);
- }
-
- check_app_gids(app_id, allowed_gids);
-}
-
-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;
}
-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<unsigned int>(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)
{
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;
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);
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);
}
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());
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());
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());
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);
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);
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);
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);
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);
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);
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());
}
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);
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);
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)
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);
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);
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)
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);
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);
// 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)
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)
{
--- /dev/null
+/*
+ * 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 <sys/capability.h>
+#include <sys/smack.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <attr/xattr.h>
+
+#include <cstdlib>
+#include <dpl/test/test_runner.h>
+#include <memory>
+#include <scoped_label.h>
+#include <service_manager.h>
+#include <sm_api.h>
+#include <sm_commons.h>
+#include <sm_request.h>
+#include <synchronization_pipe.h>
+#include <tests_common.h>
+#include <tzplatform.h>
+#include <uds.h>
+
+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);
+}