ADD_DEFINITIONS("-DCYNARA_DB_DIR=\"${CYNARA_DB_DIR}\"")
ADD_DEFINITIONS("-DAPP_USER=\"${APP_USER}\"")
+# Enabler for popups; this should be done on system-level somewhere, but since it isn't
+# and we already have such definition in security-manager, lets have it also here
+ADD_DEFINITIONS("-DASKUSER_ENABLED")
+
IF(SMACK_ENABLE)
ADD_DEFINITIONS("-DWRT_SMACK_ENABLED")
ENDIF(SMACK_ENABLE)
<filesystem path="/usr/bin/test-performance-check.sh" exec_label="_" />
<filesystem path="/usr/bin/libsmack-test" exec_label="_" />
- <filesystem path="/usr/bin/security-manager-tests" exec_label="_" />
+ <filesystem path="/usr/bin/security-manager-tests" exec_label="System::Privileged" />
<filesystem path="/usr/bin/cynara-tests" exec_label="_" />
<filesystem path="/usr/bin/ckm-tests" exec_label="User" />
<filesystem path="/usr/bin/ckm-tests" exec_label="System" />
BuildRequires: boost-devel
BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(libgum) >= 1.0.5
+BuildRequires: pkgconfig(security-privilege-manager)
Requires: perf
Requires: gdb
Requires: diffutils
-DCYNARA_DB_DIR=%{_localstatedir}/cynara/db \
-DAPP_USER="security_test_user" \
-DCKM_TEST_DIR=%{ckm_test_dir} \
- -DCKM_RW_DATA_DIR=%{ckm_rw_data_dir}
+ -DCKM_RW_DATA_DIR=%{ckm_rw_data_dir} \
+ -DGLOBAL_APP_DIR=%{TZ_SYS_RW_APP}
make %{?jobs:-j%jobs}
%install
/usr/bin/security-manager-tests
/etc/smack/test_smack_rules
/etc/smack/test_smack_rules_lnk
-/usr/apps/*
+%{TZ_SYS_RW_APP}*
/usr/bin/cynara-test
/usr/bin/ckm-tests
/usr/bin/ckm-integration-tests
${PROJECT_SOURCE_DIR}/src/common/fs_label_manager.cpp
${PROJECT_SOURCE_DIR}/src/common/passwd_access.cpp
${PROJECT_SOURCE_DIR}/src/common/uds.cpp
+ ${PROJECT_SOURCE_DIR}/src/common/message_pipe.cpp
${PROJECT_SOURCE_DIR}/src/common/synchronization_pipe.cpp
${PROJECT_SOURCE_DIR}/src/common/timeout.cpp
${PROJECT_SOURCE_DIR}/src/common/temp_test_user.cpp
--- /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.
+ */
+/**
+ * @file message_pipe.cpp
+ * @author Zofia Abramowska
+ * @version 1.0
+ * @brief Simple wrapper for message pipe
+ */
+
+#include "message_pipe.h"
+
+static void closeFd(int *fd) {
+ if (*fd > -1) {
+ close(*fd);
+ *fd = -1;
+ }
+}
+
+MessagePipe::MessagePipe() {
+ auto ret = pipe(m_pipeCP);
+ RUNNER_ASSERT_ERRNO_MSG(ret == 0, "pipe failed");
+
+ ret = pipe(m_pipePC);
+ RUNNER_ASSERT_ERRNO_MSG(ret == 0, "pipe failed");
+}
+
+MessagePipe::~MessagePipe() {
+ closeFd(m_pipeCP + 0);
+ closeFd(m_pipeCP + 1);
+ closeFd(m_pipePC + 0);
+ closeFd(m_pipePC + 1);
+}
+
+void MessagePipe::claimParentEp() {
+ if (m_epClaimed)
+ return;
+
+ m_readEp = m_pipeCP[0];
+ closeFd(m_pipeCP + 1);
+
+ m_writeEp = m_pipePC[1];
+ closeFd(m_pipePC + 0);
+
+ m_epClaimed = true;
+}
+
+void MessagePipe::claimChildEp() {
+ if (m_epClaimed)
+ return;
+
+ m_readEp = m_pipePC[0];
+ closeFd(m_pipePC + 1);
+
+ m_writeEp = m_pipeCP[1];
+ closeFd(m_pipeCP + 0);
+
+ m_epClaimed = true;
+}
+
--- /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.
+ */
+/**
+ * @file message_pipe.h
+ * @author Zofia Abramowska <z.abramowska@samsung.com>
+ * @version 1.0
+ * @brief Simple message pipe wrapper
+ */
+
+#pragma once
+
+#include <unistd.h>
+
+#include <dpl/test/test_runner.h>
+
+class MessagePipe {
+public:
+ MessagePipe();
+ ~MessagePipe();
+
+ void claimParentEp();
+ void claimChildEp();
+
+ template <class T>
+ void write(const T& data) {
+ RUNNER_ASSERT_MSG(m_epClaimed == true, "Endpoint not claimed");
+ auto ret = TEMP_FAILURE_RETRY(::write(m_writeEp, &data, sizeof(data)));
+ RUNNER_ASSERT_ERRNO_MSG(ret > 0, "Write failed ret = " << ret);
+ RUNNER_ASSERT_MSG(ret == sizeof(data), "ERROR : lazy programmer didn't implement write properly");
+
+ }
+ template <class T>
+ void read(T& data) {
+ RUNNER_ASSERT_MSG(m_epClaimed == true, "Endpoint not claimed");
+ auto ret = TEMP_FAILURE_RETRY(::read(m_readEp, &data, sizeof(data)));
+ RUNNER_ASSERT_ERRNO_MSG(ret > 0, "Read failed ret = " << ret);
+ RUNNER_ASSERT_MSG(ret == sizeof(data), "ERROR : lazy programmer didn't implement read properly");
+ }
+
+private:
+ int m_pipeCP[2]; // Child -> Parent
+ int m_pipePC[2]; // Parent -> Child
+ int m_readEp = -1;
+ int m_writeEp = -1;
+ bool m_epClaimed = false;
+};
#include "passwd_access.h"
-namespace PasswdAccess {
- uid_t uid(const std::string &username) {
- struct passwd *passwd = nullptr;
+namespace {
+ struct passwd *getPasswd(const std::string &username) {
+ struct passwd *info = nullptr;
do {
errno = 0;
- passwd = getpwnam(username.c_str());
- } while (passwd == nullptr && errno == EINTR);
- RUNNER_ASSERT_ERRNO_MSG(passwd != nullptr, "Error in getpwnam(). Username: " << username);
- return passwd->pw_uid;
+ info = getpwnam(username.c_str());
+ } while (info == nullptr && errno == EINTR);
+ RUNNER_ASSERT_ERRNO_MSG(info != nullptr, "Error in getpwnam(). Username: " << username);
+ return info;
+ }
+}
+
+namespace PasswdAccess {
+ uid_t uid(const std::string &username) {
+ return getPasswd(username)->pw_uid;
+ }
+
+ void allUser(const std::string &username, uid_t &uid, gid_t &gid) {
+ auto info = getPasswd(username);
+ uid = info->pw_uid;
+ gid = info->pw_gid;
}
gid_t gid(const std::string &groupname) {
namespace PasswdAccess {
uid_t uid(const std::string &username);
+ void allUser(const std::string &username, uid_t &uid, gid_t &gid);
gid_t gid(const std::string &groupname);
} // namespace PasswdAccess
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-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.
#include <sys/types.h>
#include <sys/socket.h>
+TemporaryTestUser::TemporaryTestUser(TemporaryTestUser &&other)
+ : m_uid(other.m_uid), m_gid(other.m_gid), m_userName(std::move(other.m_userName)),
+ m_userType(other.m_userType), m_offline(other.m_offline), m_creatorPid(other.m_creatorPid)
+{
+ other.m_creatorPid = -1;
+}
void TemporaryTestUser::create(void)
{
if (m_uid != 0)
remove();
+/*
+ Below line of code is a hack for Gumd commit that removes Smack management capabilities:
+
+ | commit 9b45c1afa49103dcb4101f4b28bf7c145f3294a6
+ |/ Author: Yunmi Ha <yunmi.ha@samsung.com>
+ | Date: Tue Jul 5 13:40:16 2016 +0900
+ |
+ | Remove smack capability
+ |
+ | with wearable profile, CAP_MAC_ADMIN and CAP_MAC_OVERRIDE capabilities are removed.
+ | (can't use useradd/del/modify function without offline option.)
+ | with other profile, only CAP_MAC_OVERRIDE capability is removed.
+ |
+ | For this, gumd launcher was changed to systemd.
+ |
+ | Change-Id: Ic95fceed41afc41e37e93606c3abf830536ac7d6
+ | Signed-off-by: Yunmi Ha <yunmi.ha@samsung.com>
+*/
+ m_offline = true;
+
bool ret = m_runner.userCreate(m_userName, m_userType, m_offline, m_uid, m_gid);
RUNNER_ASSERT_MSG(ret, "Failed to add user");
RUNNER_ASSERT_MSG(m_uid != 0, "Something strange happened during user creation. uid == 0.");
TemporaryTestUser::~TemporaryTestUser()
{
- this->remove();
+ if (m_creatorPid == getpid())
+ remove();
}
TemporaryTestUser::GumdRunner TemporaryTestUser::m_runner = TemporaryTestUser::GumdRunner();
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-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.
#include <sys/types.h>
#include <gum-user.h>
#include <common/gum-user-types.h>
+#include <sys/types.h>
+#include <unistd.h>
class TemporaryTestUser {
public:
- TemporaryTestUser() = delete;
- TemporaryTestUser(std::string userName, GumUserType userType, bool offline) :
+ TemporaryTestUser(std::string userName, GumUserType userType, bool offline = false) :
m_uid(0),
m_gid(0),
m_userName(userName),
m_userType(userType),
- m_offline(offline)
+ m_offline(offline),
+ m_creatorPid(getpid())
{};
+ // TODO - copy constructor should be deleted
+ TemporaryTestUser(const TemporaryTestUser &) = default;
+ TemporaryTestUser(TemporaryTestUser &&other);
+ TemporaryTestUser& operator=(const TemporaryTestUser &) = delete;
~TemporaryTestUser();
void remove(void);
uid_t getUid() const {return m_uid;}
uid_t getGid() const {return m_gid;}
void create(void);
- void getUidString(std::string& uidstr) const {uidstr = std::to_string(static_cast<unsigned int>(m_uid));}
+ std::string getUidString() const {return std::to_string(static_cast<unsigned int>(m_uid));}
const std::string& getUserName() const {return m_userName;}
GumUserType getUserType() const {return m_userType;}
std::string m_userName;
GumUserType m_userType;
bool m_offline;
+ pid_t m_creatorPid;
};
#endif
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <unistd.h>
#include <grp.h>
#include <errno.h>
RUNNER_ASSERT_ERRNO_MSG(0 == rmdir(path.c_str()), "rmdir for <" << path << "> failed");
}
+void waitPid(pid_t pid)
+{
+ int status;
+ pid_t ret = waitpid(pid, &status, 0);
+ RUNNER_ASSERT_MSG((ret != -1) && WIFEXITED(status) && WEXITSTATUS(status) == 0,
+ "Child process exited abnormally" <<
+ ": ret=" << ret << ", errno=" << errno << ", status=" << status);
+}
// changes process label
void change_label(const char* label)
{
int ret = smack_set_label_for_self(label);
RUNNER_ASSERT_MSG(0 == ret, "Error in smack_set_label_for_self("<<label<<"). Error: " << ret);
}
-
#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 creatSafe(const std::string &path, mode_t mode);
void symlinkSafe(const std::string &targetPath, const std::string &linkPath);
void removeDir(const std::string &path);
+void waitPid(pid_t pid);
void change_label(const char* label);
#define RUNNER_TEST_SMACK(Proc, ...) \
"doesn't match expected. " << dump());
}
+void Admin::getPolicyTypeForDescription(const std::string &description,
+ int &policyType, int expectedResult)
+{
+ auto descr_deleter = [](cynara_admin_policy_descr** descr) {
+ if (descr != nullptr)
+ for (int i = 0; descr[i] != nullptr; i++) {
+ free(descr[i]->name);
+ free(descr[i]);
+ }
+ free(descr);
+ };
+ struct cynara_admin_policy_descr **descriptions = nullptr;
+ int ret = cynara_admin_list_policies_descriptions(m_admin, &descriptions);
+ std::unique_ptr<cynara_admin_policy_descr*, decltype(descr_deleter)>
+ descrPtr(descriptions, descr_deleter);
+ RUNNER_ASSERT_MSG(ret == expectedResult,
+ "cynara_admin_list_policies_descriptions returned wrong value: " <<
+ ret << " != " << expectedResult);
+ ret = 0;
+ for (int i = 0; descriptions[i] != nullptr; i++) {
+ if (descriptions[i]->name == description) {
+ policyType = descriptions[i]->result;
+ ret = 1;
+ }
+ }
+ if (!ret)
+ RUNNER_FAIL_MSG("Policy type for description " << description << " not found: ");
+}
+
} // namespace CynaraTestAdmin
#include <cynara-admin.h>
#include <ostream>
#include <vector>
+#include <string>
namespace CynaraTestAdmin {
int expectedResult = CYNARA_API_SUCCESS);
void listPoliciesDescriptions(CynaraTestPlugins::Descriptions &expectedDescriptions,
int expectedResult = CYNARA_API_SUCCESS);
+ void getPolicyTypeForDescription(const std::string &description, int &policyType,
+ int expectedResult = CYNARA_API_SUCCESS);
private:
struct cynara_admin *m_admin;
bool m_online;
cynara_finish(m_cynara);
}
-void Client::check(const char *client, const char *session,
- const char *user, const char *privilege,
+void Client::check(const std::string &client, const std::string &session,
+ const std::string &user, const std::string &privilege,
int expectedResult)
{
- int ret = cynara_check(m_cynara, client, session, user, privilege);
+ int ret = cynara_check(m_cynara, client.c_str(), session.c_str(), user.c_str(), privilege.c_str());
RUNNER_ASSERT_MSG(ret == expectedResult,
"cynara_check returned wrong value: "
<< ret << " != " << expectedResult << "."
- << " client: " << formatCstr(client) << ","
- << " session: " << formatCstr(session) << ","
- << " user: " << formatCstr(user) << ","
- << " privilege: " << formatCstr(privilege));
+ << " client: " << formatCstr(client.c_str()) << ","
+ << " session: " << formatCstr(session.c_str()) << ","
+ << " user: " << formatCstr(user.c_str()) << ","
+ << " privilege: " << formatCstr(privilege.c_str()));
}
} //namespace CynaraTestClient
#ifndef CYNARA_TEST_CLIENT_H
#define CYNARA_TEST_CLIENT_H
+#include <string>
+
#include <cynara-client.h>
namespace CynaraTestClient {
Client();
virtual ~Client();
- void check(const char *client, const char *session,
- const char *user, const char *privilege,
+ void check(const std::string &client, const std::string &session,
+ const std::string &user, const std::string &privilege,
int expectedResult = CYNARA_API_ACCESS_ALLOWED);
private:
--- /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)
cynara-client
cynara-admin
security-manager
+ security-privilege-manager
libtzplatform-config
sqlite3
libcap
${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/test_cases_credentials.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_dyntransition.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_nss.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_privacy_manager.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_private_sharing.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_public_sharing.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_register_paths.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_shm.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_trusted_sharing.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_prepare_app.cpp
${PROJECT_SOURCE_DIR}/src/security-manager-tests/security_manager_tests.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/app_install_helper.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/policy_configuration.cpp
${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_api.cpp
- ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_db.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_commons.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_label_monitor.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
${SEC_MGR_TESTS_DEP_LIBRARIES}
dpl-test-framework
tests-common
+ rt
${CMAKE_THREAD_LIBS_INIT}
)
INSTALL(DIRECTORY
${PROJECT_SOURCE_DIR}/src/security-manager-tests/app_files/
- DESTINATION /usr/apps/
+ DESTINATION ${GLOBAL_APP_DIR}
)
--- /dev/null
+/*
+ * Copyright (c) 2014-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 <fcntl.h>
+#include <map>
+#include <string>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/smack.h>
+#include <unistd.h>
+#include <utility>
+
+#include <security-manager-types.h>
+
+#include <dpl/test/test_runner.h>
+#include <sm_commons.h>
+#include <tzplatform.h>
+
+#include "app_install_helper.h"
+
+AppInstallHelper::AppInstallHelper(AppInstallHelper &&other)
+ : m_appName(std::move(other.m_appName)), m_pkgName(std::move(other.m_pkgName)),
+ m_isLocal(other.m_isLocal), m_uidGid(other.m_uidGid),
+ m_version(std::move(other.m_version)), m_installType(other.m_installType),
+ m_isHybrid(other.m_isHybrid), m_installDir(std::move(other.m_installDir)),
+ m_dirTypeMap(std::move(other.m_dirTypeMap)), m_fileTypeMap(std::move(other.m_fileTypeMap)),
+ m_privileges(std::move(other.m_privileges)), m_author(std::move(other.m_author)),
+ m_creatorPid(other.m_creatorPid)
+{
+ other.m_creatorPid = -1;
+}
+
+std::string AppInstallHelper::getInstallDir() const {
+ return m_installDir + getPkgId();
+}
+
+std::string AppInstallHelper::getTrustedDir(int i) const {
+ return getInstallDir() + "/trustedDir" + std::to_string(i);
+}
+
+std::string AppInstallHelper::getPrivateDir(int i) const {
+ return getInstallDir() + "/app_dir" + std::to_string(i) +"/";
+}
+
+std::string AppInstallHelper::getPrivateRODir(int i) const {
+ return getInstallDir() + "/app_dir_ro" + std::to_string(i) +"/";
+}
+
+std::string AppInstallHelper::getPublicDir() const {
+ return getInstallDir() + "/app_public_ro/";
+}
+
+std::string AppInstallHelper::getPrivatePath(int i) const {
+ return getPrivateDir() + "shareme" + std::to_string(i);
+}
+
+std::string AppInstallHelper::getSharedRODir(int i) const {
+ return getInstallDir() + "/app_dir_rw_others_ro" + std::to_string(i) +"/";
+}
+
+std::string AppInstallHelper::getAppId() const {
+ return m_appName + "_app_id";
+}
+
+std::string AppInstallHelper::getPkgId() const {
+ return m_pkgName + "_pkg_id";
+}
+
+void AppInstallHelper::setVersion(const std::string &version) {
+ m_version = version;
+}
+
+std::string AppInstallHelper::getVersion() const {
+ return m_version;
+}
+
+int AppInstallHelper::getUID() const {
+ return m_uidGid;
+}
+
+int AppInstallHelper::getGID() const {
+ return m_uidGid;
+}
+
+void AppInstallHelper::createInstallDir() {
+ create(mkdir, getInstallDir());
+ m_isInstallDirCreated = true;
+}
+
+void AppInstallHelper::createTrustedDir(int i) {
+ if (create(mkdir, getTrustedDir(i)))
+ m_dirTypeMap[SECURITY_MANAGER_PATH_TRUSTED_RW].emplace_back(getTrustedDir(i));
+}
+
+void AppInstallHelper::createPrivateDir(int i) {
+ if (create(mkdir, getPrivateDir(i)))
+ m_dirTypeMap[SECURITY_MANAGER_PATH_RW].emplace_back(getPrivateDir(i));
+}
+
+void AppInstallHelper::createPublicDir() {
+ if (mkdir(getPublicDir().c_str(), 0777) == 0) {
+ m_dirTypeMap[SECURITY_MANAGER_PATH_PUBLIC_RO].emplace_back(getPublicDir());
+ }
+}
+
+void AppInstallHelper::createPrivateFile(int i) {
+ // This is intentional, let all private file be in one directory
+ createPrivateDir();
+ if (create(creat, getPrivatePath(i)))
+ m_fileTypeMap[SECURITY_MANAGER_PATH_RW].emplace_back(getPrivatePath(i));
+}
+
+void AppInstallHelper::createSharedRODir(int i) {
+ if (create(mkdir, getSharedRODir(i)))
+ m_dirTypeMap[SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO].emplace_back(getSharedRODir(i));
+}
+
+void AppInstallHelper::createPrivateRODir(int i) {
+ if (create(mkdir, getPrivateRODir(i)))
+ m_dirTypeMap[SECURITY_MANAGER_PATH_RO].emplace_back(getPrivateRODir(i));
+}
+
+void AppInstallHelper::setHybrid() {
+ m_isHybrid = true;
+}
+
+bool AppInstallHelper::getIsHybrid() const {
+ return m_isHybrid;
+}
+
+void AppInstallHelper::addPrivilege(const std::string &privilege) {
+ m_privileges.push_back(privilege);
+}
+
+void AppInstallHelper::addPrivileges(const std::vector<std::string> &privileges) {
+ std::copy(privileges.begin(), privileges.end(), std::back_inserter(m_privileges));
+}
+
+std::vector<std::string> AppInstallHelper::getPrivileges() const {
+ return m_privileges;
+}
+
+void AppInstallHelper::revokeRules() const {
+ RUNNER_ASSERT_MSG(
+ 0 == smack_revoke_subject(generateAppLabel().c_str()),
+ "Revoking smack subject failed");
+}
+
+std::string AppInstallHelper::generateAppLabel() const {
+ return generateProcessLabel(getAppId(), getPkgId(), getIsHybrid());
+}
+
+std::string AppInstallHelper::generatePkgLabel() const {
+ return generatePathRWLabel(getPkgId());
+}
+
+const AppInstallHelper::TypePathsMap& AppInstallHelper::getDirsMap() const {
+ return m_dirTypeMap;
+}
+
+const AppInstallHelper::TypePathsMap& AppInstallHelper::getFilesMap() const {
+ return m_fileTypeMap;
+}
+
+void AppInstallHelper::removePaths() {
+ for (const auto &oneTypePaths : m_dirTypeMap)
+ for (const auto& path : oneTypePaths.second)
+ rmdir(path.c_str());
+
+ m_dirTypeMap.clear();
+
+ for (const auto &oneTypePaths : m_fileTypeMap)
+ for (const auto& path : oneTypePaths.second)
+ unlink(path.c_str());
+
+ m_fileTypeMap.clear();
+
+ rmdir(getInstallDir().c_str());
+ m_isInstallDirCreated = false;
+}
+
+void AppInstallHelper::setInstallPath() {
+ if (m_isLocal)
+ m_installDir = TzPlatformConfig::appDirPath(getUID());
+ else
+ m_installDir = TzPlatformConfig::globalAppDir() + "/";
+}
+
+bool AppInstallHelper::create(std::function<int(const char*, mode_t)> &&creatFun, const std::string &path) {
+ if (!m_isInstallDirCreated && path != getInstallDir())
+ createInstallDir();
+ if (creatFun(path.c_str(), 0751) == 0) {
+ // Local paths need user change
+ if (!m_isLocal || chown(path.c_str(), m_uidGid, m_uidGid) == 0)
+ return true;
+ }
+ return false;
+}
+
+void AppInstallHelper::setAuthor(const std::string &author) {
+ m_author = author;
+}
+std::string AppInstallHelper::getAuthor() const {
+ return m_author;
+}
+
+void AppInstallHelper::setInstallType(app_install_type type) {
+ m_installType = type;
+}
+app_install_type AppInstallHelper::getInstallType() const {
+ return m_installType;
+}
+
*/
#pragma once
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/smack.h>
-
+#include <fcntl.h>
+#include <functional>
+#include <map>
#include <string>
+#include <sys/types.h>
+#include <vector>
+#include <unistd.h>
+#include <security-manager-types.h>
struct AppInstallHelper {
- AppInstallHelper(const std::string &name)
- : m_name(name)
- {}
-
- std::string getInstallDir() {
- return "/usr/apps/" + getPkgId();
- }
-
- std::string getTrustedDir(int i = 0) {
- return getInstallDir() + "/trustedDir" + std::to_string(i);
- }
-
- std::string getPrivateDir() {
- return getInstallDir() + "/app_dir/";
- }
-
- std::string getSharedPath(int i = 0) {
- return getPrivateDir() + "shareme" + std::to_string(i);
- }
- std::string getAppId() {
- return m_name + "_app_id";
- }
- std::string getPkgId() {
- return m_name + "_pkg_id";
+ using TypePathsMap = std::map<app_install_path_type, std::vector<std::string>>;
+ AppInstallHelper(const std::string &appNamePrefix,
+ const std::string &pkgNamePrefix,
+ bool isLocal,
+ uid_t uid,
+ std::string version = std::string())
+ : m_appName(appNamePrefix), m_pkgName(pkgNamePrefix), m_isLocal(isLocal), m_uidGid(uid), m_version(version),
+ m_installType(SM_APP_INSTALL_NONE), m_isHybrid(false), m_isInstallDirCreated(false), m_creatorPid(getpid())
+ {
+ setInstallPath();
}
- void createInstallDir() {
- if (mkdir(getInstallDir().c_str(), 0777) == 0) {
- m_dirs.push_back(getInstallDir());
- }
- }
+ AppInstallHelper(const std::string &appNamePrefix,
+ const std::string &pkgNamePrefix,
+ uid_t uid)
+ : AppInstallHelper(appNamePrefix, pkgNamePrefix, false, uid)
+ {}
- void createTrustedDir(int i = 0) {
- if (mkdir(getTrustedDir(i).c_str(), 0777) == 0) {
- m_dirs.push_back(getTrustedDir(i));
- }
- }
- void createPrivateDir() {
- if (mkdir(getPrivateDir().c_str(), 0777) == 0) {
- m_dirs.push_back(getPrivateDir());
- }
- }
+ AppInstallHelper(const std::string &namePrefix)
+ : AppInstallHelper(namePrefix, namePrefix, false, geteuid())
+ {}
- void createSharedFile(int i = 0) {
- if (creat(getSharedPath(i).c_str(), 0777) == 0) {
- m_files.push_back(getSharedPath(i));
- }
- }
+ AppInstallHelper(const std::string &appNamePrefix, const std::string &pkgNamePrefix)
+ : AppInstallHelper(appNamePrefix, pkgNamePrefix, false, geteuid())
+ {}
- void revokeRules() {
- RUNNER_ASSERT_MSG(
- 0 == smack_revoke_subject(generateAppLabel().c_str()),
- "Revoking smack subject failed");
- RUNNER_ASSERT_MSG(
- 0 == smack_revoke_subject(generatePkgLabel().c_str()),
- "Revoking smack subject failed");
- }
+ AppInstallHelper(const std::string &namePrefix, uid_t uid)
+ : AppInstallHelper(namePrefix, namePrefix, true, uid)
+ {}
- std::string generateAppLabel() {
- return "User::App::" + getAppId();
- }
+ AppInstallHelper(const std::string &appNamePrefix, const std::string &pkgNamePrefix, uid_t uid,
+ const std::string &version)
+ : AppInstallHelper(appNamePrefix, pkgNamePrefix, true, uid, version)
+ {}
- std::string generatePkgLabel() {
- return "User::Pkg::" + getPkgId();
- }
+ AppInstallHelper(const std::string &namePrefix, uid_t uid, const std::string &version)
+ : AppInstallHelper(namePrefix, namePrefix, true, uid, version)
+ {}
+ AppInstallHelper(const AppInstallHelper &other) = default;
+ AppInstallHelper& operator=(const AppInstallHelper &other) = delete;
+ AppInstallHelper(AppInstallHelper &&other);
+
+ // App info getters and setters
+ std::string getAppId() const;
+ std::string getPkgId() const;
+ int getUID() const;
+ int getGID() const;
+ void setVersion(const std::string &version);
+ std::string getVersion() const;
+ void setAuthor(const std::string &author);
+ std::string getAuthor() const;
+ void setInstallType(app_install_type type);
+ app_install_type getInstallType() const;
+ void setHybrid();
+ bool getIsHybrid() const;
+
+ // Path types creation and removal on file system
+ void createInstallDir();
+ void createTrustedDir(int i = 0);
+ void createPrivateDir(int i = 0);
+ void createPublicDir();
+ void createPrivateFile(int i = 0);
+ void createSharedRODir(int i = 0);
+ void createPrivateRODir(int i = 0);
+ void removePaths();
+
+ // Path getters
+ std::string getInstallDir() const;
+ std::string getTrustedDir(int i = 0) const;
+ std::string getPrivateDir(int i = 0) const;
+ std::string getPrivateRODir(int i = 0) const;
+ std::string getPublicDir() const;
+ std::string getPrivatePath(int i = 0) const;
+ std::string getSharedRODir(int i = 0) const;
+ const TypePathsMap& getDirsMap() const;
+ const TypePathsMap& getFilesMap() const;
+
+ // Privileges
+ void addPrivilege(const std::string &privilege);
+ void addPrivileges(const std::vector<std::string> &privileges);
+ std::vector<std::string> getPrivileges() const;
+
+ // Smack
+ std::string generateAppLabel() const;
+ std::string generatePkgLabel() const;
+ void revokeRules() const;
virtual ~AppInstallHelper() {
- // TODO we should also remove trusted dirs created with custom params
- for (const auto &dir : m_dirs) {
- rmdir(dir.c_str());
- }
- for (const auto &file : m_files) {
- unlink(file.c_str());
- }
+ if (m_creatorPid == getpid())
+ removePaths();
}
protected:
- std::string m_name;
- std::vector<std::string> m_dirs;
- std::vector<std::string> m_files;
+ void setInstallPath();
+ bool create(std::function<int(const char*, mode_t)> &&creatFun, const std::string &path);
+ std::string m_appName;
+ std::string m_pkgName;
+ bool m_isLocal;
+ int m_uidGid;
+ std::string m_version;
+ app_install_type m_installType;
+ bool m_isHybrid;
+ std::string m_installDir;
+ bool m_isInstallDirCreated;
+ TypePathsMap m_dirTypeMap;
+ TypePathsMap m_fileTypeMap;
+ std::vector<std::string> m_privileges;
+ std::string m_author;
+
+ pid_t m_creatorPid;
};
-
--- /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 <fstream>
+#include <regex>
+#include <string>
+#include <vector>
+
+#include <grp.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <policy_configuration.h>
+
+#define CONF_DIR "/usr/share/security-manager/policy/"
+#define CONF_GROUP_FILE "privilege-group.list"
+#define CONF_USER_TEMPLATE_FILE "usertype-%s.profile"
+
+namespace SecurityManagerTest {
+
+gid_t nameToGid(const char *name) {
+ struct group entry, *gresult;
+ char buffer[1024];
+ RUNNER_ASSERT_MSG(
+ 0 == getgrnam_r(name, &entry, buffer, 1024, &gresult) && (gresult != NULL),
+ "Error in getgrnam. Group name: " << name);
+ return entry.gr_gid;
+}
+
+
+std::string PolicyConfiguration::getConfigFilePath(UserType userType) {
+ const char *user = NULL;
+ switch(userType) {
+ case GUEST: user = "guest"; break;
+ case NORMAL: user = "normal"; break;
+ case ADMIN: user = "admin"; break;
+ case SYSTEM: user = "system"; break;
+ }
+ char buffer[1024];
+ snprintf(buffer, 1024, CONF_DIR CONF_USER_TEMPLATE_FILE, user);
+ return std::string(buffer);
+}
+
+PolicyConfiguration::PrivVector PolicyConfiguration::getUserPriv(PolicyConfiguration::UserType userType) {
+ return getUserDescription(userType).privVector;
+}
+
+PolicyConfiguration::GroupVector PolicyConfiguration::getUserGroup(PolicyConfiguration::UserType userType) {
+ return getUserDescription(userType).groupVector;
+}
+
+PolicyConfiguration::GidVector PolicyConfiguration::getUserGid(PolicyConfiguration::UserType userType) {
+ return getUserDescription(userType).gidVector;
+}
+
+PolicyConfiguration::GidVector PolicyConfiguration::getGid() {
+ return groupToGid(getGroup());
+}
+
+PolicyConfiguration::GroupVector PolicyConfiguration::getGroup() {
+ GroupVector result;
+ if (m_privGroupMap.empty())
+ loadPrivGroupMap();
+ for (auto &e : m_privGroupMap)
+ result.push_back(e.second);
+ return result;
+}
+
+PolicyConfiguration::UserDescription& PolicyConfiguration::getUserDescription(PolicyConfiguration::UserType userType) {
+ auto it = m_userDescriptionMap.find(userType);
+ if (it == m_userDescriptionMap.end())
+ m_userDescriptionMap[userType] = loadUserDescription(userType);
+ return m_userDescriptionMap[userType];
+}
+
+gid_t PolicyConfiguration::groupToGid(const std::string &gname) {
+ auto it = m_groupGidMap.find(gname);
+ if (it == m_groupGidMap.end())
+ m_groupGidMap[gname] = nameToGid(gname.c_str());
+ return m_groupGidMap[gname];
+}
+
+PolicyConfiguration::GidVector PolicyConfiguration::groupToGid(const PolicyConfiguration::GroupVector &groupVector) {
+ GidVector result;
+ for (auto &e : groupVector)
+ result.push_back(groupToGid(e));
+ return result;
+}
+
+PolicyConfiguration::PrivGroupMap PolicyConfiguration::getPrivGroupMap()
+{
+ if (m_privGroupMap.empty())
+ loadPrivGroupMap();
+ return m_privGroupMap;
+}
+
+bool PolicyConfiguration::getIsAskuserEnabled() {
+#ifdef ASKUSER_ENABLED
+ return true;
+#else
+ return false;
+#endif
+}
+
+PolicyConfiguration::UserDescription PolicyConfiguration::loadUserDescription(PolicyConfiguration::UserType userType) {
+ UserDescription result;
+ std::string path = getConfigFilePath(userType);
+ result.privVector = loadPrivFile(path);
+ result.groupVector = privToGroup(result.privVector);
+ result.gidVector = groupToGid(result.groupVector);
+ return result;
+}
+
+PolicyConfiguration::PrivVector PolicyConfiguration::loadPrivFile(const std::string &path) {
+ PrivVector result;
+ std::ifstream file(path);
+ std::string line;
+ std::regex r("^\\*[ \t]+(.*)");
+ while (std::getline(file, line)) {
+ std::smatch m;
+ if (std::regex_search(line, m, r))
+ result.push_back(m[1]);
+ }
+ return result;
+}
+
+PolicyConfiguration::GroupVector PolicyConfiguration::privToGroup(const PolicyConfiguration::PrivVector &privVector) {
+ GroupVector result;
+ if (m_privGroupMap.empty())
+ loadPrivGroupMap();
+ for (auto &e : privVector) {
+ auto it = m_privGroupMap.find(e);
+ if (it == m_privGroupMap.end())
+ continue;
+ result.push_back(it->second);
+ }
+ return result;
+}
+
+void PolicyConfiguration::loadPrivGroupMap(void) {
+ std::string pgPath(CONF_DIR CONF_GROUP_FILE);
+ std::ifstream file(pgPath);
+
+ RUNNER_ASSERT_MSG(file.is_open(),
+ "Unable to read group mapping file " << pgPath);
+
+ std::string line;
+ std::regex r("^(http(.*)) +(.*)");
+ while (std::getline(file, line)) {
+ std::smatch m;
+ if (std::regex_search(line, m, r))
+ m_privGroupMap[m[1]] = m[3];
+ }
+}
+
+} // namespace SecurityManagerTest
+
--- /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.
+ */
+#ifndef _SECURITY_MANAGER_TEST_POLICY_CONFIGURATION_
+#define _SECURITY_MANAGER_TEST_POLICY_CONFIGURATION_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <sys/types.h>
+
+namespace SecurityManagerTest {
+
+gid_t nameToGid(const char *name);
+
+class PolicyConfiguration {
+public:
+ typedef std::vector<gid_t> GidVector;
+ typedef std::vector<std::string> GroupVector;
+ typedef std::vector<std::string> PrivVector;
+ typedef std::map<std::string, std::string> PrivGroupMap;
+
+ struct UserDescription {
+ PrivVector privVector;
+ GroupVector groupVector;
+ GidVector gidVector;
+ };
+
+ enum UserType { GUEST, NORMAL, ADMIN, SYSTEM };
+
+ std::string getConfigFilePath(UserType userType);
+ PrivVector getUserPriv(UserType userType);
+ GroupVector getUserGroup(UserType userType);
+ GidVector getUserGid(UserType userType);
+ GidVector getGid();
+ GroupVector getGroup();
+ UserDescription& getUserDescription(UserType userType);
+ gid_t groupToGid(const std::string &gname);
+ PrivGroupMap getPrivGroupMap();
+ GroupVector privToGroup(const PrivVector &privVector);
+
+static bool getIsAskuserEnabled();
+
+private:
+ GidVector groupToGid(const GroupVector &groupVector);
+ UserDescription loadUserDescription(UserType userType);
+ PrivVector loadPrivFile(const std::string &path);
+ void loadPrivGroupMap(void);
+
+ PrivGroupMap m_privGroupMap;
+ std::map<std::string, gid_t> m_groupGidMap;
+ std::map<UserType, UserDescription> m_userDescriptionMap;
+};
+
+} // namespace SecurityManagerTest
+
+#endif
--- /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 <ftw.h>
+#include <string>
+#include <sys/capability.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <vector>
+
+#include <security-manager-types.h>
+
+#include <app_install_helper.h>
+#include <memory.h>
+#include <sm_request.h>
+#include <sm_api.h>
+#include <temp_test_user.h>
+#include <synchronization_pipe.h>
+#include <dpl/test/safe_cleanup.h>
+
+class ScopedInstaller {
+public:
+ ScopedInstaller(const AppInstallHelper &app, bool requestUid = true)
+ : m_appId(app.getAppId()),
+ m_uid(app.getUID()),
+ m_installType(app.getInstallType()),
+ m_shouldUninstall(true),
+ m_requestUid(requestUid),
+ m_creatorPid(getpid())
+ {
+ SecurityManagerTest::InstallRequest instReq;
+ instReq.setAppId(app.getAppId());
+ instReq.setPkgId(app.getPkgId());
+ if (app.getIsHybrid())
+ instReq.setHybrid();
+ if (app.getInstallType() != SM_APP_INSTALL_NONE)
+ instReq.setInstallType(app.getInstallType());
+ if (requestUid)
+ instReq.setUid(app.getUID());
+ if (!app.getVersion().empty())
+ instReq.setAppTizenVersion(app.getVersion());
+ if (!app.getAuthor().empty())
+ instReq.setAuthorId(app.getAuthor());
+ for (const auto& typePaths : app.getDirsMap())
+ for (const auto& path : typePaths.second)
+ instReq.addPath(path, typePaths.first);
+ for (const auto& typePaths : app.getFilesMap())
+ for (const auto& path : typePaths.second)
+ instReq.addPath(path, typePaths.first);
+ for (const auto &priv : app.getPrivileges()) {
+ instReq.addPrivilege(priv.c_str());
+ }
+ SecurityManagerTest::Api::install(instReq);
+ }
+
+ ScopedInstaller(const ScopedInstaller &) = delete;
+ ScopedInstaller(ScopedInstaller &&other)
+ : m_appId(std::move(other.m_appId)),
+ m_uid(other.m_uid),
+ m_installType(other.m_installType),
+ m_shouldUninstall(other.m_shouldUninstall),
+ m_requestUid(other.m_requestUid),
+ m_creatorPid(other.m_creatorPid)
+ {
+ other.m_uid = 0;
+ other.m_shouldUninstall = false;
+ other.m_creatorPid = -1;
+ }
+
+ ScopedInstaller& operator=(const ScopedInstaller &) = delete;
+
+ virtual ~ScopedInstaller() {
+ if (m_creatorPid == getpid())
+ {
+ SafeCleanup::run([this]{ uninstallApp(); });
+ }
+ }
+
+ void uninstallApp() {
+ if (!m_shouldUninstall)
+ return;
+ SecurityManagerTest::InstallRequest uninstReq;
+ uninstReq.setAppId(m_appId);
+ if (m_requestUid)
+ uninstReq.setUid(m_uid);
+ if (m_installType != SM_APP_INSTALL_NONE)
+ uninstReq.setInstallType(m_installType);
+ SecurityManagerTest::Api::uninstall(uninstReq);
+ m_shouldUninstall = false;
+ }
+
+protected:
+ std::string m_appId;
+ uid_t m_uid;
+ app_install_type m_installType;
+ bool m_shouldUninstall;
+ bool m_requestUid;
+ pid_t m_creatorPid;
+};
--- /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) 2014-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 <vector>
+#include <utility>
+
+class ScopedPathRemover {
+public:
+ ScopedPathRemover(std::initializer_list<std::string> &&vec)
+ : m_dirVec(std::move(vec))
+ {}
+
+ ~ScopedPathRemover() {
+ // FIXME : Properly remove files and not empty directories
+ for (const auto &dir : m_dirVec)
+ rmdir(dir.c_str());
+ }
+
+protected:
+ std::vector<std::string> m_dirVec;
+};
<< " Expected result: " << expectedResult);
}
-std::string getPkgId(const char *appId, lib_retcode expectedResult)
+std::string getPkgId(const std::string &appId, lib_retcode expectedResult)
{
char *pkgId = nullptr;
- int result = security_manager_get_app_pkgid(&pkgId, appId);
+ int result = security_manager_get_app_pkgid(&pkgId, appId.c_str());
RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
"getting pkg id from app id returned wrong value."
<< " App id: " << appId << ";"
return str;
}
-void setProcessLabel(const char *appId, lib_retcode expectedResult)
+void setProcessLabel(const std::string &appId, lib_retcode expectedResult)
{
- int result = security_manager_set_process_label_from_appid(appId);
+ int result = security_manager_set_process_label_from_appid(appId.c_str());
RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
"setting process label from app id returned wrong value."
<< " App id: " << appId << ";"
<< " Expected result: " << expectedResult);
}
-void setProcessGroups(const char *appId, lib_retcode expectedResult)
+void setProcessGroups(const std::string &appId, lib_retcode expectedResult)
{
- int result = security_manager_set_process_groups_from_appid(appId);
+ int result = security_manager_set_process_groups_from_appid(appId.c_str());
RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
"setting process groups from app id returned wrong value."
<< " App id: " << appId << ";"
<< " Expected result: " << expectedResult);
}
-void prepareApp(const char *appId, lib_retcode expectedResult)
+void prepareApp(const std::string &appId, lib_retcode expectedResult)
{
- int result = security_manager_prepare_app(appId);
+ int result = security_manager_prepare_app(appId.c_str());
RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
"preparing app returned wrong value."
<< " App id: " << appId << ";"
<< " Result: " << result << ";"
<< " Expected result: " << expectedResult);
- if (pkgId && result == SECURITY_MANAGER_SUCCESS) {
- RUNNER_ASSERT_MSG(pkg_Id != nullptr, "getting pkg and app id did not allocate memory");
- }
-
- if (appId && result == SECURITY_MANAGER_SUCCESS) {
- RUNNER_ASSERT_MSG(app_Id != nullptr, "getting pkg and app id did not allocate memory");
- }
-
if (pkg_Id) {
*pkgId = pkg_Id;
free(pkg_Id);
<< " Result: " << result << ";"
<< " Expected result: " << expectedResult);
- if (pkgId && result == SECURITY_MANAGER_SUCCESS) {
- RUNNER_ASSERT_MSG(pkg_Id != nullptr, "getting pkg and app id did not allocate memory");
+ if (pkg_Id) {
+ *pkgId = pkg_Id;
+ free(pkg_Id);
}
- if (appId && result == SECURITY_MANAGER_SUCCESS) {
- RUNNER_ASSERT_MSG(app_Id != nullptr, "getting pkg and app id did not allocate memory");
+ if (app_Id) {
+ *appId = app_Id;
+ free(app_Id);
}
+}
+
+void getPkgIdByCynaraClient(const std::string &client, std::string *pkgId, std::string *appId,
+ lib_retcode expectedResult)
+{
+ char *pkg_Id = nullptr;
+ char *app_Id = nullptr;
+
+ int result = security_manager_identify_app_from_cynara_client(client.c_str(),
+ pkgId == nullptr ? nullptr : &pkg_Id,
+ appId == nullptr ? nullptr : &app_Id);
+
+ RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+ "getting pkg id from pid returned wrong value."
+ << " client: " << client << ";"
+ << " Result: " << result << ";"
+ << " Expected result: " << expectedResult);
if (pkg_Id) {
*pkgId = pkg_Id;
}
}
-void appHasPrivilege(const char *appId, const char *privilege, uid_t user, int &value, lib_retcode expectedResult)
+void appHasPrivilege(const std::string &appId, const std::string &privilege, uid_t user,
+ int &value, lib_retcode expectedResult)
{
- int result = security_manager_app_has_privilege(appId, privilege, user, &value);
+ int result = security_manager_app_has_privilege(appId.c_str(), privilege.c_str(), user, &value);
RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
"checking application privilege returned wrong result."
<< " Expected result: " << expectedResult);
}
+void getSecurityManagerGroups(char ***groups, size_t *groups_count, lib_retcode expectedResult)
+{
+ int result = security_manager_groups_get(groups, groups_count);
+ RUNNER_ASSERT_MSG(static_cast<lib_retcode>(result) == expectedResult,
+ "Unexpected result in security_manager_groups_get()" << std::endl
+ << " Result: " << result << " Expected: " << expectedResult);
+}
+
+void registerPaths(const PathsRequest& req, lib_retcode expectedResult)
+{
+ int result = security_manager_paths_register(req.get());
+ RUNNER_ASSERT_MSG(static_cast<lib_retcode>(result) == expectedResult,
+ "Unexpected result in security_manager_paths_register()" << std::endl
+ << " Result: " << result << " Expected: " << expectedResult);
+}
+
+void labelsMonitorGetFd(const LabelMonitor &monitor, int *fd, lib_retcode expectedResult)
+{
+ int result = security_manager_app_labels_monitor_get_fd(monitor.get(), fd);
+ RUNNER_ASSERT_MSG(static_cast<lib_retcode>(result) == expectedResult,
+ "Unexpected result in security_manager_app_labels_monitor_get_fd()"
+ << std::endl << " Result: " << result << " Expected: "
+ << expectedResult);
+};
+
+void labelsProcess(const LabelMonitor &monitor, lib_retcode expectedResult)
+{
+ int result = security_manager_app_labels_monitor_process(monitor.get());
+ RUNNER_ASSERT_MSG(static_cast<lib_retcode>(result) == expectedResult,
+ "Unexpected result in security_manager_app_labels_monitor_process()"
+ << std::endl << " Result: " << result << " Expected: "
+ << expectedResult);
+}
+
} // namespace Api
} // namespace SecurityManagerTest
#ifndef SECURITY_MANAGER_TEST_API
#define SECURITY_MANAGER_TEST_API
-#include <sm_request.h>
-#include <sm_user_request.h>
+#include <sm_label_monitor.h>
#include <sm_policy_request.h>
+#include <sm_request.h>
#include <sm_sharing_request.h>
+#include <sm_user_request.h>
#include <security-manager.h>
void install(const InstallRequest &request, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
void uninstall(const InstallRequest &request, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
-std::string getPkgId(const char *appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
-void setProcessLabel(const char *appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
-void setProcessGroups(const char *appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+std::string getPkgId(const std::string &appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void setProcessLabel(const std::string &appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void setProcessGroups(const std::string &appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
void dropProcessPrivileges(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
-void prepareApp(const char *appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void prepareApp(const std::string &appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
void addUser(const UserRequest &request, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
void deleteUser(const UserRequest &request, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
void sendPolicy(const PolicyRequest &request, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
void dropSharing(const SharingRequest &req, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
void getPkgIdBySocket(int socketFd, std::string *pkgId, std::string *appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
void getPkgIdByPid(pid_t pid, std::string *pkgId, std::string *appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
-void appHasPrivilege(const char *appId, const char *privilege, uid_t user, int &value, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void getPkgIdByCynaraClient(const std::string &client, std::string *pkgId, std::string *appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void appHasPrivilege(const std::string &appId, const std::string &privilege, uid_t user, int &value, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void getSecurityManagerGroups(char ***groups, size_t *groups_count, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void registerPaths(const PathsRequest& req, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void labelsMonitorGetFd(const LabelMonitor &monitor, int *fd, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void labelsProcess(const LabelMonitor &monitor, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+
} // namespace Api
} // namespace SecurityManagerTest
-
#endif // SECURITY_MANAGER_TEST_API
--- /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 <algorithm>
+#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_map>
+#include <cstdlib>
+
+#include <unordered_set>
+#include <vector>
+
+#include <security-manager-types.h>
+#include <app-runtime.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 <synchronization_pipe.h>
+#include <sm_request.h>
+#include <tests_common.h>
+#include <policy_configuration.h>
+#include "tzplatform.h"
+
+using namespace SecurityManagerTest;
+
+// Common implementation details
+
+std::string generateProcessLabel(const std::string &appId, const std::string &pkgId, bool isHybrid)
+{
+ std::string label = "User::Pkg::" + pkgId;
+ if (isHybrid) {
+ label += "::App::" + appId;
+ }
+ return label;
+}
+
+std::string generatePathRWLabel(const std::string &pkgId)
+{
+ return "User::Pkg::" + pkgId;
+}
+
+std::string generatePathROLabel(const std::string &pkgId)
+{
+ return generatePathRWLabel(pkgId) + "::RO";
+}
+
+std::string generatePathSharedROLabel(const std::string &pkgId)
+{
+ return generatePathRWLabel(pkgId) + "::SharedRO";
+}
+
+std::string generatePathTrustedLabel(int64_t authorId)
+{
+ return "User::Author::" + std::to_string(authorId);
+}
+
+std::string getPublicPathLabel()
+{
+ return "User::Home";
+}
+
+// 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;
+}
+
+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;
+}
+
+void check_app_permissions(const std::string &app_id, const std::string &pkg_id,
+ const std::string &user, const privileges_t &allowed_privs,
+ const privileges_t &denied_privs, bool isHybrid)
+{
+ (void) pkg_id;
+ std::string smackLabel = generateProcessLabel(app_id, pkg_id, isHybrid);
+
+ CynaraTestClient::Client ctc;
+
+ for (auto &priv : allowed_privs) {
+ ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_ALLOWED);
+ }
+
+ for (auto &priv : denied_privs) {
+ ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_DENIED);
+ }
+}
+
+void sm_app_has_privileges(const AppInstallHelper &app,
+ const std::vector<std::string> &privileges,
+ int expectedResult)
+{
+ for (auto const &privilege : privileges) {
+ int result;
+ Api::appHasPrivilege(app.getAppId(), privilege, app.getUID(), result);
+ RUNNER_ASSERT_MSG(result == expectedResult, "Application " << app.getAppId()
+ << " has unexpected access to " << privilege << ", is : "
+ << " should be : " << expectedResult );
+ }
+}
+
+static void check_app(const std::string &appId, const std::string &pkgId, bool shouldBeInstalled)
+{
+ char *retPkgId;
+ int ret = security_manager_get_app_pkgid(&retPkgId, appId.c_str());
+
+ if (shouldBeInstalled) {
+ RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "The given appId is not installed.");
+
+ if (ret == SECURITY_MANAGER_SUCCESS) {
+ CStringPtr retPkgIdPtr(retPkgId);
+ RUNNER_ASSERT_MSG(strcmp(pkgId.c_str(), retPkgId) == 0,
+ "The given appId does not belong to the given pkgId.");
+ }
+ } else {
+ RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT, "The given appId is installed.");
+ }
+}
+
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id)
+{
+ check_app(app_id, pkg_id, true);
+}
+
+static void check_app_gids(const std::string &app_id, const std::vector<gid_t> &allowed_gids)
+{
+ int ret;
+ gid_t main_gid = getgid();
+ std::unordered_set<gid_t> reference_gids(allowed_gids.begin(), allowed_gids.end());
+
+ // Reset supplementary groups
+ ret = setgroups(0, NULL);
+ RUNNER_ASSERT_MSG(ret != -1, "Unable to set supplementary groups");
+
+ Api::setProcessGroups(app_id);
+
+ ret = getgroups(0, nullptr);
+ RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
+
+ std::vector<gid_t> actual_gids(ret);
+ ret = getgroups(ret, actual_gids.data());
+ RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
+
+ for (const auto &gid : actual_gids) {
+ RUNNER_ASSERT_MSG(gid == main_gid || reference_gids.count(gid) > 0,
+ "Application shouldn't get access to group " << gid);
+ reference_gids.erase(gid);
+ }
+
+ RUNNER_ASSERT_MSG(reference_gids.empty(), "Application didn't get access to some groups");
+}
+
+static const char *const ANY_USER_REPRESENTATION = "anyuser";/*this may be actually any string*/
+
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
+ const privileges_t &allowed_privs,
+ const privileges_t &denied_privs,
+ bool isHybrid)
+{
+ check_app(app_id, pkg_id, true);
+
+ /* Privileges should be granted to all users if root installs app */
+ check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, allowed_privs, denied_privs, isHybrid);
+
+ PolicyConfiguration policy;
+ const PolicyConfiguration::GroupVector allowed_groups = policy.privToGroup(allowed_privs);
+ RUNNER_ASSERT_MSG(allowed_groups.size() == allowed_privs.size(),
+ "Some privileges given were not found in the policy");
+
+ std::vector<gid_t> allowed_gids;
+ for (const auto &groupName : allowed_groups) {
+ errno = 0;
+ struct group* grp = getgrnam(groupName.c_str());
+ RUNNER_ASSERT_ERRNO_MSG(grp, "Group: " << groupName << " not found");
+ allowed_gids.push_back(grp->gr_gid);
+ }
+
+ check_app_gids(app_id, allowed_gids);
+}
+
+void check_path(const std::string &path, const std::string &label, bool transmute, bool execute) {
+ nftw_expected_label = label;
+ nftw_expected_transmute = transmute;
+ nftw_expected_exec = execute;
+
+ // 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_after_uninstall(const std::string &app_id, const std::string &pkg_id)
+{
+ check_app(app_id, pkg_id, false);
+}
+
+void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
+ const privileges_t &privileges, bool isHybrid)
+{
+ check_app(app_id, pkg_id, false);
+
+ /* Privileges should not be granted anymore to any user */
+ check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, {}, privileges, isHybrid);
+}
+
+std::string access_opposite(std::string &access) {
+ static const std::map<char, int> access_mapping = {{'r', 0}, {'w', 1}, {'x', 2}, {'a', 3},
+ {'t', 4}, {'l', 5}};
+ // May write implies may lock
+ if (access.find('w') != std::string::npos && access.find('l') == std::string::npos) {
+ access.append("l");
+ }
+ std::string access_opposite = "rwxatl";
+ for (char c : access) {
+ access_opposite[access_mapping.at(c)] = '-';
+ }
+ auto it = std::remove_if(access_opposite.begin(), access_opposite.end(), [](char c) {return c == '-';});
+ access_opposite.erase(it, access_opposite.end());
+ return access_opposite;
+}
+
+void check_exact_smack_accesses(const std::string &subject, const std::string &object,
+ const std::string &access) {
+ std::string access_str(access);
+ auto no_access = access_opposite(access_str);
+ for (char c : access_str) {
+ int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
+ RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object
+ << ">, <" << c << "> errno=" << strerror(errno));
+ RUNNER_ASSERT_MSG(ret == 1, "Access " << c << " from " << subject << " to "
+ << object << " not given");
+ }
+
+ for (char c : no_access) {
+ int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
+ RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object
+ << ">, <" << c << "> errno=" << strerror(errno));
+ RUNNER_ASSERT_MSG(ret == 0, "Access " << c << " from " << subject << " to "
+ << object << " unnecessarily given");
+ }
+}
+
+CapsSetsUniquePtr setCaps(const char *cap_string)
+{
+ CapsSetsUniquePtr caps(cap_init());
+ 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;
+}
+
+pid_t runInChild(const std::function<void(void)> &process) {
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "fork failed");
+
+ if (pid == 0) {
+ process();
+ exit(EXIT_SUCCESS);
+ }
+ return pid;
+}
+
+void runInChildParentWait(const std::function<void(void)> &process) {
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "fork failed");
+ if (pid == 0) {
+ process();
+ exit(EXIT_SUCCESS);
+ } else {
+ waitPid(pid);
+ }
+}
+
+static int getOppositeAccessType(int accessType) {
+ return accessType ^ (R_OK | W_OK | X_OK);
+}
+
+static const std::unordered_map<int, const char* const> accessTypeToString {
+ std::make_pair(0, "F_OK"),
+ std::make_pair(1, "X_OK"),
+ std::make_pair(2, "W_OK"),
+ std::make_pair(3, "W_OK|X_OK"),
+ std::make_pair(4, "R_OK"),
+ std::make_pair(5, "R_OK|X_OK"),
+ std::make_pair(6, "R_OK|W_OK"),
+ std::make_pair(7, "R_OK|W_OK|X_OK")
+};
+
+void accessCheck(const std::string &id, const std::string &path, int accessType,
+ int expected)
+{
+ RUNNER_ASSERT_MSG(::access(path.c_str(), accessType) == expected,
+ "access from " << id << " to path " << path
+ << (expected == 0 ? " not granted" : " unnecessarily granted")
+ << " (" << accessTypeToString.at(accessType) << ")");
+}
+
+void runAccessTest(const std::string &label, uid_t uid, gid_t gid,
+ const std::string &testPath, int accessType) {
+ auto fun = [&](){
+ int oppositeAccessType = getOppositeAccessType(accessType);
+ change_label(label.c_str());
+ RUNNER_ASSERT_ERRNO_MSG(0 == drop_root_privileges(uid, gid),
+ "drop_root_privileges failed.");
+
+ if (accessType != 0)
+ accessCheck(label, testPath, accessType, 0);
+ if (oppositeAccessType != 0) {
+ std::vector<int> singleAccessTypes = {R_OK, W_OK, X_OK};
+ for (auto singleAccessType : singleAccessTypes)
+ if (oppositeAccessType & singleAccessType)
+ accessCheck(label, testPath, singleAccessType, -1);
+ }
+ };
+
+ runInChildParentWait(fun);
+}
+
+void runAccessTest(const AppInstallHelper &app, const std::string &testPath, int accessType) {
+ auto fun = [&](){
+ int oppositeAccessType = getOppositeAccessType(accessType);
+ Api::setProcessLabel(app.getAppId());
+ RUNNER_ASSERT_ERRNO_MSG(0 == drop_root_privileges(app.getUID(), app.getGID()),
+ "drop_root_privileges failed.");
+ if (accessType != 0)
+ accessCheck(app.getAppId(), testPath, accessType, 0);
+ if (oppositeAccessType != 0) {
+ std::vector<int> singleAccessTypes = {R_OK, W_OK, X_OK};
+ for (auto singleAccessType : singleAccessTypes)
+ if (oppositeAccessType & singleAccessType)
+ accessCheck(app.getAppId(), testPath, singleAccessType, -1);
+ }
+ };
+
+ runInChildParentWait(fun);
+}
+
+static const std::vector<std::string> SM_SYSTEM_LABELS = {"System", "System::Privileged", "User"};
+
+void runSystemAccessTest(uid_t uid, gid_t gid, const std::string &testPath, int accessType) {
+ for (const auto &label : SM_SYSTEM_LABELS)
+ runAccessTest(label, uid, gid, testPath, accessType);
+}
+
--- /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 <ftw.h>
+#include <string>
+#include <sys/capability.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <vector>
+#include <functional>
+
+#include <security-manager-types.h>
+
+#include <app_install_helper.h>
+#include <memory.h>
+#include <temp_test_user.h>
+#include <tzplatform.h>
+
+DEFINE_SMARTPTR(cap_free, _cap_struct, CapsSetsUniquePtr);
+
+const int FTW_MAX_FDS = 16;
+
+std::string generateProcessLabel(const std::string &appId, const std::string &pkgId, bool isHybrid = false);
+std::string generatePathRWLabel(const std::string &pkgId);
+std::string generatePathROLabel(const std::string &pkgId);
+std::string generatePathSharedROLabel(const std::string &pkgId);
+std::string generatePathTrustedLabel(int64_t authorId);
+std::string getPublicPathLabel();
+
+typedef std::vector<std::string> privileges_t;
+
+int nftw_remove_labels(const char *fpath, const struct stat* /*sb*/,
+ int /*typeflag*/, struct FTW* /*ftwbuf*/);
+void check_app_permissions(const std::string &app_id, const std::string &pkg_id,
+ const std::string &user, const privileges_t &allowed_privs,
+ const privileges_t &denied_privs, bool isHybrid = false);
+void sm_app_has_privileges(const AppInstallHelper &app,
+ const std::vector<std::string> &privileges,
+ int result);
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id);
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
+ const privileges_t &allowed_privs,
+ const privileges_t &denied_privs,
+ bool isHybrid = false);
+void check_path(const std::string &path, const std::string &label,
+ bool transmute = true, bool execute = false);
+void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id);
+void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
+ const privileges_t &privileges, bool isHybrid = false);
+
+std::string access_opposite(std::string &access);
+void check_exact_smack_accesses(const std::string &subject,
+ const std::string &object,
+ const std::string &access);
+
+CapsSetsUniquePtr setCaps(const char *cap_string);
+
+pid_t runInChild(const std::function<void(void)> &process);
+
+void runInChildParentWait(const std::function<void(void)> &process);
+void runAccessTest(const std::string &label, uid_t uid, gid_t gid,
+ const std::string &testPath, int accessType);
+void runAccessTest(const AppInstallHelper &app, const std::string &testPath, int accessType);
+void runSystemAccessTest(uid_t uid, gid_t gid, const std::string &testPath, int accessType);
+++ /dev/null
-/*
- * Copyright (c) 2014-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.
-*/
-
-/*
- * @file sm_db.cpp
- * @author Marcin Lis (m.lis@samsung.com)
- * @version 1.0
- * @brief security-manager tests database record check functions
- */
-
-#include <tests_common.h>
-#include <tzplatform_config.h>
-#include <sstream>
-#include "sm_db.h"
-#include "db_sqlite.h"
-
-/* Keep this consistent with the database file path used in the security-manager */
-const char *const PRIVILEGE_DB_PATH = tzplatform_mkpath(TZ_SYS_DB, ".security-manager.db");
-
-/* Initialize static constants */
-const bool TestSecurityManagerDatabase::NOT_REMOVED = false;
-const bool TestSecurityManagerDatabase::REMOVED = true;
-
-TestSecurityManagerDatabase::TestSecurityManagerDatabase() : m_base(PRIVILEGE_DB_PATH, SQLITE_OPEN_READWRITE)
-{
-}
-
-void TestSecurityManagerDatabase::test_db_after__app_install(const std::string &app_name,
- const std::string &pkg_name)
-{
- const privileges_t dummy; /* just some empty privileges set */
-
- test_db_after__app_install(app_name, pkg_name, dummy);
-}
-
-void TestSecurityManagerDatabase::test_db_after__app_install(const std::string &app_name,
- const std::string &pkg_name,
- const privileges_t &privileges)
-{
- if (!m_base.is_open())
- m_base.open();
-
- RUNNER_ASSERT_MSG(!app_name.empty(), "Request is corrupted, appId is empty");
- RUNNER_ASSERT_MSG(!pkg_name.empty(), "Request is corrupted, pkgId is empty");
-
- check_app_and_pkg(app_name, pkg_name, NOT_REMOVED);
-
- if (!privileges.empty()) {
- check_privileges(app_name, pkg_name, privileges);
- }
-}
-
-void TestSecurityManagerDatabase::test_db_after__app_uninstall(const std::string &app_name,
- const std::string &pkg_name,
- const bool is_pkg_removed)
-{
- const privileges_t dummy; /* just some empty privileges set */
-
- test_db_after__app_uninstall(app_name, pkg_name, dummy, is_pkg_removed);
-}
-
-void TestSecurityManagerDatabase::test_db_after__app_uninstall(const std::string &app_name,
- const std::string &pkg_name,
- const privileges_t &privileges,
- const bool is_pkg_removed)
-{
- if (!m_base.is_open())
- m_base.open();
-
- RUNNER_ASSERT_MSG(!app_name.empty(), "Request is corrupted, appId is empty");
- RUNNER_ASSERT_MSG(!pkg_name.empty(), "Request is corrupted, pkgId is empty");
-
- check_app_and_pkg(app_name, pkg_name, REMOVED);
- check_pkg(pkg_name, is_pkg_removed);
-
- if (!privileges.empty()) {
- check_privileges_removed(app_name, pkg_name, privileges);
- }
-}
-
-void TestSecurityManagerDatabase::check_privileges(const std::string &app_name,
- const std::string &pkg_name,
- const privileges_t &privileges)
-{
- bool result;
-
- RUNNER_ASSERT_MSG(!app_name.empty(), "Request is corrupted, appId is empty");
- RUNNER_ASSERT_MSG(!pkg_name.empty(), "Request is corrupted, pkgId is empty");
-
- for (auto it = privileges.begin(); it != privileges.end(); ++it) {
- result = check_privilege(app_name, pkg_name, *it);
-
- RUNNER_ASSERT_MSG(result == true, "privilege: <" << *it << "> not added to app: <" <<
- app_name << "> from pkg_id: <" << pkg_name << ">");
- }
-}
-
-void TestSecurityManagerDatabase::check_privileges_removed(const std::string &app_name,
- const std::string &pkg_name,
- const privileges_t &privileges)
-{
- bool result;
-
- RUNNER_ASSERT_MSG(!app_name.empty(), "Request is corrupted, appId is empty");
- RUNNER_ASSERT_MSG(!pkg_name.empty(), "Request is corrupted, pkgId is empty");
-
- for (auto it = privileges.begin(); it != privileges.end(); ++it) {
- result = check_privilege(app_name, pkg_name, *it);
-
- RUNNER_ASSERT_MSG(result == false, "privilege: <" << *it << "> not removed for app: <" <<
- app_name << "> from pkg_id: <" << pkg_name << ">");
- }
-}
-
-void TestSecurityManagerDatabase::check_app_and_pkg(const std::string &app_name, const std::string &pkg_name,
- const bool is_app_removed)
-{
- Sqlite3DBaseSelectResult result;
- std::ostringstream sql;
- sql << "SELECT app_name, pkg_name FROM app_pkg_view"
- " WHERE app_name == '" << app_name << "' "
- " AND pkg_name == '" << pkg_name << "' ;";
- m_base.execute(sql.str(), result);
-
- if (is_app_removed) /* expect 0 results */
- RUNNER_ASSERT_MSG(result.rows.size() == 0, "query : <" << sql.str() <<
- "> returned [" << result.rows.size() << "] rows, expected [0]");
- else /* expect exactly 1 result with 2 columns */
- RUNNER_ASSERT_MSG(result.rows.size() == 1 && result.rows[0].size() == 2, "query : <" <<
- sql.str() << "> returned [" << result.rows.size() << "] rows, expected [1]");
-}
-
-void TestSecurityManagerDatabase::check_pkg(const std::string &pkg_name,
- const bool is_pkg_removed)
-{
- const unsigned expected_rows = is_pkg_removed ? 0 : 1;
- Sqlite3DBaseSelectResult result;
- std::ostringstream sql;
- sql << "SELECT pkg_id FROM pkg"
- " WHERE name == '" << pkg_name << "' ;";
- m_base.execute(sql.str(), result);
-
- RUNNER_ASSERT_MSG(result.rows.size() == expected_rows, "query : <" <<
- sql.str() << "> returned [" << result.rows.size() << "] rows, expected [" <<
- expected_rows << "] rows");
-}
-
-bool TestSecurityManagerDatabase::check_privilege(const std::string &app_name,
- const std::string &pkg_name,
- const std::string &privilege)
-{
- Sqlite3DBaseSelectResult result;
- std::ostringstream sql;
- sql << "SELECT privilege_id FROM app_privilege_view"
- " WHERE app_name == '" << app_name << "' "
- " AND pkg_name == '" << pkg_name << "' "
- " AND privilege_name == '" << privilege << "' "
- ";";
- m_base.execute(sql.str(), result);
-
- /* only 0 or 1 resulting rows are alowed */
- RUNNER_ASSERT_MSG(result.rows.size() == 0 || result.rows.size() == 1, "query : <" << sql.str() << "> returned [" <<
- result.rows.size() << "] rows");
-
- return result.rows.size() == 1;
-}
-
-void TestSecurityManagerDatabase::setup_privilege_groups(const std::string &privilege,
- const std::vector<std::string> &groups)
-{
- Sqlite3DBaseSelectResult result;
- std::ostringstream sql;
-
- if (!m_base.is_open())
- m_base.open();
-
- for (const auto &group : groups) {
- sql.clear();
- sql.str("");
- sql << "INSERT INTO privilege_group_view (privilege_name, group_name) "
- "VALUES ("
- << "'" << privilege << "'" << ","
- << "'" << group << "'" << ")";
- m_base.execute(sql.str(), result);
- }
-}
-
-int64_t TestSecurityManagerDatabase::get_author_id(const std::string &authorName)
-{
- Sqlite3DBaseSelectResult result;
- std::ostringstream sql;
-
- if (!m_base.is_open())
- m_base.open();
-
- sql.clear();
- sql.str("SELECT author_id FROM author where name=\"" + authorName + "\"");
- m_base.execute(sql.str(), result);
-
- if(result.rows.empty())
- return 0;
-
- std::istringstream os(result.rows[0][0]);
- int64_t id;
- os >> id;
- return id;
-}
-
-std::string TestSecurityManagerDatabase::get_path_label(const std::string &path)
-{
- Sqlite3DBaseSelectResult result;
- std::ostringstream sql;
- if (!m_base.is_open())
- m_base.open();
- sql.clear();
- sql.str("SELECT path_label FROM shared_path WHERE path=\"" + path + "\"");
- m_base.execute(sql.str(), result);
-
- if(result.rows.empty())
- return "";
-
- return result.rows[0][0];
-}
+++ /dev/null
-/*
- * Copyright (c) 2014-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.
-*/
-
-/*
- * @file sm_db.h
- * @author Marcin Lis (m.lis@samsung.com)
- * @version 1.0
- * @brief security-manager tests database record check functions
- */
-
-#ifndef SECURITY_MANAGER_TEST_DB_H_
-#define SECURITY_MANAGER_TEST_DB_H_
-
-#include <string>
-#include "db_sqlite.h"
-
-typedef std::vector<std::string> privileges_t;
-
-/**
- * @class TestSecurityManagerDatabase
- * @brief Class containing methods for testing libprivlege database.
- */
-class TestSecurityManagerDatabase
-{
-public:
-/**
- * @brief A usefull constant to indicate that app/pkg should be present in db
- */
- const static bool NOT_REMOVED;
-/**
- * @brief A usefull constant to indicate that app/pkg should not be present in db
- */
- const static bool REMOVED;
-/**
- * @brief A constructor
- */
- TestSecurityManagerDatabase();
-
-/**
- * @brief A destructor
- */
- ~TestSecurityManagerDatabase() = default;
-
-/**
- * @brief Method for testing database after "security_manager_app_install" was run.
- *
- * It checks existence of proper: - app_name
- * - pkg_name
- *
- * @param app_name name of the app previously used in security_manager_app_install.
- * @param pkg_name name of the pkg previously used in security_manager_app_install.
- */
- void test_db_after__app_install(const std::string &app_name, const std::string &pkg_name);
-
-/**
- * @brief Method for testing database after "security_manager_app_install" was run.
- *
- * It checks existence of proper: - app_name
- * - pkg_name
- * - privileges
- * TODO: appPaths are currently not handled directly by security-manager, so they are not tested.
- *
- * @param app_name name of the app previously used in security_manager_app_install.
- * @param pkg_name name of the pkg previously used in security_manager_app_install.
- * @param privileges vector of privileges previously used in security_manager_app_install.
- */
- void test_db_after__app_install(const std::string &app_name, const std::string &pkg_name,
- const privileges_t &privileges);
-
-/**
- * @brief Method for testing database after "security_manager_app_uninstall" was run.
- *
- * It checks absence of proper: - app_name
- * - optionally pkg_name
- *
- * @param app_name name of the app previously used in security_manager_app_uninstall.
- * @param pkg_name name of the pkg previously used in security_manager_app_uninstall.
- * @param is_pkg_removed tells if pkg_id is expected to remain in db or not.
- */
- void test_db_after__app_uninstall(const std::string &app_name, const std::string &pkg_name,
- const bool is_pkg_removed);
-
-/**
- * @brief Method for testing database after "security_manager_app_uninstall" was run.
- *
- * It checks absence of proper: - app_name
- * - optionally pkg_name
- * - app privileges
- * TODO: appPaths are currently not handled directly by security-manager, so they are not tested.
- *
- * @param app_name name of the app previously used in security_manager_app_uninstall.
- * @param pkg_name name of the pkg previously used in security_manager_app_uninstall.
- * @param privileges vector of privileges previously used in security_manager_app_uninstall.
- * @param is_pkg_removed tells if pkg_id is expected to remain in db or not.
- */
- void test_db_after__app_uninstall(const std::string &app_name, const std::string &pkg_name,
- const privileges_t &privileges, const bool is_pkg_removed);
-
-/**
- * @brief It checks db for existence of a all privileges from install request.
- *
- * @param app_name name of the app previously used i.e. in security_manager_app_install.
- * @param pkg_name name of the pkg previously used i.e. in security_manager_app_install.
- * @param privileges vector of privileges previously used i.e. in security_manager_app_install.
- */
- void check_privileges(const std::string &app_name, const std::string &pkg_name,
- const privileges_t &privileges);
-
-/**
- * @brief It checks in db if all app privileges from install request are removed.
- *
- * @param app_name name of the app previously used i.e. in security_manager_app_uninstall.
- * @param pkg_name name of the pkg previously used i.e. in security_manager_app_uninstall.
- * @param privileges vector of privileges previously used i.e. in security_manager_app_uninstall.
- */
- void check_privileges_removed(const std::string &app_name, const std::string &pkg_name,
- const privileges_t &privileges);
-
-/**
- * @brief Method for setting privilege to groups mapping in security-manager database
- *
- * @param privilege name of the privilege
- * @param groups vector of group names
- */
- void setup_privilege_groups(const std::string &privilege,
- const std::vector<std::string> &groups);
-
-/**
- * @brief Method for getting author id from database.
- */
- int64_t get_author_id(const std::string &authorName);
-/**
- * @brief Method for path label from database.
- */
- std::string get_path_label(const std::string &path);
-private:
-/**
- * @var base
- * @brief Sqlite3DBase object giving simple access to database
- *
- * Connection to database is open first time it is needed
- * and closed in destructor of TestSecurityManagerDatabase.
- */
- Sqlite3DBase m_base;
-
-/**
- * @brief Check db for [non]existence of given app_name in pkg_name
- *
- * @param app_name name of application
- * @param pkg_name name of package
- * @param is_app_removed tells if app is expected in db
- */
- void check_app_and_pkg(const std::string &app_name, const std::string &pkg_name,
- const bool is_app_removed);
-
-/**
- * @brief Check db for [non]existence of given pkg_name
- *
- * @param pkg_name name of the package
- * @param is_pkg_removed tells if pkg is expected in db
- */
- void check_pkg(const std::string &pkg_name,
- const bool is_pkg_removed);
-
-/**
- * @brief Check db for existence of a single privilege.
- *
- * @param app_name name of application
- * @param pkg_name application's package name
- * @param privilege name of the privilege
- *
- * @return true when privilege present
- * false when privilege not present
- */
- bool check_privilege(const std::string &app_name, const std::string &pkg_name,
- const std::string &privilege);
-};
-
-#endif /* SECURITY_MANAGER_TEST_DB_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.
+ */
+
+#include "sm_label_monitor.h"
+
+#include <dpl/test/test_runner.h>
+
+namespace SecurityManagerTest {
+
+LabelMonitor::LabelMonitor()
+ : m_monitor(nullptr)
+{
+ int result = security_manager_app_labels_monitor_init(&m_monitor);
+ RUNNER_ASSERT_MSG(static_cast<lib_retcode>(result) == SECURITY_MANAGER_SUCCESS,
+ "security_manager_app_labels_monitor_init failed with " << result);
+ RUNNER_ASSERT_MSG(m_monitor != nullptr,
+ "security_manager_app_labels_monitor_init didn't allocate memory");
+}
+
+LabelMonitor::~LabelMonitor()
+{
+ security_manager_app_labels_monitor_finish(m_monitor);
+}
+
+} // namespace SecurityManagerTest
--- /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 <security-manager.h>
+
+namespace SecurityManagerTest {
+
+class LabelMonitor
+{
+public:
+ LabelMonitor();
+ LabelMonitor(const LabelMonitor&) = delete;
+ LabelMonitor& operator=(const LabelMonitor&) = delete;
+ ~LabelMonitor();
+
+ app_labels_monitor *get() const { return m_monitor; }
+private:
+ app_labels_monitor *m_monitor;
+};
+
+} // namespace SecurityManagerTest
+
security_manager_policy_entry_free(m_entry);
}
+bool PolicyEntry::operator==(const PolicyEntry &other) const
+{
+ auto cmp = [](const std::pair<bool, std::string> &a, const std::pair<bool, std::string> &b)->bool
+ {
+ return (a.first) ? (b.first && a.second == b.second) : !b.first;
+ };
+
+ return (
+ cmp(m_appId, other.m_appId) &&
+ cmp(m_user, other.m_user) &&
+ cmp(m_privilege, other.m_privilege) &&
+ cmp(m_currentLevel, other.m_currentLevel) &&
+ cmp(m_maxLevel, other.m_maxLevel));
+}
+
+std::string PolicyEntry::toString() const
+{
+ std::stringstream ss;
+ auto append = [&](const std::pair<bool, std::string> &x)
+ {
+ if (x.first)
+ ss << x.second;
+ ss << '\0';
+ };
+
+ append(m_appId);
+ append(m_user);
+ append(m_privilege);
+ append(m_currentLevel);
+ append(m_maxLevel);
+
+ return ss.str();
+}
PolicyRequest::PolicyRequest()
: m_req(nullptr),
void free(void);
friend std::ostream& operator<<(std::ostream &, const PolicyEntry&);
+ bool operator==(const PolicyEntry &) const;
+ std::string toString() const;
private:
policy_entry *m_entry;
} // namespace SecurityManagerTest
+namespace std {
+
+template<>
+struct hash<SecurityManagerTest::PolicyEntry> {
+ size_t operator()(const SecurityManagerTest::PolicyEntry &x) const { return hash<string>()(x.toString()); }
+};
+
+} // namespace std
+
#endif // SECURITY_MANAGER_TEST_USERREQUEST
namespace SecurityManagerTest {
+void prepare_request(InstallRequest &request,
+ const std::string &app_id,
+ const std::string &pkg_id,
+ app_install_path_type pathType,
+ const std::string &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")
m_pkgId = std::move(pkgId);
}
-void InstallRequest::addPrivilege(const char *privilege, lib_retcode expectedResult)
+void InstallRequest::addPrivilege(const std::string &privilege, lib_retcode expectedResult)
{
- int result = security_manager_app_inst_req_add_privilege(m_req, privilege);
+ int result = security_manager_app_inst_req_add_privilege(m_req, privilege.c_str());
RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
"adding privilege returned wrong value."
<< " Privilege: " << privilege << ";"
<< " Result: " << result << ";"
<< " Expected result: " << expectedResult);
- m_privileges.push_back(strdup(privilege));
+ m_privileges.push_back(privilege);
}
void InstallRequest::addPath(std::string path, app_install_path_type pathType, lib_retcode expectedResult)
m_authorId = std::move(authorId);
}
+void InstallRequest::setInstallType(const enum app_install_type &type, lib_retcode expectedResult)
+{
+ int result = security_manager_app_inst_req_set_install_type(m_req, type);
+ RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+ "setting install type returned wrong value."
+ << " Install type: " << type << ";"
+ << " Result: " << result << ";"
+ << " Expected result: " << expectedResult);
+}
+
+void InstallRequest::setHybrid(lib_retcode expectedResult)
+{
+ int result = security_manager_app_inst_req_set_hybrid(m_req);
+ RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+ "setting security_manager_app_inst_req_set_hybrid returned wrong value."
+ << " Result: " << result << ";"
+ << " Expected result: " << expectedResult);
+}
+
std::ostream& operator<<(std::ostream &os, const InstallRequest &request)
{
if (!request.m_appId.empty())
return os;
}
+PathsRequest::PathsRequest()
+ : m_req(nullptr)
+ , m_uid(false, 0)
+{
+ int result = security_manager_path_req_new(&m_req);
+ RUNNER_ASSERT_MSG((lib_retcode)result == SECURITY_MANAGER_SUCCESS,
+ "creation of new request failed. Result: " << result);
+ RUNNER_ASSERT_MSG(m_req != nullptr, "creation of new request did not allocate memory");
+}
+
+PathsRequest::~PathsRequest()
+{
+ security_manager_path_req_free(m_req);
+}
+
+void PathsRequest::setPkgId(std::string pkgId, lib_retcode expectedResult)
+{
+ int result = security_manager_path_req_set_pkg_id(m_req, pkgId.c_str());
+ RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+ "setting pkg id returned wrong value."
+ << " Pkg id: " << pkgId << ";"
+ << " Result: " << result << ";"
+ << " Expected result: " << expectedResult);
+ m_pkgId = std::move(pkgId);
+}
+
+void PathsRequest::addPath(std::string path, app_install_path_type pathType, lib_retcode expectedResult)
+{
+ int result = security_manager_path_req_add_path(m_req, path.c_str(), pathType);
+ RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+ "adding path returned wrong value."
+ << " Path: " << path << ";"
+ << " Path type: " << pathType << ";"
+ << " Result: " << result << ";"
+ << " Expected result: " << expectedResult);
+ m_paths.emplace_back(std::pair<std::string, app_install_path_type>(std::move(path), pathType));
+}
+
+void PathsRequest::setUid(const uid_t uid, lib_retcode expectedResult)
+{
+ int result = security_manager_path_req_set_uid(m_req, uid);
+ RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+ "setting uid returned wrong value."
+ << " Uid: " << uid << ";"
+ << " Result: " << result << ";"
+ << " Expected result: " << expectedResult);
+ m_uid.first = true;
+ m_uid.second = uid;
+}
+
+void PathsRequest::setInstallType(const enum app_install_type &type, lib_retcode expectedResult)
+{
+ int result = security_manager_path_req_set_install_type(m_req, type);
+ RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+ "setting install type returned wrong value."
+ << " Install type: " << type << ";"
+ << " Result: " << result << ";"
+ << " Expected result: " << expectedResult);
+}
+
+std::ostream& operator<<(std::ostream &os, const PathsRequest &request)
+{
+ if (!request.m_pkgId.empty())
+ os << "pkg id: " << request.m_pkgId << "; ";
+ if (!request.m_paths.empty()) {
+ os << "paths: [ " << "< " << request.m_paths[0].first << "; "
+ << request.m_paths[0].second << " >";
+ for (size_t i=1; i < request.m_paths.size(); ++i) {
+ os << "; < " << request.m_paths[i].first << "; "
+ << request.m_paths[i].second << " >";
+ }
+ os << " ]";
+ }
+ if (request.m_uid.first)
+ os << "uid: " << request.m_uid.second << "; ";
+ return os;
+}
+
} // namespace SecurityManagerTest
#include <security-manager.h>
namespace SecurityManagerTest {
-
+class InstallRequest;
+void prepare_request(InstallRequest &request,
+ const std::string &app_id,
+ const std::string &pkg_id,
+ app_install_path_type pathType,
+ const std::string &path,
+ uid_t uid);
class InstallRequest
{
public:
InstallRequest();
InstallRequest(const InstallRequest&) = delete;
InstallRequest& operator=(const InstallRequest&) = delete;
+ InstallRequest(InstallRequest &&other)
+ : m_req(std::move(other.m_req)),
+ m_appId(std::move(other.m_appId)),
+ m_pkgId(std::move(other.m_pkgId)),
+ m_authorId(std::move(other.m_authorId)),
+ m_privileges(std::move(other.m_privileges)),
+ m_paths(std::move(other.m_paths)),
+ m_uid(std::move(other.m_uid))
+ {
+ other.m_req = nullptr;
+ other.m_uid.first = false;
+ other.m_uid.second = 0;
+ }
~InstallRequest();
void setAppTizenVersion(std::string tizenVer,
lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS);
void setAppId(std::string appId, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS);
void setPkgId(std::string pkgId, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS);
- void addPrivilege(const char *privilege, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS);
+ void addPrivilege(const std::string &privilege, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS);
void addPath(std::string path, app_install_path_type pathType,
lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
void setUid(const uid_t uid, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS);
void setAuthorId(std::string authorId, lib_retcode expectedResult= SECURITY_MANAGER_SUCCESS);
-
+ void setInstallType(const enum app_install_type &type, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+ void setHybrid(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
std::string getAppTizenVersion() const { return m_tizenVer; }
app_inst_req *get() { return m_req; }
const app_inst_req *get() const { return m_req; }
std::ostream& operator<<(std::ostream &os, const SecurityManagerTest::InstallRequest &request);
+class PathsRequest
+{
+public:
+ PathsRequest();
+ PathsRequest(const PathsRequest&) = delete;
+ PathsRequest& operator=(const PathsRequest&) = delete;
+ ~PathsRequest();
+
+ void setPkgId(std::string pkgId, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS);
+ void addPath(std::string path, app_install_path_type pathType,
+ lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+ void setUid(const uid_t uid, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS);
+ void setInstallType(const enum app_install_type &type, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+
+ //app_inst_req *get() { return m_req; }
+ const path_req *get() const { return m_req; }
+ friend std::ostream& operator<<(std::ostream &, const PathsRequest&);
+
+private:
+ path_req *m_req;
+
+ std::string m_pkgId;
+ std::vector<std::pair<std::string, app_install_path_type> > m_paths;
+ std::pair<bool, uid_t> m_uid;
+};
+
+std::ostream& operator<<(std::ostream &os, const SecurityManagerTest::PathsRequest &request);
+
} // namespace SecurityManagerTest
#endif // SECURITY_MANAGER_TEST_INSTALLREQUEST
--- /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)
+{
+ return appDirPath(user.getUid()) + pkgId + "/" + appId;
+}
+
+const std::string appDirPath(uid_t uid)
+{
+ struct tzplatform_context *tzCtxPtr = nullptr;
+
+ RUNNER_ASSERT(0 == tzplatform_context_create(&tzCtxPtr));
+ TzPlatformContextPtr tzCtxPtrSmart(tzCtxPtr);
+
+ RUNNER_ASSERT_MSG(0 == tzplatform_context_set_user(tzCtxPtr, uid),
+ "Unable to set user with uid <" << uid << "> for tzplatform context");
+
+ const char *appDir = tzplatform_context_getenv(tzCtxPtr,
+ getGlobalUserId() == uid ? TZ_SYS_RW_APP : TZ_USER_APP);
+ RUNNER_ASSERT_MSG(nullptr != appDir,
+ "tzplatform_context_getenv failed"
+ << "for getting sys rw app of user with uid<" << uid << ">");
+
+ return std::string(appDir) + "/";
+}
+
+const std::string globalAppDir()
+{
+ struct tzplatform_context *tzCtxPtr = nullptr;
+
+ RUNNER_ASSERT_MSG(0 == tzplatform_context_create(&tzCtxPtr), "Couldn't create tzplatform context");
+ TzPlatformContextPtr tzCtxPtrSmart(tzCtxPtr);
+
+ const char *appDir = tzplatform_context_getenv(tzCtxPtr, TZ_SYS_RW_APP);
+ RUNNER_ASSERT_MSG(nullptr != appDir,
+ "tzplatform_context_getenv failed for getting sys rw app");
+ return appDir;
+}
+
+}
+
--- /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);
+
+const std::string globalAppDir();
+
+const std::string appDirPath(uid_t uid);
+}
+
+/*
+ * Copyright (c) 2014-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 <fcntl.h>
-#include <stdio.h>
-#include <memory.h>
-#include <semaphore.h>
-#include <unistd.h>
-
-#include <attr/xattr.h>
-#include <linux/xattr.h>
-#include <sys/capability.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-#include <sys/smack.h>
-
-#include <algorithm>
-#include <fstream>
-#include <string>
-#include <unordered_set>
-
-#include <ftw.h>
-#include <grp.h>
-#include <pwd.h>
-
-#include <tzplatform_config.h>
-#include <security-manager.h>
-
-#include <access_provider.h>
-#include <dpl/log/log.h>
#include <dpl/test/test_runner.h>
-#include <passwd_access.h>
-#include <tests_common.h>
-#include <sm_api.h>
-#include <sm_db.h>
-#include <sm_request.h>
-#include <sm_sharing_request.h>
-#include <sm_user_request.h>
-#include <app_install_helper.h>
-#include <synchronization_pipe.h>
-#include <temp_test_user.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"
-
-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/location",
- "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()),
- "Error in smack_set_label_for_self(" << label << ")");
-
- RUNNER_ASSERT_ERRNO_MSG(0 == setgid(gid), "Error in setgid.");
- 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("/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 = "/usr/apps/sm_test_02_pkg_id_full/app_dir";
-
-static const char *const SM_DENIED_PATH = "/usr/apps/non_app_dir";
-static const char *const SM_TRUSTED_PATH = "/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";
-static const std::string PRIVILEGE_MANAGER_SELF_PRIVILEGE = "http://tizen.org/privilege/systemsettings";
-static const std::string PRIVILEGE_MANAGER_ADMIN_PRIVILEGE = "http://tizen.org/privilege/systemsettings.admin";
-
-static const std::vector<std::string> MANY_APPS = {
- "security_manager_10_app_1",
- "security_manager_10_app_2",
- "security_manager_10_app_3",
- "security_manager_10_app_4",
- "security_manager_10_app_5"
-};
-
-struct app_attributes {
- std::string package;
- std::string Tizen_ver;
-};
-static const std::map<std::string, struct app_attributes> MANY_APPS_PKGS = {
- {"security_manager_10_app_1", {"security_manager_10_pkg_1", "2.1"}},
- {"security_manager_10_app_2", {"security_manager_10_pkg_2", "3.0"}},
- {"security_manager_10_app_3", {"security_manager_10_pkg_3", "2.1.1"}},
- {"security_manager_10_app_4", {"security_manager_10_pkg_4", "3.1"}},
- {"security_manager_10_app_5", {"security_manager_10_pkg_5", "2.2"}},
- {PRIVILEGE_MANAGER_APP, {PRIVILEGE_MANAGER_PKG, "3.0"}}
-};
-
-static const std::vector<privileges_t> MANY_APPS_PRIVILEGES = {
- {
- "http://tizen.org/privilege/internet",
- "http://tizen.org/privilege/location"
- },
- {
- "http://tizen.org/privilege/telephony",
- "http://tizen.org/privilege/camera"
- },
- {
- "http://tizen.org/privilege/contact.read",
- "http://tizen.org/privilege/led",
- "http://tizen.org/privilege/email"
- },
- {
- "http://tizen.org/privilege/led",
- "http://tizen.org/privilege/email",
- "http://tizen.org/privilege/telephony",
- "http://tizen.org/privilege/camera"
- },
- {
- "http://tizen.org/privilege/internet",
- "http://tizen.org/privilege/location",
- "http://tizen.org/privilege/led",
- "http://tizen.org/privilege/email"
- }
-};
-
-static 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, allowed_privs);
- dbtest.check_privileges_removed(app_id, pkg_id, denied_privs);
-
- /*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, privileges, 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)
-{
- InstallRequest request;
- request.setAppId(app_id);
- request.setPkgId(pkg_id);
- request.setUid(uid);
- Api::install(request);
-
- check_app_after_install(app_id, pkg_id);
-}
-
-static void uninstall_app(const char *app_id, const char *pkg_id, bool expect_pkg_removed)
-{
- InstallRequest request;
- request.setAppId(app_id);
-
- Api::uninstall(request);
-
- check_app_after_uninstall(app_id, pkg_id, expect_pkg_removed);
-}
-
-static inline void register_current_process_as_privilege_manager(uid_t uid, bool forAdmin = false)
-{
- InstallRequest request;
- request.setAppId(PRIVILEGE_MANAGER_APP.c_str());
- request.setPkgId(PRIVILEGE_MANAGER_PKG.c_str());
- request.setUid(uid);
- request.addPrivilege(PRIVILEGE_MANAGER_SELF_PRIVILEGE.c_str());
- if (forAdmin)
- request.addPrivilege(PRIVILEGE_MANAGER_ADMIN_PRIVILEGE.c_str());
- Api::install(request);
- Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str());
-};
-
-static inline struct passwd *getUserStruct(const std::string &userName) {
- struct passwd *pw = nullptr;
- errno = 0;
-
- while(!(pw = getpwnam(userName.c_str()))) {
- RUNNER_ASSERT_ERRNO_MSG(errno == EINTR, "getpwnam() failed");
- };
-
- return pw;
-};
-
-static inline struct passwd *getUserStruct(const uid_t uid) {
- struct passwd *pw = nullptr;
- errno = 0;
-
- while(!(pw = getpwuid(uid))) {
- RUNNER_ASSERT_ERRNO_MSG(errno == EINTR, "getpwnam() failed");
- };
-
- return pw;
-};
-
-void check_exact_access(const std::string& subject, const std::string& object, const std::string& access)
-{
- // check access
- if (!access.empty()) {
- int result = smack_have_access(subject.c_str(), object.c_str(), access.c_str());
- RUNNER_ASSERT_MSG(result >= 0, "smack_have_access failed");
- RUNNER_ASSERT_MSG(result == 1,
- "No smack access: " << subject << " " << object << " " << access);
- }
- // check excessive access
- auto foundInAccess = [&access](std::string::value_type c) {
- return access.find(c) != std::string::npos; };
-
- std::string negative = "rwxatl";
- auto end = std::remove_if(negative.begin(), negative.end(), foundInAccess);
- negative.erase(end, negative.end());
-
- for(const auto& c : negative) {
- int result = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
- RUNNER_ASSERT_MSG(result >= 0, "smack_have_access failed");
- RUNNER_ASSERT_MSG(result == 0,
- "Unexpected smack access: " << subject << " " << object << " " << c);
- }
-}
-
-std::string access_opposite(std::string &access) {
- static const std::map<char, int> access_mapping = {{'r', 0}, {'w', 1}, {'x', 2}, {'a', 3},
- {'t', 4}, {'l', 5}};
- //May write implies may lock
- if (access.find('w') != std::string::npos && access.find('l') == std::string::npos) {
- access.append("l");
- }
- std::string access_opposite = "rwxatl";
- for (char c : access) {
- access_opposite[access_mapping.at(c)] = '-';
- }
- auto it = std::remove_if(access_opposite.begin(), access_opposite.end(), [](char c) {return c == '-';});
- access_opposite.erase(it, access_opposite.end());
- return access_opposite;
-}
-
-void check_exact_smack_accesses(const std::string &subject, const std::string &object, const std::string &access) {
- std::string access_str(access);
- auto no_access = access_opposite(access_str);
- for (char c : access_str) {
- int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
- RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object << ">, <" << c << "> errno=" << strerror(errno));
- RUNNER_ASSERT_MSG(ret == 1, "Access " << c << " from " << subject << " to "
- << object << " not given");
- }
-
- for (char c : no_access) {
- int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
- RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object << ">, <" << c << "> errno=" << strerror(errno));
- RUNNER_ASSERT_MSG(ret == 0, "Access " << c << " from " << subject << " to "
- << object << " unnecessarily given");
- }
-}
-
-
-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);
- 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);
-
- 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_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_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 << "\"");
-
- uninstall_app(app_id, pkg_id, true);
-}
-
-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);
-
- 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 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)
-{
- //TEST DATA
- const std::string username("sm_test_10_user_name");
- unsigned int privileges_count = 0;
-
- std::map<std::string, std::map<std::string, std::set<std::string>>> users2AppsMap;
- std::map<std::string, std::set<std::string>> apps2PrivsMap;
-
- for(unsigned int i = 0; i < MANY_APPS.size(); ++i) {
- apps2PrivsMap.insert(std::pair<std::string, std::set<std::string>>(
- MANY_APPS.at(i), std::set<std::string>(
- MANY_APPS_PRIVILEGES.at(i).begin(),
- MANY_APPS_PRIVILEGES.at(i).end())));
- privileges_count+=MANY_APPS_PRIVILEGES.at(i).size();
- };
-
- apps2PrivsMap.insert(std::pair<std::string, std::set<std::string>>(
- PRIVILEGE_MANAGER_APP, std::set<std::string>{PRIVILEGE_MANAGER_SELF_PRIVILEGE}));
- ++privileges_count;
- users2AppsMap.insert(std::pair<std::string, std::map<std::string, std::set<std::string>>>(username, apps2PrivsMap));
- //TEST DATA END
-
- sem_t *mutex;
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno);
- pid_t pid = fork();
-
- if (pid != 0) { //parent process
- TemporaryTestUser tmpUser(username, GUM_USERTYPE_NORMAL, false);
- tmpUser.create();
-
- for(const auto &user : users2AppsMap) {
-
- for(const auto &app : user.second) {
- InstallRequest requestInst;
- requestInst.setAppId(app.first.c_str());
- try {
- requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).package.c_str());
- } catch (const std::out_of_range &e) {
- RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first);
- };
- requestInst.setUid(tmpUser.getUid());
-
- for (const auto &privilege : app.second) {
- requestInst.addPrivilege(privilege.c_str());
- };
-
- Api::install(requestInst);
- };
-
- //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str());
- };
- //Start child process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno);
-
- int status;
- wait(&status);
-
- tmpUser.remove();
- };
-
- if (pid == 0) { //child process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child process failed, errno: " << errno);
- //the above call, registers 1 new privilege for the given user, hence the incrementation of below variable
-
- struct passwd *pw = getUserStruct(username);
- register_current_process_as_privilege_manager(pw->pw_uid);
- int result = drop_root_privileges(pw->pw_uid, pw->pw_gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- std::vector<PolicyEntry> policyEntries;
- PolicyEntry filter;
- Api::getPolicy(filter, policyEntries);
-
- RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
- RUNNER_ASSERT_MSG(policyEntries.size() == privileges_count, "Number of policies doesn't match - should be: " << privileges_count << " and is " << policyEntries.size());
-
- for (const auto &policyEntry : policyEntries) {
- std::string user = policyEntry.getUser();
- std::string app = policyEntry.getAppId();
- std::string privilege = policyEntry.getPrivilege();
-
- try {
- struct passwd *pw_current = getUserStruct(static_cast<uid_t>(std::stoul(user)));
- std::set<std::string>::iterator tmp = users2AppsMap.at(pw_current->pw_name).at(app).find(privilege);
- if (tmp == users2AppsMap.at(pw_current->pw_name).at(app).end())
- RUNNER_FAIL_MSG("Unexpected policy entry: unexpected privilege: " << policyEntry);
- } catch (const std::out_of_range &e) {
- RUNNER_FAIL_MSG("Unexpected policy entry: unexpected user or app: " << policyEntry << ". Exception: " << e.what());
- } catch (const std::invalid_argument& e) {
- RUNNER_FAIL_MSG("Incorrect UID: " << user << ". Exception: " << e.what());
- };
- };
- exit(0);
- };
-}
-
-RUNNER_CHILD_TEST(security_manager_11_privacy_manager_fetch_whole_policy_for_admin_unprivileged)
-{
- //TEST DATA
- const std::vector<std::string> usernames = {"sm_test_11_user_name_1", "sm_test_11_user_name_2"};
- unsigned int privileges_count = 0;
-
- std::map<std::string, std::map<std::string, std::set<std::string>>> users2AppsMap;
- std::map<std::string, std::set<std::string>> apps2PrivsMap;
-
- for (const auto &username : usernames) {
- //Only entries for one of the users will be listed
- privileges_count = 0;
-
- for(unsigned int i = 0; i < MANY_APPS.size(); ++i) {
- apps2PrivsMap.insert(std::pair<std::string, std::set<std::string>>(
- MANY_APPS.at(i), std::set<std::string>(
- MANY_APPS_PRIVILEGES.at(i).begin(),
- MANY_APPS_PRIVILEGES.at(i).end())));
- privileges_count+=MANY_APPS_PRIVILEGES.at(i).size();
- };
-
- users2AppsMap.insert(std::pair<std::string, std::map<std::string, std::set<std::string>>>(username, apps2PrivsMap));
- };
-
- users2AppsMap.at(usernames.at(0)).insert(std::pair<std::string, std::set<std::string>>(
- PRIVILEGE_MANAGER_APP, std::set<std::string>{PRIVILEGE_MANAGER_SELF_PRIVILEGE}));
-
- ++privileges_count;
- //TEST DATA END
-
- sem_t *mutex;
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno);
- pid_t pid = fork();
-
- if (pid != 0) { //parent process
- std::vector<TemporaryTestUser> users = {
- TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false),
- TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false)
- };
-
- users.at(0).create();
- users.at(1).create();
-
- //Install apps for both users
- for(const auto &user : users) {
- for(const auto &app : users2AppsMap.at(user.getUserName())) {
- InstallRequest requestInst;
- requestInst.setAppId(app.first.c_str());
- try {
- requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).package.c_str());
- } catch (const std::out_of_range &e) {
- RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first);
- };
- requestInst.setUid(user.getUid());
-
- for (const auto &privilege : app.second) {
- requestInst.addPrivilege(privilege.c_str());
- };
-
- Api::install(requestInst);
- };
-
- //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str());
- };
- //Start child
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno);
-
- int status;
- wait(&status);
-
- for(auto &user : users) {
- user.remove();
- };
- };
-
- if (pid == 0) {
- errno = 0;
- RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child failed, errno: " << errno);
- struct passwd *pw = getUserStruct(usernames.at(0));
- register_current_process_as_privilege_manager(pw->pw_uid);
-
- //change uid to normal user
- errno = 0;
- int result = drop_root_privileges(pw->pw_uid, pw->pw_gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- std::vector<PolicyEntry> policyEntries;
- PolicyEntry filter;
-
- //this call should only return privileges belonging to the current uid
- Api::getPolicy(filter, policyEntries);
-
- RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
- RUNNER_ASSERT_MSG(policyEntries.size() == privileges_count, "Number of policies doesn't match - should be: " << privileges_count << " and is " << policyEntries.size());
-
- for (const auto &policyEntry : policyEntries) {
- std::string user = policyEntry.getUser();
- std::string app = policyEntry.getAppId();
- std::string privilege = policyEntry.getPrivilege();
-
- try {
- struct passwd *pw_current = getUserStruct(static_cast<uid_t>(std::stoul(user)));
- std::set<std::string>::iterator tmp = users2AppsMap.at(pw_current->pw_name).at(app).find(privilege);
- if (tmp == users2AppsMap.at(pw_current->pw_name).at(app).end())
- RUNNER_FAIL_MSG("Unexpected policy entry: unexpected privilege: " << policyEntry);
- } catch (const std::out_of_range &e) {
- RUNNER_FAIL_MSG("Unexpected policy entry: unexpected user or app: " << policyEntry << ". Exception: " << e.what());
- } catch (const std::invalid_argument& e) {
- RUNNER_FAIL_MSG("Incorrect UID: " << user << ". Exception: " << e.what());
- };
- };
- exit(0);
- };
-}
-
-RUNNER_CHILD_TEST(security_manager_12_privacy_manager_fetch_whole_policy_for_admin_privileged)
-{
- //TEST DATA
- const std::vector<std::string> usernames = {"sm_test_12_user_name_1", "sm_test_12_user_name_2"};
- unsigned int privileges_count = 0;
-
- std::map<std::string, std::map<std::string, std::set<std::string>>> users2AppsMap;
- std::map<std::string, std::set<std::string>> apps2PrivsMap;
-
- for (const auto &username : usernames) {
-
- for(unsigned int i = 0; i < MANY_APPS.size(); ++i) {
- apps2PrivsMap.insert(std::pair<std::string, std::set<std::string>>(
- MANY_APPS.at(i), std::set<std::string>(
- MANY_APPS_PRIVILEGES.at(i).begin(),
- MANY_APPS_PRIVILEGES.at(i).end())));
- privileges_count+=MANY_APPS_PRIVILEGES.at(i).size();
- };
-
- users2AppsMap.insert(std::pair<std::string, std::map<std::string, std::set<std::string>>>(username, apps2PrivsMap));
- };
-
- users2AppsMap.at(usernames.at(1)).insert(std::pair<std::string, std::set<std::string>>(
- PRIVILEGE_MANAGER_APP, std::set<std::string>{PRIVILEGE_MANAGER_SELF_PRIVILEGE, PRIVILEGE_MANAGER_ADMIN_PRIVILEGE}));
-
- privileges_count += 2;
- //TEST DATA END
-
- sem_t *mutex;
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno);
- pid_t pid = fork();
-
- if (pid != 0) { //parent process
- std::vector<TemporaryTestUser> users = {
- TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false),
- TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false)
- };
-
- users.at(0).create();
- users.at(1).create();
- //Install apps for both users
- for(const auto &user : users) {
- for(const auto &app : users2AppsMap.at(user.getUserName())) {
- InstallRequest requestInst;
- requestInst.setAppId(app.first.c_str());
- try {
- requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).package.c_str());
- } catch (const std::out_of_range &e) {
- RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first);
- };
- requestInst.setUid(user.getUid());
-
- for (const auto &privilege : app.second) {
- requestInst.addPrivilege(privilege.c_str());
- };
-
- Api::install(requestInst);
- };
-
- //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str());
- };
-
- //Start child
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno);
-
- //Wait for child to finish
- int status;
- wait(&status);
-
- for(auto &user : users) {
- user.remove();
- };
- };
-
- if (pid == 0) { //child process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child failed, errno: " << errno);
-
- struct passwd *pw = getUserStruct(usernames.at(1));
- register_current_process_as_privilege_manager(pw->pw_uid, true);
-
- //change uid to normal user
- int result = drop_root_privileges(pw->pw_uid, pw->pw_gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- std::vector<PolicyEntry> policyEntries;
- PolicyEntry filter;
- //this call should succeed as the calling user is privileged
- Api::getPolicy(filter, policyEntries);
-
- RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
- RUNNER_ASSERT_MSG(policyEntries.size() == privileges_count, "Number of policies doesn't match - should be: " << privileges_count << " and is " << policyEntries.size());
-
- for (const auto &policyEntry : policyEntries) {
- std::string user = policyEntry.getUser();
- std::string app = policyEntry.getAppId();
- std::string privilege = policyEntry.getPrivilege();
-
- try {
- struct passwd *pw_current = getUserStruct(static_cast<uid_t>(std::stoul(user)));
- std::set<std::string>::iterator tmp = users2AppsMap.at(pw_current->pw_name).at(app).find(privilege);
- if (tmp == users2AppsMap.at(pw_current->pw_name).at(app).end())
- RUNNER_FAIL_MSG("Unexpected policy entry: unexpected privilege: " << policyEntry);
- } catch (const std::out_of_range &e) {
- RUNNER_FAIL_MSG("Unexpected policy entry: unexpected user or app: " << policyEntry << ". Exception: " << e.what());
- } catch (const std::invalid_argument& e) {
- RUNNER_FAIL_MSG("Incorrect UID: " << user << ". Exception: " << e.what());
- };
- };
-
- exit(0);
- };
-}
-
-RUNNER_CHILD_TEST(security_manager_13_privacy_manager_fetch_policy_after_update_unprivileged)
-{
- //TEST DATA
- const std::vector<std::string> usernames = {"sm_test_13_user_name_1", "sm_test_13_user_name_2"};
-
- std::map<std::string, std::map<std::string, std::set<std::string>>> users2AppsMap;
- std::map<std::string, std::set<std::string>> apps2PrivsMap;
-
- for (const auto &username : usernames) {
-
- for(unsigned int i = 0; i < MANY_APPS.size(); ++i) {
- apps2PrivsMap.insert(std::pair<std::string, std::set<std::string>>(
- MANY_APPS.at(i), std::set<std::string>(
- MANY_APPS_PRIVILEGES.at(i).begin(),
- MANY_APPS_PRIVILEGES.at(i).end())));
- };
-
- users2AppsMap.insert(std::pair<std::string, std::map<std::string, std::set<std::string>>>(username, apps2PrivsMap));
- };
-
- users2AppsMap.at(usernames.at(1)).insert(std::pair<std::string, std::set<std::string>>(
- PRIVILEGE_MANAGER_APP, std::set<std::string>{PRIVILEGE_MANAGER_SELF_PRIVILEGE}));
-
- //TEST DATA END
-
- pid_t pid[2];
- sem_t *mutex[2];
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex[0] = sem_open("mutex_1", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex #1, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex[1] = sem_open("mutex_2", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex #2, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex[0], 1, 0) == 0, "failed to setup mutex #1, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex[1], 1, 0) == 0, "failed to setup mutex #2, errno: " << errno);
- std::vector<PolicyEntry> policyEntries;
-
- pid[0] = fork();
-
- if(pid[0] == 0) { //child #1 process
- RUNNER_ASSERT_MSG(sem_wait(mutex[0]) == 0, "sem_wait in child #1 failed, errno: " << errno);
- struct passwd *pw = getUserStruct(usernames.at(0));
- register_current_process_as_privilege_manager(pw->pw_uid);
-
- //change uid to normal user
- int result = drop_root_privileges(pw->pw_uid, pw->pw_gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- PolicyEntry filter;
- PolicyRequest policyRequest;
- //this call should succeed as the calling user is privileged
- Api::getPolicyForSelf(filter, policyEntries);
-
- RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty");
-
- PolicyEntry policyEntry(
- MANY_APPS[0],
- std::to_string(pw->pw_uid),
- "http://tizen.org/privilege/internet"
- );
- policyEntry.setLevel("Deny");
-
- policyRequest.addEntry(policyEntry);
- policyEntry = PolicyEntry(
- MANY_APPS[1],
- std::to_string(pw->pw_uid),
- "http://tizen.org/privilege/location"
- );
- policyEntry.setLevel("Deny");
-
- policyRequest.addEntry(policyEntry);
- Api::sendPolicy(policyRequest);
- Api::getPolicyForSelf(filter, policyEntries);
-
- RUNNER_ASSERT_MSG(policyEntries.size() == 2, "Number of policies doesn't match - should be: 2 and is " << policyEntries.size());
- exit(0);
- };
-
- if (pid[0] != 0) {//parent process
- pid[1] = fork();
-
- if (pid[1] == 0) { //child #2 process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_wait(mutex[1]) == 0, "sem_wait in child #2 failed, errno: " << errno);
- struct passwd *pw_target = getUserStruct(usernames.at(0));
- struct passwd *pw = getUserStruct(usernames.at(1));
- register_current_process_as_privilege_manager(pw->pw_uid);
-
- //change uid to normal user
- int result = drop_root_privileges(pw->pw_uid, pw->pw_gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- PolicyEntry filter = PolicyEntry(
- SECURITY_MANAGER_ANY,
- std::to_string(pw_target->pw_uid),
- SECURITY_MANAGER_ANY
- );
-
- //U2 requests contents of U1 privacy manager - should fail
- Api::getPolicyForSelf(filter, policyEntries);
- RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty");
-
- filter = PolicyEntry(
- SECURITY_MANAGER_ANY,
- SECURITY_MANAGER_ANY,
- SECURITY_MANAGER_ANY
- );
-
- policyEntries.clear();
-
- //U2 requests contents of ADMIN bucket - should fail
- Api::getPolicyForAdmin(filter, policyEntries, SECURITY_MANAGER_ERROR_ACCESS_DENIED);
- RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty");
- exit(0);
- };
-
- if (pid[1] != 0) { //parent
-
- std::vector<TemporaryTestUser> users = {
- TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false),
- TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false)
- };
-
- users.at(0).create();
- users.at(1).create();
-
- //Install apps for both users
- for(const auto &user : users2AppsMap) {
-
- for(const auto &app : user.second) {
- InstallRequest requestInst;
- requestInst.setAppId(app.first.c_str());
- try {
- requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).package.c_str());
- } catch (const std::out_of_range &e) {
- RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first);
- };
- requestInst.setUid(users.at(0).getUid());
-
- for (const auto &privilege : app.second) {
- requestInst.addPrivilege(privilege.c_str());
- };
-
- Api::install(requestInst);
- };
-
- //check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str());
- };
-
- int status;
- //Start child #1
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex[0]) == 0, "Error while opening mutex #1, errno: " << errno);
-
- //Wait until child #1 finishes
- pid_t ret = wait(&status);
- RUNNER_ASSERT_MSG((ret != -1) && WIFEXITED(status), "Updating privileges failed");
-
- //Start child #2
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex[1]) == 0, "Error while opening mutex #2, errno: " << errno);
- //Wait until child #2 finishes
- ret = wait(&status);
- RUNNER_ASSERT_MSG((ret =-1) && WIFEXITED(status), "Listing privileges failed");
-
- for(auto &user : users) {
- user.remove();
- };
-
- sem_close(mutex[0]);
- sem_close(mutex[1]);
- };
- };
-}
-
-RUNNER_CHILD_TEST(security_manager_14_privacy_manager_fetch_and_update_policy_for_admin)
-{
- //TEST DATA
- const std::vector<std::string> usernames = {"sm_test_14_user_name_1", "sm_test_14_user_name_2"};
- unsigned int privileges_count = 0;
-
- std::map<std::string, std::map<std::string, std::set<std::string>>> users2AppsMap;
- std::map<std::string, std::set<std::string>> apps2PrivsMap;
-
- for (const auto &username : usernames) {
-
- for(unsigned int i = 0; i < MANY_APPS.size(); ++i) {
- apps2PrivsMap.insert(std::pair<std::string, std::set<std::string>>(
- MANY_APPS.at(i), std::set<std::string>(
- MANY_APPS_PRIVILEGES.at(i).begin(),
- MANY_APPS_PRIVILEGES.at(i).end())));
- privileges_count+=MANY_APPS_PRIVILEGES.at(i).size();
- };
-
- users2AppsMap.insert(std::pair<std::string, std::map<std::string, std::set<std::string>>>(username, apps2PrivsMap));
- };
-
- users2AppsMap.at(usernames.at(1)).insert(std::pair<std::string, std::set<std::string>>(
- PRIVILEGE_MANAGER_APP, std::set<std::string>{PRIVILEGE_MANAGER_SELF_PRIVILEGE}));
-
- privileges_count += 2;
- //TEST DATA END
- sem_t *mutex;
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno);
-
- pid_t pid = fork();
- if (pid != 0) {
- std::vector<TemporaryTestUser> users = {
- TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false),
- TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false)
- };
-
- users.at(0).create();
- users.at(1).create();
-
- //Install apps for both users
- for(const auto &user : users) {
-
- for(const auto &app : users2AppsMap.at(user.getUserName())) {
- InstallRequest requestInst;
- requestInst.setAppId(app.first.c_str());
- try {
- requestInst.setPkgId(MANY_APPS_PKGS.at(app.first).package.c_str());
- } catch (const std::out_of_range &e) {
- RUNNER_FAIL_MSG("Couldn't find package for app: " << app.first);
- };
- requestInst.setUid(user.getUid());
-
- for (const auto &privilege : app.second) {
- requestInst.addPrivilege(privilege.c_str());
- };
-
- Api::install(requestInst);
- };
- };
- //Start child process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno);
- int status;
- //Wait for child process to finish
- wait(&status);
-
- //switch back to root
- for(auto &user : users) {
- user.remove();
- };
-
- sem_close(mutex);
- }
-
- if (pid == 0) { //child process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child process failed, errno: " << errno);
-
- struct passwd *pw = getUserStruct(usernames.at(0));
- register_current_process_as_privilege_manager(pw->pw_uid, true);
-
- //change uid to normal user
- int result = drop_root_privileges(pw->pw_uid, pw->pw_gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- PolicyRequest *policyRequest = new PolicyRequest();
- PolicyEntry filter;
- std::vector<PolicyEntry> policyEntries;
- //this call should succeed as the calling user is privileged
- Api::getPolicyForSelf(filter, policyEntries);
-
- RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty");
-
- PolicyEntry policyEntry(
- SECURITY_MANAGER_ANY,
- SECURITY_MANAGER_ANY,
- "http://tizen.org/privilege/internet"
- );
- policyEntry.setMaxLevel("Deny");
-
- policyRequest->addEntry(policyEntry);
- policyEntry = PolicyEntry(
- SECURITY_MANAGER_ANY,
- SECURITY_MANAGER_ANY,
- "http://tizen.org/privilege/location"
- );
- policyEntry.setMaxLevel("Deny");
-
- policyRequest->addEntry(policyEntry);
- Api::sendPolicy(*policyRequest);
- Api::getPolicyForAdmin(filter, policyEntries);
-
- RUNNER_ASSERT_MSG(policyEntries.size() == 2, "Number of policies doesn't match - should be: 2 and is " << policyEntries.size());
-
- delete policyRequest;
- policyRequest = new PolicyRequest();
- policyEntry = PolicyEntry(
- SECURITY_MANAGER_ANY,
- SECURITY_MANAGER_ANY,
- "http://tizen.org/privilege/internet"
- );
- policyEntry.setMaxLevel(SECURITY_MANAGER_DELETE);
- policyRequest->addEntry(policyEntry);
-
- policyEntry = PolicyEntry(
- SECURITY_MANAGER_ANY,
- SECURITY_MANAGER_ANY,
- "http://tizen.org/privilege/location"
- );
- policyEntry.setMaxLevel(SECURITY_MANAGER_DELETE);
-
- policyRequest->addEntry(policyEntry);
- Api::sendPolicy(*policyRequest);
-
- policyEntries.clear();
- Api::getPolicyForAdmin(filter, policyEntries);
- RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Number of policies doesn't match - should be: 0 and is " << policyEntries.size());
-
- delete policyRequest;
-
- exit(0);
- };
-
-}
-
-RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_admin)
-{
- RUNNER_IGNORED_MSG("temporarily disabled due to gumd timeouts");
- const char *const update_app_id = "security_manager_15_update_app_id";
- const char *const update_privilege = "http://tizen.org/privilege/led";
- const char *const check_start_bucket = "ADMIN";
- const std::string username("sm_test_15_username");
- PolicyRequest addPolicyRequest;
- CynaraTestAdmin::Admin admin;
-
- struct message {
- uid_t uid;
- gid_t gid;
- } msg;
-
- int pipefd[2];
- pid_t pid;
- int result = 0;
-
- RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed");
-
- TemporaryTestUser user(username, GUM_USERTYPE_ADMIN, false);
- user.create();
-
- pid = fork();
- RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
- if (pid != 0)//parent process
- {
- FdUniquePtr pipeptr(pipefd+1);
- close(pipefd[0]);
-
- register_current_process_as_privilege_manager(user.getUid(), true);
-
- //send info to child
- msg.uid = user.getUid();
- msg.gid = user.getGid();
-
- ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed");
-
- //wait for child
- RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed");
-
- admin.adminCheck(check_start_bucket, false, generateAppLabel(update_app_id).c_str(),
- std::to_string(static_cast<int>(msg.uid)).c_str(), update_privilege, CYNARA_ADMIN_ALLOW, nullptr);
- }
- if(pid == 0)
- {
- FdUniquePtr pipeptr(pipefd);
- close(pipefd[1]);
-
- ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed");
-
- //become admin privacy manager manager
- Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str());
- result = drop_root_privileges(msg.uid, msg.gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- PolicyEntry entry(update_app_id, std::to_string(static_cast<int>(msg.uid)), update_privilege);
- entry.setMaxLevel("Allow");
-
- addPolicyRequest.addEntry(entry);
- Api::sendPolicy(addPolicyRequest);
- exit(0);
- }
-}
-
-RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_admin_wildcard)
-{
- RUNNER_IGNORED_MSG("temporarily disabled due to gumd timeouts");
- const char *const update_other_app_id = "security_manager_15_update_other_app_id";
- const char *const update_privilege = "http://tizen.org/privilege/led";
- const char *const check_start_bucket = "ADMIN";
- const std::string username("sm_test_15_username");
- PolicyRequest addPolicyRequest;
- CynaraTestAdmin::Admin admin;
-
- struct message {
- uid_t uid;
- gid_t gid;
- } msg;
-
- int pipefd[2];
- pid_t pid;
- int result = 0;
-
- RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed");
-
- TemporaryTestUser user(username, GUM_USERTYPE_ADMIN, false);
- user.create();
-
- pid = fork();
- RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
- if (pid != 0)//parent process
- {
- FdUniquePtr pipeptr(pipefd+1);
- close(pipefd[0]);
-
- register_current_process_as_privilege_manager(user.getUid(), true);
-
- //send info to child
- msg.uid = user.getUid();
- msg.gid = user.getGid();
-
- ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed");
-
- //wait for child
- RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed");
-
- admin.adminCheck(check_start_bucket, false, generateAppLabel(update_other_app_id).c_str(),
- std::to_string(static_cast<int>(msg.uid)).c_str(), update_privilege, CYNARA_ADMIN_ALLOW, nullptr);
- }
- if(pid == 0)
- {
- FdUniquePtr pipeptr(pipefd);
- close(pipefd[1]);
-
- ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed");
-
- //become admin privacy manager manager
- Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str());
- result = drop_root_privileges(msg.uid, msg.gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- // use wildcard as appId
- PolicyEntry entry(SECURITY_MANAGER_ANY, std::to_string(static_cast<int>(msg.uid)), update_privilege);
- entry.setMaxLevel("Allow");
-
- addPolicyRequest.addEntry(entry);
- Api::sendPolicy(addPolicyRequest);
- exit(0);
- }
-}
-
-RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_self)
-{
- RUNNER_IGNORED_MSG("temporarily disabled due to gumd timeouts");
- const char *const update_app_id = "security_manager_15_update_app_id";
- const char *const update_privilege = "http://tizen.org/privilege/led";
- const char *const check_start_bucket = "";
- const std::string username("sm_test_15_username");
- PolicyRequest addPolicyRequest;
- CynaraTestAdmin::Admin admin;
-
- struct message {
- uid_t uid;
- gid_t gid;
- } msg;
-
- int pipefd[2];
- pid_t pid;
- int result = 0;
-
- RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed");
-
- TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, false);
- user.create();
-
- pid = fork();
- RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
- if (pid != 0)//parent process
- {
- FdUniquePtr pipeptr(pipefd+1);
- close(pipefd[0]);
-
- register_current_process_as_privilege_manager(user.getUid(), false);
-
- //send info to child
- msg.uid = user.getUid();
- msg.gid = user.getGid();
-
- ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed");
-
- //wait for child
- RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed");
-
- admin.adminCheck(check_start_bucket, false, generateAppLabel(update_app_id).c_str(),
- std::to_string(static_cast<int>(msg.uid)).c_str(), update_privilege, CYNARA_ADMIN_ALLOW, nullptr);
- }
- if(pid == 0)
- {
- FdUniquePtr pipeptr(pipefd);
- close(pipefd[1]);
-
- ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed");
-
- //become admin privacy manager manager
- Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str());
- result = drop_root_privileges(msg.uid, msg.gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- PolicyEntry entry(update_app_id, std::to_string(static_cast<int>(msg.uid)), update_privilege);
- entry.setLevel("Allow");
-
- addPolicyRequest.addEntry(entry);
- Api::sendPolicy(addPolicyRequest);
- exit(0);
- }
-}
-
-RUNNER_CHILD_TEST(security_manager_16_policy_levels_get)
-{
- const std::string username("sm_test_16_user_cynara_policy");
- CynaraTestAdmin::Admin admin;
- int pipefd[2];
- pid_t pid;
- int result = 0;
-
- struct message {
- uid_t uid;
- gid_t gid;
- } msg;
-
- RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed");
-
- TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, false);
- user.create();
-
- pid = fork();
- RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
- if (pid != 0)//parent process
- {
- FdUniquePtr pipeptr(pipefd+1);
- close(pipefd[0]);
-
- //send info to child
- msg.uid = user.getUid();
- msg.gid = user.getGid();
-
- ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed");
-
- //wait for child
- RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed");
- }
- if(pid == 0)
- {
- int ret;
- char** levels;
- std::string allow_policy, deny_policy;
- size_t count;
- FdUniquePtr pipeptr(pipefd);
- close(pipefd[1]);
-
- ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed");
-
- //become admin privacy manager manager
- result = drop_root_privileges(msg.uid, msg.gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- // without plugins there should only be 2 policies - Allow and Deny
- ret = security_manager_policy_levels_get(&levels, &count);
-
- RUNNER_ASSERT_MSG((lib_retcode)ret == SECURITY_MANAGER_SUCCESS,
- "Invlid return code: " << ret);
-
- RUNNER_ASSERT_MSG(count == 2, "Invalid number of policy levels. Should be 2, instead there is: " << static_cast<int>(count));
-
- deny_policy = std::string(levels[0]);
- allow_policy = std::string(levels[count-1]);
-
- // first should always be Deny
- RUNNER_ASSERT_MSG(deny_policy.compare("Deny") == 0,
- "Invalid first policy level. Should be Deny, instead there is: " << levels[0]);
-
- // last should always be Allow
- RUNNER_ASSERT_MSG(allow_policy.compare("Allow") == 0,
- "Invalid last policy level. Should be Allow, instead there is: " << levels[count-1]);
-
- security_manager_policy_levels_free(levels, count);
- exit(0);
- }
-}
-
-RUNNER_CHILD_TEST(security_manager_17_privacy_manager_delete_policy_for_self)
-{
- const char *const update_app_id = "security_manager_17_update_app_id";
- const char *const update_privilege = "http://tizen.org/privilege/led";
- const char *const check_start_bucket = "";
- const std::string username("sm_test_17_username");
- PolicyRequest addPolicyRequest;
- CynaraTestAdmin::Admin admin;
-
- struct message {
- uid_t uid;
- gid_t gid;
- } msg;
-
- int pipefd[2];
- int pipefd2[2];
- pid_t pid;
- int result = 0;
-
- RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed");
- RUNNER_ASSERT_MSG((pipe(pipefd2) != -1),"second pipe failed");
-
- TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, false);
- user.create();
-
- pid = fork();
- RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
- if (pid != 0)//parent process
- {
- FdUniquePtr pipeptr(pipefd+1);
- close(pipefd[0]);
-
- register_current_process_as_privilege_manager(user.getUid(), false);
-
- //send info to child
- msg.uid = user.getUid();
- msg.gid = user.getGid();
-
- ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed");
-
- //wait for child
- RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed");
-
- admin.adminCheck(check_start_bucket, false, generateAppLabel(update_app_id).c_str(),
- std::to_string(static_cast<int>(msg.uid)).c_str(), update_privilege, CYNARA_ADMIN_ALLOW, nullptr);
-
- pid = fork();
- if (pid != 0)//parent process
- {
- FdUniquePtr pipeptr(pipefd2+1);
- close(pipefd2[0]);
-
- //send info to child
- msg.uid = user.getUid();
- msg.gid = user.getGid();
-
- ssize_t written = TEMP_FAILURE_RETRY(write(pipefd2[1], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed");
-
- //wait for child
- RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed");
-
- //wait for child
- waitpid(-1, &result, 0);
-
- admin.adminCheck(check_start_bucket, false, generateAppLabel(update_app_id).c_str(),
- std::to_string(static_cast<int>(msg.uid)).c_str(), update_privilege, CYNARA_ADMIN_DENY, nullptr);
- }
- if(pid == 0)
- {
- FdUniquePtr pipeptr(pipefd2);
- close(pipefd2[1]);
-
- ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd2[0], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed");
-
- //become admin privacy manager manager
- Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str());
- result = drop_root_privileges(msg.uid, msg.gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- // delete this entry
- PolicyRequest deletePolicyRequest;
- PolicyEntry deleteEntry(update_app_id, std::to_string(static_cast<int>(msg.uid)), update_privilege);
- deleteEntry.setLevel(SECURITY_MANAGER_DELETE);
-
- deletePolicyRequest.addEntry(deleteEntry);
- Api::sendPolicy(deletePolicyRequest);
- exit(0);
- }
- }
- if(pid == 0)
- {
- FdUniquePtr pipeptr(pipefd);
- close(pipefd[1]);
-
- ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed");
-
- //become admin privacy manager manager
- Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str());
- result = drop_root_privileges(msg.uid, msg.gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- PolicyEntry entry(update_app_id, std::to_string(static_cast<int>(msg.uid)), update_privilege);
- entry.setLevel("Allow");
-
- addPolicyRequest.addEntry(entry);
- Api::sendPolicy(addPolicyRequest);
- exit(0);
- }
-}
-
-RUNNER_CHILD_TEST(security_manager_17_privacy_manager_fetch_whole_policy_for_self_filtered)
-{
- const std::string username("sm_test_17_user_name");
-
- struct message {
- uid_t uid;
- gid_t gid;
- unsigned int privileges_count;
- } msg;
-
- int pipefd[2];
- pid_t pid;
- int result = 0;
-
- RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed");
-
- pid = fork();
- RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
- if (pid != 0)//parent process
- {
- FdUniquePtr pipeptr(pipefd+1);
- close(pipefd[0]);
-
- TemporaryTestUser user(username, static_cast<GumUserType>(GUM_USERTYPE_NORMAL), false);
- user.create();
-
- unsigned int privileges_count = 0;
-
- register_current_process_as_privilege_manager(user.getUid(), false);
- //the above call, registers 1 new privilege for the given user, hence the incrementation of below variable
- ++privileges_count;
-
- for(unsigned int i = 0; i < MANY_APPS.size(); ++i) {
- InstallRequest requestInst;
- requestInst.setAppId(MANY_APPS[i].c_str());
- requestInst.setPkgId(MANY_APPS_PKGS.at(MANY_APPS[i]).package.c_str());
- requestInst.setUid(user.getUid());
-
- for (auto &priv : MANY_APPS_PRIVILEGES.at(i)) {
- requestInst.addPrivilege(priv.c_str());
- };
-
- Api::install(requestInst);
- privileges_count += MANY_APPS_PRIVILEGES.at(i).size();
- };
-
- //send info to child
- msg.uid = user.getUid();
- msg.gid = user.getGid();
- msg.privileges_count = privileges_count;
-
- ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed");
-
- //wait for child
- RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed");
- }
- if(pid == 0)
- {
- FdUniquePtr pipeptr(pipefd);
- close(pipefd[1]);
-
- ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed");
-
- //become admin privacy manager manager
- Api::setProcessLabel(PRIVILEGE_MANAGER_APP.c_str());
- result = drop_root_privileges(msg.uid, msg.gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
-
- // filter by privilege
- std::vector<PolicyEntry> policyEntries;
- PolicyEntry filter(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, "http://tizen.org/privilege/internet");
- Api::getPolicy(filter, policyEntries);
-
- RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
- RUNNER_ASSERT_MSG(policyEntries.size() == 2, "Number of policies doesn't match - should be: 2 and is " << policyEntries.size());
-
- // filter by other privilege
- policyEntries.clear();
- PolicyEntry filter2(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, "http://tizen.org/privilege/email");
- Api::getPolicy(filter2, policyEntries);
-
- RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
- RUNNER_ASSERT_MSG(policyEntries.size() == 3, "Number of policies doesn't match - should be: 3 and is " << policyEntries.size());
-
- // filter by appId
- policyEntries.clear();
- PolicyEntry filter3(MANY_APPS[4].c_str(), SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY);
- Api::getPolicy(filter3, policyEntries);
-
- RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
- RUNNER_ASSERT_MSG(policyEntries.size() == 4, "Number of policies doesn't match - should be: 4 and is " << policyEntries.size());
- }
-}
-
-RUNNER_CHILD_TEST(security_manager_18_user_cynara_policy)
-{
- RUNNER_IGNORED_MSG("temporarily disabled due to gumd timeouts");
- const char *const MAIN_BUCKET = "MAIN";
- const char *const MANIFESTS_BUCKET = "MANIFESTS";
- const char *const ADMIN_BUCKET = "ADMIN";
- const char *const USER_TYPE_NORMAL_BUCKET = "USER_TYPE_NORMAL";
- const std::string username("sm_test_10_user_cynara_policy");
- CynaraTestAdmin::Admin admin;
- std::string uid_string;
- TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, true);
- user.create();
- user.getUidString(uid_string);
-
- CynaraTestAdmin::CynaraPoliciesContainer nonemptyContainer;
- nonemptyContainer.add(MAIN_BUCKET,CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, CYNARA_ADMIN_BUCKET, USER_TYPE_NORMAL_BUCKET);
- admin.listPolicies(MAIN_BUCKET, CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, nonemptyContainer,CYNARA_API_SUCCESS);
-
- user.remove();
- CynaraTestAdmin::CynaraPoliciesContainer emptyContainer;
-
- admin.listPolicies(MAIN_BUCKET, CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, emptyContainer, CYNARA_API_SUCCESS);
- admin.listPolicies(MANIFESTS_BUCKET, CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, emptyContainer, CYNARA_API_SUCCESS);
- admin.listPolicies(CYNARA_ADMIN_DEFAULT_BUCKET, CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, emptyContainer, CYNARA_API_SUCCESS);
- admin.listPolicies(ADMIN_BUCKET, CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, emptyContainer, CYNARA_API_SUCCESS);
-}
-
-RUNNER_CHILD_TEST(security_manager_19_security_manager_cmd_install)
-{
- RUNNER_IGNORED_MSG("temporarily disabled due to gumd timeouts");
- int ret;
- const int SUCCESS = 0;
- const int FAILURE = 256;
- const std::string app_id = "security_manager_10_app";
- const std::string pkg_id = "security_manager_10_pkg";
- const std::string username("sm_test_10_user_name");
- std::string uid_string;
- TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, true);
- 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 pkgopt = " --pkg=" + pkg_id;
- const std::string appopt = " --app=" + app_id;
- const std::string uidopt = " --uid=" + uid_string;
-
- mktreeSafe(path1.c_str(), 0);
- mktreeSafe(path2.c_str(), 0);
-
- const std::string installcmd = "security-manager-cmd --install " + appopt + pkgopt + uidopt;
-
- struct operation {
- std::string command;
- int expected_result;
- };
- std::vector<struct operation> operations = {
- {"security-manager-cmd", FAILURE},//no option
- {"security-manager-cmd --blah", FAILURE},//blah option is not known
- {"security-manager-cmd --help", SUCCESS},
- {"security-manager-cmd --install", FAILURE},//no params
- {"security-manager-cmd -i", FAILURE},//no params
- {"security-manager-cmd --i --app=app_id_10 --pkg=pkg_id_10", FAILURE},//no uid
- {installcmd, SUCCESS},
- {"security-manager-cmd -i -a" + app_id + " -g" + pkg_id + uidopt, SUCCESS},
- {installcmd + " --path " + path1 + " writable", SUCCESS},
- {installcmd + " --path " + path1, FAILURE},//no path type
- {installcmd + " --path " + path1 + " writable" + " --path " + path2 + " readable", SUCCESS},
- {installcmd + " --path " + path1 + " prie" + " --path " + path2 + " readable", FAILURE},//wrong path type
- {installcmd + " --path " + path1 + " writable" + " --privilege somepriv --privilege somepriv2" , SUCCESS},
- };
-
- for (auto &op : operations) {
- ret = system(op.command.c_str());
- RUNNER_ASSERT_MSG(ret == op.expected_result,
- "Unexpected result for command '" << op.command <<"': "
- << ret << " Expected was: "<< op.expected_result);
- }
-}
-
-RUNNER_CHILD_TEST(security_manager_20_security_manager_cmd_users)
-{
- RUNNER_IGNORED_MSG("temporarily disabled due to gumd timeouts");
- int ret;
- const int SUCCESS = 0;
- const int FAILURE = 256;
- const std::string username("sm_test_11_user_name");
- std::string uid_string;
- TemporaryTestUser user(username, GUM_USERTYPE_NORMAL, true);
- user.create();
- user.getUidString(uid_string);
- const std::string uidopt = " --uid=" + uid_string;
-
- struct operation {
- std::string command;
- int expected_result;
- };
- std::vector<struct operation> operations = {
- {"security-manager-cmd --manage-users=remove", FAILURE},//no params
- {"security-manager-cmd -m", FAILURE},//no params
- {"security-manager-cmd -mr", FAILURE},//no uid
- {"security-manager-cmd -mr --uid" + uidopt, FAILURE},//no uid
- {"security-manager-cmd -mr --sdfj" + uidopt, FAILURE},//sdfj?
- {"security-manager-cmd --msdf -u2004" , FAILURE},//sdf?
- {"security-manager-cmd -mr" + uidopt, SUCCESS},//ok, removed
- {"security-manager-cmd -mr --blah" + uidopt, FAILURE},//blah
- {"security-manager-cmd -ma" + uidopt, SUCCESS},//ok, added
- {"security-manager-cmd -ma --usertype=normal" + uidopt, SUCCESS},//ok, added
- {"security-manager-cmd -ma --usertype=mal" + uidopt, FAILURE},//ok, added
- };
-
- for (auto &op : operations) {
- ret = system(op.command.c_str());
- RUNNER_ASSERT_MSG(ret == op.expected_result,
- "Unexpected result for command '" << op.command <<"': "
- << ret << " Expected was: "<< op.expected_result);
- }
-}
-
-RUNNER_CHILD_TEST(security_manager_21_security_manager_admin_deny_user_priv)
-{
- const int BUFFER_SIZE = 128;
- struct message {
- uid_t uid;
- gid_t gid;
- char buf[BUFFER_SIZE];
- } msg;
-
- privileges_t admin_required_privs = {
- "http://tizen.org/privilege/systemsettings.admin",
- "http://tizen.org/privilege/systemsettings"};
- privileges_t manifest_privs = {
- "http://tizen.org/privilege/internet",
- "http://tizen.org/privilege/camera"};
- privileges_t real_privs_allow = {"http://tizen.org/privilege/camera"};
- privileges_t real_privs_deny = {"http://tizen.org/privilege/internet"};
-
- const std::string pirivman_id = "sm_test_13_ADMIN_APP";
- const std::string pirivman_pkg_id = "sm_test_13_ADMIN_PKG";
- const std::string app_id = "sm_test_13_SOME_APP";
- const std::string pkg_id = "sm_test_13_SOME_PKG";
-
- int pipefd[2];
- pid_t pid;
- int result = 0;
-
- RUNNER_ASSERT_MSG((pipe(pipefd) != -1),"pipe failed");
- pid = fork();
- RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
- if (pid != 0)//parent process
- {
- std::string childuidstr;
- TemporaryTestUser admin("sm_test_13_ADMIN_USER", GUM_USERTYPE_ADMIN, true);
- TemporaryTestUser child("sm_test_13_NORMAL_USER", GUM_USERTYPE_NORMAL, true);
-
- InstallRequest request,request2;
- FdUniquePtr pipeptr(pipefd+1);
- close(pipefd[0]);
-
- admin.create();
- child.create();
- child.getUidString(childuidstr);
-
- //install privacy manager for admin
- request.setAppId(pirivman_id.c_str());
- request.setPkgId(pirivman_pkg_id.c_str());
- request.setUid(admin.getUid());
- for (auto &priv: admin_required_privs)
- request.addPrivilege(priv.c_str());
- Api::install(request);
-
- //install app for child that has internet privilege
- request2.setAppId(app_id.c_str());
- request2.setPkgId(pkg_id.c_str());
- request2.setUid(child.getUid());
- for (auto &priv: manifest_privs)
- request2.addPrivilege(priv.c_str());
- Api::install(request2);
-
- check_app_permissions(app_id.c_str(), pkg_id.c_str(), childuidstr.c_str(),
- manifest_privs, SM_NO_PRIVILEGES);
-
- //send info to child
- msg.uid = admin.getUid();
- msg.gid = admin.getGid();
- strncpy (msg.buf, childuidstr.c_str(), BUFFER_SIZE);
-
- ssize_t written = TEMP_FAILURE_RETRY(write(pipefd[1], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG((written == sizeof(struct message)),"write failed");
-
- //wait for child
- RUNNER_ASSERT_MSG(wait(&result) == pid, "wait failed");
-
- check_app_permissions(app_id.c_str(), pkg_id.c_str(), childuidstr.c_str(),
- real_privs_allow, real_privs_deny);
- }
- if (pid == 0)//child
- {
- FdUniquePtr pipeptr(pipefd);
- close(pipefd[1]);
-
- ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd[0], &msg, sizeof(struct message)));
- RUNNER_ASSERT_MSG(fetched == sizeof(struct message), "read failed");
-
- //become admin privacy manager manager
- Api::setProcessLabel(pirivman_id.c_str());
- result = drop_root_privileges(msg.uid, msg.gid);
- RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
- PolicyRequest addPolicyReq;
- //change rights
- for (auto &denypriv:real_privs_deny) {
- /*this entry will deny some privileges for user whose uid (as c string)
- was sent in message's buf field.
- That user would be denying internet for child in this case*/
- PolicyEntry entry(SECURITY_MANAGER_ANY, msg.buf, denypriv);
- entry.setMaxLevel("Deny");
- addPolicyReq.addEntry(entry);
- }
- Api::sendPolicy(addPolicyReq);
- exit(0);
- }
-}
-
-namespace {
-const int sm_app_shared_test_id = 27;
-const char *const sm_app_shared_id = "sm_test_27_app_id_full";
-const char *const sm_app_shared_another_in_package_id = "sm_test_27_app_2_id_full";
-const char *const sm_pkg_shared_id = "sm_test_27_pkg_id_full";
-
-void test_success_worker(const std::string &appName, int test_num)
-{
- std::string SM_OWNER_RW_OTHERS_RO_PATH = genOwnerRWOthersROPath(test_num);
-
- changeSecurityContext(generateAppLabel(appName), APP_UID, APP_GID);
-
- RUNNER_ASSERT_ERRNO_MSG(::access(SM_OWNER_RW_OTHERS_RO_PATH.c_str(), R_OK|X_OK) != -1,
- "access (" << SM_OWNER_RW_OTHERS_RO_PATH << ") from " << appName << " failed " << " to " << SM_OWNER_RW_OTHERS_RO_PATH );
-}
-
-void test_fail_worker(const std::string &appName, int test_num)
-{
- std::string SM_OWNER_RW_OTHERS_RO_PATH = genOwnerRWOthersROPath(test_num);
-
- changeSecurityContext(generateAppLabel(appName), APP_UID, APP_GID);
-
- RUNNER_ASSERT_MSG(::access(SM_OWNER_RW_OTHERS_RO_PATH.c_str(), R_OK|X_OK) == -1,
- "access (" << SM_OWNER_RW_OTHERS_RO_PATH << ") from " << appName
- << " surprisingly succeeded, while expecting fail");
-}
-}
-
-RUNNER_TEST(security_manager_27a_API2X_app_install)
-{
- std::string SM_RW_PATH = genRWPath(sm_app_shared_test_id);
- std::string SM_RO_PATH = genROPath(sm_app_shared_test_id);
- std::string SM_PUBLIC_RO_PATH = genPublicROPath(sm_app_shared_test_id);
- std::string SM_OWNER_RW_OTHERS_RO_PATH = genOwnerRWOthersROPath(sm_app_shared_test_id);
- prepare_app_env(sm_app_shared_test_id, true);
-
- // install other apps
- for(const auto &app : MANY_APPS_PKGS) {
- InstallRequest requestInst;
- requestInst.setAppId(app.first.c_str());
- requestInst.setPkgId(app.second.package.c_str());
- requestInst.setAppTizenVersion(app.second.Tizen_ver.c_str());
-
- Api::install(requestInst);
- };
-
- // install
- {
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_shared_id);
- requestInst.setPkgId(sm_pkg_shared_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);
- requestInst.addPath(SM_OWNER_RW_OTHERS_RO_PATH, SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
- requestInst.setAppTizenVersion("2.4");
- Api::install(requestInst);
- }
-
- // another app in package
- {
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_shared_another_in_package_id);
- requestInst.setPkgId(sm_pkg_shared_id);
- requestInst.addPrivilege(SM_ALLOWED_PRIVILEGES[0].c_str());
- requestInst.addPrivilege(SM_ALLOWED_PRIVILEGES[1].c_str());
- requestInst.addPath(SM_OWNER_RW_OTHERS_RO_PATH, SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
- requestInst.setAppTizenVersion("2.4");
- Api::install(requestInst);
- }
-
- /* Check records in the security-manager database */
- check_app_after_install(sm_app_shared_id, sm_pkg_shared_id,
- SM_ALLOWED_PRIVILEGES, SM_DENIED_PRIVILEGES, SM_ALLOWED_GROUPS);
- /* Check records in the security-manager database */
- check_app_after_install(sm_app_shared_another_in_package_id, sm_pkg_shared_id,
- SM_ALLOWED_PRIVILEGES, SM_DENIED_PRIVILEGES, SM_ALLOWED_GROUPS);
-
- /* TODO: add parameters to this function */
- check_app_path_after_install(sm_app_shared_test_id, sm_pkg_shared_id, true);
-
- RUNNER_ASSERT_ERRNO_MSG(::access(SM_OWNER_RW_OTHERS_RO_PATH.c_str(), R_OK|X_OK) != -1, "access (" << SM_OWNER_RW_OTHERS_RO_PATH << ") failed");
-}
-
-RUNNER_CHILD_TEST(security_manager_27b_owner_1_have_access)
-{
- test_success_worker(sm_app_shared_id, sm_app_shared_test_id);
-}
-
-RUNNER_CHILD_TEST(security_manager_27c_owner_2_have_access)
-{
- test_success_worker(sm_app_shared_another_in_package_id, sm_app_shared_test_id);
-}
-
-RUNNER_CHILD_TEST(security_manager_27d_API2X_apps_have_access_app_1)
-{
- test_success_worker("security_manager_10_app_1", sm_app_shared_test_id);
-}
-
-RUNNER_CHILD_TEST(security_manager_27e_API2X_apps_dont_have_access_app_2)
-{
- test_fail_worker("security_manager_10_app_2", sm_app_shared_test_id);
-}
-
-RUNNER_CHILD_TEST(security_manager_27f_API2X_apps_have_access_app_3)
-{
- test_success_worker("security_manager_10_app_3", sm_app_shared_test_id);
-}
-
-RUNNER_CHILD_TEST(security_manager_27g_API2X_apps_dont_have_access_app_4)
-{
- test_fail_worker("security_manager_10_app_4", sm_app_shared_test_id);
-}
-
-RUNNER_CHILD_TEST(security_manager_27h_API2X_apps_have_access_app_5)
-{
- test_success_worker("security_manager_10_app_5", sm_app_shared_test_id);
-}
-
-
-RUNNER_TEST(security_manager_27i_API2X_app_uninstall)
-{
- {
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_shared_id);
- Api::uninstall(requestUninst);
- }
- {
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_shared_another_in_package_id);
- Api::uninstall(requestUninst);
- }
-
- /* Check records in the security-manager database,
- * all previously allowed privileges should be removed */
- check_app_after_uninstall(sm_app_shared_id, sm_pkg_shared_id,
- SM_ALLOWED_PRIVILEGES, TestSecurityManagerDatabase::REMOVED);
- check_app_after_uninstall(sm_app_shared_another_in_package_id, sm_pkg_shared_id,
- SM_ALLOWED_PRIVILEGES, TestSecurityManagerDatabase::REMOVED);
-}
-
-RUNNER_TEST(security_manager_27j_API30_app_install)
-{
- std::string SM_RW_PATH = genRWPath(sm_app_shared_test_id);
- std::string SM_RO_PATH = genROPath(sm_app_shared_test_id);
- std::string SM_PUBLIC_RO_PATH = genPublicROPath(sm_app_shared_test_id);
- std::string SM_OWNER_RW_OTHERS_RO_PATH = genOwnerRWOthersROPath(sm_app_shared_test_id);
- prepare_app_env(sm_app_shared_test_id, true);
-
- // install
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_shared_id);
- requestInst.setPkgId(sm_pkg_shared_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);
- requestInst.addPath(SM_OWNER_RW_OTHERS_RO_PATH, SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
- requestInst.setAppTizenVersion("3.0");
-
- Api::install(requestInst);
-
- /* Check records in the security-manager database */
- check_app_after_install(sm_app_shared_id, sm_pkg_shared_id,
- SM_ALLOWED_PRIVILEGES, SM_DENIED_PRIVILEGES, SM_ALLOWED_GROUPS);
-
- /* TODO: add parameters to this function */
- check_app_path_after_install(sm_app_shared_test_id, sm_pkg_shared_id, true);
-
- RUNNER_ASSERT_ERRNO_MSG(::access(SM_OWNER_RW_OTHERS_RO_PATH.c_str(), R_OK|X_OK) != -1, "access (" << SM_OWNER_RW_OTHERS_RO_PATH << ") failed");
-}
-
-RUNNER_CHILD_TEST(security_manager_27k_API30_apps_dont_have_access_app_1)
-{
- test_fail_worker("security_manager_10_app_1", sm_app_shared_test_id);
-}
-
-RUNNER_CHILD_TEST(security_manager_27l_API30_apps_dont_have_access_app_2)
-{
- test_fail_worker("security_manager_10_app_2", sm_app_shared_test_id);
-}
-
-RUNNER_CHILD_TEST(security_manager_27m_API30_apps_dont_have_access_app_3)
-{
- test_fail_worker("security_manager_10_app_3", sm_app_shared_test_id);
-}
-
-RUNNER_CHILD_TEST(security_manager_27n_API30_apps_dont_have_access_app_4)
-{
- test_fail_worker("security_manager_10_app_4", sm_app_shared_test_id);
-}
-
-RUNNER_CHILD_TEST(security_manager_27o_API30_apps_dont_have_access_app_5)
-{
- test_fail_worker("security_manager_10_app_5", sm_app_shared_test_id);
-}
-
-RUNNER_TEST(security_manager_27p_API30_app_uninstall)
-{
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_shared_id);
-
- Api::uninstall(requestUninst);
-
- /* Check records in the security-manager database,
- * all previously allowed privileges should be removed */
- check_app_after_uninstall(sm_app_shared_id, sm_pkg_shared_id,
- SM_ALLOWED_PRIVILEGES, TestSecurityManagerDatabase::REMOVED);
-
- // install other apps
- for(const auto &app : MANY_APPS_PKGS) {
- InstallRequest requestUninst;
- requestUninst.setAppId(app.first);
-
- Api::uninstall(requestUninst);
- };
-}
-
-namespace {
-const char *const owner_access = "rwxat";
-const char *const target_path_access = "rxl";
-const char *const target_dir_access = "x";
-const char *const no_access = "";
-
-void check_system_access(const std::string pathLabel, bool apply = true) {
- check_exact_smack_accesses("User", pathLabel, (apply ? owner_access : no_access));
- check_exact_smack_accesses("System", pathLabel, (apply ? owner_access : no_access));
-}
-
-void check_owner_access(const std::string &ownerLabel, const std::string &pathLabel, bool apply = true) {
- check_exact_smack_accesses(ownerLabel, pathLabel, (apply ? owner_access : no_access));
-}
-
-void check_target_access(const std::string &ownerPkgLabel, const std::string &targetLabel,
- const std::string &pathLabel, bool pathShared = true, bool anyPathShared = true) {
- check_exact_smack_accesses(targetLabel, pathLabel, (pathShared ? target_path_access : no_access));
- check_exact_smack_accesses(targetLabel, ownerPkgLabel, (anyPathShared ? target_dir_access : no_access));
-}
-
-void check_path_label(const std::string &path, const std::string &expectedLabel) {
- char *label = nullptr;
- int ret = smack_new_label_from_path(path.c_str(), XATTR_NAME_SMACK, 0, &label);
- RUNNER_ASSERT_MSG(ret > 0, "smack_new_label_from_path failed for " << path);
- SmackLabelPtr realLabel(label);
- RUNNER_ASSERT_MSG(realLabel.get() == expectedLabel, "Fetched label from " << path << " different"
- " than expected, is : " << realLabel.get() << " should be " << expectedLabel);
-}
-
-void createFile(const std::string &filePath)
-{
- //create temporary file and set label for it
- mode_t systemMask;
-
- unlink(filePath.c_str());
- //allow to create file with 777 rights
- systemMask = umask(0000);
- int fd = open(filePath.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
- //restore system mask
- umask(systemMask);
- RUNNER_ASSERT_ERRNO_MSG(fd > -1, "Unable to create file for tests");
-
- //for descriptor protection
- FdUniquePtr fd_ptr(&fd);
-
- //change owner and group to user APP
- int ret = chown(filePath.c_str(), APP_UID, APP_GID);
- RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Unable to change file owner");
-}
-
-}
-
-RUNNER_TEST(security_manager_30a_send_incomplete_req1)
-{
- SharingRequest request;
- Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
- request.setOwnerAppId("someOwner");
- Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
- request.setTargetAppId("someTarget");
- Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
-}
-
-RUNNER_TEST(security_manager_30b_send_incomplete_req2)
-{
- SharingRequest request;
- request.setTargetAppId("someTarget");
- Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
- request.setOwnerAppId("someOwner");
- Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
-}
-
-RUNNER_TEST(security_manager_30c_send_incomplete_req3)
-{
- SharingRequest request;
- const char *somePaths[] = {"path1", "path2"};
- request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0]));
- Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
- request.setOwnerAppId("someOwner");
- Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
-}
-
-RUNNER_TEST(security_manager_30d_unknown_owner)
-{
- // This test depends on order of checks in security-manager service implementation
- SharingRequest request;
- request.setOwnerAppId("ImPrettySureIDontExist");
- request.setTargetAppId("IDontMatter");
- const char *somePaths[] = {"path1", "path2"};
- request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0]));
- Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
-}
-
-RUNNER_TEST(security_manager_30e_unknown_target)
-{
- // This test depends on order of checks in security-manager service implementation
- AppInstallHelper owner("installedApp");
- owner.revokeRules();
- owner.createInstallDir();
- InstallRequest ownerInst;
- ownerInst.setAppId(owner.getAppId());
- ownerInst.setPkgId(owner.getPkgId());
- Api::install(ownerInst);
-
- SharingRequest request;
- request.setOwnerAppId(owner.getAppId());
- request.setTargetAppId("NowImPrettySureIDontExist");
- const char *somePaths[] = {"path1", "path2"};
- request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0]));
- Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
-
- Api::uninstall(ownerInst);
-}
-
-RUNNER_TEST(security_manager_30f_bad_paths)
-{
- // This test depends on order of checks in security-manager service implementation
- AppInstallHelper owner("installedApp");
- owner.revokeRules();
- owner.createInstallDir();
- InstallRequest ownerInst;
- ownerInst.setAppId(owner.getAppId());
- ownerInst.setPkgId(owner.getPkgId());
- Api::install(ownerInst);
-
- AppInstallHelper target("secondInstalledApp");
- target.revokeRules();
- target.createInstallDir();
- InstallRequest targetInst;
- targetInst.setAppId(target.getAppId());
- targetInst.setPkgId(target.getPkgId());
- Api::install(targetInst);
-
- SharingRequest request;
- request.setOwnerAppId(owner.getAppId());
- request.setTargetAppId(target.getAppId());
-
- const char *somePath = "/tmp/somePath";
- createFile(somePath);
- const char *somePaths[] = {somePath};
- request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0]));
- Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_NOT_PATH_OWNER);
-
- Api::uninstall(ownerInst);
-}
-
-RUNNER_TEST(security_manager_31_simple_share)
-{
- std::vector<AppInstallHelper> helper {{"app30a"}, {"app30b"}};
- auto &owner = helper[0];
- auto &target = helper[1];
-
- for (auto &e : helper) {
- e.revokeRules();
- e.createInstallDir();
- }
-
- owner.createPrivateDir();
- owner.createSharedFile();
-
- InstallRequest ownerReq;
- ownerReq.setAppId(owner.getAppId());
- ownerReq.setPkgId(owner.getPkgId());
- ownerReq.addPath(owner.getSharedPath(), SECURITY_MANAGER_PATH_RW);
- int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir());
- Api::install(ownerReq);
-
- InstallRequest targetReq;
- targetReq.setAppId(target.getAppId());
- targetReq.setPkgId(target.getAppId());
- Api::install(targetReq);
-
- SharingRequest share1;
- std::string sharedPath = owner.getSharedPath();
- share1.setOwnerAppId(owner.getAppId());
- share1.setTargetAppId(target.getAppId());
- const char *path[] = {sharedPath.c_str()};
- share1.addPaths(path, 1);
- Api::applySharing(share1);
-
- TestSecurityManagerDatabase db;
- std::string pathLabel1 = db.get_path_label(sharedPath.c_str());
- RUNNER_ASSERT_MSG(!pathLabel1.empty(), "Couldn't fetch path label from database for file " << sharedPath);
-
- check_system_access(pathLabel1);
- check_owner_access(owner.generateAppLabel(), pathLabel1);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1);
- check_path_label(sharedPath, pathLabel1);
-
- Api::dropSharing(share1);
- check_system_access(pathLabel1, false);
- check_owner_access(owner.generateAppLabel(), pathLabel1, false);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1, false, false);
- check_path_label(sharedPath, owner.generatePkgLabel());
-
- Api::uninstall(ownerReq);
- Api::uninstall(targetReq);
-}
-
-RUNNER_TEST(security_manager_32_double_share)
-{
- std::vector<AppInstallHelper> helper {{"app31a"}, {"app31b"}};
- auto &owner = helper[0];
- auto &target = helper[1];
-
- // cleanup
- for (auto &e : helper) {
- e.revokeRules();
- e.createInstallDir();
- }
- owner.createPrivateDir();
- owner.createSharedFile();
-
- InstallRequest ownerReq;
- ownerReq.setAppId(owner.getAppId());
- ownerReq.setPkgId(owner.getPkgId());
- ownerReq.addPath(owner.getSharedPath(), SECURITY_MANAGER_PATH_RW);
-
- int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir());
- Api::install(ownerReq);
-
- InstallRequest targetReq;
- targetReq.setAppId(target.getAppId());
- targetReq.setPkgId(target.getAppId());
- Api::install(targetReq);
-
- SharingRequest share1;
- std::string sharedPath = owner.getSharedPath(0);
- share1.setOwnerAppId(owner.getAppId());
- share1.setTargetAppId(target.getAppId());
- const char *path[] = {sharedPath.c_str()};
- share1.addPaths(path, 1);
- Api::applySharing(share1);
-
- TestSecurityManagerDatabase db;
- std::string pathLabel = db.get_path_label(sharedPath.c_str());
- RUNNER_ASSERT_MSG(!pathLabel.empty(), "Couldn't fetch path label from database for file " << sharedPath);
-
- check_system_access(pathLabel);
- check_owner_access(owner.generateAppLabel(), pathLabel);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel);
- check_path_label(sharedPath, pathLabel);
-
- Api::applySharing(share1);
- check_system_access(pathLabel);
- check_owner_access(owner.generateAppLabel(), pathLabel);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel);
- check_path_label(sharedPath, pathLabel);
-
- Api::dropSharing(share1);
- check_system_access(pathLabel);
- check_owner_access(owner.generateAppLabel(), pathLabel);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel);
- check_path_label(sharedPath, pathLabel);
-
- Api::dropSharing(share1);
- check_system_access(pathLabel, false);
- check_owner_access(owner.generateAppLabel(), pathLabel, false);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel, false, false);
- check_path_label(sharedPath, owner.generatePkgLabel());
-
- Api::uninstall(ownerReq);
- Api::uninstall(targetReq);
-}
-RUNNER_TEST(security_manager_33_share_two_with_one)
-{
- std::vector<AppInstallHelper> helper {{"app32a"}, {"app32b"}};
- auto &owner = helper[0];
- auto &target = helper[1];
-
- // cleanup
- for (auto &e : helper) {
- e.revokeRules();
- e.createInstallDir();
- }
- owner.createPrivateDir();
- owner.createSharedFile(0);
- owner.createSharedFile(1);
-
- InstallRequest ownerReq;
- ownerReq.setAppId(owner.getAppId());
- ownerReq.setPkgId(owner.getPkgId());
- ownerReq.addPath(owner.getSharedPath(0), SECURITY_MANAGER_PATH_RW);
- ownerReq.addPath(owner.getSharedPath(1), SECURITY_MANAGER_PATH_RW);
-
- int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir());
- Api::install(ownerReq);
-
- InstallRequest targetReq;
- targetReq.setAppId(target.getAppId());
- targetReq.setPkgId(target.getAppId());
- Api::install(targetReq);
-
- SharingRequest share1, share2;
- std::string sharedPath1 = owner.getSharedPath(0);
- std::string sharedPath2 = owner.getSharedPath(1);
- share1.setOwnerAppId(owner.getAppId());
- share2.setOwnerAppId(owner.getAppId());
- share1.setTargetAppId(target.getAppId());
- share2.setTargetAppId(target.getAppId());
- const char *path1[] = {sharedPath1.c_str()};
- const char *path2[] = {sharedPath2.c_str()};
- share1.addPaths(path1, 1);
- share2.addPaths(path2, 1);
-
- Api::applySharing(share1);
- TestSecurityManagerDatabase db;
- std::string pathLabel1 = db.get_path_label(sharedPath1.c_str());
- RUNNER_ASSERT_MSG(!pathLabel1.empty(), "Couldn't fetch path label from database for file " << sharedPath1);
-
- check_system_access(pathLabel1);
- check_owner_access(owner.generateAppLabel(), pathLabel1);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1);
- check_path_label(sharedPath1, pathLabel1);
-
- Api::applySharing(share2);
- std::string pathLabel2 = db.get_path_label(sharedPath2.c_str());
- RUNNER_ASSERT_MSG(!pathLabel2.empty(), "Couldn't fetch path label from database for file " << sharedPath2);
- RUNNER_ASSERT_MSG(pathLabel1 != pathLabel2, "Labels for private shared paths should be unique!");
-
- check_system_access(pathLabel1);
- check_system_access(pathLabel2);
- check_owner_access(owner.generateAppLabel(), pathLabel1);
- check_owner_access(owner.generateAppLabel(), pathLabel2);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel2);
- check_path_label(sharedPath1, pathLabel1);
- check_path_label(sharedPath2, pathLabel2);
-
- Api::dropSharing(share1);
- check_system_access(pathLabel1, false);
- check_system_access(pathLabel2);
- check_owner_access(owner.generateAppLabel(), pathLabel1, false);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1, false);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel2);
- check_path_label(sharedPath1, owner.generatePkgLabel());
- check_path_label(sharedPath2, pathLabel2);
-
- Api::dropSharing(share2);
- check_system_access(pathLabel1, false);
- check_system_access(pathLabel2, false);
- check_owner_access(owner.generateAppLabel(), pathLabel1, false);
- check_owner_access(owner.generateAppLabel(), pathLabel2, false);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1, false, false);
- check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel2, false, false);
- check_path_label(sharedPath1, owner.generatePkgLabel());
- check_path_label(sharedPath2, owner.generatePkgLabel());
-
- Api::uninstall(ownerReq);
- Api::uninstall(targetReq);
-}
-
-RUNNER_TEST(security_manager_34_share_one_with_two)
-{
- std::vector<AppInstallHelper> helper {{"app33a"}, {"app33b"}, {"app33c"}};
- auto &owner = helper[0];
- auto &target1 = helper[1];
- auto &target2 = helper[2];
-
- // cleanup
- for (auto &e : helper) {
- e.revokeRules();
- e.createInstallDir();
- }
- owner.createPrivateDir();
- owner.createSharedFile();
-
- InstallRequest ownerReq;
- ownerReq.setAppId(owner.getAppId());
- ownerReq.setPkgId(owner.getPkgId());
- ownerReq.addPath(owner.getSharedPath(), SECURITY_MANAGER_PATH_RW);
- int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir());
- Api::install(ownerReq);
-
- for (size_t i = 1; i < helper.size(); i++) {
- InstallRequest targetReq;
- targetReq.setAppId(helper[i].getAppId());
- targetReq.setPkgId(helper[i].getAppId());
- Api::install(targetReq);
- }
-
- SharingRequest share1, share2;
- std::string sharedPath = owner.getSharedPath(0).c_str();
- share1.setOwnerAppId(owner.getAppId());
- share2.setOwnerAppId(owner.getAppId());
- share1.setTargetAppId(target1.getAppId());
- share2.setTargetAppId(target2.getAppId());
-
- const char *path[] = {sharedPath.c_str()};
- share1.addPaths(path, 1);
- share2.addPaths(path, 1);
-
- Api::applySharing(share1);
- TestSecurityManagerDatabase db;
- std::string pathLabel = db.get_path_label(sharedPath.c_str());
- RUNNER_ASSERT_MSG(!pathLabel.empty(), "Couldn't fetch path label from database for file " << sharedPath);
-
- check_system_access(pathLabel);
- check_owner_access(owner.generateAppLabel(), pathLabel);
- check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel);
- check_path_label(sharedPath, pathLabel);
-
- Api::applySharing(share2);
- check_system_access(pathLabel);
- check_owner_access(owner.generateAppLabel(), pathLabel);
- check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel);
- check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel);
- check_path_label(sharedPath, pathLabel);
-
- Api::dropSharing(share1);
- check_system_access(pathLabel);
- check_owner_access(owner.generateAppLabel(), pathLabel);
- check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel, false, false);
- check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel);
- check_path_label(sharedPath, pathLabel);
-
- Api::dropSharing(share2);
- check_system_access(pathLabel, false);
- check_owner_access(owner.generateAppLabel(), pathLabel, false);
- check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel, false, false);
- check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel, false, false);
- check_path_label(sharedPath, owner.generatePkgLabel());
-
- Api::uninstall(ownerReq);
- for (size_t i = 1; i < helper.size(); i++) {
- InstallRequest targetReq;
- targetReq.setAppId(helper[i].getAppId());
- targetReq.setPkgId(helper[i].getAppId());
- Api::uninstall(targetReq);
- }
-}
-
-RUNNER_TEST(security_manager_35_share_two_with_two)
-{
- std::vector<AppInstallHelper> helper {{"app34a"}, {"app34b"}, {"app34c"}};
- auto &owner = helper[0];
- auto &target1 = helper[1];
- auto &target2 = helper[2];
-
- // cleanup
- for (auto &e : helper) {
- e.revokeRules();
- e.createInstallDir();
- }
- owner.createPrivateDir();
- owner.createSharedFile(0);
- owner.createSharedFile(1);
-
- InstallRequest ownerReq;
- ownerReq.setAppId(owner.getAppId());
- ownerReq.setPkgId(owner.getPkgId());
- ownerReq.addPath(owner.getSharedPath(0), SECURITY_MANAGER_PATH_RW);
- ownerReq.addPath(owner.getSharedPath(1), SECURITY_MANAGER_PATH_RW);
-
- int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir());
- Api::install(ownerReq);
-
- for (size_t i = 1; i < helper.size(); i++) {
- InstallRequest targetReq;
- targetReq.setAppId(helper[i].getAppId());
- targetReq.setPkgId(helper[i].getAppId());
- Api::install(targetReq);
- }
-
- SharingRequest share1, share2;
- std::string sharedPath1 = owner.getSharedPath(0).c_str();
- std::string sharedPath2 = owner.getSharedPath(1).c_str();
- share1.setOwnerAppId(owner.getAppId());
- share2.setOwnerAppId(owner.getAppId());
- share1.setTargetAppId(target1.getAppId());
- share2.setTargetAppId(target2.getAppId());
-
- const char *path1[] = {sharedPath1.c_str()};
- const char *path2[] = {sharedPath2.c_str()};
- share1.addPaths(path1, 1);
- share2.addPaths(path2, 1);
-
- Api::applySharing(share1);
- TestSecurityManagerDatabase db;
- std::string pathLabel1 = db.get_path_label(sharedPath1.c_str());
- RUNNER_ASSERT_MSG(!pathLabel1.empty(), "Couldn't fetch path label from database for file " << sharedPath1);
-
- check_system_access(pathLabel1);
- check_owner_access(owner.generateAppLabel(), pathLabel1);
- check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1);
- check_path_label(sharedPath1, pathLabel1);
-
- Api::applySharing(share2);
- std::string pathLabel2 = db.get_path_label(sharedPath2.c_str());
- RUNNER_ASSERT_MSG(!pathLabel2.empty(), "Couldn't fetch path label from database for file " << sharedPath2);
- RUNNER_ASSERT_MSG(pathLabel1 != pathLabel2, "Labels for shared files should be unique!");
-
- check_system_access(pathLabel1);
- check_system_access(pathLabel2);
- check_owner_access(owner.generateAppLabel(), pathLabel1);
- check_owner_access(owner.generateAppLabel(), pathLabel2);
- check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1);
- check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel2);
- check_path_label(sharedPath1, pathLabel1);
- check_path_label(sharedPath2, pathLabel2);
-
- Api::dropSharing(share2);
- check_system_access(pathLabel1);
- check_system_access(pathLabel2, false);
- check_owner_access(owner.generateAppLabel(), pathLabel1);
- check_owner_access(owner.generateAppLabel(), pathLabel2, false);
- check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1);
- check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel2, false, false);
- check_path_label(sharedPath1, pathLabel1);
- check_path_label(sharedPath2, owner.generatePkgLabel());
-
- Api::dropSharing(share1);
- check_system_access(pathLabel1, false);
- check_system_access(pathLabel2, false);
- check_owner_access(owner.generateAppLabel(), pathLabel1, false);
- check_owner_access(owner.generateAppLabel(), pathLabel2, false);
- check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1, false, false);
- check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel2, false, false);
- check_path_label(sharedPath1, owner.generatePkgLabel());
- check_path_label(sharedPath2, owner.generatePkgLabel());
- Api::uninstall(ownerReq);
- for (size_t i = 1; i < helper.size(); i++) {
- InstallRequest targetReq;
- targetReq.setAppId(helper[i].getAppId());
- targetReq.setPkgId(helper[i].getAppId());
- Api::uninstall(targetReq);
- }
-}
-
-RUNNER_TEST(security_manager_40_set_wrong_author_id)
-{
- InstallRequest requestInst;
-
- RUNNER_ASSERT(SECURITY_MANAGER_ERROR_INPUT_PARAM ==
- security_manager_app_inst_req_set_author_id(requestInst.get(), NULL));
-
- RUNNER_ASSERT(SECURITY_MANAGER_ERROR_INPUT_PARAM ==
- security_manager_app_inst_req_set_author_id(requestInst.get(), ""));
-}
-
-RUNNER_TEST(security_manager_41_set_author_id_multiple_times)
-{
- for(unsigned int i=0; i<10; ++i) {
- std::string authorId = "some-author-id" + std::to_string(i);
-
- InstallRequest requestInst;
- requestInst.setAuthorId(authorId);
- }
-}
-
-RUNNER_TEST(security_manager_43_app_install_with_trusted_path)
-{
- std::vector<AppInstallHelper> helper {{"app43a"}, {"app43b"}, {"app43c"}};
- auto &provider = helper[0];
- auto &user = helper[1];
- auto &untrusted = helper[2];
-
- TestSecurityManagerDatabase dbtest;
- const char *author_id = "custom_author_id_test 41";
-
- const char *const trusted_access = "rwxatl";
- const char *const system_access = "rwxatl";
-
- int result;
-
- // cleanup
- for (auto &e : helper) {
- e.revokeRules();
- e.createInstallDir();
- e.createTrustedDir();
- }
-
- result = nftw(provider.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to set Smack labels in " << SM_TRUSTED_PATH);
-
- // install app with shared/trusted dir
- InstallRequest trustingApp;
- trustingApp.setAppId(provider.getAppId());
- trustingApp.setPkgId(provider.getPkgId());
- trustingApp.setAuthorId("author id to be overwritten");
- trustingApp.setAuthorId(author_id);
- trustingApp.addPath(provider.getTrustedDir().c_str(), SECURITY_MANAGER_PATH_TRUSTED_RW);
- Api::install(trustingApp);
-
- int64_t authorDb = dbtest.get_author_id(author_id);
- 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 rules
- check_exact_access("System", trusted_label, system_access);
- check_exact_access("User", trusted_label, system_access);
- check_exact_access(generateAppLabel(provider.getAppId()), trusted_label, trusted_access);
- check_exact_access(generatePkgLabel(provider.getPkgId()), trusted_label, "");
-
- // install trusted app
- InstallRequest trustedApp;
- trustedApp.setAppId(user.getAppId());
- trustedApp.setPkgId(user.getPkgId());
- trustedApp.setAuthorId(author_id);
- Api::install(trustedApp);
-
- // check rules
- check_exact_access(generateAppLabel(user.getAppId()), trusted_label, trusted_access);
- check_exact_access(generatePkgLabel(user.getPkgId()), trusted_label, "");
-
- // install untrusted app
- InstallRequest untrustedApp;
- untrustedApp.setAppId(untrusted.getAppId());
- untrustedApp.setPkgId(untrusted.getPkgId());
- Api::install(untrustedApp);
-
- // check rules
- check_exact_access(generateAppLabel(untrusted.getAppId()), trusted_label, "");
- check_exact_access(generatePkgLabel(untrusted.getPkgId()), trusted_label, "");
-
- // uninstall trusting app
- Api::uninstall(trustingApp);
-
- // there's still one app with author id, rules should be kept
- check_exact_access("System", trusted_label, system_access);
- check_exact_access("User", trusted_label, system_access);
- check_exact_access(generateAppLabel(provider.getAppId()), trusted_label, "");
- check_exact_access(generatePkgLabel(provider.getPkgId()), trusted_label, "");
- check_exact_access(generateAppLabel(user.getAppId()), trusted_label, trusted_access);
- check_exact_access(generatePkgLabel(user.getPkgId()), trusted_label, "");
-
- Api::uninstall(trustedApp);
-
- // no more apps with author id
- check_exact_access("System", trusted_label, "");
- check_exact_access("User", trusted_label, "");
- check_exact_access(generateAppLabel(user.getAppId()), trusted_label, "");
- check_exact_access(generatePkgLabel(user.getPkgId()), trusted_label, "");
-
- Api::uninstall(untrustedApp);
-}
-
-
-RUNNER_TEST(security_manager_44_app_install_with_trusted_path_no_author_id)
-{
- AppInstallHelper help("app44");
- help.createInstallDir();
- help.createTrustedDir();
-
- // install app with shared/trusted dir but without authors id
- InstallRequest app;
- app.setAppId(help.getAppId());
- app.setPkgId(help.getPkgId());
- app.addPath(help.getTrustedDir(), SECURITY_MANAGER_PATH_TRUSTED_RW);
- Api::install(app, SECURITY_MANAGER_ERROR_INPUT_PARAM);
-}
-
-class ProcessCredentials {
-public:
- ProcessCredentials(const std::string &smackLabel) : m_label(smackLabel) {}
-
- const std::string &label(void) const {
- return m_label;
- }
-
- uid_t uid(void) const {
- return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
- }
-
- gid_t gid(void) const {
- return PasswdAccess::gid("users");
- }
-
-private:
- std::string m_label;
-};
-
-pid_t runInChild(const std::function<void(void)> &process) {
- pid_t pid = fork();
- RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "fork failed");
-
- if (pid == 0) {
- process();
- exit(EXIT_SUCCESS);
- }
-
- return pid;
-}
-
-void udsServer(SynchronizationPipe &pipe, const struct sockaddr_un &sockaddr,
- const struct ProcessCredentials &peerCredentials) {
- SecurityServer::AccessProvider ap(peerCredentials.label());
- ap.applyAndSwithToUser(peerCredentials.uid(), peerCredentials.gid());
- pipe.claimChildEp();
-
- int sock = UDSHelpers::createServer(&sockaddr);
- SockUniquePtr sockPtr(&sock);
- pipe.post();
- int clientSock = UDSHelpers::acceptClient(sock);
-
- UDSHelpers::waitForDisconnect(clientSock);
-}
-
-typedef std::function<void(int sock, pid_t pid)> SocketAssertionFn;
-
-void clientTestTemplate(SocketAssertionFn assertion, const std::string &scope, const std::string &smackLabel) {
- const auto sockaddr = UDSHelpers::makeAbstractAddress("test_sm_" + scope + ".socket");
- const ProcessCredentials peerCredentials(smackLabel);
-
- SynchronizationPipe pipe;
-
- pid_t pid = runInChild(std::bind(udsServer, std::ref(pipe), std::cref(sockaddr),
- std::cref(peerCredentials)));
-
- pipe.claimParentEp();
- pipe.wait();
- int sock = UDSHelpers::createClient(&sockaddr);
- SockUniquePtr sockPtr(&sock);
-
- assertion(sock, pid);
-}
-
-RUNNER_CHILD_TEST(security_manager_45a_get_id_by_socket)
-{
- const char *const sm_app_id = "sm_test_45a_app";
- const char *const sm_pkg_id = "sm_test_45a_pkg";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
-
- Api::install(requestInst);
-
- std::string smackLabel = generateAppLabel(sm_app_id);
-
- clientTestTemplate([&] (int sock, pid_t) {
- std::string rcvPkgId, rcvAppId;
- Api::getPkgIdBySocket(sock, &rcvPkgId, &rcvAppId);
- RUNNER_ASSERT_MSG(rcvPkgId == sm_pkg_id, "pkgIds don't match ret = " << rcvPkgId
- << "; expected = " << sm_pkg_id);
- RUNNER_ASSERT_MSG(rcvAppId == sm_app_id, "appIds don't match ret = " << rcvAppId
- << "; expected = " << sm_app_id);
- }, "tcsm27a", smackLabel);
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
-
- Api::uninstall(requestUninst);
-}
-
-RUNNER_CHILD_TEST(security_manager_45b_get_id_by_socket)
-{
- const char *const sm_app_id = "sm_test_45b_app";
- const char *const sm_pkg_id = "sm_test_45b_pkg";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
-
- Api::install(requestInst);
-
- std::string smackLabel = generateAppLabel(sm_app_id);
-
- clientTestTemplate([&] (int sock, pid_t) {
- std::string rcvPkgId, rcvAppId;
- Api::getPkgIdBySocket(sock + 1, &rcvPkgId, &rcvAppId, SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT);
- }, "tcsm27b", smackLabel);
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
-
- Api::uninstall(requestUninst);
-}
-
-RUNNER_CHILD_TEST(security_manager_45c_get_id_by_socket)
-{
- const char *const sm_app_id = "sm_test_45c_app";
- const char *const sm_pkg_id = "sm_test_45c_pkg";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
-
- Api::install(requestInst);
-
- std::string smackLabel = generateAppLabel(sm_app_id);
-
- clientTestTemplate([&] (int sock, pid_t) {
- std::string rcvPkgId;
- Api::getPkgIdBySocket(sock, &rcvPkgId, nullptr);
- RUNNER_ASSERT_MSG(rcvPkgId == sm_pkg_id, "pkgIds don't match ret = " << rcvPkgId
- << "; expected = " << sm_pkg_id);
- }, "tcsm27c", smackLabel);
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
-
- Api::uninstall(requestUninst);
-}
-
-RUNNER_CHILD_TEST(security_manager_45d_get_id_by_socket)
-{
- const char *const sm_app_id = "sm_test_45d_app";
- const char *const sm_pkg_id = "sm_test_45d_pkg";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
-
- Api::install(requestInst);
-
- std::string smackLabel = generateAppLabel(sm_app_id);
-
- clientTestTemplate([&] (int sock, pid_t) {
- std::string rcvAppId;
- Api::getPkgIdBySocket(sock, nullptr, &rcvAppId);
- RUNNER_ASSERT_MSG(rcvAppId == sm_app_id, "appIds don't match ret = " << rcvAppId
- << "; expected = " << sm_app_id);
- }, "tcsm27d", smackLabel);
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
-
- Api::uninstall(requestUninst);
-}
-
-RUNNER_CHILD_TEST(security_manager_45e_get_id_by_socket)
-{
- const char *const sm_app_id = "sm_test_45e_app";
- const char *const sm_pkg_id = "sm_test_45e_pkg";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
-
- Api::install(requestInst);
-
- std::string smackLabel = generateAppLabel(sm_app_id);
-
- clientTestTemplate([&] (int sock, pid_t) {
- Api::getPkgIdBySocket(sock, nullptr, nullptr, SECURITY_MANAGER_ERROR_INPUT_PARAM);
- }, "tcsm27e", smackLabel);
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
-
- Api::uninstall(requestUninst);
-}
-
-RUNNER_CHILD_TEST(security_manager_46a_get_id_by_pid)
-{
- const char *const sm_app_id = "sm_test_46a_app";
- const char *const sm_pkg_id = "sm_test_46a_pkg";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
-
- Api::install(requestInst);
-
- std::string smackLabel = generateAppLabel(sm_app_id);
-
- clientTestTemplate([&] (int, pid_t pid) {
- std::string rcvPkgId, rcvAppId;
- Api::getPkgIdByPid(pid, &rcvPkgId, &rcvAppId);
- RUNNER_ASSERT_MSG(rcvPkgId == sm_pkg_id, "pkgIds don't match ret = " << rcvPkgId
- << "; expected = " << sm_pkg_id);
- RUNNER_ASSERT_MSG(rcvAppId == sm_app_id, "appIds don't match ret = " << rcvAppId
- << "; expected = " << sm_app_id);
- }, "tcsm28a", smackLabel);
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
-
- Api::uninstall(requestUninst);
-}
-
-RUNNER_CHILD_TEST(security_manager_46b_get_id_by_pid)
-{
- const char *const sm_app_id = "sm_test_46b_app";
- const char *const sm_pkg_id = "sm_test_46b_pkg";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
-
- Api::install(requestInst);
-
- std::string smackLabel = generateAppLabel(sm_app_id);
-
- clientTestTemplate([&] (int, pid_t pid) {
- std::string rcvPkgId, rcvAppId;
- Api::getPkgIdByPid(pid + 1, &rcvPkgId, &rcvAppId, SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT);
- }, "tcsm28b", smackLabel);
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
-
- Api::uninstall(requestUninst);
-}
-
-RUNNER_CHILD_TEST(security_manager_46c_get_id_by_pid)
-{
- const char *const sm_app_id = "sm_test_46c_app";
- const char *const sm_pkg_id = "sm_test_46c_pkg";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
-
- Api::install(requestInst);
-
- std::string smackLabel = generateAppLabel(sm_app_id);
-
- clientTestTemplate([&] (int, pid_t pid) {
- std::string rcvPkgId;
- Api::getPkgIdByPid(pid, &rcvPkgId, nullptr);
- RUNNER_ASSERT_MSG(rcvPkgId == sm_pkg_id, "pkgIds don't match ret = " << rcvPkgId
- << "; expected = " << sm_pkg_id);
- }, "tcsm28c", smackLabel);
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
-
- Api::uninstall(requestUninst);
-}
-
-RUNNER_CHILD_TEST(security_manager_46d_get_id_by_pid)
-{
- const char *const sm_app_id = "sm_test_46d_app";
- const char *const sm_pkg_id = "sm_test_46d_pkg";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
-
- Api::install(requestInst);
-
- std::string smackLabel = generateAppLabel(sm_app_id);
-
- clientTestTemplate([&] (int, pid_t pid) {
- std::string rcvAppId;
- Api::getPkgIdByPid(pid, nullptr, &rcvAppId);
- RUNNER_ASSERT_MSG(rcvAppId == sm_app_id, "appIds don't match ret = " << rcvAppId
- << "; expected = " << sm_app_id);
- }, "tcsm28d", smackLabel);
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
-
- Api::uninstall(requestUninst);
-}
-
-RUNNER_CHILD_TEST(security_manager_46e_get_id_by_pid)
-{
- const char *const sm_app_id = "sm_test_46e_app";
- const char *const sm_pkg_id = "sm_test_46e_pkg";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
-
- Api::install(requestInst);
-
- std::string smackLabel = generateAppLabel(sm_app_id);
-
- clientTestTemplate([&] (int sock, pid_t) {
- Api::getPkgIdByPid(sock, nullptr, nullptr, SECURITY_MANAGER_ERROR_INPUT_PARAM);
- }, "tcsm28e", smackLabel);
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
-
- Api::uninstall(requestUninst);
-}
-
-RUNNER_CHILD_TEST(security_manager_47_app_has_privilege)
-{
- const char *const sm_app_id = "sm_test_47_app";
- const char *const sm_pkg_id = "sm_test_47_pkg";
- const std::string new_user_name = "sm_test_47_user_name";
-
- InstallRequest requestInst;
- requestInst.setAppId(sm_app_id);
- requestInst.setPkgId(sm_pkg_id);
- for (auto const &privilege : SM_ALLOWED_PRIVILEGES)
- requestInst.addPrivilege(privilege.c_str());
- Api::install(requestInst);
-
- for (auto const &privilege : SM_ALLOWED_PRIVILEGES) {
- int result;
- Api::appHasPrivilege(sm_app_id, privilege.c_str(), 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);
- RUNNER_ASSERT_MSG(result == 0, "Application " << sm_app_id <<
- " should not have access to privilege " << privilege);
- }
-
- InstallRequest requestUninst;
- requestUninst.setAppId(sm_app_id);
- Api::uninstall(requestUninst);
-}
int main(int argc, char *argv[])
{
--- /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.
+ */
+
+// cstdlibg has to be included before attr/xattr
+#include <cstdlib>
+#include <attr/xattr.h>
+#include <fstream>
+#include <memory>
+#include <regex>
+#include <string>
+#include <sys/capability.h>
+#include <sys/smack.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cynara-admin.h>
+
+#include <app_install_helper.h>
+#include <cynara_test_admin.h>
+#include <dpl/test/test_runner.h>
+#include <message_pipe.h>
+#include <policy_configuration.h>
+#include <scoped_installer.h>
+#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 <temp_test_user.h>
+#include <tests_common.h>
+#include <tzplatform.h>
+#include <uds.h>
+
+using namespace SecurityManagerTest;
+
+namespace {
+std::vector<std::string> merge(const std::vector<std::string> &one, const std::vector<std::string> &two) {
+ std::vector<std::string> sum;
+ sum.reserve(one.size() + two.size());
+ sum.insert(sum.end(), one.begin(), one.end());
+ sum.insert(sum.end(), two.begin(), two.end());
+ return sum;
+}
+}
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER)
+
+RUNNER_TEST(security_manager_01a_app_double_install_double_uninstall)
+{
+ AppInstallHelper app("sm_test_01a_app");
+ {
+ ScopedInstaller appInstall(app);
+ check_app_after_install(app.getAppId(), app.getPkgId());
+ {
+ ScopedInstaller appInstall2(app);
+ check_app_after_install(app.getAppId(), app.getPkgId());
+ }
+ check_app_after_uninstall(app.getAppId(), app.getPkgId());
+ }
+}
+
+RUNNER_TEST(security_manager_01b_app_double_install_wrong_pkg_id)
+{
+ AppInstallHelper app("sm_test_01b");
+ {
+ ScopedInstaller appInstall(app);
+
+ InstallRequest requestInst2;
+ requestInst2.setAppId(app.getAppId());
+ requestInst2.setPkgId(app.getPkgId() + "_wrong");
+
+ Api::install(requestInst2, SECURITY_MANAGER_ERROR_INPUT_PARAM);
+
+ check_app_after_install(app.getAppId(), app.getPkgId());
+ }
+ check_app_after_uninstall(app.getAppId(), app.getPkgId());
+}
+
+RUNNER_TEST(security_manager_01c_app_uninstall_wrong_pkg_id)
+{
+ AppInstallHelper app("sm_test_01c");
+ ScopedInstaller appInstall(app);
+
+ check_app_after_install(app.getAppId(), app.getPkgId());
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(app.getAppId());
+ requestUninst.setPkgId(app.getPkgId() + "_wrong_pkg_id");
+
+ Api::uninstall(requestUninst, SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT);
+}
+
+/*
+ * This test uses files installed with security-tests package
+ */
+RUNNER_TEST(security_manager_01d_app_install_complicated_dir_tree)
+{
+ const std::string appId = "sm_test_01d_app_id_full";
+ const std::string pkgId = "sm_test_01d_pkg_id_full";
+
+ const std::string rootDir = TzPlatformConfig::globalAppDir() + "/" + pkgId + "/";
+ const std::string privateDir = rootDir + "app_dir/";
+ const std::string privateRODir = rootDir + "app_dir_ro/";
+ const std::string publicRODir = rootDir + "app_dir_public_ro/";
+ const std::string sharedRODir = rootDir + "app_dir_rw_others_ro/";
+
+ int result = nftw(rootDir.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
+ RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << rootDir);
+
+ InstallRequest requestInst;
+ requestInst.setAppId(appId);
+ requestInst.setPkgId(pkgId);
+ requestInst.addPath(privateDir, SECURITY_MANAGER_PATH_RW);
+ requestInst.addPath(privateRODir, SECURITY_MANAGER_PATH_RO);
+ requestInst.addPath(publicRODir, SECURITY_MANAGER_PATH_PUBLIC_RO);
+ requestInst.addPath(sharedRODir, SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
+ Api::install(requestInst);
+
+ std::unique_ptr<InstallRequest, std::function<void(InstallRequest*)>> appCleanup(&requestInst,
+ [](InstallRequest *req) {
+ Api::uninstall(*req);
+ });
+
+ check_path(privateDir, generatePathRWLabel(pkgId));
+ check_path(privateRODir, generatePathROLabel(pkgId), false);
+ check_path(publicRODir, getPublicPathLabel());
+ check_path(sharedRODir, generatePathSharedROLabel(pkgId));
+}
+
+RUNNER_TEST(security_manager_02_app_install_uninstall_full)
+{
+ PolicyConfiguration policy;
+ PolicyConfiguration::PrivGroupMap privGroupMap = policy.getPrivGroupMap();
+
+ RUNNER_ASSERT_MSG(privGroupMap.size() >= 4, "Failed to get policy of a suitable size");
+
+ privileges_t allowedPrivs;
+ privileges_t someDeniedPrivs;
+
+ int counter = 0;
+ for (auto const &it: privGroupMap) {
+ if (counter < 2)
+ allowedPrivs.push_back(it.first);
+ else if (counter < 4)
+ someDeniedPrivs.push_back(it.first);
+ else
+ break;
+ ++counter;
+ }
+
+ AppInstallHelper app("sm_test_02");
+ app.createPrivateDir();
+ app.createPrivateRODir();
+ app.createPublicDir();
+ app.createSharedRODir();
+ app.addPrivileges(allowedPrivs);
+ {
+ ScopedInstaller appInstall(app);
+
+ check_app_after_install(app.getAppId(), app.getPkgId(),
+ app.getPrivileges(), someDeniedPrivs);
+
+ check_path(app.getPrivateDir(), generatePathRWLabel(app.getPkgId()));
+ check_path(app.getPrivateRODir(), generatePathROLabel(app.getPkgId()), false);
+ check_path(app.getPublicDir(), getPublicPathLabel());
+ check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId()));
+ }
+
+ check_app_after_uninstall(app.getAppId(), app.getPkgId(), app.getPrivileges());
+}
+
+RUNNER_CHILD_TEST_SMACK(security_manager_03_set_label_from_appid)
+{
+ std::string expectedSockLabel = "labelExpectedOnlyFromSocket";
+
+ AppInstallHelper app("sm_test_03a");
+ std::string expectedProcLabel = generateProcessLabel(app.getAppId(), app.getPkgId());
+
+ const auto sockaddr = UDSHelpers::makeAbstractAddress("sm_test_03a.socket");
+ int sock = UDSHelpers::createServer(&sockaddr);
+ SockUniquePtr sockPtr(&sock);
+
+ //Set socket label to something different than expeced process label
+ int result = smack_set_label_for_file(*sockPtr, XATTR_NAME_SMACKIPIN, expectedSockLabel.c_str());
+ RUNNER_ASSERT_ERRNO_MSG(result == 0,
+ "Can't set socket label. Result: " << result);
+ result = smack_set_label_for_file(*sockPtr, XATTR_NAME_SMACKIPOUT, expectedSockLabel.c_str());
+ RUNNER_ASSERT_ERRNO_MSG(result == 0,
+ "Can't set socket label. Result: " << result);
+
+ ScopedInstaller appInstall(app);
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+ if (pid == 0) { // child
+ Api::setProcessLabel(app.getAppId());
+
+ char *label = nullptr;
+ CStringPtr labelPtr;
+ 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 = expectedSockLabel.compare(label);
+ RUNNER_ASSERT_MSG(result == 0, "Socket label is incorrect. Expected: " <<
+ expectedProcLabel << " 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 = expectedSockLabel.compare(label);
+ RUNNER_ASSERT_MSG(result == 0, "Socket label is incorrect. Expected: " <<
+ expectedProcLabel << " 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 = expectedProcLabel.compare(label);
+ RUNNER_ASSERT_MSG(result == 0,
+ " Process label is incorrect. Expected: \"" << expectedProcLabel <<
+ "\" Actual: \"" << label << "\"");
+ } else { // parent
+ waitPid(pid);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_04a_app_install_uninstall_by_app_user_for_self)
+{
+ const std::vector<std::string> allowedPrivs = {
+ "http://tizen.org/privilege/bluetooth",
+ "http://tizen.org/privilege/power"
+ };
+ const std::vector<std::string> someDeniedPrivs = {
+ "http://tizen.org/privilege/display",
+ "http://tizen.org/privilege/nfc"
+ };
+
+ TemporaryTestUser testUser("sm_test_04a_user_name", GUM_USERTYPE_NORMAL);
+ testUser.create();
+
+ AppInstallHelper app("sm_test_04a", testUser.getUid());
+ app.addPrivileges(allowedPrivs);
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+ {
+ ScopedInstaller appInstall(app, false);
+ check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
+ allowedPrivs, someDeniedPrivs);
+ }
+ check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
+ {}, merge(allowedPrivs, someDeniedPrivs));
+}
+
+RUNNER_CHILD_TEST(security_manager_04b_app_install_by_root_for_app_user) {
+ const std::vector<std::string> allowedPrivs = {
+ "http://tizen.org/privilege/internet",
+ "http://tizen.org/privilege/led"
+ };
+ const std::vector<std::string> someDeniedPrivs = {
+ "http://tizen.org/privilege/location",
+ "http://tizen.org/privilege/notification"
+ };
+
+ TemporaryTestUser testUser("sm_test_04b_user_name", GUM_USERTYPE_NORMAL);
+ testUser.create();
+
+ AppInstallHelper app("sm_test_04b", testUser.getUid());
+ app.addPrivileges(allowedPrivs);
+
+ {
+ ScopedInstaller appInstall(app);
+ check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
+ allowedPrivs, someDeniedPrivs);
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+ }
+ check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
+ {}, merge(allowedPrivs, someDeniedPrivs));
+}
+
+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_TEST(security_manager_06_install_app_offline)
+{
+ ServiceManager("security-manager.service").stopService();
+
+ ServiceManager serviceManager("security-manager.socket");
+ serviceManager.stopService();
+
+ AppInstallHelper app("sm_test_06");
+ ScopedInstaller appInstall(app);
+ // TODO - check if app is installed properly
+ // start service before uninstall, offline mode doesn't support uninstall
+ serviceManager.startService();
+ appInstall.uninstallApp();
+ // TODO - check if app is uninstalled properly
+}
+
+RUNNER_TEST(security_manager_07a_user_add_app_install)
+{
+ const std::vector<std::string> allowedPrivs = {
+ "http://tizen.org/privilege/internet",
+ "http://tizen.org/privilege/led"
+ };
+ const std::vector<std::string> someDeniedPrivs = {
+ "http://tizen.org/privilege/location",
+ "http://tizen.org/privilege/notification"
+ };
+
+ TemporaryTestUser testUser("sm_test_07a_user_name", GUM_USERTYPE_NORMAL);
+ testUser.create();
+
+ AppInstallHelper app("sm_test_07a", testUser.getUid());
+ app.addPrivileges(allowedPrivs);
+
+ InstallRequest req;
+ req.setAppId(app.getAppId());
+ req.setPkgId(app.getPkgId());
+ req.setUid(app.getUID());
+ for (const auto &priv: app.getPrivileges()) {
+ req.addPrivilege(priv);
+ }
+ Api::install(req);
+
+ check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
+ allowedPrivs, someDeniedPrivs);
+
+ testUser.remove();
+
+ check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
+ {}, merge(allowedPrivs, someDeniedPrivs));
+
+ // TODO - check if app is uninstalled
+}
+
+RUNNER_TEST(security_manager_07b_user_add_offline)
+{
+ ServiceManager("security-manager.service").stopService();
+
+ ServiceManager serviceManager("security-manager.socket");
+ serviceManager.stopService();
+
+ TemporaryTestUser testUser("sm_test_07b_user_name", GUM_USERTYPE_NORMAL, true);
+ testUser.create();
+
+ AppInstallHelper app("sm_test_07b", testUser.getUid());
+ ScopedInstaller appInstall(app);
+
+ serviceManager.startService();
+ check_app_after_install(app.getAppId(), app.getPkgId());
+
+ testUser.remove();
+ check_app_after_uninstall(app.getAppId(), app.getPkgId());
+}
+
+RUNNER_TEST(security_manager_08_user_double_add_double_remove)
+{
+ std::vector<std::string> somePrivs = {
+ "http://tizen.org/privilege/internet", "http://tizen.org/privilege/led",
+ "http://tizen.org/privilege/location", "http://tizen.org/privilege/notification"
+ };
+ // gumd
+ TemporaryTestUser testUser("sm_test_08_user_name", GUM_USERTYPE_NORMAL);
+ testUser.create();
+
+ // security-manager
+ UserRequest addUserRequest;
+ addUserRequest.setUid(testUser.getUid());
+ addUserRequest.setUserType(SM_USER_TYPE_NORMAL);
+ Api::addUser(addUserRequest);
+
+ AppInstallHelper app("sm_test_08", testUser.getUid());
+ ScopedInstaller appInstall(app);
+
+ check_app_after_install(app.getAppId(), app.getPkgId());
+ check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(), {}, somePrivs);
+
+ // gumd
+ testUser.remove();
+
+ check_app_after_uninstall(app.getAppId(), app.getPkgId());
+ check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(), {}, somePrivs);
+
+ // security-manager
+ UserRequest deleteUserRequest;
+ deleteUserRequest.setUid(testUser.getUid());
+ Api::deleteUser(deleteUserRequest);
+}
+
+RUNNER_TEST(security_manager_09_app_install_constraint_check)
+{
+ auto install = [](const TemporaryTestUser& user,
+ const char *pkgId,
+ const char *appId,
+ const char *version,
+ const char *author,
+ bool isHybrid,
+ enum lib_retcode expected,
+ bool uninstall = true)
+ {
+ InstallRequest request;
+ request.setAppId(appId);
+ request.setPkgId(pkgId);
+ request.setAppTizenVersion(version);
+ request.setAuthorId(author);
+ request.setUid(user.getUid());
+ if (isHybrid)
+ request.setHybrid();
+ Api::install(request, expected);
+
+ if(expected == SECURITY_MANAGER_SUCCESS && uninstall) {
+ Api::uninstall(request);
+ }
+ };
+
+ std::vector<TemporaryTestUser> users = {
+ {"sm_test_09_user_name_0", GUM_USERTYPE_NORMAL, false},
+ {"sm_test_09_user_name_1", GUM_USERTYPE_NORMAL, false}
+ };
+
+ for(auto& gu : users)
+ gu.create();
+
+ const char *const pkgId[] = {"sm_test_09_pkg_id_0", "sm_test_09_pkg_id_1"};
+ const char *const appId[] = {"sm_test_09_app_id_0", "sm_test_09_app_id_1"};
+ const char *const version[] = {"sm_test_09_version_0", "sm_test_09_version_1"};
+ const char *const author[] = {"sm_test_09_author_0", "sm_test_09_author_1"};
+ bool hybrid[] = {false, true};
+
+ // uid_0, pkg_0, app_0, version_0, author_0, not hybrid
+ install(users[0], pkgId[0], appId[0], version[0], author[0], hybrid[0], SECURITY_MANAGER_SUCCESS, false);
+ // uid_1, pkg_0, app_0, version_0, author_0, not hybrid -> ok (different uid)
+ install(users[1], pkgId[0], appId[0], version[0], author[0], hybrid[0], SECURITY_MANAGER_SUCCESS);
+ // uid_0, pkg_0, app_0, version_0, author_0, hybrid -> fail (different hybrid setting)
+ install(users[0], pkgId[0], appId[0], version[0], author[0], hybrid[1], SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ // uid_0, pkg_0, app_1, version_0, author_0, hybrid -> fail (different hybrid setting)
+ install(users[0], pkgId[0], appId[1], version[0], author[0], hybrid[1], SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ // uid_1, pkg_0, app_0, version_0, author_0, hybrid -> fail (different hybrid setting)
+ install(users[1], pkgId[0], appId[0], version[0], author[0], hybrid[1], SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ // uid_1, pkg_0, app_0, version_0, author_1, not hybrid -> fail (author of app_0 must be the same)
+ install(users[1], pkgId[0], appId[0], version[0], author[1], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ // uid_1, pkg_0, app_0, version_1, author_0, not hybrid -> ok (version upgrade)
+ install(users[1], pkgId[0], appId[0], version[1], author[0], hybrid[0], SECURITY_MANAGER_SUCCESS);
+ // uid_1, pkg_1, app_0, version_0, author_0, not hybrid -> fail (pkg of app_0 must be the same)
+ install(users[1], pkgId[1], appId[0], version[0], author[0], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ // uid_0, pkg_0, app_0, version_0, author_0, not hybrid -> ok (the same app again)
+ install(users[0], pkgId[0], appId[0], version[0], author[0], hybrid[0], SECURITY_MANAGER_SUCCESS, false);
+ // uid_0, pkg_1, app_0, version_0, author_0, not hybrid -> fail (app_name + uid must be unique)
+ install(users[0], pkgId[1], appId[0], version[0], author[0], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ // uid_0, pkg_0, app_0, version_0, author_1, not hybrid -> fail (app_name + uid must be unique)
+ install(users[0], pkgId[0], appId[0], version[0], author[1], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
+RUNNER_CHILD_TEST(security_manager_10_app_has_privilege)
+{
+ const std::vector<std::string> allowedPrivs = {
+ "http://tizen.org/privilege/wifidirect",
+ "http://tizen.org/privilege/telephony"
+ };
+ const std::vector<std::string> someDeniedPrivs = {
+ "http://tizen.org/privilege/vpnservice",
+ "http://tizen.org/privilege/notification"
+ };
+ AppInstallHelper app("sm_test_10");
+ app.addPrivileges(allowedPrivs);
+ ScopedInstaller appInstall(app);
+
+ sm_app_has_privileges(app, allowedPrivs, 1);
+ // FIXME - all other existing privileges should be checked
+ sm_app_has_privileges(app, someDeniedPrivs, 0);
+}
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_POLICY)
+
+RUNNER_TEST(security_manager_20_user_cynara_policy)
+{
+ // FIXME - whitebox - cynara
+ const char *const MAIN_BUCKET = "MAIN";
+ const char *const MANIFESTS_BUCKET = "MANIFESTS";
+ const char *const ADMIN_BUCKET = "ADMIN";
+ const char *const USER_TYPE_NORMAL_BUCKET = "USER_TYPE_NORMAL";
+ CynaraTestAdmin::Admin admin;
+
+ TemporaryTestUser user("sm_test_20_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+ std::string uid_string = user.getUidString();
+
+ CynaraTestAdmin::CynaraPoliciesContainer nonemptyContainer;
+ nonemptyContainer.add(MAIN_BUCKET,CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, CYNARA_ADMIN_BUCKET, USER_TYPE_NORMAL_BUCKET);
+ admin.listPolicies(MAIN_BUCKET, CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, nonemptyContainer,CYNARA_API_SUCCESS);
+
+ user.remove();
+ CynaraTestAdmin::CynaraPoliciesContainer emptyContainer;
+
+ admin.listPolicies(MAIN_BUCKET, CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, emptyContainer, CYNARA_API_SUCCESS);
+ admin.listPolicies(MANIFESTS_BUCKET, CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, emptyContainer, CYNARA_API_SUCCESS);
+ admin.listPolicies(CYNARA_ADMIN_DEFAULT_BUCKET, CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, emptyContainer, CYNARA_API_SUCCESS);
+ admin.listPolicies(ADMIN_BUCKET, CYNARA_ADMIN_WILDCARD, uid_string.c_str(), CYNARA_ADMIN_WILDCARD, emptyContainer, CYNARA_API_SUCCESS);
+}
+
+RUNNER_CHILD_TEST(security_manager_21_security_manager_admin_deny_user_priv)
+{
+ const privileges_t adminRequiredPrivs = {
+ "http://tizen.org/privilege/notexist",
+ "http://tizen.org/privilege/internal/usermanagement"
+ };
+ const privileges_t manifestPrivs = {
+ "http://tizen.org/privilege/internet",
+ "http://tizen.org/privilege/datasharing"
+ };
+ const privileges_t allowedPrivsAfterChange = {"http://tizen.org/privilege/datasharing"};
+ const privileges_t deniedPrivsAfterChange = {"http://tizen.org/privilege/internet"};
+ TemporaryTestUser adminUser("sm_test_21_admin_user_name", GUM_USERTYPE_ADMIN, false);
+ TemporaryTestUser normalUser("sm_test_21_normal_user_name", GUM_USERTYPE_NORMAL, false);
+
+ adminUser.create();
+ normalUser.create();
+ std::string childUidStr = normalUser.getUidString();
+
+ AppInstallHelper adminApp("sm_test_21_admin", adminUser.getUid());
+ adminApp.addPrivileges(adminRequiredPrivs);
+ ScopedInstaller adminAppInstall(adminApp);
+
+ AppInstallHelper normalApp("sm_test_21_normal", normalUser.getUid());
+ normalApp.addPrivileges(manifestPrivs);
+ ScopedInstaller normalAppInstall(normalApp);
+
+ check_app_permissions(normalApp.getAppId(), normalApp.getPkgId(), childUidStr,
+ manifestPrivs, {});
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
+ if (pid != 0) { //parent process
+ waitPid(pid);
+ check_app_permissions(normalApp.getAppId(), normalApp.getPkgId(), childUidStr,
+ allowedPrivsAfterChange, deniedPrivsAfterChange);
+ } else {
+ Api::setProcessLabel(adminApp.getAppId());
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(adminUser.getUid(),adminUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ PolicyRequest addPolicyReq;
+ for (auto &deniedPriv : deniedPrivsAfterChange) {
+ PolicyEntry entry(SECURITY_MANAGER_ANY, normalUser.getUidString(), deniedPriv);
+ entry.setMaxLevel("Deny");
+ addPolicyReq.addEntry(entry);
+ }
+ Api::sendPolicy(addPolicyReq);
+ exit(0);
+ }
+}
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_CMD)
+
+RUNNER_TEST(security_manager_22_security_manager_cmd_install)
+{
+ int ret;
+ const int SUCCESS = 0;
+ const int FAILURE = 256;
+ const std::string app_id = "sm_test_22_app_id";
+ const std::string pkg_id = "sm_test_22_pkg_id";
+ const std::string username("sm_test_22_user_name");
+
+ TemporaryTestUser user(username, GUM_USERTYPE_NORMAL);
+ user.create();
+
+ 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=" + user.getUidString();
+
+ mktreeSafe(path1.c_str(), 0);
+ mktreeSafe(path2.c_str(), 0);
+
+ const std::string installcmd = "security-manager-cmd --install " + appopt + pkgopt + uidopt;
+
+ struct operation {
+ std::string command;
+ int expected_result;
+ };
+ std::vector<struct operation> operations = {
+ {"security-manager-cmd", FAILURE},//no option
+ {"security-manager-cmd --blah", FAILURE},//blah option is not known
+ {"security-manager-cmd --help", SUCCESS},
+ {"security-manager-cmd --install", FAILURE},//no params
+ {"security-manager-cmd -i", FAILURE},//no params
+ {"security-manager-cmd --i --app=app_id_10 --pkg=pkg_id_10", FAILURE},//no uid
+ {installcmd, SUCCESS},
+ {"security-manager-cmd -i -a" + app_id + " -g" + pkg_id + uidopt, SUCCESS},
+ {installcmd + " --path " + path1 + " rw", SUCCESS},
+ {installcmd + " --path " + path1, FAILURE},//no path type
+ {installcmd + " --path " + path1 + " rw" + " --path " + path2 + " ro", SUCCESS},
+ {installcmd + " --path " + path1 + " prie" + " --path " + path2 + " ro", FAILURE},//wrong path type
+ {installcmd + " --path " + path1 + " rw" + " --privilege somepriv --privilege somepriv2" , SUCCESS},
+ };
+
+ for (auto &op : operations) {
+ ret = system((op.command + " 1>/dev/null 2>&1").c_str());
+ RUNNER_ASSERT_MSG(ret == op.expected_result,
+ "Unexpected result for command '" << op.command <<"': "
+ << ret << " Expected was: "<< op.expected_result);
+ }
+}
+
+RUNNER_TEST(security_manager_23_security_manager_cmd_users)
+{
+ const int SUCCESS = 0;
+ const int FAILURE = 256;
+ TemporaryTestUser user("sm_test_23_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+ const std::string uidopt = " --uid=" + user.getUidString();
+
+ struct operation {
+ std::string command;
+ int expected_result;
+ };
+ std::vector<struct operation> operations = {
+ {"security-manager-cmd --manage-users=remove", FAILURE},//no params
+ {"security-manager-cmd -m", FAILURE},//no params
+ {"security-manager-cmd -mr", FAILURE},//no uid
+ {"security-manager-cmd -mr --uid" + uidopt, FAILURE},//no uid
+ {"security-manager-cmd -mr --sdfj" + uidopt, FAILURE},//sdfj?
+ {"security-manager-cmd --msdf -u2004" , FAILURE},//sdf?
+ {"security-manager-cmd -mr" + uidopt, SUCCESS},//ok, removed
+ {"security-manager-cmd -mr --blah" + uidopt, FAILURE},//blah
+ {"security-manager-cmd -ma" + uidopt, SUCCESS},//ok, added
+ {"security-manager-cmd -ma --usertype=normal" + uidopt, SUCCESS},//ok, added
+ {"security-manager-cmd -ma --usertype=mal" + uidopt, FAILURE},//ok, added
+ };
+
+ for (auto &op : operations) {
+ int ret = system((op.command + " 1>/dev/null 2>&1").c_str());
+ RUNNER_ASSERT_MSG(ret == op.expected_result,
+ "Unexpected result for command '" << op.command <<"': "
+ << ret << " Expected was: "<< op.expected_result);
+ }
+}
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_GROUPS)
+
+RUNNER_TEST(security_manager_24_groups_get)
+{
+ PolicyConfiguration pc;
+ char ** c_groups;
+ size_t count = 0;
+
+ Api::getSecurityManagerGroups(&c_groups, &count);
+ std::unique_ptr<char *, std::function<void(char **)>> groupsPtr(c_groups, [count] (char ** groups) {
+ security_manager_groups_free(groups, count);
+ });
+
+ auto policyGroups = pc.getGroup();
+ RUNNER_ASSERT_MSG(count == policyGroups.size(), "security_manager_groups_get should set count to: "
+ << policyGroups.size() << " but count is: " << count);
+
+ for (const auto &group : policyGroups) {
+ bool found = false;
+ for (size_t i = 0; i < count; ++i) {
+ if (group == c_groups[i]) {
+ found = true;
+ break;
+ }
+ }
+ RUNNER_ASSERT_MSG(found, "PrivilegeGroup: " << group << " was not found");
+ }
+}
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_INSTALL_TYPE)
+
+RUNNER_TEST(security_manager_25a_global_user_set_install_type_global)
+{
+ AppInstallHelper app("sm_test_25a");
+ app.setInstallType(SM_APP_INSTALL_GLOBAL);
+ {
+ ScopedInstaller appInstall(app);
+
+ check_app_after_install(app.getAppId(), app.getPkgId());
+ }
+
+ // Check records in the security-manager database
+ check_app_after_uninstall(app.getAppId(), app.getPkgId());
+}
+
+RUNNER_TEST(security_manager_25b_global_user_set_install_type_local)
+{
+ AppInstallHelper app("sm_test_25b");
+
+ InstallRequest requestInst;
+ requestInst.setAppId(app.getAppId());
+ requestInst.setPkgId(app.getPkgId());
+ requestInst.setInstallType(SM_APP_INSTALL_LOCAL);
+
+ Api::install(requestInst, (lib_retcode)SECURITY_MANAGER_ERROR_SERVER_ERROR);
+}
+
+RUNNER_TEST(security_manager_25c_global_user_set_install_type_preloaded)
+{
+ AppInstallHelper app("sm_test_25c");
+ app.setInstallType(SM_APP_INSTALL_PRELOADED);
+ {
+ ScopedInstaller appInstall(app);
+ check_app_after_install(app.getAppId(), app.getPkgId());
+ }
+ check_app_after_uninstall(app.getAppId(), app.getPkgId());
+}
+
+RUNNER_TEST(security_manager_25d_local_user_set_install_type_invalid)
+{
+ InstallRequest requestPrivateUser;
+ requestPrivateUser.setInstallType((app_install_type)0, (lib_retcode)SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ requestPrivateUser.setInstallType((app_install_type)22, (lib_retcode)SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
+/*
+ * It is possible for local user to install global application but one needs app_install privileges
+ * By default only global user or root can install global apps (or "User", "System", "System::Privileged"...)
+ */
+RUNNER_CHILD_TEST(security_manager_25e_unprivileged_install_type_global)
+{
+ TemporaryTestUser testUser("sm_test_25e_user_name", GUM_USERTYPE_NORMAL);
+ testUser.create();
+
+ AppInstallHelper app("sm_test_25e");
+
+ change_label("_");
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ InstallRequest invalidReq;
+ invalidReq.setAppId(app.getAppId());
+ invalidReq.setPkgId(app.getPkgId());
+ invalidReq.setInstallType(SM_APP_INSTALL_GLOBAL);
+
+ Api::install(invalidReq, (lib_retcode)SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED);
+}
+
+RUNNER_CHILD_TEST(security_manager_25f_unprivileged_install_type_preloaded)
+{
+ TemporaryTestUser testUser("sm_test_25f_user_name", GUM_USERTYPE_NORMAL);
+ testUser.create();
+
+ AppInstallHelper app("sm_test_25f");
+
+ change_label("_");
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+ InstallRequest invalidReq;
+ invalidReq.setAppId(app.getAppId());
+ invalidReq.setPkgId(app.getPkgId());
+ invalidReq.setInstallType(SM_APP_INSTALL_PRELOADED);
+ Api::install(invalidReq, (lib_retcode)SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED);
+}
+
+
+RUNNER_CHILD_TEST(security_manager_25g_local_user_set_install_type_local)
+{
+ std::vector<std::string> allowedPrivs = {
+ "http://tizen.org/privilege/volume.set",
+ "http://tizen.org/privilege/systemmonitor",
+ "http://tizen.org/privilege/internet"
+ };
+ std::vector<std::string> someDeniedPrivs = {
+ "http://tizen.org/privilege/push",
+ "http://tizen.org/privilege/power",
+ "http://tizen.org/privilege/notification"
+ };
+
+ TemporaryTestUser testUser("sm_test_25g_user_name", GUM_USERTYPE_NORMAL);
+ testUser.create();
+
+ AppInstallHelper app("sm_test_25g", testUser.getUid());
+ app.createPrivateDir();
+ app.setInstallType(SM_APP_INSTALL_LOCAL);
+ app.addPrivileges(allowedPrivs);
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+ {
+ ScopedInstaller appInstall(app);
+ check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
+ allowedPrivs, someDeniedPrivs);
+
+ }
+ check_app_permissions(app.getAppId(), app.getPkgId(), testUser.getUidString(),
+ {}, merge(allowedPrivs, someDeniedPrivs));
+ // TODO - check if app is properly uninstalled
+}
+
+RUNNER_CHILD_TEST(security_manager_25h_local_path_global_install)
+{
+ TemporaryTestUser testUser("sm_test_25h_user_name", GUM_USERTYPE_NORMAL);
+ testUser.create();
+
+ AppInstallHelper app("sm_test_25h", testUser.getUid());
+ app.createPrivateDir();
+
+ InstallRequest invalidReq;
+ invalidReq.setAppId(app.getAppId());
+ invalidReq.setPkgId(app.getPkgId());
+ invalidReq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+ invalidReq.setInstallType(SM_APP_INSTALL_GLOBAL);
+ Api::install(invalidReq, (lib_retcode)SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED);
+}
+
+RUNNER_CHILD_TEST(security_manager_25i_local_path_preloaded_install)
+{
+ TemporaryTestUser testUser("sm_test_25i_user_name", GUM_USERTYPE_NORMAL);
+ testUser.create();
+
+ AppInstallHelper app("sm_test_25i", testUser.getUid());
+ app.createPrivateDir();
+
+ InstallRequest invalidReq;
+ invalidReq.setAppId(app.getAppId());
+ invalidReq.setPkgId(app.getPkgId());
+ invalidReq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+ invalidReq.setInstallType(SM_APP_INSTALL_PRELOADED);
+ Api::install(invalidReq, (lib_retcode)SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED);
+}
+
+RUNNER_CHILD_TEST(security_manager_25j_global_path_local_install)
+{
+ TemporaryTestUser testUser("sm_test_25j_user_name", GUM_USERTYPE_NORMAL);
+ testUser.create();
+
+ AppInstallHelper appLocal("sm_test_25j", testUser.getUid());
+
+ AppInstallHelper appGlobal("sm_test_25");
+ appGlobal.createPrivateDir();
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ InstallRequest invalidReq;
+ invalidReq.setAppId(appLocal.getAppId());
+ invalidReq.setPkgId(appLocal.getPkgId());
+ invalidReq.addPath(appGlobal.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+ invalidReq.setInstallType(SM_APP_INSTALL_LOCAL);
+
+ Api::install(invalidReq, SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED);
+}
+
--- /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 <functional>
+#include <string>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <access_provider.h>
+#include <cynara_helpers_creds.h>
+#include <dpl/test/test_runner.h>
+#include <memory.h>
+#include <passwd_access.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>
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_CREDENTIAL_API)
+
+using namespace SecurityManagerTest;
+
+class ProcessCredentials {
+public:
+ ProcessCredentials(const std::string &smackLabel) : m_label(smackLabel) {}
+
+ const std::string &label(void) const {
+ return m_label;
+ }
+
+ uid_t uid(void) const {
+ return TzPlatformConfig::getGlobalUserId();
+ }
+
+ gid_t gid(void) const {
+ return PasswdAccess::gid("users");
+ }
+
+private:
+ std::string m_label;
+};
+
+void udsServer(SynchronizationPipe &pipe, const struct sockaddr_un &sockaddr,
+ const struct ProcessCredentials &peerCredentials) {
+ SecurityServer::AccessProvider ap(peerCredentials.label());
+ ap.applyAndSwithToUser(peerCredentials.uid(), peerCredentials.gid());
+ pipe.claimChildEp();
+
+ int sock = UDSHelpers::createServer(&sockaddr);
+ SockUniquePtr sockPtr(&sock);
+ pipe.post();
+ int clientSock = UDSHelpers::acceptClient(sock);
+
+ UDSHelpers::waitForDisconnect(clientSock);
+}
+
+typedef std::function<void(int sock, pid_t pid)> SocketAssertionFn;
+
+void clientTestTemplate(SocketAssertionFn assertion, const std::string &scope, const std::string &smackLabel) {
+ const auto sockaddr = UDSHelpers::makeAbstractAddress("test_sm_" + scope + ".socket");
+ const ProcessCredentials peerCredentials(smackLabel);
+
+ SynchronizationPipe pipe;
+
+ pid_t pid = runInChild(std::bind(udsServer, std::ref(pipe), std::cref(sockaddr),
+ std::cref(peerCredentials)));
+
+ pipe.claimParentEp();
+ pipe.wait();
+ int sock = UDSHelpers::createClient(&sockaddr);
+ SockUniquePtr sockPtr(&sock);
+
+ assertion(sock, pid);
+}
+
+void test_51a_get_id_by_socket(bool isHybrid) {
+ const char *const sm_app_id = "sm_test_51a_app";
+ const char *const sm_pkg_id = "sm_test_51a_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+ if (isHybrid)
+ requestInst.setHybrid();
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id, isHybrid);
+
+ clientTestTemplate([&] (int sock, pid_t) {
+ std::string rcvPkgId, rcvAppId;
+ Api::getPkgIdBySocket(sock, &rcvPkgId, &rcvAppId);
+ RUNNER_ASSERT_MSG(rcvPkgId == sm_pkg_id, "pkgIds don't match ret = " << rcvPkgId
+ << "; expected = " << sm_pkg_id);
+ if (isHybrid)
+ RUNNER_ASSERT_MSG(rcvAppId == sm_app_id, "appIds don't match ret = " << rcvAppId
+ << "; expected = " << sm_app_id);
+ else
+ RUNNER_ASSERT_MSG(rcvAppId.empty(), "magically acquired appId from nonhybrid app");
+ }, "tcsm27a", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_51a_get_id_by_socket_hybrid)
+{
+ test_51a_get_id_by_socket(true);
+}
+
+RUNNER_CHILD_TEST(security_manager_51a_get_id_by_socket_nonhybrid)
+{
+ test_51a_get_id_by_socket(false);
+}
+
+RUNNER_CHILD_TEST(security_manager_51b_get_id_by_socket_bad_fd)
+{
+ const char *const sm_app_id = "sm_test_51b_app";
+ const char *const sm_pkg_id = "sm_test_51b_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id);
+
+ clientTestTemplate([&] (int sock, pid_t) {
+ std::string rcvPkgId, rcvAppId;
+ Api::getPkgIdBySocket(sock + 1, &rcvPkgId, &rcvAppId, SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT);
+ }, "tcsm27b", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_51c_get_id_by_socket_only_pkg)
+{
+ const char *const sm_app_id = "sm_test_51c_app";
+ const char *const sm_pkg_id = "sm_test_51c_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id);
+
+ clientTestTemplate([&] (int sock, pid_t) {
+ std::string rcvPkgId;
+ Api::getPkgIdBySocket(sock, &rcvPkgId, nullptr);
+ RUNNER_ASSERT_MSG(rcvPkgId == sm_pkg_id, "pkgIds don't match ret = " << rcvPkgId
+ << "; expected = " << sm_pkg_id);
+ }, "tcsm27c", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_51d_get_id_by_socket_only_appid)
+{
+ const char *const sm_app_id = "sm_test_51d_app";
+ const char *const sm_pkg_id = "sm_test_51d_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+ requestInst.setHybrid();
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id, true);
+
+ clientTestTemplate([&] (int sock, pid_t) {
+ std::string rcvAppId;
+ Api::getPkgIdBySocket(sock, nullptr, &rcvAppId);
+ RUNNER_ASSERT_MSG(rcvAppId == sm_app_id, "appIds don't match ret = " << rcvAppId
+ << "; expected = " << sm_app_id);
+ }, "tcsm27d", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_51e_get_id_by_socket_nulls)
+{
+ const char *const sm_app_id = "sm_test_51e_app";
+ const char *const sm_pkg_id = "sm_test_51e_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id);
+
+ clientTestTemplate([&] (int sock, pid_t) {
+ Api::getPkgIdBySocket(sock, nullptr, nullptr, SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ }, "tcsm27e", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+void test_52a_get_id_by_pid(bool isHybrid) {
+ const char *const sm_app_id = "sm_test_52a_app";
+ const char *const sm_pkg_id = "sm_test_52a_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+ if (isHybrid)
+ requestInst.setHybrid();
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id, isHybrid);
+
+ clientTestTemplate([&] (int, pid_t pid) {
+ std::string rcvPkgId, rcvAppId;
+ Api::getPkgIdByPid(pid, &rcvPkgId, &rcvAppId);
+ RUNNER_ASSERT_MSG(rcvPkgId == sm_pkg_id, "pkgIds don't match ret = " << rcvPkgId
+ << "; expected = " << sm_pkg_id);
+ if (isHybrid)
+ RUNNER_ASSERT_MSG(rcvAppId == sm_app_id, "appIds don't match ret = " << rcvAppId
+ << "; expected = " << sm_app_id);
+ else
+ RUNNER_ASSERT_MSG(rcvAppId.empty(), "magically acquired appId from nonhybrid app");
+ }, "tcsm28a", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_52a_get_id_by_pid_hybrid)
+{
+ test_52a_get_id_by_pid(true);
+}
+
+RUNNER_CHILD_TEST(security_manager_52a_get_id_by_pid_nonhybrid)
+{
+ test_52a_get_id_by_pid(false);
+}
+
+RUNNER_CHILD_TEST(security_manager_52b_get_id_by_pid_bad_fd)
+{
+ const char *const sm_app_id = "sm_test_52b_app";
+ const char *const sm_pkg_id = "sm_test_52b_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id);
+
+ clientTestTemplate([&] (int, pid_t pid) {
+ std::string rcvPkgId, rcvAppId;
+ Api::getPkgIdByPid(pid + 1, &rcvPkgId, &rcvAppId, SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT);
+ }, "tcsm28b", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_52c_get_id_by_pid_only_pkg)
+{
+ const char *const sm_app_id = "sm_test_52c_app";
+ const char *const sm_pkg_id = "sm_test_52c_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id);
+
+ clientTestTemplate([&] (int, pid_t pid) {
+ std::string rcvPkgId;
+ Api::getPkgIdByPid(pid, &rcvPkgId, nullptr);
+ RUNNER_ASSERT_MSG(rcvPkgId == sm_pkg_id, "pkgIds don't match ret = " << rcvPkgId
+ << "; expected = " << sm_pkg_id);
+ }, "tcsm28c", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_52d_get_id_by_pid_only_appid)
+{
+ const char *const sm_app_id = "sm_test_52d_app";
+ const char *const sm_pkg_id = "sm_test_52d_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+ requestInst.setHybrid();
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id, true);
+
+ clientTestTemplate([&] (int, pid_t pid) {
+ std::string rcvAppId;
+ Api::getPkgIdByPid(pid, nullptr, &rcvAppId);
+ RUNNER_ASSERT_MSG(rcvAppId == sm_app_id, "appIds don't match ret = " << rcvAppId
+ << "; expected = " << sm_app_id);
+ }, "tcsm28d", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_52e_get_id_by_pid_nulls)
+{
+ const char *const sm_app_id = "sm_test_52e_app";
+ const char *const sm_pkg_id = "sm_test_52e_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id);
+
+ clientTestTemplate([&] (int sock, pid_t) {
+ Api::getPkgIdByPid(sock, nullptr, nullptr, SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ }, "tcsm28e", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+void test_53a_get_id_by_cynara_client(bool isHybrid) {
+ const char *const sm_app_id = "sm_test_53a_app";
+ const char *const sm_pkg_id = "sm_test_53a_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+ if (isHybrid)
+ requestInst.setHybrid();
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id, isHybrid);
+
+ clientTestTemplate([&] (int sock, pid_t) {
+ std::string rcvPkgId, rcvAppId;
+ CStringPtr cynaraClient(CynaraHelperCredentials::socketGetClient(sock, CLIENT_METHOD_SMACK));
+ RUNNER_ASSERT_MSG(cynaraClient, "Cynara client from socket returned NULL");
+ Api::getPkgIdByCynaraClient(cynaraClient.get(), &rcvPkgId, &rcvAppId);
+ RUNNER_ASSERT_MSG(rcvPkgId == sm_pkg_id, "pkgIds don't match ret = " << rcvPkgId
+ << "; expected = " << sm_pkg_id);
+ if (isHybrid)
+ RUNNER_ASSERT_MSG(rcvAppId == sm_app_id, "appIds don't match ret = " << rcvAppId
+ << "; expected = " << sm_app_id);
+ }, "tcsmc53a", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_53a_get_id_by_cynara_client_hybrid)
+{
+ test_53a_get_id_by_cynara_client(true);
+}
+
+RUNNER_CHILD_TEST(security_manager_53a_get_id_by_cynara_client_nonhybrid)
+{
+ test_53a_get_id_by_cynara_client(false);
+}
+
+RUNNER_CHILD_TEST(security_manager_53b_get_id_by_cynara_client_wrong_client)
+{
+
+ std::string rcvPkgId, rcvAppId;
+ Api::getPkgIdByCynaraClient("NotAnApp", &rcvPkgId, &rcvAppId,
+ SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT);
+}
+
+RUNNER_CHILD_TEST(security_manager_53c_get_id_by_cynara_client_only_pkgid)
+{
+ const char *const sm_app_id = "sm_test_53c_app";
+ const char *const sm_pkg_id = "sm_test_53c_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id);
+
+ clientTestTemplate([&] (int sock, pid_t) {
+ std::string rcvPkgId;
+ CStringPtr cynaraClient(CynaraHelperCredentials::socketGetClient(sock, CLIENT_METHOD_SMACK));
+ RUNNER_ASSERT_MSG(cynaraClient, "Cynara client from socket returned NULL");
+ Api::getPkgIdByCynaraClient(cynaraClient.get(), &rcvPkgId, nullptr);
+ RUNNER_ASSERT_MSG(rcvPkgId == sm_pkg_id, "pkgIds don't match ret = " << rcvPkgId
+ << "; expected = " << sm_pkg_id);
+ }, "tcsm28c", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_53d_get_id_by_cynara_client_only_appid)
+{
+ const char *const sm_app_id = "sm_test_53d_app";
+ const char *const sm_pkg_id = "sm_test_53d_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+ requestInst.setHybrid();
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id, true);
+
+ clientTestTemplate([&] (int sock, pid_t) {
+ std::string rcvAppId;
+ CStringPtr cynaraClient(CynaraHelperCredentials::socketGetClient(sock, CLIENT_METHOD_SMACK));
+ RUNNER_ASSERT_MSG(cynaraClient, "Cynara client from socket returned NULL");
+ Api::getPkgIdByCynaraClient(cynaraClient.get(), nullptr, &rcvAppId);
+ RUNNER_ASSERT_MSG(rcvAppId == sm_app_id, "appIds don't match ret = " << rcvAppId
+ << "; expected = " << sm_app_id);
+ }, "tcsm28d", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
+
+RUNNER_CHILD_TEST(security_manager_53e_get_id_by_cynara_client_nulls)
+{
+ const char *const sm_app_id = "sm_test_53e_app";
+ const char *const sm_pkg_id = "sm_test_53e_pkg";
+
+ InstallRequest requestInst;
+ requestInst.setAppId(sm_app_id);
+ requestInst.setPkgId(sm_pkg_id);
+
+ Api::install(requestInst);
+
+ std::string smackLabel = generateProcessLabel(sm_app_id, sm_pkg_id);
+
+ clientTestTemplate([&] (int sock, pid_t) {
+ std::string rcvAppId;
+ CStringPtr cynaraClient(CynaraHelperCredentials::socketGetClient(sock, CLIENT_METHOD_SMACK));
+ RUNNER_ASSERT_MSG(cynaraClient, "Cynara client from socket returned NULL");
+ Api::getPkgIdByCynaraClient(cynaraClient.get(), nullptr, nullptr, SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ }, "tcsm28e", smackLabel);
+
+ InstallRequest requestUninst;
+ requestUninst.setAppId(sm_app_id);
+
+ Api::uninstall(requestUninst);
+}
--- /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 <poll.h>
+#include <string>
+#include <sys/prctl.h>
+#include <sys/smack.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <app_install_helper.h>
+#include <dpl/test/test_runner.h>
+#include <memory.h>
+#include <message_pipe.h>
+#include <scoped_installer.h>
+#include <sm_api.h>
+#include <sm_commons.h>
+#include <sm_label_monitor.h>
+#include <synchronization_pipe.h>
+#include <temp_test_user.h>
+#include <tests_common.h>
+
+using namespace SecurityManagerTest;
+
+struct UidGidMsg {
+ uid_t uid;
+ gid_t gid;
+};
+
+static void testSetLabelForSelf(const std::string &appName, const std::string &pkgName,
+ bool expected_success)
+{
+ std::string label = generateProcessLabel(appName, pkgName);
+ int result = smack_set_label_for_self(label.c_str());
+ if (expected_success)
+ RUNNER_ASSERT_MSG(result == 0, "smack_set_label_for_self(" << label <<
+ ") failed. Error: " << result);
+ else
+ RUNNER_ASSERT_MSG(result != 0, "smack_set_label_for_self(" << label <<
+ ") wrongly succeeded");
+}
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_LABEL_MONITOR_API)
+
+RUNNER_CHILD_TEST(security_manager_71_app_label_monitor_user_local_global)
+{
+ SynchronizationPipe synchPipe;
+ TemporaryTestUser testUser("sm_test_71_user_name", GUM_USERTYPE_NORMAL, false);
+ testUser.create();
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+ if (pid != 0) { //parent process
+ synchPipe.claimParentEp();
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ synchPipe.wait(); //synchronization point A1
+ AppInstallHelper appLocal("sm_test_71_local", testUser.getUid());
+ appLocal.setInstallType(SM_APP_INSTALL_LOCAL);
+ ScopedInstaller appLocalInstall(appLocal);
+ synchPipe.post(); //synchronization point A2
+
+ synchPipe.wait(); //synchronization point B1
+ AppInstallHelper appGlobal("sm_test_71_global");
+ appLocal.setInstallType(SM_APP_INSTALL_GLOBAL);
+ // This shouldn't be possible with dropped privileges, but uid and gid doesn't suffice
+ // to lose privileges to install applications (tests are running with System::Privileged)
+ ScopedInstaller appGlobalInstall(appGlobal);
+ synchPipe.post(); //synchronization point B2
+
+ synchPipe.wait(); //synchronization point C1
+ appLocalInstall.uninstallApp();
+ synchPipe.post(); //synchronization point C2
+
+ synchPipe.wait(); //synchronization point D1
+ appGlobalInstall.uninstallApp();
+ synchPipe.post(); //synchronization point D2
+
+ waitPid(pid);
+ } else { //child process
+ synchPipe.claimChildEp();
+ setCaps("cap_mac_admin+ep cap_setuid+ep cap_setgid+ep");
+ RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed");
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ setCaps("cap_mac_admin+ep");
+
+ LabelMonitor monitor;
+ int fd;
+ Api::labelsMonitorGetFd(monitor, &fd);
+ struct pollfd fds[1] = {fd, POLLIN, 0};
+ for (int i = 0; i < 4; i++) { //A,B,C,D
+ synchPipe.post(); //synchronization point {A,B,C,D}1
+ synchPipe.wait(); //synchronization point {A,B,C,D}2
+ nfds_t nfds = 1;
+ int poll_num = TEMP_FAILURE_RETRY(poll(fds, nfds, 0));
+ RUNNER_ASSERT_MSG(poll_num > 0, "Application installation was not detected");
+ RUNNER_ASSERT_MSG((fds[0].revents & POLLIN) > 0, "There is no data to read "
+ "regarding app installation");
+ }
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_72_app_label_monitor_user_local)
+{
+ SynchronizationPipe synchPipe;
+ TemporaryTestUser testUser("sm_test_75_user_name", GUM_USERTYPE_NORMAL, false);
+ testUser.create();
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+ if (pid != 0) { //parent process
+ synchPipe.claimParentEp();
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ synchPipe.wait(); //synchronization point A1
+ AppInstallHelper appLocal("sm_test_72_local1", testUser.getUid());
+ appLocal.setInstallType(SM_APP_INSTALL_LOCAL);
+ ScopedInstaller appLocalInstall(appLocal);
+ synchPipe.post(); //synchronization point A2
+
+ synchPipe.wait(); //synchronization point B1
+ AppInstallHelper appLocal2("sm_test_72_local2");
+ appLocal2.setInstallType(SM_APP_INSTALL_LOCAL);
+ ScopedInstaller appLocal2Install(appLocal2);
+ synchPipe.post(); //synchronization point B2
+
+ synchPipe.wait(); //synchronization point C1
+ appLocalInstall.uninstallApp();
+ synchPipe.post(); //synchronization point C2
+
+ synchPipe.wait(); //synchronization point D1
+ appLocal2Install.uninstallApp();
+ synchPipe.post(); //synchronization point D2
+
+ waitPid(pid);
+ } else { //child process
+ synchPipe.claimChildEp();
+
+ setCaps("cap_mac_admin+ep cap_setuid+ep cap_setgid+ep");
+ RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed");
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+ setCaps("cap_mac_admin+ep");
+
+ LabelMonitor monitor;
+ int fd;
+ Api::labelsMonitorGetFd(monitor, &fd);
+ struct pollfd fds[1] = {fd, POLLIN, 0};
+ for (int i = 0; i < 4; i++) { //A,B,C,D
+ synchPipe.post(); //synchronization point {A,B,C,D}1
+ synchPipe.wait(); //synchronization point {A,B,C,D}2
+ nfds_t nfds = 1;
+ int poll_num = TEMP_FAILURE_RETRY(poll(fds, nfds, 0));
+ RUNNER_ASSERT_MSG(poll_num > 0, "Application installation was not detected");
+ RUNNER_ASSERT_MSG((fds[0].revents & POLLIN) > 0, "There is no data to read "
+ "regarding app installation");
+ }
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_73_app_label_monitor_different_users)
+{
+ const std::string appLocalName = "sm_test_73_local";
+ const std::string appGlobalName = "sm_test_73_global";
+
+ TemporaryTestUser testUser1("sm_test_73_user_name_1", GUM_USERTYPE_NORMAL, false);
+ testUser1.create();
+
+ TemporaryTestUser testUser2("sm_test_73_user_name_2", GUM_USERTYPE_NORMAL, false);
+ testUser2.create();
+
+ AppInstallHelper appLocal(appLocalName, testUser1.getUid());
+ appLocal.setInstallType(SM_APP_INSTALL_LOCAL);
+ ScopedInstaller appLocalInstall(appLocal);
+
+ AppInstallHelper appGlobal(appGlobalName);
+ appGlobal.setInstallType(SM_APP_INSTALL_GLOBAL);
+ ScopedInstaller appGlobalInstall(appGlobal);
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+ if (pid != 0) { //parent process
+ waitPid(pid);
+ } else { //child process
+ setCaps("cap_mac_admin+ep cap_setuid+ep cap_setgid+ep");
+ RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed");
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser2.getUid(), testUser2.getGid()) == 0,
+ "drop_root_privileges failed");
+ setCaps("cap_mac_admin+ep");
+ LabelMonitor monitor;
+
+ Api::labelsProcess(monitor);
+ setCaps("cap_mac_admin-eip");
+ // Only for proper appId and pkgId generation
+ AppInstallHelper appLocal(appLocalName), appGlobal(appGlobalName);
+ testSetLabelForSelf(appLocal.getAppId(), appLocal.getPkgId(), false);
+ testSetLabelForSelf(appGlobal.getAppId(), appGlobal.getPkgId(), true);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_74_app_label_monitor_relabel_changes_global)
+{
+ const std::string appGlobalName1 = "sm_test_74_global1";
+ const std::string appGlobalName2 = "sm_test_74_global2";
+
+ AppInstallHelper appGlobal1(appGlobalName1);
+ AppInstallHelper appGlobal2(appGlobalName2);
+ ScopedInstaller appGlobalInstall1(appGlobal1);
+ ScopedInstaller appGlobalInstall2(appGlobal2);
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+ if (pid != 0) { // parent
+ waitPid(pid);
+ } else { // child
+ TemporaryTestUser testUser("sm_test_74_user_name", GUM_USERTYPE_NORMAL, false);
+
+ setCaps("all=eip");
+ RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed");
+ testUser.create();
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+ setCaps("cap_mac_admin=eip");
+
+ LabelMonitor monitor;
+ Api::labelsProcess(monitor);
+ setCaps("cap_mac_admin-eip");
+
+ testSetLabelForSelf(appGlobal1.getAppId(), appGlobal1.getPkgId(), true); // global installation (OK)
+ testSetLabelForSelf(appGlobal1.getAppId(), appGlobal1.getPkgId(), false); //second change
+ testSetLabelForSelf(appGlobal2.getAppId(), appGlobal2.getPkgId(), false); //third change
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_75_app_label_monitor_relabel_changes_local)
+{
+ const std::string appLocalName1 = "sm_test_75_local1";
+ const std::string appLocalName2 = "sm_test_75_local2";
+ const std::string appLocalName3 = "sm_test_75_local3";
+ const std::string new_user_name = "sm_test_75";
+ TemporaryTestUser testUser("sm_test_75_user_name", GUM_USERTYPE_NORMAL, false);
+ testUser.create();
+ SynchronizationPipe synchPipe;
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+ if (pid != 0) { //parent process
+ synchPipe.claimParentEp();
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ AppInstallHelper appLocal1(appLocalName1, testUser.getUid());
+ AppInstallHelper appLocal2(appLocalName2, testUser.getUid());
+ AppInstallHelper appLocal3(appLocalName3, testUser.getUid());
+ ScopedInstaller appLocalInstall1(appLocal1), appLocalInstall2(appLocal2), appLocalInstall3(appLocal3);
+ appLocalInstall1.uninstallApp();
+ synchPipe.post();
+
+ waitPid(pid);
+ } else { //child process
+ synchPipe.claimChildEp();
+
+ setCaps("all=eip");
+ RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed");
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(testUser.getUid(), testUser.getGid()) == 0,
+ "drop_root_privileges failed");
+ setCaps("cap_mac_admin=eip");
+
+ synchPipe.wait();
+ LabelMonitor monitor;
+ Api::labelsProcess(monitor);
+
+ setCaps("cap_mac_admin-eip");
+ testSetLabelForSelf("unknownApp", "unknownPkg", false); //not premitted
+
+ // Only for proper appId and pkgId generation
+ AppInstallHelper appLocal1(appLocalName1), appLocal2(appLocalName2), appLocal3(appLocalName3);
+ testSetLabelForSelf(appLocal1.getAppId(), appLocal1.getPkgId(), false); //uninstalled
+ testSetLabelForSelf(appLocal2.getAppId(), appLocal2.getPkgId(), true); //installed
+ testSetLabelForSelf(appLocal3.getAppId(), appLocal3.getPkgId(), false); //second change
+ }
+}
--- /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 <algorithm>
+#include <string>
+#include <vector>
+
+#include <grp.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <policy_configuration.h>
+#include <sm_api.h>
+#include <sm_policy_request.h>
+#include <sm_user_request.h>
+#include <temp_test_user.h>
+
+#include <security-manager.h>
+
+using namespace SecurityManagerTest;
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_NSS_PLUGIN)
+
+RUNNER_CHILD_TEST(nss_01_unknown_user) {
+ const std::string newUserName = "nss_01_user";
+ PolicyConfiguration pc;
+ TemporaryTestUser testUser(newUserName, GUM_USERTYPE_NORMAL, false);
+ testUser.create();
+
+ auto gidVector = pc.getGid();
+
+ RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
+
+ gid_t list[64];
+ int grsize = getgroups(64, list);
+ size_t counter = 0;
+
+ for (size_t i=0; i<gidVector.size(); ++i) {
+ for (int j=0; j<grsize; ++j)
+ if(list[j] == gidVector[i]) {
+ counter++;
+ break;
+ }
+ }
+
+ RUNNER_ASSERT_MSG(gidVector.size() == counter,
+ "Process should have all groups related with privileges but it have only " <<
+ counter << " of " << gidVector.size() << " required groups");
+}
+
+RUNNER_CHILD_TEST(nss_02_normal_user_all_priv) {
+ const std::string newUserName = "nss_02_user";
+ PolicyConfiguration pc;
+ TemporaryTestUser testUser(newUserName, GUM_USERTYPE_NORMAL, false);
+ testUser.create();
+
+ auto gidVector = pc.getUserGid(PolicyConfiguration::NORMAL);
+
+ UserRequest addUserRequest;
+ addUserRequest.setUid(testUser.getUid());
+ addUserRequest.setUserType(SM_USER_TYPE_NORMAL);
+ Api::addUser(addUserRequest);
+
+ RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
+
+ gid_t list[64];
+ int grsize = getgroups(64, list);
+ size_t counter = 0;
+
+ for (size_t i=0; i<gidVector.size(); ++i) {
+ for (int j=0; j<grsize; ++j)
+ if(list[j] == gidVector[i]) {
+ counter++;
+ break;
+ }
+ }
+
+ RUNNER_ASSERT_MSG(gidVector.size() == counter,
+ "Process should have all groups related with privileges but it have only " <<
+ counter << " of " << gidVector.size() << " required groups");
+}
+
+RUNNER_CHILD_TEST(nss_03_normal_user_without_camera) {
+ const std::string newUserName = "nss_03_user";
+ TemporaryTestUser testUser(newUserName, GUM_USERTYPE_NORMAL, false);
+ testUser.create();
+ gid_t cameraPrivId = nameToGid("priv_camera");
+
+ UserRequest addUserRequest;
+ addUserRequest.setUid(testUser.getUid());
+ addUserRequest.setUserType(SM_USER_TYPE_NORMAL);
+ Api::addUser(addUserRequest);
+
+ PolicyRequest policyRequest;
+ PolicyEntry entry(
+ SECURITY_MANAGER_ANY,
+ std::to_string(static_cast<int>(testUser.getUid())),
+ "http://tizen.org/privilege/camera");
+ entry.setMaxLevel("Deny");
+ policyRequest.addEntry(entry);
+ Api::sendPolicy(policyRequest);
+
+ RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
+
+ gid_t list[64];
+ int grsize = getgroups(64, list);
+ size_t counter = 0;
+
+ for (int i=0; i<grsize; ++i) {
+ if (list[i] == cameraPrivId) {
+ counter++;
+ break;
+ }
+ }
+
+ RUNNER_ASSERT_MSG(0 == counter, "Process should not have priv_camera group");
+
+ PolicyConfiguration pc;
+ auto gidVector = pc.getUserGid(PolicyConfiguration::NORMAL);
+ gidVector.erase(
+ std::remove_if(gidVector.begin(), gidVector.end(), [=](gid_t g) { return g == cameraPrivId; }),
+ gidVector.end());
+
+ for (size_t i=0; i<gidVector.size(); ++i) {
+ for (int j=0; j<grsize; ++j)
+ if(list[j] == gidVector[i]) {
+ counter++;
+ break;
+ }
+ }
+
+ RUNNER_ASSERT_MSG(gidVector.size() == counter,
+ "Process should have all groups related with privileges but it have only " <<
+ counter << " of " << gidVector.size() << " required groups");
+}
+
+RUNNER_CHILD_TEST(nss_04_guest_user) {
+ const std::string newUserName = "nss_04_user";
+ TemporaryTestUser testUser(newUserName, GUM_USERTYPE_GUEST, false);
+ testUser.create();
+
+ UserRequest addUserRequest;
+ addUserRequest.setUid(testUser.getUid());
+ addUserRequest.setUserType(SM_USER_TYPE_GUEST);
+ Api::addUser(addUserRequest);
+
+ RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
+
+ gid_t list[64];
+ int grsize = getgroups(64, list);
+ size_t counter = 0;
+
+ PolicyConfiguration pc;
+ auto gidVector = pc.getUserGid(PolicyConfiguration::GUEST);
+
+ for (size_t i=0; i<gidVector.size(); ++i) {
+ for (int j=0; j<grsize; ++j)
+ if(list[j] == gidVector[i]) {
+ counter++;
+ break;
+ }
+ }
+
+ RUNNER_ASSERT_MSG(gidVector.size() == counter,
+ "Process should have all groups related with privileges but it have only " <<
+ counter << " of " << gidVector.size() << " required groups");
+}
+
+
--- /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/smack.h>
+#include <sys/capability.h>
+
+#include <thread>
+#include <string>
+#include <memory>
+#include <mutex>
+
+#include <dpl/test/test_runner_child.h>
+#include <dpl/test/test_runner.h>
+
+#include <app_install_helper.h>
+#include <scoped_installer.h>
+#include <sm_api.h>
+#include <sm_commons.h>
+#include <memory.h>
+#include <tests_common.h>
+
+using namespace SecurityManagerTest;
+
+namespace {
+bool finish = false;
+const size_t THREADS = 10;
+
+const std::string SYNC_TEST_APP("app100");
+
+typedef std::unique_ptr<_cap_struct, decltype(&cap_free)> CapPtr;
+
+std::string thread_errors;
+std::mutex error_mutex;
+
+#define THREAD_ASSERT_MSG(test, message) \
+ do \
+ { \
+ if (!(test)) \
+ { \
+ std::ostringstream assertMsg; \
+ assertMsg << #test << " " << __FILE__ << " " << __LINE__ << " " << \
+ message << std::endl; \
+ std::lock_guard<std::mutex> guard(error_mutex); \
+ thread_errors.append(assertMsg.str()); \
+ } \
+ } while (0)
+
+void threadFn(int i, const std::string &expectedLabel)
+{
+ if (i % 2 == 0) {
+ // block all signals
+ sigset_t sigset;
+ THREAD_ASSERT_MSG(sigfillset(&sigset) == 0, "sigfillset failed");
+ THREAD_ASSERT_MSG(sigprocmask(SIG_BLOCK, &sigset, NULL) == 0, "sigprocmask failed");
+ }
+
+ while (!finish)
+ usleep(1000);
+
+ char* label;
+ THREAD_ASSERT_MSG(smack_new_label_from_self(&label) > 0, "smack_new_label_from_self failed");
+ CStringPtr labelPtr(label);
+
+ THREAD_ASSERT_MSG(expectedLabel.compare(label) == 0,
+ "Thread " << i << " has a wrong label: " << label);
+
+ CapPtr expectedCaps(cap_init(), cap_free);
+ THREAD_ASSERT_MSG(expectedCaps, "cap_init() failed");
+ THREAD_ASSERT_MSG(cap_clear(expectedCaps.get()) == 0, "cap_clear() failed");
+
+ CapPtr realCaps(cap_get_proc(), cap_free);
+ THREAD_ASSERT_MSG(realCaps, "cap_get_proc() failed");
+ THREAD_ASSERT_MSG(cap_compare(realCaps.get(), expectedCaps.get()) == 0,
+ "Thread " << i << " has wrong caps");
+}
+
+struct ThreadWrapper
+{
+
+ ThreadWrapper()
+ {
+ }
+ ~ThreadWrapper()
+ {
+ finish = true;
+ thread.join();
+ }
+
+ void run(int i, const std::string &expectedLabel)
+ {
+ THREAD_ASSERT_MSG(!thread.joinable(), "Thread already started");
+ thread = std::thread(threadFn, i, expectedLabel);
+ }
+
+ std::thread thread;
+};
+
+} // anonymous namespace
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_PREPARE_APP)
+
+RUNNER_CHILD_TEST(security_manager_100_synchronize_credentials_test)
+{
+ AppInstallHelper app(SYNC_TEST_APP.c_str());
+ ScopedInstaller appInstall(app);
+ const std::string expectedLabel = app.generateAppLabel();
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+ if (pid == 0) {
+ {
+ ThreadWrapper threads[THREADS];
+
+ for (size_t i = 0; i < THREADS; i++)
+ threads[i].run(i, expectedLabel);
+
+ Api::prepareApp(app.getAppId().c_str());
+ }
+ RUNNER_ASSERT_MSG(thread_errors.empty(), std::endl << thread_errors);
+ exit(0);
+ } else {
+ waitPid(pid);
+ }
+}
--- /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 <algorithm>
+#include <cstdlib>
+#include <map>
+#include <string>
+#include <sys/types.h>
+#include <unistd.h>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+#include <privilege_info.h>
+
+#include <app_install_helper.h>
+#include <cynara_test_admin.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <policy_configuration.h>
+#include <scoped_installer.h>
+#include <sm_api.h>
+#include <sm_commons.h>
+#include <sm_policy_request.h>
+#include <sm_request.h>
+#include <synchronization_pipe.h>
+#include <temp_test_user.h>
+#include <tests_common.h>
+
+using namespace SecurityManagerTest;
+namespace {
+struct UserInfo {
+ std::string userName;
+ GumUserType userType;
+};
+
+// Privileges required for having permission to self/admin get/set policies.
+const std::string SELF_PRIVILEGE = "http://tizen.org/privilege/notexist";
+const std::string ADMIN_PRIVILEGE = "http://tizen.org/privilege/internal/usermanagement";
+
+typedef std::vector<std::string> Privileges;
+const std::vector<Privileges> TEST_PRIVILEGES = {
+ {
+ "http://tizen.org/privilege/internet",
+ "http://tizen.org/privilege/display"
+ },
+ {
+ "http://tizen.org/privilege/telephony",
+ "http://tizen.org/privilege/datasharing"
+ },
+ {
+ "http://tizen.org/privilege/content.write",
+ "http://tizen.org/privilege/led",
+ "http://tizen.org/privilege/email"
+ },
+ {
+ "http://tizen.org/privilege/led",
+ "http://tizen.org/privilege/email",
+ "http://tizen.org/privilege/telephony",
+ "http://tizen.org/privilege/datasharing"
+ },
+ {
+ "http://tizen.org/privilege/internet",
+ "http://tizen.org/privilege/display",
+ "http://tizen.org/privilege/led",
+ "http://tizen.org/privilege/email"
+ }
+};
+
+const std::vector<Privileges> TEST_PRIVACY_PRIVILEGES = {
+ {
+ "http://tizen.org/privilege/telephony",
+ "http://tizen.org/privilege/led",
+ "http://tizen.org/privilege/callhistory.read", // privacy-related privileges start here
+ "http://tizen.org/privilege/account.read",
+ "http://tizen.org/privilege/healthinfo"
+ },
+ {
+ "http://tizen.org/privilege/telephony",
+ "http://tizen.org/privilege/led",
+ "http://tizen.org/privilege/callhistory.read" // privacy-related privileges start here
+ }
+};
+
+bool isPrivilegePrivacy(const std::string &priv) {
+ return (1 == privilege_info_is_privacy(priv.c_str()));
+}
+
+int countPrivacyPrivileges(const Privileges &privs) {
+ return std::count_if(privs.begin(), privs.end(), isPrivilegePrivacy);
+}
+
+}
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_PRIVACY_MANAGER)
+
+RUNNER_CHILD_TEST(security_manager_10_privacy_manager_fetch_whole_policy_for_self)
+{
+ TemporaryTestUser tmpUser("sm_test_10_user_name", GUM_USERTYPE_NORMAL, false);
+ tmpUser.create();
+
+ unsigned expectedPolicyCount = 0;
+ std::map<std::string, AppInstallHelper> appIdToAIH;
+ for (unsigned i = 0; i < TEST_PRIVILEGES.size(); i++) {
+ AppInstallHelper app("sm_test_10_" + std::to_string(i), tmpUser.getUid());
+ app.addPrivileges(TEST_PRIVILEGES[i]);
+ expectedPolicyCount += app.getPrivileges().size();
+ appIdToAIH.emplace(app.getAppId(), std::move(app));
+ }
+
+ AppInstallHelper privManager("sm_test_10_privilege_manager", tmpUser.getUid());
+ std::string privManagerAppId = privManager.getAppId();
+ privManager.addPrivilege(SELF_PRIVILEGE);
+ expectedPolicyCount += privManager.getPrivileges().size();
+ appIdToAIH.emplace(privManager.getAppId(), std::move(privManager));
+
+ std::vector<ScopedInstaller> scopedInstallations;
+ for (const auto &appIdAIH : appIdToAIH) {
+ scopedInstallations.emplace_back(ScopedInstaller(appIdAIH.second));
+ }
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid != -1, "Fork failed");
+ if (pid != 0) { //parent process
+ waitPid(pid);
+ } else { //child process
+ Api::setProcessLabel(privManagerAppId);
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(tmpUser.getUid(), tmpUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ std::vector<PolicyEntry> policyEntries;
+ Api::getPolicy(PolicyEntry(), policyEntries);
+
+ RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
+ RUNNER_ASSERT_MSG(policyEntries.size() == expectedPolicyCount,
+ "Number of policies doesn't match - should be: " << expectedPolicyCount
+ << " and is " << policyEntries.size());
+
+ for (const auto &policyEntry : policyEntries) {
+ std::string user = policyEntry.getUser();
+ std::string app = policyEntry.getAppId();
+ std::string privilege = policyEntry.getPrivilege();
+
+ RUNNER_ASSERT_MSG(user == tmpUser.getUidString(), "Unexpected user: " << user);
+
+ auto appIt = appIdToAIH.find(app);
+ RUNNER_ASSERT_MSG(appIt != appIdToAIH.end(), "Policy returned unexpected app: " << app);
+
+ AppInstallHelper &aih = appIt->second;
+ auto appPrivileges = aih.getPrivileges();
+ auto privIt = std::find(appPrivileges.begin(), appPrivileges.end(), privilege);
+ RUNNER_ASSERT_MSG(privIt != appPrivileges.end(),
+ "Unexpected privilege " << privilege << " for app " << app);
+ }
+ exit(0);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_11_privacy_manager_fetch_whole_policy_for_admin_unprivileged)
+{
+ const std::string normalNameToSwitch = "sm_test_11_user_name_normal";
+ const std::vector<UserInfo> userInfos = {{normalNameToSwitch, GUM_USERTYPE_NORMAL},
+ {"sm_test_11_user_name_admin", GUM_USERTYPE_ADMIN}};
+
+ std::map<std::string, TemporaryTestUser> usernameToTTU;
+ // uid + app_id -> AppInstallHelper (different users can have same app_id installed)
+ std::map<std::pair<uid_t,std::string>, AppInstallHelper> userAppIdToAIH;
+ unsigned expectedPolicyCount = 0;
+
+ for (unsigned int u_i = 0; u_i < userInfos.size(); u_i++) {
+ TemporaryTestUser user(userInfos[u_i].userName, userInfos[u_i].userType);
+ user.create();
+
+ for (unsigned int p_i = 0; p_i < TEST_PRIVILEGES.size(); p_i++) {
+ AppInstallHelper app("sm_test_11_" + std::to_string(p_i), user.getUid());
+ app.addPrivileges(TEST_PRIVILEGES[p_i]);
+ if (user.getUserName() == normalNameToSwitch) // Only entries for this user should be fetched
+ expectedPolicyCount += app.getPrivileges().size();
+ userAppIdToAIH.emplace(std::make_pair(user.getUid(), app.getAppId()), std::move(app));
+ };
+
+ usernameToTTU.emplace(userInfos[u_i].userName, std::move(user));
+ };
+
+ TemporaryTestUser &normalUserToSwitch = usernameToTTU.at(normalNameToSwitch);
+
+ AppInstallHelper privManager("sm_test_11_priv_manager", normalUserToSwitch.getUid());
+ std::string privManagerAppId = privManager.getAppId();
+ privManager.addPrivilege(SELF_PRIVILEGE);
+ expectedPolicyCount += privManager.getPrivileges().size();
+ userAppIdToAIH.emplace(std::make_pair(normalUserToSwitch.getUid(), privManager.getAppId()),
+ std::move(privManager));
+
+ std::vector<ScopedInstaller> scopedInstallations;
+ for (const auto &userAppIdAIH : userAppIdToAIH) {
+ scopedInstallations.emplace_back(ScopedInstaller(userAppIdAIH.second));
+ }
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid != -1, "Fork failed");
+ if (pid != 0) { //parent process
+ waitPid(pid);
+ } else { //child process
+ Api::setProcessLabel(privManagerAppId);
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(normalUserToSwitch.getUid(),
+ normalUserToSwitch.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ std::vector<PolicyEntry> policyEntries;
+ Api::getPolicy(PolicyEntry(), policyEntries);
+
+ RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
+ RUNNER_ASSERT_MSG(policyEntries.size() == expectedPolicyCount,
+ "Number of policies doesn't match - should be: " << expectedPolicyCount
+ << " and is " << policyEntries.size());
+
+ for (const auto &policyEntry : policyEntries) {
+ // Expect policy only for current process user
+ std::string user = policyEntry.getUser();
+ std::string app = policyEntry.getAppId();
+ std::string privilege = policyEntry.getPrivilege();
+
+ RUNNER_ASSERT_MSG(normalUserToSwitch.getUidString() == user, "Unexpected user: " << user);
+ auto userAppIdToAIHIt = userAppIdToAIH.find(std::make_pair(static_cast<uid_t>(std::stoi(user)), app));
+ RUNNER_ASSERT_MSG(userAppIdToAIHIt != userAppIdToAIH.end(),
+ "Unknown app " << app << " for user " << user);
+
+ AppInstallHelper &aih = userAppIdToAIHIt->second;
+ auto privs = aih.getPrivileges();
+
+ auto appPrivileges = aih.getPrivileges();
+ auto privIt = std::find(appPrivileges.begin(), appPrivileges.end(), privilege);
+ RUNNER_ASSERT_MSG(privIt != appPrivileges.end(),
+ "Unexpected privilege " << privilege << " for app " << app);
+ }
+ exit(0);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_12_privacy_manager_fetch_whole_policy_for_admin_privileged)
+{
+ std::vector<PolicyEntry> oldPolicyVec;
+ Api::getPolicy(PolicyEntry(), oldPolicyVec);
+ std::unordered_set<PolicyEntry> oldPolicySet(oldPolicyVec.begin(), oldPolicyVec.end());
+
+ std::string adminNameToSwitch = "sm_test_12_user_name_admin";
+ const std::vector<UserInfo> userInfos = {{"sm_test_12_user_name_normal",GUM_USERTYPE_NORMAL},
+ {adminNameToSwitch, GUM_USERTYPE_ADMIN}};
+
+ std::map<std::string, TemporaryTestUser> usernameToTTU;
+ std::vector<std::string> uidStrings;
+ // uidstring + app_id -> AppInstallHelper
+ std::map<std::pair<uid_t, std::string>, AppInstallHelper> userAppIdToAIH;
+ unsigned expectedPolicyCount = oldPolicyVec.size();
+
+ for (unsigned int u_i = 0; u_i < userInfos.size(); u_i++) {
+ TemporaryTestUser user(userInfos[u_i].userName, userInfos[u_i].userType);
+ user.create();
+ uidStrings.push_back(user.getUidString());
+
+ for (unsigned int p_i = 0; p_i < TEST_PRIVILEGES.size(); p_i++) {
+ AppInstallHelper app("sm_test_12_" + std::to_string(p_i), user.getUid());
+ // Shift privileges, so same app_id for different users doesn't have same privileges
+ app.addPrivileges(TEST_PRIVILEGES.at((p_i + u_i) % TEST_PRIVILEGES.size()));
+ expectedPolicyCount += app.getPrivileges().size();
+ userAppIdToAIH.emplace(std::make_pair(user.getUid(), app.getAppId()), std::move(app));
+ };
+ usernameToTTU.emplace(user.getUserName(), std::move(user));
+ };
+
+ TemporaryTestUser &adminUserToSwitch = usernameToTTU.at(adminNameToSwitch);
+
+ AppInstallHelper privManager("sm_test_12_priv_manager", adminUserToSwitch.getUid());
+ std::string privManagerAppId = privManager.getAppId();
+ privManager.addPrivilege(SELF_PRIVILEGE);
+ privManager.addPrivilege(ADMIN_PRIVILEGE);
+ expectedPolicyCount += privManager.getPrivileges().size();
+
+ userAppIdToAIH.emplace(std::make_pair(adminUserToSwitch.getUid(), privManager.getAppId()),
+ std::move(privManager));
+
+ std::vector<ScopedInstaller> scopedInstallations;
+ for (const auto &userAppIdAIH : userAppIdToAIH) {
+ scopedInstallations.emplace_back(ScopedInstaller(userAppIdAIH.second));
+ }
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid != -1, "Fork failed");
+ if (pid != 0) { //parent process
+ waitPid(pid);
+ } else { //child process
+ Api::setProcessLabel(privManagerAppId);
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(adminUserToSwitch.getUid(),
+ adminUserToSwitch.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ std::vector<PolicyEntry> policyEntries;
+ Api::getPolicy(PolicyEntry(), policyEntries);
+ RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
+ RUNNER_ASSERT_MSG(policyEntries.size() == expectedPolicyCount,
+ "Number of policies doesn't match - should be: " << expectedPolicyCount
+ << " and is " << policyEntries.size());
+
+ for (const auto &policyEntry : policyEntries) {
+ // Expect policy for all users to be returned
+ if (oldPolicySet.count(policyEntry))
+ continue;
+ std::string user = policyEntry.getUser();
+ std::string app = policyEntry.getAppId();
+ std::string privilege = policyEntry.getPrivilege();
+
+ auto uidStringIt = std::find(uidStrings.begin(), uidStrings.end(), user);
+ RUNNER_ASSERT_MSG(uidStringIt != uidStrings.end(), "Unexpected user: " << user);
+
+ auto userAppIdToAIHIt = userAppIdToAIH.find(
+ std::make_pair(static_cast<uid_t>(std::stoi(user)), app));
+ RUNNER_ASSERT_MSG(userAppIdToAIHIt != userAppIdToAIH.end(),
+ "Unknown app " << app << " for user " << user);
+
+ AppInstallHelper &aih = userAppIdToAIHIt->second;
+ auto privs = aih.getPrivileges();
+
+ auto appPrivileges = aih.getPrivileges();
+ auto privIt = std::find(appPrivileges.begin(), appPrivileges.end(), privilege);
+ RUNNER_ASSERT_MSG(privIt != appPrivileges.end(),
+ "Unexpected privilege " << privilege << " for app " << app);
+ };
+ exit(0);
+ };
+}
+
+RUNNER_CHILD_TEST(security_manager_13_privacy_manager_fetch_policy_after_update_unprivileged)
+{
+ std::string normalName = "sm_test_13_user_name_normal";
+ std::string adminName = "sm_test_13_user_name_admin";
+ const std::vector<UserInfo> userInfos = {{normalName,GUM_USERTYPE_NORMAL},
+ {adminName, GUM_USERTYPE_ADMIN}};
+
+ std::map<std::string, TemporaryTestUser> usernameToTTU;
+ std::map<uid_t, std::vector<AppInstallHelper>> uidToAIHs;
+ unsigned expectedPolicyCount = 0;
+ std::string privManagerAppId;
+
+ for (unsigned int u_i = 0; u_i < userInfos.size(); u_i++) {
+ //Only entries for one of the users will be listed
+ TemporaryTestUser user(userInfos[u_i].userName, userInfos[u_i].userType);
+ user.create();
+
+ for (unsigned int p_i = 0; p_i < TEST_PRIVILEGES.size(); p_i++) {
+ AppInstallHelper app("sm_test_13_" + std::to_string(p_i), user.getUid());
+ // Shift privileges, so same app_id for different user doesn't have same privileges
+ app.addPrivileges(TEST_PRIVILEGES.at((p_i + u_i) % TEST_PRIVILEGES.size()));
+ expectedPolicyCount += app.getPrivileges().size();
+ uidToAIHs[user.getUid()].emplace_back(std::move(app));
+ };
+ AppInstallHelper privManager("sm_test_13_priv_manager", user.getUid());
+ privManagerAppId = privManager.getAppId();
+ privManager.addPrivilege(SELF_PRIVILEGE);
+ expectedPolicyCount += privManager.getPrivileges().size();
+ uidToAIHs[user.getUid()].emplace_back(std::move(privManager));
+
+ usernameToTTU.emplace(user.getUserName(), std::move(user));
+ };
+
+ std::vector<ScopedInstaller> scopedInstallations;
+ for (const auto &userAIHs : uidToAIHs) {
+ for (const auto &aih : userAIHs.second)
+ scopedInstallations.emplace_back(ScopedInstaller(aih));
+ }
+
+ TemporaryTestUser &adminUser = usernameToTTU.at(adminName);
+ TemporaryTestUser &normalUser = usernameToTTU.at(normalName);
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >=0, "Fork failed");
+ if (pid == 0) { //child #1 process
+ Api::setProcessLabel(privManagerAppId);
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(normalUser.getUid(), normalUser.getGid()) == 0,
+ "drop_root_privileges failed");
+ auto &app1 = uidToAIHs[normalUser.getUid()][0];
+ auto &app2 = uidToAIHs[normalUser.getUid()][0];
+ PolicyRequest policyRequest;
+ PolicyEntry policyEntry(
+ app1.getAppId(),
+ normalUser.getUidString(),
+ app1.getPrivileges()[0]
+ );
+ policyEntry.setLevel("Deny");
+
+ policyRequest.addEntry(policyEntry);
+ policyEntry = PolicyEntry(
+ app2.getAppId(),
+ normalUser.getUidString(),
+ app1.getPrivileges()[1]
+ );
+ policyEntry.setLevel("Deny");
+ policyRequest.addEntry(policyEntry);
+ Api::sendPolicy(policyRequest);
+
+ exit(0);
+ } else {
+ waitPid(pid);
+ pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >=0, "Fork failed");
+ if (pid == 0) { //child #2 process
+ Api::setProcessLabel(privManagerAppId);
+ // Admin user, but in context of app, which doesn't have usermanagement privilege
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(adminUser.getUid(), adminUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ PolicyEntry filter = PolicyEntry(
+ SECURITY_MANAGER_ANY,
+ normalUser.getUidString(),
+ SECURITY_MANAGER_ANY
+ );
+ std::vector<PolicyEntry> policyEntries;
+ //U2 requests contents of U1 privacy manager - should fail
+ Api::getPolicyForSelf(filter, policyEntries, SECURITY_MANAGER_ERROR_ACCESS_DENIED);
+ RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty, but has "
+ << policyEntries.size() << " entries");
+
+ filter = PolicyEntry(
+ SECURITY_MANAGER_ANY,
+ SECURITY_MANAGER_ANY,
+ SECURITY_MANAGER_ANY
+ );
+
+ policyEntries.clear();
+
+ //U2 requests contents of ADMIN bucket - should fail
+ Api::getPolicyForAdmin(filter, policyEntries, SECURITY_MANAGER_ERROR_ACCESS_DENIED);
+ RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty, but has "
+ << policyEntries.size() << " entries");
+ exit(0);
+ } else {
+ waitPid(pid);
+ }
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_14_privacy_manager_fetch_and_update_policy_for_admin)
+{
+ TemporaryTestUser adminUserToSwitch("sm_test_14_user_name_admin", GUM_USERTYPE_ADMIN);
+ adminUserToSwitch.create();
+
+ AppInstallHelper privManager("sm_test_14_priv_manager", adminUserToSwitch.getUid());
+ privManager.addPrivilege(ADMIN_PRIVILEGE);
+
+ ScopedInstaller privManagerInstall(privManager);
+
+ pid_t pid = fork();
+ if (pid != 0) {
+ waitPid(pid);
+ } else { //child process
+ Api::setProcessLabel(privManager.getAppId());
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(adminUserToSwitch.getUid(),
+ adminUserToSwitch.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ PolicyRequest setPolicyRequest;
+ std::vector<PolicyEntry> policyEntries;
+
+ const std::string internetPriv = "http://tizen.org/privilege/internet";
+ const std::string displayPriv = "http://tizen.org/privilege/display";
+
+ PolicyEntry internetPolicyEntry(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, internetPriv);
+ internetPolicyEntry.setMaxLevel("Deny");
+ setPolicyRequest.addEntry(internetPolicyEntry);
+
+ PolicyEntry displayPolicyEntry(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, displayPriv);
+ displayPolicyEntry.setMaxLevel("Deny");
+ setPolicyRequest.addEntry(displayPolicyEntry);
+
+ Api::sendPolicy(setPolicyRequest);
+
+ Api::getPolicyForAdmin(PolicyEntry(), policyEntries);
+ RUNNER_ASSERT_MSG(policyEntries.size() == 2, "Number of policies doesn't match - should be: 2"
+ " and is " << policyEntries.size());
+
+ PolicyRequest delPolicyRequest;
+
+ internetPolicyEntry.setMaxLevel(SECURITY_MANAGER_DELETE);
+ delPolicyRequest.addEntry(internetPolicyEntry);
+
+ displayPolicyEntry.setMaxLevel(SECURITY_MANAGER_DELETE);
+ delPolicyRequest.addEntry(displayPolicyEntry);
+
+ Api::sendPolicy(delPolicyRequest);
+
+ policyEntries.clear();
+ Api::getPolicyForAdmin(PolicyEntry(), policyEntries);
+ RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Number of policies doesn't match - should be: 0"
+ " and is " << policyEntries.size());
+ exit(0);
+ };
+}
+
+RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_admin)
+{
+ const std::string updatePriv = "http://tizen.org/privilege/led";
+
+ TemporaryTestUser adminUser("sm_test_15_username", GUM_USERTYPE_ADMIN);
+ adminUser.create();
+
+ AppInstallHelper updatedApp("security_manager_15_update");
+ ScopedInstaller updatedAppInstall(updatedApp);
+
+ AppInstallHelper privManager("security_manager_15_priv_manager", adminUser.getUid());
+ privManager.addPrivilege(ADMIN_PRIVILEGE);
+ ScopedInstaller privManagerInstall(privManager);
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "fork failed");
+ if (pid != 0) { //parent process
+ waitPid(pid);
+ CynaraTestAdmin::Admin admin;
+ admin.adminCheck("ADMIN", false, updatedApp.generateAppLabel().c_str(),
+ adminUser.getUidString().c_str(), updatePriv.c_str(), CYNARA_ADMIN_ALLOW,
+ nullptr);
+ } else {
+ Api::setProcessLabel(privManager.getAppId());
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(adminUser.getUid(), adminUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ PolicyEntry entry(updatedApp.getAppId(), adminUser.getUidString(), updatePriv);
+ entry.setMaxLevel("Allow");
+ PolicyRequest addPolicyRequest;
+ addPolicyRequest.addEntry(entry);
+ Api::sendPolicy(addPolicyRequest);
+ exit(0);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_admin_wildcard)
+{
+ const std::string updatePriv = "http://tizen.org/privilege/led";
+
+ TemporaryTestUser adminUser("sm_test_15_username", GUM_USERTYPE_ADMIN);
+ adminUser.create();
+
+ AppInstallHelper app("security_manager_15");
+ ScopedInstaller appInstall(app);
+
+ AppInstallHelper privManager("security_manager_15_priv_manager", adminUser.getUid());
+ privManager.addPrivilege(ADMIN_PRIVILEGE);
+ ScopedInstaller privManagerInstall(privManager);
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "fork failed");
+ if (pid != 0) {
+ waitPid(pid);
+ CynaraTestAdmin::Admin admin;
+ admin.adminCheck("ADMIN", false, app.generateAppLabel().c_str(),
+ adminUser.getUidString().c_str(), updatePriv.c_str(), CYNARA_ADMIN_ALLOW,
+ nullptr);
+ } else {
+ Api::setProcessLabel(privManager.getAppId());
+ RUNNER_ASSERT_MSG(drop_root_privileges(adminUser.getUid(), adminUser.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ PolicyEntry entry(SECURITY_MANAGER_ANY, adminUser.getUidString(), updatePriv);
+ entry.setMaxLevel("Allow");
+
+ PolicyRequest addPolicyRequest;
+ addPolicyRequest.addEntry(entry);
+ Api::sendPolicy(addPolicyRequest);
+ exit(0);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_15_privacy_manager_send_policy_update_for_self)
+{
+ const std::string updatePriv = "http://tizen.org/privilege/led";
+
+ TemporaryTestUser user("sm_test_15_username", GUM_USERTYPE_NORMAL);
+ user.create();
+
+ AppInstallHelper app("security_manager_15");
+ ScopedInstaller appInstall(app);
+
+ AppInstallHelper privManager("security_manager_15_priv_manager", user.getUid());
+ privManager.addPrivilege(SELF_PRIVILEGE);
+ ScopedInstaller privManagerInstall(privManager);
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
+ if (pid != 0) {
+ waitPid(pid);
+ CynaraTestAdmin::Admin admin;
+ admin.adminCheck("", false, app.generateAppLabel().c_str(), user.getUidString().c_str(),
+ updatePriv.c_str(), CYNARA_ADMIN_ALLOW, nullptr);
+ } else {
+ Api::setProcessLabel(privManager.getAppId());
+ RUNNER_ASSERT_MSG(drop_root_privileges(user.getUid(), user.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ PolicyEntry entry(app.getAppId(), user.getUidString(), updatePriv);
+ entry.setLevel("Allow");
+
+ PolicyRequest addPolicyRequest;
+ addPolicyRequest.addEntry(entry);
+ Api::sendPolicy(addPolicyRequest);
+ exit(0);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_16_policy_levels_get)
+{
+ TemporaryTestUser user("sm_test_16_user_name", GUM_USERTYPE_NORMAL);
+ user.create();
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "fork failed");
+ if (pid != 0) {
+ waitPid(pid);
+ } else {
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(user.getUid(), user.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ char** levels;
+ size_t count;
+ int ret = security_manager_policy_levels_get(&levels, &count);
+ RUNNER_ASSERT_MSG((lib_retcode)ret == SECURITY_MANAGER_SUCCESS,
+ "Invlid return code: " << ret);
+ std::unique_ptr<char *, std::function<void(char**)>> descriptionsPtr(levels,
+ [count](char **levels) { security_manager_policy_levels_free(levels, count);});
+
+ RUNNER_ASSERT_MSG(count >= 2, "Invalid number of policy levels. Should be 3,"
+ " instead there is: " << count);
+
+ std::string denyPolicy = std::string(levels[0]);
+ std::string allowPolicy = std::string(levels[count-1]);
+
+ // first should always be Deny
+ RUNNER_ASSERT_MSG(denyPolicy.compare("Deny") == 0,
+ "Invalid first policy level. Should be Deny, instead there is: " << levels[0]);
+
+ // last should always be Allow
+ RUNNER_ASSERT_MSG(allowPolicy.compare("Allow") == 0,
+ "Invalid last policy level. Should be Allow, instead there is: " << levels[count-1]);
+ exit(0);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_17a_privacy_manager_delete_policy_for_self)
+{
+ const std::string updatePriv = "http://tizen.org/privilege/led";
+
+ TemporaryTestUser user("sm_test_17a_username", GUM_USERTYPE_NORMAL);
+ user.create();
+
+ AppInstallHelper app("security_manager_17a");
+ ScopedInstaller appInstall(app);
+
+ SynchronizationPipe synchPipe;
+ pid_t pid = fork();
+ RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
+ if (pid != 0) {
+ synchPipe.claimParentEp();
+
+ synchPipe.wait();
+ CynaraTestAdmin::Admin admin;
+ admin.adminCheck("", false, app.generateAppLabel().c_str(), user.getUidString().c_str(),
+ updatePriv.c_str(), CYNARA_ADMIN_ALLOW, nullptr);
+ synchPipe.post();
+
+ synchPipe.wait();
+ admin.adminCheck("", false, app.generateAppLabel().c_str(), user.getUidString().c_str(),
+ updatePriv.c_str(), CYNARA_ADMIN_DENY, nullptr);
+ waitPid(pid);
+ } else {
+ synchPipe.claimChildEp();
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(user.getUid(), user.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ PolicyEntry entry(app.getAppId(), user.getUidString(), updatePriv);
+ entry.setLevel("Allow");
+ PolicyRequest addPolicyRequest;
+ addPolicyRequest.addEntry(entry);
+ Api::sendPolicy(addPolicyRequest);
+ synchPipe.post();
+
+ synchPipe.wait();
+ PolicyEntry deleteEntry(app.getAppId(), user.getUidString(), updatePriv);
+ deleteEntry.setLevel(SECURITY_MANAGER_DELETE);
+ PolicyRequest deletePolicyRequest;
+ deletePolicyRequest.addEntry(deleteEntry);
+ Api::sendPolicy(deletePolicyRequest);
+ synchPipe.post();
+
+ exit(0);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_17b_privacy_manager_delete_policy_for_self)
+{
+ const std::string updatePriv = "http://tizen.org/privilege/led";
+
+ TemporaryTestUser user("sm_test_17b_username", GUM_USERTYPE_NORMAL);
+ user.create();
+
+ AppInstallHelper app("security_manager_17b");
+ ScopedInstaller appInstall(app);
+
+ AppInstallHelper privManager("security_manager_17b_priv_manager", user.getUid());
+ privManager.addPrivilege(SELF_PRIVILEGE);
+ ScopedInstaller privManagerInstall(privManager);
+
+ SynchronizationPipe synchPipe;
+ pid_t pid = fork();
+ RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
+ if (pid != 0) {
+ synchPipe.claimParentEp();
+ synchPipe.wait();
+ CynaraTestAdmin::Admin admin;
+ admin.adminCheck("", false, app.generateAppLabel().c_str(), user.getUidString().c_str(),
+ updatePriv.c_str(), CYNARA_ADMIN_ALLOW, nullptr);
+ synchPipe.post();
+
+ synchPipe.wait();
+ admin.adminCheck("", false, app.generateAppLabel().c_str(),
+ user.getUidString().c_str(), updatePriv.c_str(), CYNARA_ADMIN_DENY, nullptr);
+ waitPid(pid);
+
+ } else {
+ synchPipe.claimChildEp();
+ Api::setProcessLabel(privManager.getAppId());
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(user.getUid(), user.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ PolicyEntry entry(app.getAppId(), user.getUidString(), updatePriv);
+ entry.setLevel("Allow");
+ PolicyRequest addPolicyRequest;
+ addPolicyRequest.addEntry(entry);
+ Api::sendPolicy(addPolicyRequest);
+ synchPipe.post();
+
+ synchPipe.wait();
+ PolicyRequest deletePolicyRequest;
+ PolicyEntry deleteEntry(app.getAppId(), user.getUidString(), updatePriv);
+ deleteEntry.setLevel(SECURITY_MANAGER_DELETE);
+ deletePolicyRequest.addEntry(deleteEntry);
+ Api::sendPolicy(deletePolicyRequest);
+ synchPipe.post();
+ exit(0);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_17_privacy_manager_fetch_whole_policy_for_self_filtered)
+{
+ const std::string username("sm_test_17_user_name");
+ std::vector<AppInstallHelper> appHelpers;
+ std::vector<ScopedInstaller> scopedInstallations;
+ std::map<std::string, unsigned> privToCount;
+ unsigned policyCount = 0;
+
+ TemporaryTestUser user(username, static_cast<GumUserType>(GUM_USERTYPE_NORMAL), false);
+ user.create();
+
+ for (unsigned int i = 0; i < TEST_PRIVILEGES.size(); i++) {
+ AppInstallHelper app("sm_test_17_" + std::to_string(i), user.getUid());
+ app.addPrivileges(TEST_PRIVILEGES[i]);
+ policyCount += app.getPrivileges().size();
+
+ appHelpers.emplace_back(std::move(app));
+ for (auto &priv: TEST_PRIVILEGES[i]) {
+ privToCount[priv]++;
+ }
+ }
+
+ AppInstallHelper privManager("sm_test_17_priv_manager", user.getUid());
+ std::string privManagerAppId = privManager.getAppId();
+ privManager.addPrivilege(SELF_PRIVILEGE);
+ privToCount[SELF_PRIVILEGE]++;
+ policyCount += privManager.getPrivileges().size();
+
+ appHelpers.emplace_back(std::move(privManager));
+ for (const auto &app : appHelpers)
+ scopedInstallations.emplace_back(std::move(ScopedInstaller(app)));
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_MSG(pid >= 0, "fork failed");
+ if (pid != 0)//parent process
+ {
+ waitPid(pid);
+ } else {
+ Api::setProcessLabel(privManagerAppId);
+ RUNNER_ASSERT_MSG(drop_root_privileges(user.getUid(), user.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ for (const auto &privCount : privToCount) {
+ std::vector<PolicyEntry> policyEntries;
+ PolicyEntry filter(SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY, privCount.first);
+ Api::getPolicy(filter, policyEntries);
+ RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
+ RUNNER_ASSERT_MSG(policyEntries.size() == privCount.second,
+ "Number of policies doesn't match - should be: " << privCount.second
+ << " and is " << policyEntries.size());
+ }
+
+ for (const auto &app : appHelpers) {
+ std::vector<PolicyEntry> policyEntries;
+ PolicyEntry filter(app.getAppId(), SECURITY_MANAGER_ANY, SECURITY_MANAGER_ANY);
+ Api::getPolicy(filter, policyEntries);
+ RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
+ RUNNER_ASSERT_MSG(policyEntries.size() == app.getPrivileges().size(),
+ "Number of policies doesn't match - should be: " << app.getPrivileges().size()
+ << " and is " << policyEntries.size());
+ }
+
+ std::vector<PolicyEntry> policyEntries;
+ PolicyEntry filter(SECURITY_MANAGER_ANY, user.getUidString(), SECURITY_MANAGER_ANY);
+ Api::getPolicy(filter, policyEntries);
+ RUNNER_ASSERT_MSG(policyEntries.size() != 0, "Policy is empty");
+ RUNNER_ASSERT_MSG(policyEntries.size() == policyCount,
+ "Number of policies doesn't match - should be: " << policyCount
+ << " and is " << policyEntries.size());
+
+ exit(0);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_18_privacy_manager_privacy_related_privileges_policy_install_remove)
+{
+ const std::string askUserDescription = "Ask user";
+ TemporaryTestUser user("sm_test_18_username", GUM_USERTYPE_NORMAL);
+ user.create();
+
+ AppInstallHelper app("sm_test_18", user.getUid());
+ app.addPrivileges(TEST_PRIVACY_PRIVILEGES[0]);
+
+ PolicyEntry filter (app.getAppId(), user.getUidString(), SECURITY_MANAGER_ANY);
+ std::vector<PolicyEntry> policyEntries;
+ {
+ ScopedInstaller installer(app);
+ unsigned int privacyNum = countPrivacyPrivileges(app.getPrivileges());
+
+ Api::getPolicy(filter, policyEntries);
+
+ RUNNER_ASSERT_MSG(policyEntries.size() == app.getPrivileges().size(),
+ "Number of policy entries doesn't match; should be " << app.getPrivileges().size()
+ << " but is " << policyEntries.size());
+
+ if (PolicyConfiguration::getIsAskuserEnabled() ) {
+ unsigned int privacyActNum = 0;
+ for (auto &entry : policyEntries)
+ if (isPrivilegePrivacy(entry.getPrivilege())) {
+ RUNNER_ASSERT_MSG(entry.getCurrentLevel() == askUserDescription,
+ "Invalid policy setup; policy should be \"Ask user\" but is "
+ << entry.getCurrentLevel());
+ ++privacyActNum;
+ }
+ RUNNER_ASSERT_MSG(privacyActNum == privacyNum,
+ "Should be " << privacyNum << " privacy privileges,"
+ "but is " << privacyActNum);
+ }
+ }
+
+ policyEntries.clear();
+ Api::getPolicy(filter, policyEntries);
+ RUNNER_ASSERT_MSG(policyEntries.size() == 0,
+ "After deinstallation, policy entries size should be 0,"
+ "but is: " << policyEntries.size());
+}
+
+void test_privacy_related_privileges(bool isHybrid) {
+ const std::string askUserDescription = "Ask user";
+ TemporaryTestUser user("sm_test_19_username", GUM_USERTYPE_NORMAL);
+ user.create();
+
+ const std::string pkgId = "sm_test_19_pkg_id";
+
+ AppInstallHelper app1("sm_test_19_app_id_1", pkgId, user.getUid());
+ if (isHybrid)
+ app1.setHybrid();
+ app1.addPrivileges(TEST_PRIVACY_PRIVILEGES[0]);
+ ScopedInstaller installer1(app1);
+
+ AppInstallHelper app2("sm_test_19_app_id_2", pkgId, user.getUid());
+ if (isHybrid)
+ app2.setHybrid();
+ app2.addPrivileges(TEST_PRIVACY_PRIVILEGES[1]);
+ ScopedInstaller installer2(app2);
+
+ int privacyCount1, privacyCount2;
+ if (!PolicyConfiguration::getIsAskuserEnabled()) {
+ privacyCount1 = 0;
+ privacyCount2 = 0;
+ } else if (isHybrid) {
+ privacyCount1 = countPrivacyPrivileges(app1.getPrivileges());
+ privacyCount2 = countPrivacyPrivileges(app2.getPrivileges());
+ } else {
+ privacyCount1 = privacyCount2 = countPrivacyPrivileges(app2.getPrivileges());
+ }
+
+ std::vector<PolicyEntry> policyEntries;
+ PolicyEntry filter(SECURITY_MANAGER_ANY, user.getUidString(), SECURITY_MANAGER_ANY);
+ Api::getPolicy(filter, policyEntries);
+
+ int privacyAct1 = 0, privacyAct2 = 0;
+ for (auto &entry : policyEntries) {
+ RUNNER_ASSERT_MSG(entry.getAppId() == app1.getAppId() || entry.getAppId() == app2.getAppId(),
+ "Invalid appId: should be either " << app1.getAppId() << " or "
+ << app2.getAppId() << " but is " << entry.getAppId());
+ if (PolicyConfiguration::getIsAskuserEnabled() && isPrivilegePrivacy(entry.getPrivilege())) {
+ RUNNER_ASSERT_MSG(entry.getCurrentLevel() == askUserDescription,
+ "Invalid policy setup; policy should be \"Ask user\" but is "
+ << entry.getCurrentLevel());
+ if (entry.getAppId() == app1.getAppId())
+ ++privacyAct1;
+ else
+ ++privacyAct2;
+ }
+ }
+ RUNNER_ASSERT_MSG(privacyCount1 == privacyAct1, "Should be " << privacyCount1
+ << " privacy privileges, but is " << privacyAct1);
+ RUNNER_ASSERT_MSG(privacyCount2 == privacyAct2, "Should be " << privacyCount2
+ << " privacy privileges, but is " << privacyAct2);
+}
+
+RUNNER_CHILD_TEST(security_manager_19a_privacy_manager_privacy_related_privileges_policy_hybrid)
+{
+ test_privacy_related_privileges(true);
+}
+
+RUNNER_CHILD_TEST(security_manager_19b_privacy_manager_privacy_related_privileges_policy_no_hybrid)
+{
+ test_privacy_related_privileges(false);
+}
+
+RUNNER_CHILD_TEST(security_manager_20_privacy_manager_privacy_related_privileges_policy_admin_check)
+{
+ const std::string askUserDescription = "Ask user";
+ TemporaryTestUser user("sm_test_20_username", GUM_USERTYPE_NORMAL);
+ user.create();
+
+ AppInstallHelper app("sm_test_20", user.getUid());
+ app.addPrivileges(TEST_PRIVACY_PRIVILEGES[0]);
+
+ ScopedInstaller installer(app);
+
+ CynaraTestAdmin::Admin admin;
+ int policyType = CYNARA_ADMIN_ALLOW;
+ int privacyPolicyType = -1;
+ if (PolicyConfiguration::getIsAskuserEnabled())
+ admin.getPolicyTypeForDescription(askUserDescription, privacyPolicyType);
+
+ for (auto &priv : app.getPrivileges()) {
+ if (PolicyConfiguration::getIsAskuserEnabled() && isPrivilegePrivacy(priv)) {
+ admin.adminCheck("", true, app.generateAppLabel().c_str(),
+ user.getUidString().c_str(), priv.c_str(), privacyPolicyType,
+ nullptr);
+ } else {
+ admin.adminCheck("", true, app.generateAppLabel().c_str(),
+ user.getUidString().c_str(), priv.c_str(), policyType, nullptr);
+ }
+ }
+}
--- /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.
+ */
+
+// This has to be before xattr header, because it uses size_t and ssize_t and does not include this
+// I hate you, xattr
+#include <sys/types.h>
+#include <attr/xattr.h>
+#include <ftw.h>
+#include <string>
+#include <sys/smack.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <vector>
+
+#include <app_install_helper.h>
+#include <dpl/test/test_runner.h>
+#include <memory.h>
+#include <scoped_installer.h>
+#include <sm_api.h>
+#include <sm_commons.h>
+#include <sm_request.h>
+#include <sm_sharing_request.h>
+#include <tests_common.h>
+
+using namespace SecurityManagerTest;
+
+RUNNER_TEST_GROUP_INIT(SECURIT_MANAGER_PRIVATE_SHARING)
+
+/*
+ * Check if request is rejected when incomplete
+ */
+RUNNER_TEST(security_manager_30a_send_incomplete_req1)
+{
+ SharingRequest request;
+ Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+ request.setOwnerAppId("sm_test_30a_owner_app_id");
+ Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+ request.setTargetAppId("sm_test_30a_target_app_id");
+ Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+}
+
+RUNNER_TEST(security_manager_30b_send_incomplete_req2)
+{
+ SharingRequest request;
+ request.setTargetAppId("sm_test_30b_target_app_id");
+ Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+ request.setOwnerAppId("sm_test_30b_owner_app_id");
+ Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+}
+
+RUNNER_TEST(security_manager_30c_send_incomplete_req3)
+{
+ SharingRequest request;
+ const char *somePaths[] = {"path1", "path2"};
+ request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0]));
+ Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+ request.setOwnerAppId("sm_test_30_b_owner_app_id");
+ Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+}
+
+/*
+ * Check if sharing request for unknown owner app is rejected
+ */
+
+RUNNER_TEST(security_manager_30d_unknown_owner)
+{
+ AppInstallHelper target("sm_test_30d_target");
+ ScopedInstaller targetInstall(target);
+
+ AppInstallHelper notInstalledOwner("sm_test_30d_notinstalled_owner");
+ notInstalledOwner.createPrivateFile();
+
+ SharingRequest request;
+ request.setOwnerAppId(notInstalledOwner.getAppId());
+ request.setTargetAppId(target.getAppId());
+
+ std::string sharedPath = notInstalledOwner.getPrivatePath();
+ const char *paths[] = {sharedPath.c_str()};
+ request.addPaths(paths, 1);
+ Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
+}
+
+/*
+ * Check if sharing request for unknown target app is rejected
+ */
+RUNNER_TEST(security_manager_30e_unknown_target)
+{
+ AppInstallHelper owner("sm_test_30e_owner");
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ SharingRequest request;
+ request.setOwnerAppId(owner.getAppId());
+ request.setTargetAppId("sm_test_30e_notinstalled_target");
+
+ std::string sharedPath = owner.getPrivatePath();
+ const char *paths[] = {sharedPath.c_str()};
+ request.addPaths(paths, 1);
+ Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
+}
+
+/*
+ * Check if sharing not owned path is rejected
+ */
+RUNNER_TEST(security_manager_30f_bad_paths)
+{
+ AppInstallHelper owner("sm_test_30f_owner");
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target("sm_test_30f_target");
+ target.createPrivateFile();
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+
+ std::string sharedPath = target.getPrivatePath();
+ const char *paths[] = {sharedPath.c_str()};
+ share.addPaths(paths, 1);
+ Api::applySharing(share, SECURITY_MANAGER_ERROR_APP_NOT_PATH_OWNER);
+}
+
+/*
+ * Check proper access for sharing one path between applications from different packages
+ */
+RUNNER_CHILD_TEST(security_manager_31_simple_share)
+{
+ AppInstallHelper owner("sm_test_31_owner");
+ owner.createPrivateFile(0);
+ owner.createPrivateFile(1);
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target("sm_test_31_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ std::string sharedPath = owner.getPrivatePath(0);
+ std::string privatePath = owner.getPrivatePath(1);
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share.addPaths(paths, 1);
+ Api::applySharing(share);
+
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ //execute access is given to directory containing file. files have the same label as directories.
+ runAccessTest(target, privatePath, X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, 0);
+ runAccessTest(target, privatePath, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+}
+/*
+ * Private sharing can be applied multiple times. Check if double private path sharing applying
+ * between two applications from different package is accepted and if access is properly set after
+ * fist and second apply and if is properly revoked only after second drop.
+ *
+ */
+RUNNER_CHILD_TEST(security_manager_32_double_share)
+{
+ AppInstallHelper owner("sm_test_32_owner");
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target("sm_test_32_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ std::string sharedPath = owner.getPrivatePath();
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share.addPaths(paths, 1);
+
+ Api::applySharing(share);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::applySharing(share);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+}
+
+/*
+ * Check access after sharing separate private paths with one application in two separate
+ * sharing requests.
+ */
+RUNNER_CHILD_TEST(security_manager_33a_share_two_with_one)
+{
+ AppInstallHelper owner("sm_test_33a_owner");
+ owner.createPrivateFile(0);
+ owner.createPrivateFile(1);
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target("sm_test_33a_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share1, share2;
+ std::string sharedPath1 = owner.getPrivatePath(0);
+ std::string sharedPath2 = owner.getPrivatePath(1);
+ share1.setOwnerAppId(owner.getAppId());
+ share2.setOwnerAppId(owner.getAppId());
+ share1.setTargetAppId(target.getAppId());
+ share2.setTargetAppId(target.getAppId());
+ const char *paths1[] = {sharedPath1.c_str()};
+ share1.addPaths(paths1, 1);
+ const char *paths2[] = {sharedPath2.c_str()};
+ share2.addPaths(paths2, 1);
+
+ Api::applySharing(share1);
+ runAccessTest(owner, sharedPath1, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath1, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath1, R_OK|W_OK|X_OK);
+
+ Api::applySharing(share2);
+ runAccessTest(owner, sharedPath2, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath2, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath2, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share1);
+ runAccessTest(owner, sharedPath1, R_OK|W_OK|X_OK);
+ //execute access is given to directory containing file. files have the same label as directories.
+ runAccessTest(target, sharedPath1, X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath1, R_OK|W_OK|X_OK);
+ runAccessTest(owner, sharedPath2, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath2, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath2, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share2);
+ runAccessTest(owner, sharedPath2, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath2, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath1, R_OK|W_OK|X_OK);
+}
+
+/*
+ * Check access after sharing separate private paths with one application in one sharing requests.
+ */
+RUNNER_CHILD_TEST(security_manager_33b_share_two_with_one)
+{
+ AppInstallHelper owner("sm_test_33b_owner");
+ owner.createPrivateFile(0);
+ owner.createPrivateFile(1);
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target("sm_test_33b_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ std::string sharedPath1 = owner.getPrivatePath(0);
+ std::string sharedPath2 = owner.getPrivatePath(1);
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+ const char *paths[] = {sharedPath1.c_str(), sharedPath2.c_str()};
+
+ share.addPaths(paths, 2);
+
+ Api::applySharing(share);
+ runAccessTest(owner, sharedPath1, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath1, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath1, R_OK|W_OK|X_OK);
+ runAccessTest(owner, sharedPath2, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath2, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath2, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share);
+ runAccessTest(owner, sharedPath1, R_OK|W_OK|X_OK);
+ runAccessTest(owner, sharedPath2, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath1, 0);
+ runAccessTest(target, sharedPath2, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath1, R_OK|W_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath2, R_OK|W_OK|X_OK);
+}
+
+/*
+ * Check access when sharing one private path with two separate applications.
+ */
+RUNNER_CHILD_TEST(security_manager_34_share_one_with_two)
+{
+ AppInstallHelper owner("sm_test_34_owner");
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target1("sm_test_34_target1");
+ ScopedInstaller targetInstall1(target1);
+
+ AppInstallHelper target2("sm_test_34_target2");
+ ScopedInstaller targetInstall2(target2);
+
+ SharingRequest share1, share2;
+ std::string sharedPath = owner.getPrivatePath(0).c_str();
+ share1.setOwnerAppId(owner.getAppId());
+ share2.setOwnerAppId(owner.getAppId());
+ share1.setTargetAppId(target1.getAppId());
+ share2.setTargetAppId(target2.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share1.addPaths(paths, 1);
+ share2.addPaths(paths, 1);
+
+ Api::applySharing(share1);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target1, sharedPath, R_OK|X_OK);
+ runAccessTest(target2, sharedPath, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::applySharing(share2);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target2, sharedPath, R_OK|X_OK);
+ runAccessTest(target1, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share1);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target1, sharedPath, 0);
+ runAccessTest(target2, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share2);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target1, sharedPath, 0);
+ runAccessTest(target2, sharedPath, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+}
+
+/*
+ * Check access when sharing two separate private paths with two separate applications.
+ */
+RUNNER_CHILD_TEST(security_manager_35_share_two_with_two)
+{
+ AppInstallHelper owner("sm_test_35_owner");
+ owner.createPrivateFile(0);
+ owner.createPrivateFile(1);
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target1("sm_test_35_target1");
+ ScopedInstaller targetInstall1(target1);
+
+ AppInstallHelper target2("sm_test_35_target2");
+ ScopedInstaller targetInstall2(target2);
+
+ SharingRequest share1, share2;
+ std::string sharedPath1 = owner.getPrivatePath(0).c_str();
+ std::string sharedPath2 = owner.getPrivatePath(1).c_str();
+ share1.setOwnerAppId(owner.getAppId());
+ share2.setOwnerAppId(owner.getAppId());
+ share1.setTargetAppId(target1.getAppId());
+ share2.setTargetAppId(target2.getAppId());
+ const char *paths1[] = {sharedPath1.c_str()};
+ share1.addPaths(paths1, 1);
+ const char *paths2[] = {sharedPath2.c_str()};
+ share2.addPaths(paths2, 1);
+
+ Api::applySharing(share1);
+ runAccessTest(owner, sharedPath1, R_OK|W_OK|X_OK);
+ runAccessTest(target1, sharedPath1, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath1, R_OK|W_OK|X_OK);
+
+ Api::applySharing(share2);
+ runAccessTest(owner, sharedPath2, R_OK|W_OK|X_OK);
+ runAccessTest(target1, sharedPath1, R_OK|X_OK);
+ runAccessTest(target1, sharedPath2, 0);
+ runAccessTest(target2, sharedPath2, R_OK|X_OK);
+ runAccessTest(target2, sharedPath1, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath2, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share2);
+ runAccessTest(owner, sharedPath1, R_OK|W_OK|X_OK);
+ runAccessTest(owner, sharedPath2, R_OK|W_OK|X_OK);
+ runAccessTest(target1, sharedPath1, R_OK|X_OK);
+ runAccessTest(target2, sharedPath2, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath2, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share1);
+ runAccessTest(owner, sharedPath1, R_OK|W_OK|X_OK);
+ runAccessTest(owner, sharedPath2, R_OK|W_OK|X_OK);
+ runAccessTest(target1, sharedPath1, 0);
+ runAccessTest(target2, sharedPath2, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath1, R_OK|W_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath2, R_OK|W_OK|X_OK);
+}
+
+/*
+ * Check access after sharing one private path with one application and after uninstalling target
+ * application.
+ */
+RUNNER_CHILD_TEST(security_manager_35_share_uninstall_target) {
+ AppInstallHelper owner("sm_test_35_owner");
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target("sm_test_35_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ std::string sharedPath = owner.getPrivatePath();
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share.addPaths(paths, 1);
+ Api::applySharing(share);
+
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ targetInstall.uninstallApp();
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ // Reinstall, so we can change context to same app_id
+ ScopedInstaller targetInstall2(target);
+ runAccessTest(target, sharedPath, 0);
+
+ Api::dropSharing(share, SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
+/*
+ * Check access after sharing one private path with one application and after uninstalling owner
+ * application.
+ */
+RUNNER_CHILD_TEST(security_manager_35_share_uninstall_owner) {
+ AppInstallHelper owner("sm_test_35_owner");
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target("sm_test_35_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ std::string sharedPath = owner.getPrivatePath();
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share.addPaths(paths, 1);
+ Api::applySharing(share);
+
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ ownerInstall.uninstallApp();
+
+ runAccessTest(target, sharedPath, 0);
+
+ Api::dropSharing(share, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
+
+}
+
+/*
+ * Check access after sharing one private path with one application and after uninstalling owner
+ * application from package with two applications.
+ */
+RUNNER_CHILD_TEST(security_manager_36_share_pkg_owner_uninstall) {
+ std::string pkgName = "sm_test_36";
+ AppInstallHelper owner("sm_test_36_owner", pkgName);
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper samePkgAsOwnerApp("sm_test_36", pkgName);
+ ScopedInstaller samePkgAsOwnerInstall(samePkgAsOwnerApp);
+
+ AppInstallHelper target("sm_test_36_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ std::string sharedPath = owner.getPrivatePath();
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share.addPaths(paths, 1);
+ Api::applySharing(share);
+
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(samePkgAsOwnerApp, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ ownerInstall.uninstallApp();
+
+ runAccessTest(target, sharedPath, 0);
+
+ Api::dropSharing(share, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
+}
+
+/*
+ * Check access after sharing one private path with one application when owner application is from
+ * package with two applications.
+ */
+RUNNER_CHILD_TEST(security_manager_36_share_pkg_owner_drop) {
+ std::string pkgName = "sm_test_36";
+ AppInstallHelper owner("sm_test_36_owner", pkgName);
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper samePkgAsOwnerApp("sm_test_36", pkgName);
+ ScopedInstaller samePkgAsOwnerInstall(samePkgAsOwnerApp);
+
+ AppInstallHelper target("sm_test_36_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ std::string sharedPath = owner.getPrivatePath();
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share.addPaths(paths, 1);
+ Api::applySharing(share);
+
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(samePkgAsOwnerApp, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share);
+
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(samePkgAsOwnerApp, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+}
+
+/*
+ * Check access after sharing one private path with one application and after uninstalling target
+ * application when owner application is from package with two applications.
+ */
+RUNNER_CHILD_TEST(security_manager_36_share_pkg_target_uninstall) {
+ std::string pkgName = "sm_test_36";
+ AppInstallHelper owner("sm_test_36_owner", pkgName);
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper samePkgAsOwnerApp("sm_test_36", pkgName);
+ ScopedInstaller samePkgAsOwnerInstall(samePkgAsOwnerApp);
+
+ AppInstallHelper target("sm_test_36_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ std::string sharedPath = owner.getPrivatePath();
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share.addPaths(paths, 1);
+ Api::applySharing(share);
+
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(samePkgAsOwnerApp, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ targetInstall.uninstallApp();
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(samePkgAsOwnerApp, sharedPath, R_OK|W_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ // Reinstall, so we can change context to same app_id
+ ScopedInstaller targetInstall2(target);
+ runAccessTest(target, sharedPath, 0);
+
+ Api::dropSharing(share, SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
+/*
+ * Check access after double sharing one private path with one application and after uninstalling
+ * target application when owner application is from package with two applications.
+ */
+RUNNER_CHILD_TEST(security_manager_37_pkg_double_share_target_uninstall) {
+ std::string pkgName = "sm_test_37";
+ AppInstallHelper owner("sm_test_37_owner", pkgName);
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper samePkgAsOwnerApp("sm_test_37", pkgName);
+ ScopedInstaller samePkgAsOwnerInstall(samePkgAsOwnerApp);
+
+ AppInstallHelper target("sm_test_37_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ std::string sharedPath = owner.getPrivatePath();
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share.addPaths(paths, 1);
+ Api::applySharing(share);
+ Api::applySharing(share);
+
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(samePkgAsOwnerApp, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ targetInstall.uninstallApp();
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(samePkgAsOwnerApp, sharedPath, R_OK|W_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ // Reinstall, so we can change context to same app_id
+ ScopedInstaller targetInstall2(target);
+ runAccessTest(target, sharedPath, 0);
+
+ Api::dropSharing(share, SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
+/*
+ * Check access after double sharing one private path with one application and after uninstalling
+ * owner application from package with two applications.
+ */
+RUNNER_CHILD_TEST(security_manager_37_pkg_double_share_owner_uninstall) {
+ std::string pkgName = "sm_test_37";
+ AppInstallHelper owner("sm_test_37_owner", pkgName);
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper samePkgAsOwnerApp("sm_test_37", pkgName);
+ ScopedInstaller samePkgAsOwnerInstall(samePkgAsOwnerApp);
+
+ AppInstallHelper target("sm_test_37_target");
+ ScopedInstaller targetInstall(target);
+
+ SharingRequest share;
+ std::string sharedPath = owner.getPrivatePath();
+ share.setOwnerAppId(owner.getAppId());
+ share.setTargetAppId(target.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share.addPaths(paths, 1);
+ Api::applySharing(share);
+ Api::applySharing(share);
+
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(samePkgAsOwnerApp, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ ownerInstall.uninstallApp();
+
+ runAccessTest(target, sharedPath, 0);
+
+ Api::dropSharing(share, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
+}
+
+/*
+ * Check access after sharing one private path with two applications from different packages and
+ * after uninstalling one of them and dropping second sharing.
+ */
+RUNNER_CHILD_TEST(security_manager_38_share_one_with_two_uninstall_target)
+{
+ AppInstallHelper owner("sm_test_34_owner");
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target1("sm_test_34_target1");
+ ScopedInstaller targetInstall1(target1);
+
+ AppInstallHelper target2("sm_test_34_target2");
+ ScopedInstaller targetInstall2(target2);
+
+ SharingRequest share1, share2;
+ std::string sharedPath = owner.getPrivatePath(0).c_str();
+ share1.setOwnerAppId(owner.getAppId());
+ share2.setOwnerAppId(owner.getAppId());
+ share1.setTargetAppId(target1.getAppId());
+ share2.setTargetAppId(target2.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share1.addPaths(paths, 1);
+ share2.addPaths(paths, 1);
+
+ Api::applySharing(share1);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target1, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::applySharing(share2);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target2, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ targetInstall1.uninstallApp();
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target2, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ // Reinstall, so we can change context to same app_id
+ ScopedInstaller targetInstall1_2(target1);
+ runAccessTest(target1, sharedPath, 0);
+
+ Api::dropSharing(share2);
+
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target2, sharedPath, 0);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::dropSharing(share1, SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
+/*
+ * Check access after sharing one private path with two applications from different packages and
+ * after uninstalling owner application.
+ */
+RUNNER_CHILD_TEST(security_manager_38_share_one_with_two_uninstall_owner)
+{
+ AppInstallHelper owner("sm_test_34_owner");
+ owner.createPrivateFile();
+ ScopedInstaller ownerInstall(owner);
+
+ AppInstallHelper target1("sm_test_34_target1");
+ ScopedInstaller targetInstall1(target1);
+
+ AppInstallHelper target2("sm_test_34_target2");
+ ScopedInstaller targetInstall2(target2);
+
+ SharingRequest share1, share2;
+ std::string sharedPath = owner.getPrivatePath(0).c_str();
+ share1.setOwnerAppId(owner.getAppId());
+ share2.setOwnerAppId(owner.getAppId());
+ share1.setTargetAppId(target1.getAppId());
+ share2.setTargetAppId(target2.getAppId());
+ const char *paths[] = {sharedPath.c_str()};
+ share1.addPaths(paths, 1);
+ share2.addPaths(paths, 1);
+
+ Api::applySharing(share1);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target1, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ Api::applySharing(share2);
+ runAccessTest(owner, sharedPath, R_OK|W_OK|X_OK);
+ runAccessTest(target2, sharedPath, R_OK|X_OK);
+ runSystemAccessTest(geteuid(), getegid(), sharedPath, R_OK|W_OK|X_OK);
+
+ ownerInstall.uninstallApp();
+
+ runAccessTest(target2, sharedPath, 0);
+
+ Api::dropSharing(share1, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
+ Api::dropSharing(share2, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
+}
--- /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 <cstdint>
+#include <fcntl.h>
+#include <unordered_map>
+#include <string>
+#include <sys/smack.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <dpl/test/test_runner.h>
+#include <sm_commons.h>
+#include <tests_common.h>
+#include <scoped_installer.h>
+#include <scoped_path_remover.h>
+
+using namespace SecurityManagerTest;
+
+namespace {
+
+const uid_t OWNER_UID = 5001;
+
+const std::vector<std::string> versions = {
+ "2.4",
+ "3.0"
+};
+
+typedef std::vector<std::pair<std::string, std::string>> VersionCombinations;
+
+VersionCombinations makeVersionCombinations(const std::vector<std::string> &versions) {
+ VersionCombinations verCombs;
+ for (const auto &version1 : versions)
+ for (const auto &version2: versions)
+ verCombs.push_back({version1, version2});
+ return verCombs;
+}
+
+const VersionCombinations versionCombinations = makeVersionCombinations(versions);
+
+} //anonymous namespace
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_SHARED_RO)
+
+/**
+ * Check whether owner app have access to own sharedRO dir
+ */
+RUNNER_CHILD_TEST(security_manager_76_owner_access)
+{
+ for (const auto &version : versions) {
+ AppInstallHelper app("sm_test_76a", OWNER_UID, version);
+ app.createSharedRODir();
+ ScopedInstaller sharedROPkgApp(app);
+
+ runAccessTest(app, app.getSharedRODir(), R_OK|W_OK|X_OK);
+ }
+}
+
+/**
+ * Check whether app without shared RO path has access to shared RO dir and
+ * no access to private directories of application from different package between
+ * different version combinations
+ */
+RUNNER_CHILD_TEST(security_manager_77_owner_other_access_version_combinations)
+{
+ for (const auto &version : versionCombinations) {
+ AppInstallHelper sharedApp("sm_test_77_shared", OWNER_UID, version.first);
+ sharedApp.createSharedRODir();
+ sharedApp.createPrivateDir();
+ ScopedInstaller sharedAppInstall(sharedApp);
+
+ AppInstallHelper nonSharedApp("sm_test_77_nonshared", OWNER_UID, version.second);
+ ScopedInstaller nonSharedAppInstall(nonSharedApp);
+
+ runAccessTest(sharedApp, sharedApp.getSharedRODir(), R_OK|W_OK|X_OK);
+ runAccessTest(nonSharedApp, sharedApp.getPrivateDir(), 0);
+ runAccessTest(nonSharedApp, sharedApp.getSharedRODir(), R_OK|X_OK);
+ }
+}
+
+/**
+ * Check whether app with shared RO dir has access to shared RO dir and no access to
+ * private paths of an application from different package between different version
+ * combinations
+ */
+RUNNER_CHILD_TEST(security_manager_78_another_pkg_shared_ro_have_ro_access_to_shared_ro)
+{
+ for (const auto &version : versionCombinations) {
+ AppInstallHelper sharedApp1("sm_test_78_shared1", OWNER_UID, version.first);
+ sharedApp1.createSharedRODir();
+ sharedApp1.createPrivateDir();
+ ScopedInstaller sharedAppInstall1(sharedApp1);
+
+ AppInstallHelper sharedApp2("sm_test_78_shared2", OWNER_UID, version.second);
+ sharedApp2.createSharedRODir();
+ sharedApp2.createPrivateDir();
+ ScopedInstaller sharedApp2Install(sharedApp2);
+
+ runAccessTest(sharedApp2, sharedApp1.getSharedRODir(), R_OK|X_OK);
+ runAccessTest(sharedApp1, sharedApp2.getSharedRODir(), R_OK|X_OK);
+ runAccessTest(sharedApp1, sharedApp1.getSharedRODir(), R_OK|W_OK|X_OK);
+ runAccessTest(sharedApp2, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
+ runAccessTest(sharedApp2, sharedApp1.getPrivateDir(), 0);
+ runAccessTest(sharedApp1, sharedApp2.getPrivateDir(), 0);
+ }
+}
+
+/**
+ * Install two apps with shared RO dirs from one package and check accesses
+ * to shared RO dirs with different versions
+ */
+RUNNER_CHILD_TEST(security_manager_79a_same_pkg_shared_ro_have_ro_access_to_shared_ro)
+{
+ const std::string sharedPkgName = "sm_test_79a";
+
+ for (const auto &version : versions) {
+ AppInstallHelper sharedApp1("sm_test_79a_shared1", sharedPkgName, OWNER_UID, version);
+ sharedApp1.createSharedRODir();
+ ScopedInstaller sharedAppInstall1(sharedApp1);
+
+ AppInstallHelper sharedApp2("sm_test_79a_shared2", sharedPkgName, OWNER_UID, version);
+ sharedApp2.createSharedRODir();
+ ScopedInstaller sharedAppInstall2(sharedApp2);
+
+ runAccessTest(sharedApp2, sharedApp1.getSharedRODir(), R_OK|W_OK|X_OK);
+ runAccessTest(sharedApp1, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
+ };
+}
+
+/**
+ * Install two apps with and without shared RO dirs from one package and check accesses
+ * to shared RO dir with different versions
+ */
+RUNNER_CHILD_TEST(security_manager_79b_same_pkg_shared_ro_have_ro_access_to_shared_ro)
+{
+ const std::string sharedPkgName = "sm_test_79b";
+
+ for (const auto &version : versions) {
+ AppInstallHelper sharedApp("sm_test_79b_shared1", sharedPkgName, OWNER_UID, version);
+ sharedApp.createSharedRODir();
+ ScopedInstaller sharedAppInstall(sharedApp);
+
+ AppInstallHelper nonSharedApp("sm_test_79b_shared2", sharedPkgName, OWNER_UID, version);
+ ScopedInstaller nonSharedAppInstall(nonSharedApp);
+
+ runAccessTest(nonSharedApp, sharedApp.getSharedRODir(), R_OK|W_OK|X_OK);
+ };
+}
+
+/**
+ * Check whether sharedRO application from same pkg have proper access to private dir
+ * of other sharedRO app, then uninstall first app of sharedRO pkg application and check
+ * if access to second sharedRO remains.
+ */
+RUNNER_CHILD_TEST(security_manager_80_same_pkg_shared_ro_have_no_access_to_shared_ro_app_ro_dir)
+{
+ std::string sharedPkgName = "sm_test_80";
+ for (const auto &version : versions) {
+ AppInstallHelper sharedApp1("sm_test_80_shared1", sharedPkgName, OWNER_UID, version);
+ sharedApp1.createPrivateDir(1);
+ sharedApp1.createSharedRODir(1);
+ ScopedInstaller sharedAppInstall1(sharedApp1);
+
+ AppInstallHelper sharedApp2("sm_test_80_shared2", sharedPkgName, OWNER_UID, version);
+ sharedApp2.createPrivateDir(2);
+ sharedApp2.createSharedRODir(2);
+ ScopedInstaller sharedAppInstall2(sharedApp2);
+
+ AppInstallHelper nonSharedApp("sm_test_80_nonshared", sharedPkgName, OWNER_UID, version);
+ ScopedInstaller nonSharedAppInstall(nonSharedApp);
+
+ runAccessTest(sharedApp2, sharedApp1.getPrivateDir(1), R_OK|W_OK|X_OK);
+ runAccessTest(sharedApp1, sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK);
+ runAccessTest(nonSharedApp, sharedApp1.getPrivateDir(1), R_OK|W_OK|X_OK);
+ runAccessTest(nonSharedApp, sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK);
+
+ sharedAppInstall1.uninstallApp();
+
+ runAccessTest(nonSharedApp, sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK);
+ }
+}
+
+/**
+ * Try to add valid sharedRO dir to an app and check all possible accesses to to it.
+ */
+RUNNER_CHILD_TEST(security_manager_81_add_path_to_app_and_check_all)
+{
+ for (const auto &version : versionCombinations) {
+ AppInstallHelper sharedApp("sm_test_83_shared1", OWNER_UID, version.first);
+ sharedApp.createPrivateDir();
+ sharedApp.createSharedRODir();
+ ScopedInstaller sharedAppInstall(sharedApp);
+
+ AppInstallHelper nonSharedApp("sm_test_83_nonshared", OWNER_UID, version.first);
+ ScopedInstaller nonSharedAppInstall(nonSharedApp);
+
+ AppInstallHelper sharedApp2("sm_test_83_shared2", OWNER_UID, version.second);
+ ScopedInstaller nonSharedAppInstall2(sharedApp2);
+
+ //Post install
+ sharedApp2.createSharedRODir();
+
+ PathsRequest sharedRORequest;
+ sharedRORequest.setPkgId(sharedApp2.getPkgId());
+ sharedRORequest.addPath(sharedApp2.getSharedRODir(), SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
+ sharedRORequest.setUid(sharedApp2.getUID());
+ Api::registerPaths(sharedRORequest);
+
+ runAccessTest(sharedApp, sharedApp.getSharedRODir(), R_OK|W_OK|X_OK);
+ runAccessTest(sharedApp, sharedApp.getPrivateDir(), R_OK|W_OK|X_OK);
+
+ runAccessTest(sharedApp2, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
+ runAccessTest(sharedApp2, sharedApp.getSharedRODir(), R_OK|X_OK);
+ runAccessTest(sharedApp2, sharedApp.getPrivateDir(), 0);
+
+ runAccessTest(nonSharedApp, sharedApp.getSharedRODir(), R_OK|X_OK);
+ runAccessTest(nonSharedApp, sharedApp2.getSharedRODir(), R_OK|X_OK);
+ runAccessTest(nonSharedApp, sharedApp.getPrivateDir(), 0);
+ }
+}
+
+/**
+ * Try to add path which does not belong to an app and check if operation fails.
+ */
+RUNNER_CHILD_TEST(security_manager_82_add_invalid_path_to_app_and_check_all)
+{
+ for (const auto &version : versionCombinations) {
+ AppInstallHelper sharedApp("sm_test_84_shared", OWNER_UID, version.first);
+ sharedApp.createSharedRODir();
+ ScopedInstaller sharedAppInstall(sharedApp);
+
+ AppInstallHelper nonSharedApp("sm_test_84_nonshared", OWNER_UID, version.second);
+ ScopedInstaller nonSharedAppInstall(nonSharedApp);
+
+ PathsRequest sharedRORequest;
+ sharedRORequest.setPkgId(nonSharedApp.getPkgId());
+ sharedRORequest.addPath(sharedApp.getSharedRODir(), SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
+ sharedRORequest.setUid(nonSharedApp.getUID());
+ Api::registerPaths(sharedRORequest, SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED);
+ }
+}
+
+/**
+ * Install and uninstall app and check accesses to uninstalled paths from other packages.
+ */
+RUNNER_CHILD_TEST(security_manager_83_install_uninstall_shared_ro_app_and_check_cleaning)
+{
+ for (const auto &verComb : versionCombinations) {
+ AppInstallHelper sharedApp1("sm_test_85_shared1", OWNER_UID, verComb.first);
+ sharedApp1.createSharedRODir();
+ ScopedInstaller sharedAppInstall1(sharedApp1);
+
+ AppInstallHelper sharedApp2("sm_test_85_shared2", OWNER_UID, verComb.second);
+ sharedApp2.createSharedRODir();
+ ScopedInstaller sharedAppInstall2(sharedApp2);
+
+ AppInstallHelper nonSharedApp("sm_test_85_nonshared", OWNER_UID, verComb.second);
+ ScopedInstaller nonSharedAppInstall(nonSharedApp);
+
+ sharedAppInstall1.uninstallApp();
+
+ runAccessTest(nonSharedApp, sharedApp1.getSharedRODir(), 0);
+ runAccessTest(sharedApp2, sharedApp1.getSharedRODir(), 0);
+
+ runAccessTest(nonSharedApp, sharedApp2.getSharedRODir(), R_OK|X_OK);
+ runAccessTest(sharedApp2, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
+ }
+}
+
+/**
+ * Install multiple SharedRO apps, uninstall one of them and check accesses
+ * to sharedRO path within one package.
+ */
+RUNNER_CHILD_TEST(security_manager_84_install_uninstall_shared_ro_two_apps_in_one_pkg)
+{
+ std::string sharedPkgName = "sm_test_86";
+
+ for (const auto &version : versionCombinations) {
+ AppInstallHelper nonSharedApp("sm_test_86_nonshared", OWNER_UID, version.first);
+ ScopedInstaller nonSharedAppInstall(nonSharedApp);
+
+ // Apps from the same package
+ AppInstallHelper sharedApp1("sm_test_86_shared1", sharedPkgName, OWNER_UID, version.second);
+ sharedApp1.createSharedRODir(1);
+ ScopedInstaller sharedAppInstall1(sharedApp1);
+
+ AppInstallHelper sharedApp2("sm_test_86_shared2", sharedPkgName, OWNER_UID, version.second);
+ sharedApp2.createSharedRODir(2);
+ ScopedInstaller sharedAppInstall2(sharedApp2);
+
+ sharedAppInstall1.uninstallApp();
+
+ runAccessTest(nonSharedApp, sharedApp2.getSharedRODir(2), R_OK|X_OK);
+ runAccessTest(sharedApp2, sharedApp2.getSharedRODir(2), R_OK|W_OK|X_OK);
+ }
+}
--- /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 <cstdint>
+#include <string>
+
+#include <app_install_helper.h>
+#include <dpl/test/test_runner.h>
+#include <scoped_installer.h>
+#include <sm_api.h>
+#include <sm_commons.h>
+#include <temp_test_user.h>
+#include <tests_common.h>
+#include <tzplatform.h>
+
+using namespace SecurityManagerTest;
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_REGISTER_PATH)
+
+RUNNER_TEST(security_manager_54_path_req_no_pkg)
+{
+ TemporaryTestUser user("sm_test_54_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_54", user.getUid());
+ app.createPrivateDir();
+
+ PathsRequest req;
+ req.setPkgId("non-existing-pkg-id");
+ req.setUid(user.getUid());
+ req.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(req, (lib_retcode)SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
+RUNNER_TEST(security_manager_55_path_req_empty_pkg)
+{
+ TemporaryTestUser user("sm_test_55_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+ AppInstallHelper app("sm_test_55", user.getUid());
+ app.createPrivateDir();
+
+ PathsRequest req;
+ req.setPkgId("");
+ req.setUid(user.getUid());
+ req.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(req, (lib_retcode)SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+}
+
+RUNNER_TEST(security_manager_56_path_req_wrong_type)
+{
+ PathsRequest req;
+ req.setInstallType(SM_APP_INSTALL_END,
+ (lib_retcode)SECURITY_MANAGER_ERROR_INPUT_PARAM);
+ req.setInstallType((app_install_type)(SM_APP_INSTALL_NONE-1),
+ (lib_retcode)SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
+RUNNER_TEST(security_manager_57_path_req_wrong_uid)
+{
+ TemporaryTestUser user("sm_test_57_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_57", user.getUid());
+ ScopedInstaller appInstall(app);
+
+ app.createPrivateDir();
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(-1);
+ preq.setInstallType(SM_APP_INSTALL_LOCAL);
+ preq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(preq, (lib_retcode)SECURITY_MANAGER_ERROR_SERVER_ERROR);
+}
+
+RUNNER_TEST(security_manager_58_path_req_empty_paths)
+{
+ TemporaryTestUser user("sm_test_58_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+ AppInstallHelper app("sm_test_58", user.getUid());
+
+ PathsRequest req;
+ req.setPkgId(app.getPkgId());
+ req.setUid(user.getUid());
+ Api::registerPaths(req);
+}
+
+RUNNER_TEST(security_manager_59_path_req_as_root_positive)
+{
+ TemporaryTestUser user("sm_test_59_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_59", user.getUid());
+ ScopedInstaller appInstall(app);
+
+ app.createPrivateDir();
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(user.getUid());
+ preq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(preq, (lib_retcode)SECURITY_MANAGER_SUCCESS);
+}
+
+RUNNER_CHILD_TEST(security_manager_60_path_req_as_user_positive)
+{
+ TemporaryTestUser user("sm_test_60_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_60", user.getUid());
+ ScopedInstaller appInstall(app);
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(user.getUid(), user.getGid()) == 0,
+ "drop_root_privileges failed");
+ app.createPrivateDir();
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(user.getUid());
+ preq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(preq, (lib_retcode)SECURITY_MANAGER_SUCCESS);
+}
+
+RUNNER_CHILD_TEST(security_manager_61_path_req_different_user)
+{
+ TemporaryTestUser user1("sm_test_61_1_user_name", GUM_USERTYPE_NORMAL, false);
+ user1.create();
+ TemporaryTestUser user2("sm_test_61_2_user_name", GUM_USERTYPE_NORMAL, false);
+ user2.create();
+
+ AppInstallHelper app("sm_test_61", user2.getUid());
+ ScopedInstaller appInstall(app);
+
+ app.createPrivateDir();
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid != -1, "Fork failed");
+ if (pid == 0) { // child
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(user1.getUid(), user1.getGid()) == 0,
+ "drop_root_privileges failed");
+
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(user2.getUid());
+ preq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(preq, (lib_retcode)SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED);
+ } else {
+ waitPid(pid);
+ }
+}
+
+static void checkOutsidePath(const std::string& pkgId, uid_t uid, const std::string& path)
+{
+ PathsRequest preq;
+ preq.setPkgId(pkgId);
+ preq.setUid(uid);
+ preq.addPath(path, SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(preq, (lib_retcode)SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED);
+}
+
+RUNNER_TEST(security_manager_62_path_req_path_outside)
+{
+ TemporaryTestUser user1("sm_test_62_1_user_name", GUM_USERTYPE_NORMAL, false);
+ user1.create();
+ TemporaryTestUser user2("sm_test_62_2_user_name", GUM_USERTYPE_NORMAL, false);
+ user2.create();
+
+ AppInstallHelper app("sm_test_62", user1.getUid());
+ AppInstallHelper differentUserApp("sm_test_62", user2.getUid());
+ AppInstallHelper unknownApp("sm_test_62_unknown", user1.getUid());
+
+ ScopedInstaller appInstall(app);
+
+ checkOutsidePath(app.getPkgId(), app.getUID(), unknownApp.getPrivateDir());
+ checkOutsidePath(app.getPkgId(), app.getUID(), differentUserApp.getPrivateDir());
+ checkOutsidePath(app.getPkgId(), app.getUID(), std::string("/home/") + user1.getUserName());
+}
+
+RUNNER_CHILD_TEST(security_manager_63a_path_req_as_user)
+{
+ TemporaryTestUser user("sm_test_63_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_63", user.getUid());
+ ScopedInstaller appInstall(app);
+
+ app.createPrivateDir();
+
+ int result = drop_root_privileges(user.getUid(), user.getGid());
+ RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
+
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(app.getUID());
+ preq.setInstallType(SM_APP_INSTALL_GLOBAL);
+ preq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(preq, SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED);
+}
+
+RUNNER_CHILD_TEST(security_manager_63b_path_req_preloaded_as_user)
+{
+ TemporaryTestUser user("sm_test_63_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_63", user.getUid());
+ ScopedInstaller appInstall(app);
+
+ app.createPrivateDir();
+
+ int result = drop_root_privileges(user.getUid(), user.getGid());
+ RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
+
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(app.getUID());
+ preq.setInstallType(SM_APP_INSTALL_PRELOADED);
+ preq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(preq, SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED);
+}
+
+RUNNER_TEST(security_manager_64a_path_req_as_local_as_root)
+{
+ TemporaryTestUser user("sm_test_64_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_64", user.getUid());
+ ScopedInstaller appInstall(app);
+
+ app.createPrivateDir();
+
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(app.getUID());
+ preq.setInstallType(SM_APP_INSTALL_LOCAL);
+ preq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(preq, (lib_retcode)SECURITY_MANAGER_SUCCESS);
+}
+
+RUNNER_CHILD_TEST(security_manager_64b_path_req_as_local_as_global_user)
+{
+ TemporaryTestUser user("sm_test_64_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_64", user.getUid());
+ ScopedInstaller appInstall(app);
+
+ app.createPrivateDir();
+
+ RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(TzPlatformConfig::getGlobalUserId(),
+ TzPlatformConfig::getGlobalGroupId()) == 0,
+ "drop_root_privileges failed");
+
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(app.getUID());
+ preq.setInstallType(SM_APP_INSTALL_LOCAL);
+ preq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+
+ Api::registerPaths(preq, (lib_retcode)SECURITY_MANAGER_SUCCESS);
+}
+
+RUNNER_TEST(security_manager_66_path_req_check_labels)
+{
+ AppInstallHelper app("sm_test_66");
+
+ ScopedInstaller appInstall(app);
+
+ app.createPrivateDir();
+ app.createPrivateRODir();
+ app.createPublicDir();
+ app.createSharedRODir();
+
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.addPath(app.getPrivateDir(), SECURITY_MANAGER_PATH_RW);
+ preq.addPath(app.getPrivateRODir(), SECURITY_MANAGER_PATH_RO);
+ preq.addPath(app.getPublicDir(), SECURITY_MANAGER_PATH_PUBLIC_RO);
+ preq.addPath(app.getSharedRODir(), SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
+ Api::registerPaths(preq);
+
+ check_path(app.getPrivateDir(), generatePathRWLabel(app.getPkgId()));
+ check_path(app.getPrivateRODir(), generatePathROLabel(app.getPkgId()), false);
+ check_path(app.getPublicDir(), getPublicPathLabel());
+ check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId()));
+}
+
+RUNNER_TEST(security_manager_67_path_req_shared_ro_3_0)
+{
+ TemporaryTestUser user("sm_test_67_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_67", user.getUid());
+ app.setVersion("3.0");
+ ScopedInstaller appInstall(app);
+
+ app.createSharedRODir();
+
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(app.getUID());
+ preq.addPath(app.getSharedRODir(), SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
+
+ Api::registerPaths(preq);
+ check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId()));
+}
+
+RUNNER_TEST(security_manager_68_path_req_shared_ro_2_X)
+{
+ TemporaryTestUser user("sm_test_68_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_68", user.getUid());
+ app.setVersion("2.4");
+ ScopedInstaller appInstall(app);
+
+ app.createSharedRODir();
+
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(app.getUID());
+ preq.addPath(app.getSharedRODir(), SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
+
+ Api::registerPaths(preq);
+ check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId()));
+}
+
+RUNNER_TEST(security_manager_69_path_req_trusted_rw_no_author)
+{
+ TemporaryTestUser user("sm_test_69_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_69", user.getUid());
+ ScopedInstaller appInstall(app);
+
+ app.createTrustedDir();
+
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(app.getUID());
+ preq.addPath(app.getTrustedDir(), SECURITY_MANAGER_PATH_TRUSTED_RW);
+
+ Api::registerPaths(preq, (lib_retcode)SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
+RUNNER_TEST(security_manager_70_path_req_trusted_rw_positive)
+{
+ TemporaryTestUser user("sm_test_70_user_name", GUM_USERTYPE_NORMAL, false);
+ user.create();
+
+ AppInstallHelper app("sm_test_70", user.getUid());
+ app.setAuthor("sm_test_70_author");
+ ScopedInstaller appInstall(app);
+
+ app.createTrustedDir();
+
+ PathsRequest preq;
+ preq.setPkgId(app.getPkgId());
+ preq.setUid(app.getUID());
+ preq.addPath(app.getTrustedDir(), SECURITY_MANAGER_PATH_TRUSTED_RW);
+
+ Api::registerPaths(preq);
+
+ // TODO: check labels, e.g. install second label with same author and compare them
+ //check_path(app.getTrustedDir(), generatePathTrustedLabel(authorDb));
+}
--- /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 <fcntl.h>
+#include <linux/xattr.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/smack.h>
+#include <sys/stat.h>
+
+#include <memory>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+
+#include <app_install_helper.h>
+#include <memory.h>
+#include <scoped_installer.h>
+#include <sm_api.h>
+
+#include <security-manager.h>
+
+using namespace SecurityManagerTest;
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_SHM)
+
+RUNNER_TEST(shm01_create_file) {
+ AppInstallHelper app("shm01_app");
+ const char *shmName = "shm01_testName";
+ auto exLabel = app.generateAppLabel();
+ ScopedInstaller req(app);
+ char *label = NULL;
+
+ // clean up environment
+ shm_unlink(shmName);
+
+ int fd = security_manager_shm_open(shmName, O_CREAT | O_RDWR, 0666, app.getAppId().c_str());
+ RUNNER_ASSERT_ERRNO_MSG(fd >= 0, "security_manager_shm_open failed");
+ FdUniquePtr file(&fd);
+
+ ssize_t len = smack_new_label_from_file(fd, XATTR_NAME_SMACK, &label);
+ RUNNER_ASSERT_MSG(len > 0, "");
+
+ CStringPtr ptr(label);
+
+ RUNNER_ASSERT_MSG(exLabel == label, "Wrong label. Expected: " << exLabel
+ << " Found: " << label);
+
+ int ret = shm_unlink(shmName);
+ RUNNER_ASSERT_ERRNO_MSG(0 == ret, "shm_unlink failed");
+}
+
+RUNNER_TEST(shm02_double_open) {
+ AppInstallHelper app("shm02_app");
+ const char *shmName = "shm02_testName";
+ auto exLabel = app.generateAppLabel();
+ ScopedInstaller req(app);
+ char *label = NULL;
+
+ // clean up environment
+ shm_unlink(shmName);
+
+ int fd1 = security_manager_shm_open(shmName, O_CREAT | O_RDWR, 0666, app.getAppId().c_str());
+ RUNNER_ASSERT_ERRNO_MSG(fd1 >= 0, "security_manager_shm_open failed");
+ FdUniquePtr file1(&fd1);
+
+ ssize_t len = smack_new_label_from_file(fd1, XATTR_NAME_SMACK, &label);
+ RUNNER_ASSERT_MSG(len > 0, "");
+
+ CStringPtr ptr(label);
+
+ RUNNER_ASSERT_MSG(exLabel == label, "Wrong label. Expected: " << exLabel
+ << " Found: " << label);
+
+ int fd2 = security_manager_shm_open(shmName, O_CREAT | O_RDWR, 0666, app.getAppId().c_str());
+ RUNNER_ASSERT_ERRNO_MSG(fd2 >= 0, "security_manager_shm_open failed");
+ FdUniquePtr file2(&fd2);
+
+ int ret = shm_unlink(shmName);
+ RUNNER_ASSERT_ERRNO_MSG(0 == ret, "shm_unlink failed");
+}
+
+RUNNER_TEST(shm03_double_share) {
+ const char *shmName = "shm03_testName";
+
+ AppInstallHelper appa("shm03_testAppA");
+ auto exLabel = appa.generateAppLabel();
+ ScopedInstaller reqa(appa);
+
+ AppInstallHelper appb("shm03_testAppB");
+ ScopedInstaller reqb(appb);
+
+ // clean up environment
+ shm_unlink(shmName);
+
+ char *label = NULL;
+
+ int fd1 = security_manager_shm_open(shmName, O_CREAT | O_RDWR, 0666, appa.getAppId().c_str());
+ RUNNER_ASSERT_ERRNO_MSG(fd1 >= 0, "security_manager_shm_open failed");
+ FdUniquePtr file1(&fd1);
+
+ ssize_t len = smack_new_label_from_file(fd1, XATTR_NAME_SMACK, &label);
+ RUNNER_ASSERT_MSG(len > 0, "");
+
+ CStringPtr ptr(label);
+
+ RUNNER_ASSERT_MSG(exLabel == label, "Wrong label. Expected: " << exLabel
+ << " Found: " << label);
+
+ int fd2 = security_manager_shm_open(shmName, O_CREAT | O_RDWR, 0666, appb.getAppId().c_str());
+ int err = errno;
+ RUNNER_ASSERT_ERRNO_MSG(fd2 < 0 && err == EACCES, "security_manager_shm_open should failed with EPERM but is");
+ FdUniquePtr file2(&fd2);
+
+ int ret = shm_unlink(shmName);
+ RUNNER_ASSERT_ERRNO_MSG(0 == ret, "shm_unlink failed");
+}
+
+RUNNER_TEST(shm04_performance_test_shm_open) {
+ const char *shmName = "shm04_testName";
+
+ // clean up environment
+ shm_unlink(shmName);
+
+ RUNNER_PERF_TEST_BEGIN(10);
+
+ for (int i=0; i<1000; ++i) {
+ int fd = shm_open(shmName, O_CREAT | O_RDWR, 0666);
+ RUNNER_ASSERT_ERRNO_MSG(fd >= 0, "shm_open failed");
+ close(fd);
+ shm_unlink(shmName);
+ }
+
+ RUNNER_PERF_TEST_END();
+}
+
+RUNNER_TEST(shm05_performance_test_shm_open_wrapper) {
+ const char *shmName = "shm05_testName";
+
+ AppInstallHelper appa("shm05_app");
+ ScopedInstaller reqa(appa);
+
+ // clean up environment
+ shm_unlink(shmName);
+
+ std::string appId = appa.getAppId();
+
+ RUNNER_PERF_TEST_BEGIN(10);
+
+ for (int i=0; i<1000; ++i) {
+ int fd = security_manager_shm_open(shmName, O_CREAT | O_RDWR, 0666, appId.c_str());
+ RUNNER_ASSERT_ERRNO_MSG(fd >= 0, "security_manager_shm_open failed: " << fd << " iteration " << i);
+ close(fd);
+ shm_unlink(shmName);
+ }
+
+ RUNNER_PERF_TEST_END();
+}
+
--- /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 <algorithm>
+#include <ftw.h>
+#include <string>
+#include <sys/smack.h>
+#include <vector>
+#include <unistd.h>
+
+#include <security-manager.h>
+
+#include <app_install_helper.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <scoped_installer.h>
+#include <sm_api.h>
+#include <sm_commons.h>
+#include <sm_request.h>
+#include <temp_test_user.h>
+#include <tests_common.h>
+#include <tzplatform.h>
+
+using namespace SecurityManagerTest;
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_TRUSTED_SHARING)
+
+RUNNER_TEST(security_manager_40_set_wrong_author_id)
+{
+ InstallRequest requestInst;
+
+ RUNNER_ASSERT(SECURITY_MANAGER_ERROR_INPUT_PARAM ==
+ security_manager_app_inst_req_set_author_id(requestInst.get(), NULL));
+
+ RUNNER_ASSERT(SECURITY_MANAGER_ERROR_INPUT_PARAM ==
+ security_manager_app_inst_req_set_author_id(requestInst.get(), ""));
+}
+
+RUNNER_TEST(security_manager_41_set_author_id_multiple_times)
+{
+ for(unsigned int i=0; i<10; ++i) {
+ std::string authorId = "some-author-id" + std::to_string(i);
+
+ InstallRequest requestInst;
+ requestInst.setAuthorId(authorId);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_43_app_install_with_trusted_path)
+{
+ TemporaryTestUser user("sm_test_43_user_name", GUM_USERTYPE_NORMAL);
+ user.create();
+
+ const std::string authorId = "sm_test_43_author_id";
+
+ AppInstallHelper provider("sm_test_43_provider", user.getUid());
+ provider.createTrustedDir();
+ provider.setAuthor(authorId);
+
+ AppInstallHelper trusted("sm_test_43_user", user.getUid());
+ trusted.setAuthor(authorId);
+
+ AppInstallHelper untrusted("sm_test_43_untrusted");
+
+ // install app with shared/trusted dir
+ InstallRequest providerInstallReq;
+ providerInstallReq.setAppId(provider.getAppId());
+ providerInstallReq.setPkgId(provider.getPkgId());
+ providerInstallReq.setUid(provider.getUID());
+ providerInstallReq.setAuthorId("author id to be overwritten");
+ providerInstallReq.setAuthorId(provider.getAuthor());
+ providerInstallReq.addPath(provider.getTrustedDir(), SECURITY_MANAGER_PATH_TRUSTED_RW);
+ Api::install(providerInstallReq);
+
+ std::string trustedPath = provider.getTrustedDir();
+
+ // Second installation only for scoped uninstall
+ ScopedInstaller providerInstall(provider);
+
+ runAccessTest(provider, trustedPath, R_OK|W_OK|X_OK);
+ runSystemAccessTest(user.getUid(), user.getGid(), trustedPath, R_OK | W_OK | X_OK);
+
+ // install trusted app
+ ScopedInstaller userInstall(trusted);
+ runAccessTest(trusted, provider.getTrustedDir(), R_OK|W_OK|X_OK);
+
+ // install untrusted app
+ ScopedInstaller untrustedInstall(untrusted);
+ runAccessTest(untrusted, trustedPath, 0);
+
+ providerInstall.uninstallApp();
+
+ // there's still one app with author id, rules should be kept
+ runSystemAccessTest(user.getUid(), user.getGid(), trustedPath, R_OK | W_OK | X_OK);
+ runAccessTest(trusted, provider.getTrustedDir(), R_OK|W_OK|X_OK);
+ runAccessTest(untrusted, trustedPath, 0);
+
+ //Second install of provider, but without authorid, to check if there is no access
+ AppInstallHelper provider2("sm_test_43_provider");
+ ScopedInstaller providerInstall2(provider2);
+ runAccessTest(provider2, trustedPath, 0);
+
+ userInstall.uninstallApp();
+
+ // no more apps with author id
+ runSystemAccessTest(user.getUid(), user.getGid(), trustedPath, 0);
+}
+
+
+RUNNER_TEST(security_manager_44_app_install_with_trusted_path_no_author_id)
+{
+ AppInstallHelper help("app44");
+ help.createTrustedDir();
+
+ // install app with shared/trusted dir but without authors id
+ InstallRequest app;
+ app.setAppId(help.getAppId());
+ app.setPkgId(help.getPkgId());
+ app.addPath(help.getTrustedDir(), SECURITY_MANAGER_PATH_TRUSTED_RW);
+ Api::install(app, SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
+RUNNER_CHILD_TEST(security_manager_45_test_authorId_identificator_creation)
+{
+
+ AppInstallHelper trusted1("sm_test_45_1");
+ trusted1.setAuthor("sm_test_45_1_author_id");
+ trusted1.createTrustedDir();
+
+ AppInstallHelper trusted2("sm_test_45_2");
+ trusted2.setAuthor("sm_test_45_2_author_id");
+ trusted2.createTrustedDir();
+
+ ScopedInstaller trustedInstall1(trusted1);
+ ScopedInstaller trustedInstall2(trusted2);
+
+ std::string trustedPath1 = trusted1.getTrustedDir();
+ std::string trustedPath2 = trusted2.getTrustedDir();
+
+ runAccessTest(trusted1, trustedPath1, R_OK|W_OK|X_OK);
+ runAccessTest(trusted2, trustedPath1, 0);
+ runSystemAccessTest(geteuid(), getegid(), trustedPath1, R_OK | W_OK | X_OK);
+
+ runAccessTest(trusted2, trustedPath2, R_OK|W_OK|X_OK);
+ runAccessTest(trusted1, trustedPath2, 0);
+ runSystemAccessTest(geteuid(), getegid(), trustedPath2, R_OK | W_OK | X_OK);
+}
+/* Description:
+ * Lets assume that app1 and app2 are part of pkg1.
+ * Deinstalation of app1 must not remove access from system processes to trusted paths
+ */
+void test_46_pkgId_deinstallation(bool isFirstOneHybrid, bool isSecondOneHybrid) {
+ TemporaryTestUser user("sm_test_46_user_name", GUM_USERTYPE_NORMAL);
+ user.create();
+
+ const std::string authorId = "sm_test_46_author_id";
+
+ AppInstallHelper provider("sm_test_46_1", user.getUid());
+ provider.createTrustedDir();
+ provider.setAuthor(authorId);
+ if (isFirstOneHybrid)
+ provider.setHybrid();
+ ScopedInstaller providerInstaller(provider);
+
+ AppInstallHelper trusted("sm_test_46_2", user.getUid());
+ trusted.setAuthor(authorId);
+ if (isSecondOneHybrid)
+ trusted.setHybrid();
+ ScopedInstaller trustedInstaller(trusted);
+
+ const std::string trustedPath = provider.getTrustedDir();
+
+ runAccessTest(provider, trustedPath, R_OK | W_OK | X_OK);
+ runAccessTest(trusted, trustedPath, R_OK | W_OK | X_OK);
+ runSystemAccessTest(user.getUid(), user.getGid(), trustedPath, R_OK | W_OK | X_OK);
+
+ trustedInstaller.uninstallApp();
+
+ runAccessTest(provider, trustedPath, R_OK | W_OK | X_OK);
+ runSystemAccessTest(user.getUid(), user.getGid(), trustedPath, R_OK | W_OK | X_OK);
+
+ providerInstaller.uninstallApp();
+
+ runSystemAccessTest(user.getUid(), user.getGid(), trustedPath, 0);
+}
+
+RUNNER_CHILD_TEST(security_manager_46a_pkgId_deinstalation_test_hybrid)
+{
+ test_46_pkgId_deinstallation(true, true);
+}
+
+RUNNER_CHILD_TEST(security_manager_46b_pkgId_deinstalation_test_nonhybrid)
+{
+ test_46_pkgId_deinstallation(false, false);
+}
+
+RUNNER_CHILD_TEST(security_manager_46c_pkgId_deinstalation_test_hybrid_only_provider)
+{
+ test_46_pkgId_deinstallation(true, false);
+}
+
+RUNNER_CHILD_TEST(security_manager_46d_pkgId_deinstalation_test_hybrid_only_trusted)
+{
+ test_46_pkgId_deinstallation(false, true);
+}