/*
- * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Rafal Krypa <r.krypa@samsung.com>
*
*/
#include <cstdio>
+#include <functional>
+#include <memory>
#include <utility>
#include <unistd.h>
#include <client-common.h>
#include <protocols.h>
#include <service_impl.h>
+#include <connection.h>
+#include <zone-utils.h>
+
#include <security-manager.h>
#include <client-offline.h>
int retval;
ClientOffline offlineMode;
if (offlineMode.isOffline()) {
- retval = SecurityManager::ServiceImpl::appInstall(*p_req, geteuid());
+ retval = SecurityManager::ServiceImpl::appInstall(*p_req, geteuid(), false);
} else {
MessageBuffer send, recv;
//put data into buffer
- Serialization::Serialize(send, (int)SecurityModuleCall::APP_INSTALL);
- Serialization::Serialize(send, p_req->appId);
- Serialization::Serialize(send, p_req->pkgId);
- Serialization::Serialize(send, p_req->privileges);
- Serialization::Serialize(send, p_req->appPaths);
- Serialization::Serialize(send, p_req->uid);
+ Serialization::Serialize(send, (int)SecurityModuleCall::APP_INSTALL,
+ p_req->appId, p_req->pkgId, p_req->privileges, p_req->appPaths, p_req->uid);
//send buffer to server
retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
//put data into buffer
- Serialization::Serialize(send, (int)SecurityModuleCall::APP_UNINSTALL);
- Serialization::Serialize(send, p_req->appId);
+ Serialization::Serialize(send, (int)SecurityModuleCall::APP_UNINSTALL,
+ p_req->appId);
//send buffer to server
int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
}
//put data into buffer
- Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_PKGID));
- Serialization::Serialize(send, std::string(app_id));
+ Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_PKGID),
+ std::string(app_id));
//send buffer to server
int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
if (smack_smackfs_path() == NULL)
return SECURITY_MANAGER_SUCCESS;
- if (SecurityManager::generateAppLabel(std::string(app_id), appLabel) == false) {
+ // FIXME Below modifications related to zones are temporary. Remove when Smack Namespaces
+ // are implemented.
+ std::string zoneId;
+ if (!getZoneIdFromPid(getpid(), zoneId)) {
+ LogError("Failed to get ID of zone");
+ return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
+ }
+
+ try {
+ appLabel = SecurityManager::zoneSmackLabelGenerate(
+ SecurityManager::SmackLabels::generateAppLabel(app_id), zoneId);
+
+ } catch (...) {
LogError("Failed to generate smack label for appId: " << app_id);
return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
}
}
//put data into buffer
- Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_GROUPS));
- Serialization::Serialize(send, std::string(app_id));
+ Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::APP_GET_GROUPS),
+ std::string(app_id));
//send buffer to server
int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
int retval;
ClientOffline offlineMode;
if (offlineMode.isOffline()) {
- retval = SecurityManager::ServiceImpl::userAdd(p_req->uid, p_req->utype, geteuid());
+ retval = SecurityManager::ServiceImpl::userAdd(p_req->uid, p_req->utype, geteuid(),
+ false);
} else {
MessageBuffer send, recv;
//server is working
//put data into buffer
- Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_ADD));
-
- Serialization::Serialize(send, p_req->uid);
- Serialization::Serialize(send, p_req->utype);
+ Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_ADD),
+ p_req->uid, p_req->utype);
//send buffer to server
retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
return try_catch([&] {
//put data into buffer
- Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_DELETE));
-
- Serialization::Serialize(send, p_req->uid);
-
+ Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::USER_DELETE),
+ p_req->uid);
//send buffer to server
int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
return try_catch([&] {
//put request into buffer
- Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_UPDATE));
- Serialization::Serialize(send, p_req->units);
+ Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_UPDATE),
+ p_req->units);
//send it to server
int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
return try_catch([&] {
//put request into buffer
- Serialization::Serialize(send, static_cast<int>(call_type));
- Serialization::Serialize(send, *p_filter);
+ Serialization::Serialize(send, static_cast<int>(call_type),
+ *p_filter);
+
//send it to server
int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
if (retval != SECURITY_MANAGER_API_SUCCESS) {
}
//receive response from server
Deserialization::Deserialize(recv, retval);
- switch(retval) {
+ switch (retval) {
case SECURITY_MANAGER_API_SUCCESS: {
//extract and allocate buffers for privs policy entries
int entriesCnt = 0;
policy_entry **entries = nullptr;
- Deserialization::Deserialize(recv, entriesCnt);
try {
+ Deserialization::Deserialize(recv, entriesCnt);
entries = new policy_entry*[entriesCnt]();
for (int i = 0; i < entriesCnt; ++i) {
entries[i] = new policy_entry;
LogError("Error while parsing server response");
for (int i = 0; i < entriesCnt; ++i)
delete(entries[i]);
- delete entries;
+ delete[] entries;
return SECURITY_MANAGER_ERROR_UNKNOWN;
}
*p_size = entriesCnt;
SECURITY_MANAGER_API
const char *security_manager_policy_entry_get_user(policy_entry *p_entry)
{
- if (p_entry)
- return strdup(p_entry->user.c_str());
- else
- return nullptr;
+ return p_entry ? p_entry->user.c_str() : nullptr;
}
SECURITY_MANAGER_API
const char *security_manager_policy_entry_get_application(policy_entry *p_entry)
{
- if (p_entry)
- return strdup(p_entry->appId.c_str());
- else
- return nullptr;
+ return p_entry ? p_entry->appId.c_str() : nullptr;
}
SECURITY_MANAGER_API
const char *security_manager_policy_entry_get_privilege(policy_entry *p_entry)
{
- if (p_entry)
- return strdup(p_entry->privilege.c_str());
- else
- return nullptr;
+ return p_entry ? p_entry->privilege.c_str() : nullptr;
}
SECURITY_MANAGER_API
const char *security_manager_policy_entry_get_level(policy_entry *p_entry)
{
- if (p_entry)
- return strdup(p_entry->currentLevel.c_str());
- else
- return nullptr;
+ return p_entry ? p_entry->currentLevel.c_str() : nullptr;
}
SECURITY_MANAGER_API
const char *security_manager_policy_entry_get_max_level(policy_entry *p_entry)
{
- if (p_entry)
- return strdup(p_entry->maxLevel.c_str());
- else
- return nullptr;
+ return p_entry ? p_entry->maxLevel.c_str() : nullptr;
}
SECURITY_MANAGER_API
SECURITY_MANAGER_API
int security_manager_policy_levels_get(char ***levels, size_t *levels_count)
{
- (void)levels;
- (void)levels_count;
+ using namespace SecurityManager;
+ MessageBuffer send, recv;
+ if (!levels || !levels_count)
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ return try_catch([&] {
+
+ //put data into buffer
+ Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_GET_DESCRIPTIONS));
+
+ //send buffer to server
+ int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
+ if (retval != SECURITY_MANAGER_API_SUCCESS) {
+ LogError("Error in sendToServer. Error code: " << retval);
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ //receive response from server
+ Deserialization::Deserialize(recv, retval);
- return 0;
+ switch(retval) {
+ case SECURITY_MANAGER_API_SUCCESS:
+ // success - continue
+ break;
+ case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ default:
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ int count;
+ Deserialization::Deserialize(recv, count);
+ *levels_count = count;
+ LogInfo("Number of policy descriptions: " << *levels_count);
+
+ char **array = new char *[*levels_count];
+
+ for (unsigned int i = 0; i < *levels_count; ++i) {
+ std::string level;
+ Deserialization::Deserialize(recv, level);
+
+ if (level.empty()) {
+ LogError("Unexpected empty level");
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ array[i] = strdup(level.c_str());
+ if (array[i] == nullptr)
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+
+ *levels = array;
+
+ return SECURITY_MANAGER_SUCCESS;
+ });
}
SECURITY_MANAGER_API
void security_manager_policy_levels_free(char **levels, size_t levels_count)
{
- (void)levels;
- (void)levels_count;
+ for (unsigned int i = 0; i < levels_count; i++)
+ free(levels[i]);
+
+ delete[] levels;
+}
+
+lib_retcode get_privileges_mapping(const std::string &from_version,
+ const std::string &to_version,
+ const std::vector<std::string> &privileges,
+ char ***privileges_mappings,
+ size_t *mappings_count)
+{
+ using namespace SecurityManager;
+ MessageBuffer send, recv;
+ Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::GET_PRIVILEGES_MAPPING));
+ Serialization::Serialize(send, from_version);
+ Serialization::Serialize(send, to_version);
+ Serialization::Serialize(send, privileges);
+
+ //send buffer to server
+ int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
+ if (retval != SECURITY_MANAGER_API_SUCCESS) {
+ LogError("Error in sendToServer. Error code: " << retval);
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ //receive response from server
+ Deserialization::Deserialize(recv, retval);
+
+ switch(retval) {
+ case SECURITY_MANAGER_API_SUCCESS:
+ // success - continue
+ break;
+ case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ default:
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ unsigned int count;
+ Deserialization::Deserialize(recv, count);
+ LogInfo("Number of privilege mappings: " << count);
+ size_t i = 0;
+ auto free_mapping = std::bind(security_manager_privilege_mapping_free,
+ std::placeholders::_1, std::ref(i));
+ std::unique_ptr<char *[], decltype (free_mapping)> mappings_ptr(new char *[count], free_mapping);
+
+ for (; i < count; ++i) {
+ std::string privilege_mapping;
+ Deserialization::Deserialize(recv, privilege_mapping);
+ if (privilege_mapping.empty()) {
+ LogError("Unexpected empty privilege mapping");
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ mappings_ptr.get()[i] = strdup(privilege_mapping.c_str());
+ if (mappings_ptr.get()[i] == nullptr)
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+
+ *privileges_mappings = mappings_ptr.release();
+ *mappings_count = count;
+
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+SECURITY_MANAGER_API
+int security_manager_get_privileges_mapping(const char *from_version,
+ const char *to_version,
+ char const * const *privileges,
+ size_t privileges_count,
+ char ***privileges_mappings,
+ size_t *mappings_count)
+{
+ if (from_version == nullptr || privileges_mappings == nullptr || mappings_count == nullptr) {
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ }
+ return try_catch([&] {
+ std::vector<std::string> privilegesToMap;
+ if (privileges != nullptr) {
+ privilegesToMap.reserve(privileges_count);
+ privilegesToMap.insert(privilegesToMap.end(), privileges, privileges + privileges_count);
+ }
+ if (to_version == nullptr)
+ to_version = "";
+ LogDebug("security_manager_get_privileges_mapping() called with :"
+ " from_version = " << from_version << " to_version = " << to_version <<
+ " privileges_count " << privilegesToMap.size());
+
+ return get_privileges_mapping(from_version, to_version, privilegesToMap,
+ privileges_mappings, mappings_count);
+
+ });
+}
+SECURITY_MANAGER_API
+void security_manager_privilege_mapping_free(char **privileges_mappings, size_t mappings_count)
+{
+ for(size_t i = 0; i < mappings_count; i++)
+ free(privileges_mappings[i]);
+ delete [] privileges_mappings;
+}
+
+SECURITY_MANAGER_API
+int security_manager_groups_get(char ***groups, size_t *groups_count)
+{
+ using namespace SecurityManager;
+ MessageBuffer send, recv;
+ if (!groups || !groups_count)
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ return try_catch([&] {
+
+ //put data into buffer
+ Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::GROUPS_GET));
+
+ //send buffer to server
+ int retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv);
+ if (retval != SECURITY_MANAGER_API_SUCCESS) {
+ LogError("Error in sendToServer. Error code: " << retval);
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ //receive response from server
+ Deserialization::Deserialize(recv, retval);
+
+ switch(retval) {
+ case SECURITY_MANAGER_API_SUCCESS:
+ // success - continue
+ break;
+ case SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY:
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ default:
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ std::vector<std::string> vgroups;
+ Deserialization::Deserialize(recv, vgroups);
+ const auto vgroups_size = vgroups.size();
+ LogInfo("Number of groups: " << vgroups_size);
+
+ std::unique_ptr<char *, std::function<void(char **)>> array(
+ static_cast<char **>(calloc(vgroups_size, sizeof(char *))),
+ std::bind(security_manager_groups_free, std::placeholders::_1, vgroups_size));
+
+ if (array == nullptr)
+ return SECURITY_MANAGER_ERROR_MEMORY;
+
+ for (size_t i = 0; i < vgroups_size; ++i) {
+ const auto &group = vgroups.at(i);
+
+ if (group.empty()) {
+ LogError("Unexpected empty group");
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ array.get()[i] = strdup(group.c_str());
+ if (array.get()[i] == nullptr)
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+
+ *groups_count = vgroups_size;
+ *groups = array.release();
+
+ return SECURITY_MANAGER_SUCCESS;
+ });
+}
+
+SECURITY_MANAGER_API
+void security_manager_groups_free(char **groups, size_t groups_count)
+{
+ if (groups == nullptr)
+ return;
+
+ for (size_t i = 0; i < groups_count; i++)
+ free(groups[i]);
+
+ free(groups);
}