#include <sys/signalfd.h>
#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/smack.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <unistd.h>
-#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <dpl/log/log.h>
#include <dpl/assert.h>
-#include <smack-check.h>
+#include <ckm/ckm-client-info.h>
#include <socket-manager.h>
namespace {
-
const time_t SOCKET_TIMEOUT = 1000;
-int getCredentialsFromSocket(int sock, CKM::Credentials &cred) {
- CKM::Credentials credentials;
+int getCredentialsFromSocket(int sock, CKM::Credentials &cred, vsm_context_h &vsmCtx)
+{
std::vector<char> result(1);
socklen_t length = 1;
ucred peerCred;
result.push_back('\0');
cred.smackLabel = result.data();
- cred.uid = peerCred.uid;
+ if (!vsmCtx) {
+ CKM::ClientInfo clientInfo(peerCred.uid);
+ cred.clientID = clientInfo.getClientID();
+ LogError("vsmCtx == NULL. ClientID[" << cred.clientID << "]");
+ } else {
+ vsm_zone_h _vsm_zone = vsm_lookup_zone_by_pid(vsmCtx, peerCred.pid);
+ if (!_vsm_zone) {
+ if (0 > vsm_cleanup_context(vsmCtx)) {
+ LogError("Failed to vsm_cleanup_context.");
+ } else if (!(vsmCtx = vsm_create_context())) {
+ LogError("Failed to vsm_create_context.");
+ return -1;
+ }
+ LogDebug("Recreate vsm context Success. vsm_lookup_zone_by_pid:[" << peerCred.pid << "] returned NULL");
+ _vsm_zone = vsm_lookup_zone_by_pid(vsmCtx, peerCred.pid);
+
+ if (!_vsm_zone) {
+ LogError("Failed. vsm_zone lookedup by pid:[" << peerCred.pid << "]");
+ vsm_cleanup_context(vsmCtx);
+ vsmCtx = NULL;
+ return -1;
+ }
+ LogDebug("Success. vsm_lookup_zone_by_pid:[" << peerCred.pid << "]");
+ }
+
+ // construct clientInfo with default zone
+ CKM::ClientInfo clientInfo(peerCred.uid);
+
+ if (!vsm_is_host_zone(_vsm_zone))
+ clientInfo = CKM::ClientInfo(std::string(vsm_get_zone_name(_vsm_zone)), peerCred.uid);
+
+ cred.clientID = clientInfo.getClientID();
+ LogDebug("sock[" << sock << "] clientID[" << cred.clientID << "]");
+ }
return 0;
}
-
} // namespace anonymous
namespace CKM {
SocketManager::SocketManager()
: m_maxDesc(0)
, m_counter(0)
+ , m_vsmCtx(NULL)
{
FD_ZERO(&m_readSet);
FD_ZERO(&m_writeSet);
desc2.service = signalService;
LogInfo("SignalService mounted on " << filefd << " descriptor");
}
+ m_vsmCtx = vsm_create_context();
+ // TODO: handle error
}
SocketManager::~SocketManager() {
}
Credentials peerCred;
- if (0 > getCredentialsFromSocket(client, peerCred)) {
+ if (0 > getCredentialsFromSocket(client, peerCred, m_vsmCtx)) {
LogDebug("Error in getCredentialsFromSocket. Socket closed.");
TEMP_FAILURE_RETRY(close(client));
return;
ThrowMsg(Exception::InitFailed, "Error in sd_listend_fds");
}
- for(fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) {
- if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1,
- desc.serviceHandlerPath.c_str(), 0))
- {
+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) {
+ if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1, desc.serviceHandlerPath.c_str(), 0)) {
LogInfo("Useable socket " << desc.serviceHandlerPath <<
" was passed by SystemD under descriptor " << fd);
+ if (m_vsmCtx) {
+ int ret = vsm_declare_link(m_vsmCtx, desc.serviceHandlerPath.c_str(), desc.serviceHandlerPath.c_str());
+ if (ret)
+ LogError("Failed to socket declare link: " << desc.serviceHandlerPath.c_str());
+ }
return fd;
}
}
- LogError("No useable sockets were passed by systemd.");
- return -1;
-}
-
-int SocketManager::CreateDomainSocketHelp(
- const GenericSocketService::ServiceDescription &desc)
-{
- int sockfd;
-
- if (-1 == (sockfd = socket(AF_UNIX, SOCK_STREAM, 0))) {
- int err = errno;
- LogError("Error in socket: " << GetErrnoString(err));
- ThrowMsg(Exception::InitFailed, "Error in socket: " << GetErrnoString(err));
- }
- if (smack_check()) {
- LogInfo("Set up smack label: " << desc.smackLabel);
-
- if (0 != smack_fsetlabel(sockfd, desc.smackLabel.c_str(), SMACK_LABEL_IPIN)) {
- LogError("Error in smack_fsetlabel");
- ThrowMsg(Exception::InitFailed, "Error in smack_fsetlabel");
- }
- } else {
- LogInfo("No smack on platform. Socket won't be securied with smack label!");
- }
-
- int flags;
- if (-1 == (flags = fcntl(sockfd, F_GETFL, 0)))
- flags = 0;
-
- if (-1 == fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)) {
- int err = errno;
- close(sockfd);
- LogError("Error in fcntl: " << GetErrnoString(err));
- ThrowMsg(Exception::InitFailed, "Error in fcntl: " << GetErrnoString(err));
- }
-
- sockaddr_un serverAddress;
- memset(&serverAddress, 0, sizeof(serverAddress));
- serverAddress.sun_family = AF_UNIX;
- strcpy(serverAddress.sun_path, desc.serviceHandlerPath.c_str());
- unlink(serverAddress.sun_path);
-
- mode_t originalUmask;
- originalUmask = umask(0);
-
- if (-1 == bind(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress))) {
- int err = errno;
- close(sockfd);
- LogError("Error in bind: " << GetErrnoString(err));
- ThrowMsg(Exception::InitFailed, "Error in bind: " << GetErrnoString(err));
- }
-
- umask(originalUmask);
-
- if (-1 == listen(sockfd, 5)) {
- int err = errno;
- close(sockfd);
- LogError("Error in listen: " << GetErrnoString(err));
- ThrowMsg(Exception::InitFailed, "Error in listen: " << GetErrnoString(err));
- }
-
- return sockfd;
+ ThrowMsg(Exception::GetSystemdSocketFailed, "No useable sockets were passed by systemd.");
}
void SocketManager::CreateDomainSocket(
const GenericSocketService::ServiceDescription &desc)
{
int sockfd = GetSocketFromSystemD(desc);
- if (-1 == sockfd)
- sockfd = CreateDomainSocketHelp(desc);
auto &description = CreateDefaultReadSocketDescription(sockfd, false);
" Handler: " << desc.serviceHandlerPath.c_str());
}
-void SocketManager::RegisterSocketService(GenericSocketService *service) {
+void SocketManager::RegisterSocketService(
+ GenericSocketService *service)
+{
service->SetSocketManager(this);
auto serviceVector = service->GetServiceDescription();
Try {