tizen 2.4 release
[framework/security/key-manager.git] / src / manager / main / socket-manager.cpp
index 405add5..30acc9f 100644 (file)
 #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;
@@ -80,10 +77,42 @@ int getCredentialsFromSocket(int sock, CKM::Credentials &cred) {
 
     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 {
@@ -172,6 +201,7 @@ SocketManager::CreateDefaultReadSocketDescription(int sock, bool timeout)
 SocketManager::SocketManager()
   : m_maxDesc(0)
   , m_counter(0)
+  , m_vsmCtx(NULL)
 {
     FD_ZERO(&m_readSet);
     FD_ZERO(&m_writeSet);
@@ -202,6 +232,8 @@ SocketManager::SocketManager()
         desc2.service = signalService;
         LogInfo("SignalService mounted on " << filefd << " descriptor");
     }
+    m_vsmCtx = vsm_create_context();
+    // TODO: handle error
 }
 
 SocketManager::~SocketManager() {
@@ -239,7 +271,7 @@ void SocketManager::ReadyForAccept(int sock) {
     }
 
     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;
@@ -464,78 +496,20 @@ int SocketManager::GetSocketFromSystemD(
         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(
@@ -543,8 +517,6 @@ void SocketManager::CreateDomainSocket(
     const GenericSocketService::ServiceDescription &desc)
 {
     int sockfd = GetSocketFromSystemD(desc);
-    if (-1 == sockfd)
-        sockfd = CreateDomainSocketHelp(desc);
 
     auto &description = CreateDefaultReadSocketDescription(sockfd, false);
 
@@ -556,7 +528,9 @@ void SocketManager::CreateDomainSocket(
         " Handler: " << desc.serviceHandlerPath.c_str());
 }
 
-void SocketManager::RegisterSocketService(GenericSocketService *service) {
+void SocketManager::RegisterSocketService(
+    GenericSocketService *service)
+{
     service->SetSocketManager(this);
     auto serviceVector = service->GetServiceDescription();
     Try {