#include <dpl/log/log.h>
#include <dpl/serialization.h>
+#include <sys/smack.h>
+#include "connection.h"
#include "protocols.h"
#include "service.h"
#include "service_impl.h"
+#include "master-req.h"
namespace SecurityManager {
const InterfaceID IFACE = 1;
-Service::Service()
+Service::Service(const bool isSlave):
+ m_isSlave(isSlave)
{
}
GenericSocketService::ServiceDescriptionVector Service::GetServiceDescription()
{
- return ServiceDescriptionVector {
- {SERVICE_SOCKET, /* path */
- "*", /* smackLabel label (not used, we rely on systemd) */
- IFACE, /* InterfaceID */
- false, /* useSendMsg */
- true}, /* systemdOnly */
- };
+ if (m_isSlave)
+ return ServiceDescriptionVector {
+ {SLAVE_SERVICE_SOCKET, /* path */
+ "*", /* smackLabel label (not used, we rely on systemd) */
+ IFACE, /* InterfaceID */
+ false, /* useSendMsg */
+ true}, /* systemdOnly */
+ };
+ else
+ return ServiceDescriptionVector {
+ {SERVICE_SOCKET, /* path */
+ "*", /* smackLabel label (not used, we rely on systemd) */
+ IFACE, /* InterfaceID */
+ false, /* useSendMsg */
+ true}, /* systemdOnly */
+ };
}
-static bool getPeerID(int sock, uid_t &uid, pid_t &pid) {
+static bool getPeerID(int sock, uid_t &uid, pid_t &pid, std::string &smackLabel)
+{
struct ucred cr;
socklen_t len = sizeof(cr);
if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cr, &len)) {
+ char *smk;
+ ssize_t ret = smack_new_label_from_socket(sock, &smk);
+ if (ret < 0)
+ return false;
+ smackLabel = smk;
uid = cr.uid;
pid = cr.pid;
+ free(smk);
return true;
}
uid_t uid;
pid_t pid;
+ std::string smackLabel;
- if (!getPeerID(conn.sock, uid, pid)) {
- LogError("Closing socket because of error: unable to get peer's uid and pid");
+ if (!getPeerID(conn.sock, uid, pid, smackLabel)) {
+ LogError("Closing socket because of error: unable to get peer's uid, pid or smack label");
m_serviceManager->Close(conn);
return false;
}
case SecurityModuleCall::USER_DELETE:
processUserDelete(buffer, send, uid);
break;
+ case SecurityModuleCall::POLICY_UPDATE:
+ processPolicyUpdate(buffer, send, uid, pid, smackLabel);
+ break;
+ case SecurityModuleCall::GET_CONF_POLICY_ADMIN:
+ processGetConfiguredPolicy(buffer, send, uid, pid, smackLabel, true);
+ break;
+ case SecurityModuleCall::GET_CONF_POLICY_SELF:
+ processGetConfiguredPolicy(buffer, send, uid, pid, smackLabel, false);
+ break;
+ case SecurityModuleCall::GET_POLICY:
+ processGetPolicy(buffer, send, uid, pid, smackLabel);
+ break;
+ case SecurityModuleCall::POLICY_GET_DESCRIPTIONS:
+ processPolicyGetDesc(send);
+ break;
+ case SecurityModuleCall::GET_PRIVILEGES_MAPPING:
+ processPrivilegesMappings(buffer, send);
+ break;
default:
LogError("Invalid call: " << call_type_int);
Throw(ServiceException::InvalidAction);
Deserialization::Deserialize(buffer, req.privileges);
Deserialization::Deserialize(buffer, req.appPaths);
Deserialization::Deserialize(buffer, req.uid);
- Serialization::Serialize(send, ServiceImpl::appInstall(req, uid));
+ Serialization::Serialize(send, ServiceImpl::appInstall(req, uid, m_isSlave));
}
void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
std::string appId;
Deserialization::Deserialize(buffer, appId);
- Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid));
+ Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid, m_isSlave));
}
void Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
int ret;
Deserialization::Deserialize(buffer, appId);
- ret = ServiceImpl::getAppGroups(appId, uid, pid, gids);
+ ret = ServiceImpl::getAppGroups(appId, uid, pid, m_isSlave, gids);
Serialization::Serialize(send, ret);
if (ret == SECURITY_MANAGER_API_SUCCESS) {
Serialization::Serialize(send, static_cast<int>(gids.size()));
Deserialization::Deserialize(buffer, uidAdded);
Deserialization::Deserialize(buffer, userType);
- ret = ServiceImpl::userAdd(uidAdded, userType, uid);
+ ret = ServiceImpl::userAdd(uidAdded, userType, uid, m_isSlave);
Serialization::Serialize(send, ret);
}
Deserialization::Deserialize(buffer, uidRemoved);
- ret = ServiceImpl::userDelete(uidRemoved, uid);
+ ret = ServiceImpl::userDelete(uidRemoved, uid, m_isSlave);
+ Serialization::Serialize(send, ret);
+}
+
+void Service::processPolicyUpdate(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel)
+{
+ int ret;
+ std::vector<policy_entry> policyEntries;
+
+ Deserialization::Deserialize(buffer, policyEntries);
+
+ if (m_isSlave) {
+ ret = MasterReq::PolicyUpdate(policyEntries, uid, pid, smackLabel);
+ } else {
+ ret = ServiceImpl::policyUpdate(policyEntries, uid, pid, smackLabel);
+ }
+ Serialization::Serialize(send, ret);
+}
+
+void Service::processGetConfiguredPolicy(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel, bool forAdmin)
+{
+ int ret;
+ policy_entry filter;
+ Deserialization::Deserialize(buffer, filter);
+ std::vector<policy_entry> policyEntries;
+
+ if (m_isSlave) {
+ ret = MasterReq::GetConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel, policyEntries);
+ } else {
+ ret = ServiceImpl::getConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel,
+ policyEntries);
+ }
+
+ Serialization::Serialize(send, ret);
+ Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
+ for (const auto &policyEntry : policyEntries) {
+ Serialization::Serialize(send, policyEntry);
+ };
+}
+
+void Service::processGetPolicy(MessageBuffer &buffer, MessageBuffer &send, uid_t uid, pid_t pid, const std::string &smackLabel)
+{
+ int ret;
+ policy_entry filter;
+ Deserialization::Deserialize(buffer, filter);
+ std::vector<policy_entry> policyEntries;
+
+ if (m_isSlave) {
+ ret = MasterReq::GetPolicy(filter, uid, pid, smackLabel, policyEntries);
+ } else {
+ ret = ServiceImpl::getPolicy(filter, uid, pid, smackLabel, policyEntries);
+ }
+
Serialization::Serialize(send, ret);
+ Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
+ for (const auto &policyEntry : policyEntries) {
+ Serialization::Serialize(send, policyEntry);
+ };
}
+void Service::processPolicyGetDesc(MessageBuffer &send)
+{
+ int ret;
+ std::vector<std::string> descriptions;
+
+ if (m_isSlave) {
+ ret = MasterReq::PolicyGetDesc(descriptions);
+ } else {
+ ret = ServiceImpl::policyGetDesc(descriptions);
+ }
+ Serialization::Serialize(send, ret);
+ if (ret == SECURITY_MANAGER_API_SUCCESS) {
+ Serialization::Serialize(send, static_cast<int>(descriptions.size()));
+
+ for(std::vector<std::string>::size_type i = 0; i != descriptions.size(); i++) {
+ Serialization::Serialize(send, descriptions[i]);
+ }
+ }
+}
+
+void Service::processPrivilegesMappings(MessageBuffer &recv, MessageBuffer &send)
+{
+ std::vector<std::string> privileges;
+ std::string version_from, version_to;
+ Deserialization::Deserialize(recv, version_from);
+ Deserialization::Deserialize(recv, version_to);
+ Deserialization::Deserialize(recv, privileges);
+
+ std::vector<std::string> mappings;
+ int ret = ServiceImpl::getPrivilegesMappings(version_from, version_to, privileges, mappings);
+
+ Serialization::Serialize(send, ret);
+ Serialization::Serialize(send, mappings);
+}
} // namespace SecurityManager