#include <client-common.h>
#include <protocols.h>
#include <service_impl.h>
-#include <file-lock.h>
+#include <connection.h>
#include <security-manager.h>
+#include <client-offline.h>
+
+static const char *EMPTY = "";
/**
* Mapping of lib_retcode error codes to theirs strings equivalents
{SECURITY_MANAGER_ERROR_MEMORY, "Memory allocation error"},
{SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE, "Incomplete data in application request"},
{SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED, "User does not have sufficient "
- "rigths to perform an operation"}
+ "rigths to perform an operation"},
+ {SECURITY_MANAGER_ERROR_ACCESS_DENIED, "Insufficient privileges"},
};
SECURITY_MANAGER_API
if (p_req->appId.empty() || p_req->pkgId.empty())
return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
- bool offlineMode;
int retval;
-
- try {
- SecurityManager::FileLocker serviceLock(SecurityManager::SERVICE_LOCK_FILE);
- if ((offlineMode = serviceLock.Locked())) {
- LogInfo("Working in offline mode.");
- retval = SecurityManager::ServiceImpl::appInstall(*p_req, geteuid());
- }
- } catch (const SecurityManager::FileLocker::Exception::Base &e) {
- offlineMode = false;
- }
- if (!offlineMode) {
+ ClientOffline offlineMode;
+ if (offlineMode.isOffline()) {
+ retval = SecurityManager::ServiceImpl::appInstall(*p_req, geteuid());
+ } else {
MessageBuffer send, recv;
//put data into buffer
return SECURITY_MANAGER_SUCCESS;
case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
+ case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
+ return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
case SECURITY_MANAGER_API_ERROR_INPUT_PARAM:
return SECURITY_MANAGER_ERROR_INPUT_PARAM;
default:
if (smack_smackfs_path() == NULL)
return SECURITY_MANAGER_SUCCESS;
- if (SecurityManager::generateAppLabel(std::string(app_id), appLabel) == false) {
+ try {
+ appLabel = SecurityManager::SmackLabels::generateAppLabel(app_id);
+ } catch (...) {
LogError("Failed to generate smack label for appId: " << app_id);
return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
}
//receive response from server
Deserialization::Deserialize(recv, retval);
- if (retval != SECURITY_MANAGER_API_SUCCESS)
+ if (retval != SECURITY_MANAGER_API_SUCCESS) {
+ LogError("Failed to get list of groups from security-manager service. Error code: " << retval);
return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
//How many new groups?
int newGroupsCnt;
return ret;
ret = security_manager_set_process_groups_from_appid(app_id);
- if (ret != SECURITY_MANAGER_SUCCESS)
- return ret;
+ if (ret != SECURITY_MANAGER_SUCCESS) {
+ LogWarning("Unable to setup process groups for application. Privileges with direct access to resources will not work.");
+ ret = SECURITY_MANAGER_SUCCESS;
+ }
ret = security_manager_drop_process_privileges();
return ret;
int security_manager_user_add(const user_req *p_req)
{
using namespace SecurityManager;
- bool offlineMode;
- MessageBuffer send, recv;
if (!p_req)
return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+
return try_catch([&] {
int retval;
- try {
- SecurityManager::FileLocker serviceLock(SecurityManager::SERVICE_LOCK_FILE);
- if ((offlineMode = serviceLock.Locked())) {
- LogInfo("Working in offline mode.");
- retval = SecurityManager::ServiceImpl::userAdd(p_req->uid, p_req->utype, geteuid());
- }
- } catch (const SecurityManager::FileLocker::Exception::Base &e) {
- offlineMode = false;
- }
- if (!offlineMode) {
+ ClientOffline offlineMode;
+ if (offlineMode.isOffline()) {
+ retval = SecurityManager::ServiceImpl::userAdd(p_req->uid, p_req->utype, geteuid());
+ } else {
+ MessageBuffer send, recv;
//server is working
//put data into buffer
SECURITY_MANAGER_API
int security_manager_policy_update_send(policy_update_req *p_req)
{
- (void)p_req;
+ using namespace SecurityManager;
+ MessageBuffer send, recv;
+
+ if (p_req == nullptr || p_req->units.size() == 0)
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+
+ return try_catch([&] {
+
+ //put request into buffer
+ Serialization::Serialize(send, static_cast<int>(SecurityModuleCall::POLICY_UPDATE));
+ Serialization::Serialize(send, p_req->units);
- return SECURITY_MANAGER_ERROR_UNKNOWN;
+ //send it 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:
+ return SECURITY_MANAGER_SUCCESS;
+ case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
+ return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
+ case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
+ return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
+ default:
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+ });
+}
+
+static inline int security_manager_get_policy_internal(
+ SecurityManager::SecurityModuleCall call_type,
+ policy_entry *p_filter,
+ policy_entry ***ppp_privs_policy,
+ size_t *p_size)
+{
+ using namespace SecurityManager;
+ MessageBuffer send, recv;
+
+ if (ppp_privs_policy == nullptr
+ || p_size == nullptr
+ || p_filter == nullptr)
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+
+ return try_catch([&] {
+ //put request into buffer
+ Serialization::Serialize(send, static_cast<int>(call_type));
+ Serialization::Serialize(send, *p_filter);
+ //send it 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: {
+ //extract and allocate buffers for privs policy entries
+ int entriesCnt = 0;
+ policy_entry **entries = nullptr;
+ try {
+ Deserialization::Deserialize(recv, entriesCnt);
+ entries = new policy_entry*[entriesCnt]();
+ for (int i = 0; i < entriesCnt; ++i) {
+ entries[i] = new policy_entry;
+ Deserialization::Deserialize(recv, entries[i]);
+ };
+ } catch (...) {
+ LogError("Error while parsing server response");
+ for (int i = 0; i < entriesCnt; ++i)
+ delete(entries[i]);
+ delete[] entries;
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+ *p_size = entriesCnt;
+ *ppp_privs_policy = entries;
+ return SECURITY_MANAGER_SUCCESS;
+ }
+ case SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED:
+ return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
+
+ case SECURITY_MANAGER_API_ERROR_ACCESS_DENIED:
+ return SECURITY_MANAGER_ERROR_ACCESS_DENIED;
+
+ default:
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+ });
}
SECURITY_MANAGER_API
int security_manager_get_configured_policy_for_admin(
policy_entry *p_filter,
- policy_entry **pp_privs_policy,
+ policy_entry ***ppp_privs_policy,
size_t *p_size)
{
- (void)p_filter;
- (void)pp_privs_policy;
- (void)p_size;
- return SECURITY_MANAGER_ERROR_UNKNOWN;
+ return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_ADMIN, p_filter, ppp_privs_policy, p_size);
}
SECURITY_MANAGER_API
int security_manager_get_configured_policy_for_self(
policy_entry *p_filter,
- policy_entry **pp_privs_policy,
+ policy_entry ***ppp_privs_policy,
size_t *p_size)
{
- (void)p_filter;
- (void)pp_privs_policy;
- (void)p_size;
- return SECURITY_MANAGER_ERROR_UNKNOWN;
+ return security_manager_get_policy_internal(SecurityModuleCall::GET_CONF_POLICY_SELF, p_filter, ppp_privs_policy, p_size);
}
-
+SECURITY_MANAGER_API
int security_manager_get_policy(
policy_entry *p_filter,
- policy_entry **pp_privs_policy,
+ policy_entry ***ppp_privs_policy,
size_t *p_size)
{
- (void)p_filter;
- (void)pp_privs_policy;
- (void)p_size;
- return SECURITY_MANAGER_ERROR_UNKNOWN;
-}
+ return security_manager_get_policy_internal(SecurityModuleCall::GET_POLICY, p_filter, ppp_privs_policy, p_size);
+};
SECURITY_MANAGER_API
int security_manager_policy_entry_new(policy_entry **p_entry)
if (!p_entry)
return SECURITY_MANAGER_ERROR_INPUT_PARAM;
p_entry->currentLevel = policy_level;
+ p_entry->maxLevel = EMPTY;
return SECURITY_MANAGER_SUCCESS;
}
if (!p_entry)
return SECURITY_MANAGER_ERROR_INPUT_PARAM;
p_entry->maxLevel = policy_level;
+ p_entry->currentLevel = EMPTY;
return SECURITY_MANAGER_SUCCESS;
}
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;
+ }
- return 0;
+ //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;
+ }
+
+ 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;
}