Integration with cynara. 38/42538/14
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Tue, 1 Sep 2015 13:23:52 +0000 (15:23 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 8 Sep 2015 07:31:40 +0000 (09:31 +0200)
Change-Id: I75f727890d37b39e7054db4c68baad922eef1fc3

19 files changed:
packaging/key-manager.spec
src/CMakeLists.txt
src/manager/common/connection-info.h
src/manager/main/cynara.cpp [new file with mode: 0644]
src/manager/main/cynara.h [new file with mode: 0644]
src/manager/main/generic-socket-manager.h
src/manager/main/socket-manager.cpp
src/manager/main/socket-manager.h
src/manager/main/thread-service.cpp
src/manager/main/thread-service.h
src/manager/service/ckm-service.cpp
src/manager/service/ckm-service.h
src/manager/service/encryption-service.cpp
src/manager/service/encryption-service.h
src/manager/service/ocsp-logic.cpp
src/manager/service/ocsp-logic.h
src/manager/service/ocsp-service.cpp
src/manager/service/ocsp-service.h
tools/ckm_db_tool/CMakeLists.txt

index fb90bc0..255364f 100644 (file)
@@ -21,6 +21,8 @@ BuildRequires: pkgconfig(libsystemd-journal)
 BuildRequires: pkgconfig(libxml-2.0)
 BuildRequires: pkgconfig(capi-system-info)
 BuildRequires: pkgconfig(security-manager)
+BuildRequires: pkgconfig(cynara-client-async)
+BuildRequires: pkgconfig(cynara-creds-socket)
 BuildRequires: boost-devel
 Requires: libkey-manager-common = %{version}-%{release}
 %{?systemd_requires}
index 4abb93d..c529fa3 100644 (file)
@@ -10,6 +10,8 @@ PKG_CHECK_MODULES(KEY_MANAGER_DEP
     vconf
     libxml-2.0
     security-manager
+    cynara-client-async
+    cynara-creds-socket
     )
 FIND_PACKAGE(Threads REQUIRED)
 
@@ -27,6 +29,7 @@ ELSE (MOCKUP_SM MATCHES "ON")
 ENDIF (MOCKUP_SM MATCHES "ON")
 
 SET(KEY_MANAGER_SOURCES
+    ${KEY_MANAGER_PATH}/main/cynara.cpp
     ${KEY_MANAGER_PATH}/main/generic-socket-manager.cpp
     ${KEY_MANAGER_PATH}/main/socket-manager.cpp
     ${KEY_MANAGER_PATH}/main/key-manager-main.cpp
index 7ea2707..b4d22f6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Bumjin Im <bj.im@samsung.com>
  *
@@ -36,6 +36,7 @@ namespace CKM
         InterfaceID interfaceID;
         MessageBuffer buffer;
         Credentials credentials;
+        bool checkInProgress;
     };
 
     typedef std::map<int, ConnectionInfo> ConnectionInfoMap;
diff --git a/src/manager/main/cynara.cpp b/src/manager/main/cynara.cpp
new file mode 100644 (file)
index 0000000..ffdbe0e
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        cynara.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Support for cynara.
+ */
+#include <string>
+#include <map>
+
+#include <dpl/log/log.h>
+#include <cynara.h>
+
+#include <cynara-client-async.h>
+#include <cynara-creds-socket.h>
+
+namespace CKM {
+
+Cynara::Cynara(GenericSocketManager *socketManager)
+  : m_socketManager(socketManager)
+  , m_cynara(nullptr)
+{
+    if (CYNARA_API_SUCCESS != cynara_async_initialize(&m_cynara, NULL, ChangeStatusCallback, this))
+    {
+        LogError("Cynara initialization failed.");
+        throw std::runtime_error("Cynara initialization failed.");
+    }
+}
+
+void Cynara::Request(
+    const std::string &user,
+    const std::string &client,
+    const std::string &session,
+    const std::string &privilege,
+    StatusCallback callback)
+{
+    int ret = cynara_async_check_cache(
+      m_cynara,
+      client.c_str(),
+      session.c_str(),
+      user.c_str(),
+      privilege.c_str());
+
+    switch(ret) {
+    default:
+    case CYNARA_API_ACCESS_DENIED:
+        callback(false);
+        break;
+    case CYNARA_API_ACCESS_ALLOWED:
+        callback(true);
+        break;
+    case CYNARA_API_CACHE_MISS:
+        SendRequest(
+            user,
+            client,
+            session,
+            privilege,
+            std::move(callback));
+    }
+}
+
+void Cynara::ProcessSocket() {
+    if (CYNARA_API_SUCCESS != cynara_async_process(m_cynara)) {
+        LogError("Function: cynara_async_process failed.");
+    }
+}
+
+Cynara::~Cynara(){
+    cynara_async_finish(m_cynara);
+}
+
+void Cynara::ChangeStatus(int oldFd, int newFd, cynara_async_status status) {
+    m_socketManager->CynaraSocket(oldFd, newFd, status == CYNARA_STATUS_FOR_RW);
+}
+
+void Cynara::ProcessResponse(
+    cynara_check_id checkId,
+    cynara_async_call_cause cause,
+    int response)
+{
+    auto it = m_callbackMap.find(checkId);
+
+    if (it == m_callbackMap.end())
+        return;
+
+    if (cause == CYNARA_CALL_CAUSE_ANSWER && response == CYNARA_API_ACCESS_ALLOWED)
+        it->second(true);
+    else
+        it->second(false);
+
+    m_callbackMap.erase(it);
+}
+
+void Cynara::SendRequest(
+    const std::string &user,
+    const std::string &client,
+    const std::string &session,
+    const std::string &privilege,
+    StatusCallback callback)
+{
+    cynara_check_id checkId = 0;
+    int ret = cynara_async_create_request(
+        m_cynara,
+        client.c_str(),
+        session.c_str(),
+        user.c_str(),
+        privilege.c_str(),
+        &checkId,
+        ProcessResponseCallback,
+        this);
+
+    if (ret != CYNARA_API_SUCCESS)
+        return callback(false);
+
+    m_callbackMap.emplace(checkId, std::move(callback));
+}
+
+void Cynara::ChangeStatusCallback(
+  int oldFd,
+  int newFd,
+  cynara_async_status status,
+  void *ptr)
+{
+    static_cast<Cynara*>(ptr)->ChangeStatus(oldFd, newFd, status);
+}
+
+void Cynara::ProcessResponseCallback(
+  cynara_check_id checkId,
+  cynara_async_call_cause cause,
+  int response,
+  void *ptr)
+{
+    static_cast<Cynara*>(ptr)->ProcessResponse(checkId, cause, response);
+}
+
+bool Cynara::GetUserFromSocket(int socket, std::string &user) {
+    char *ptr;
+    if (CYNARA_API_SUCCESS != cynara_creds_socket_get_user(socket, USER_METHOD_DEFAULT, &ptr))
+        return false;
+    user = ptr;
+    free(ptr);
+    return true;
+}
+
+bool Cynara::GetClientFromSocket(int socket, std::string &client) {
+    char *ptr;
+    if (CYNARA_API_SUCCESS!=cynara_creds_socket_get_client(socket, CLIENT_METHOD_DEFAULT, &ptr))
+        return false;
+    client = ptr;
+    free(ptr);
+    return true;
+}
+
+} // namespace CKM
diff --git a/src/manager/main/cynara.h b/src/manager/main/cynara.h
new file mode 100644 (file)
index 0000000..80fd7f0
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        cynara.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Support for cynara.
+ */
+#pragma once
+
+#include <string>
+#include <map>
+#include <functional>
+
+#include <noncopyable.h>
+#include <generic-socket-manager.h>
+#include <cynara-client-async.h>
+
+namespace CKM {
+
+class Cynara {
+public:
+    typedef std::function<void(bool)> StatusCallback;
+    explicit Cynara(GenericSocketManager *socketManager);
+
+    NONCOPYABLE(Cynara)
+
+    void Request(
+        const std::string &user,
+        const std::string &client,
+        const std::string &session,
+        const std::string &privilege,
+        StatusCallback callback);
+
+    void ProcessSocket();
+
+    virtual ~Cynara();
+
+    static bool GetUserFromSocket(int socket, std::string &user);
+    static bool GetClientFromSocket(int socket, std::string &client);
+
+protected:
+    void ChangeStatus(int oldFd, int newFd, cynara_async_status status);
+    void ProcessResponse(cynara_check_id checkId, cynara_async_call_cause cause, int response);
+    void SendRequest(
+        const std::string &user,
+        const std::string &client,
+        const std::string &session,
+        const std::string &privilege,
+        StatusCallback callback);
+    static void ChangeStatusCallback(
+        int oldFd,
+        int newFd,
+        cynara_async_status status,
+        void *ptr);
+
+    static void ProcessResponseCallback(
+        cynara_check_id checkId,
+        cynara_async_call_cause cause,
+        int response,
+        void *ptr);
+
+    GenericSocketManager *m_socketManager;
+    cynara_async *m_cynara;
+    std::map<cynara_check_id, StatusCallback> m_callbackMap;
+};
+
+} // namespace CKM
index bec21c6..f8da495 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Bumjin Im <bj.im@samsung.com>
  *
@@ -60,16 +60,16 @@ struct GenericSocketService {
     typedef std::string ServiceHandlerPath;
     struct ServiceDescription {
         ServiceDescription(const char *path,
-            const char *smackLabel,
+            const char *privilege,
             InterfaceID interfaceID = 0,
             bool useSendMsg = false)
-          : smackLabel(smackLabel)
+          : privilege(privilege)
           , interfaceID(interfaceID)
           , serviceHandlerPath(path)
           , useSendMsg(useSendMsg)
         {}
 
-        Label smackLabel;                      // Smack label for socket
+        std::string privilege;                 // privilege for socket
         InterfaceID interfaceID;               // All data from serviceHandlerPath will be marked with this interfaceHandler
         ServiceHandlerPath serviceHandlerPath; // Path to file
         bool useSendMsg;
@@ -98,6 +98,11 @@ struct GenericSocketService {
         ConnectionID connectionID;
     };
 
+    struct SecurityEvent : public GenericEvent {
+        ConnectionID connectionID;
+        bool allowed;
+    };
+
     virtual void SetSocketManager(GenericSocketManager *manager) {
         m_serviceManager = manager;
     }
@@ -110,6 +115,7 @@ struct GenericSocketService {
     virtual void Event(const WriteEvent &event) = 0;
     virtual void Event(const ReadEvent &event) = 0;
     virtual void Event(const CloseEvent &event) = 0;
+    virtual void Event(const SecurityEvent &event) = 0;
 
     virtual void Start() = 0;
     virtual void Stop() = 0;
@@ -124,8 +130,10 @@ protected:
 struct GenericSocketManager {
     virtual void MainLoop() = 0;
     virtual void RegisterSocketService(GenericSocketService *ptr) = 0;
+    virtual void CynaraSocket(int oldFd, int newFd, bool isRW) = 0;
     virtual void Close(ConnectionID connectionID) = 0;
     virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer) = 0;
+    virtual void SecurityCheck(ConnectionID connectionID) = 0;
     virtual ~GenericSocketManager(){}
 };
 
index 9d6a632..6caeaf8 100644 (file)
@@ -46,6 +46,8 @@
 #include <socket-manager.h>
 #include <socket-2-id.h>
 
+#include <cynara.h>
+
 namespace {
 
 const time_t SOCKET_TIMEOUT = 1000;
@@ -86,6 +88,7 @@ struct DummyService : public GenericSocketService {
     void Event(const WriteEvent &) {}
     void Event(const ReadEvent &) {}
     void Event(const CloseEvent &) {}
+    void Event(const SecurityEvent &) {}
 };
 
 struct SignalService : public GenericSocketService {
@@ -109,6 +112,7 @@ struct SignalService : public GenericSocketService {
     void Event(const AcceptEvent &) {} // not supported
     void Event(const WriteEvent &) {}  // not supported
     void Event(const CloseEvent &) {}  // not supported
+    void Event(const SecurityEvent &) {} // not supported
 
     void Event(const ReadEvent &event) {
         LogDebug("Get signal information");
@@ -139,23 +143,22 @@ SocketManager::CreateDefaultReadSocketDescription(int sock, bool timeout)
         m_socketDescriptionVector.resize(sock+20);
 
     auto &desc = m_socketDescriptionVector[sock];
-    desc.isListen = false;
-    desc.isOpen = true;
+    desc.setListen(false);
+    desc.setOpen(true);
+    desc.setCynara(false);
     desc.interfaceID = 0;
     desc.service = NULL;
     desc.counter = ++m_counter;
 
     if (timeout) {
         desc.timeout = time(NULL) + SOCKET_TIMEOUT;
-        if (false == desc.isTimeout) {
-            Timeout tm;
-            tm.time = desc.timeout;
-            tm.sock = sock;
-            m_timeoutQueue.push(tm);
-        }
+        Timeout tm;
+        tm.time = desc.timeout;
+        tm.sock = sock;
+        m_timeoutQueue.push(tm);
     }
 
-    desc.isTimeout = timeout;
+    desc.setTimeout(timeout);
 
     FD_SET(sock, &m_readSet);
     m_maxDesc = sock > m_maxDesc ? sock : m_maxDesc;
@@ -195,26 +198,31 @@ SocketManager::SocketManager()
         desc2.service = signalService;
         LogInfo("SignalService mounted on " << filefd << " descriptor");
     }
+
+    // We cannot create Cynara earlier because descriptors are not initialized!
+    m_cynara.reset(new Cynara(this));
 }
 
 SocketManager::~SocketManager() {
+    m_cynara.reset(nullptr);
     std::set<GenericSocketService*> serviceMap;
 
     // Find all services. Set is used to remove duplicates.
     // In this implementation, services are not able to react in any way.
     for (size_t i=0; i < m_socketDescriptionVector.size(); ++i)
-        if (m_socketDescriptionVector[i].isOpen)
+        if (m_socketDescriptionVector[i].isOpen())
             serviceMap.insert(m_socketDescriptionVector[i].service);
 
     // Time to destroy all services.
     for (auto service : serviceMap) {
         LogDebug("delete " << (void*)(service));
-        service->Stop();
+        if (service)
+            service->Stop();
         delete service;
     }
 
     for (size_t i = 0; i < m_socketDescriptionVector.size(); ++i)
-        if (m_socketDescriptionVector[i].isOpen)
+        if (m_socketDescriptionVector[i].isOpen())
             close(i);
 
     // All socket except one were closed. Now pipe input must be closed.
@@ -225,16 +233,21 @@ void SocketManager::ReadyForAccept(int sock) {
     struct sockaddr_un clientAddr;
     unsigned int clientLen = sizeof(clientAddr);
     int client = accept4(sock, (struct sockaddr*) &clientAddr, &clientLen, SOCK_NONBLOCK);
-//    LogInfo("Accept on sock: " << sock << " Socket opended: " << client);
     if (-1 == client) {
         int err = errno;
         LogDebug("Error in accept: " << GetErrnoString(err));
         return;
     }
 
+    std::string smack;
+    std::string user;
     Credentials peerCred;
-    if (0 > getCredentialsFromSocket(client, peerCred)) {
-        LogDebug("Error in getCredentialsFromSocket. Socket closed.");
+
+    if (0 > getCredentialsFromSocket(client, peerCred)
+        || !Cynara::GetUserFromSocket(client, user)
+        || !Cynara::GetClientFromSocket(client, smack))
+    {
+        LogDebug("Error in getting credentials from socket.");
         TEMP_FAILURE_RETRY(close(client));
         return;
     }
@@ -242,6 +255,9 @@ void SocketManager::ReadyForAccept(int sock) {
     auto &desc = CreateDefaultReadSocketDescription(client, true);
     desc.interfaceID = m_socketDescriptionVector[sock].interfaceID;
     desc.service = m_socketDescriptionVector[sock].service;
+    desc.cynaraPrivilege = m_socketDescriptionVector[sock].cynaraPrivilege;
+    desc.cynaraUser = std::move(user);
+    desc.cynaraClient = std::move(smack);
 
     GenericSocketService::AcceptEvent event;
     event.connectionID.sock = client;
@@ -251,12 +267,38 @@ void SocketManager::ReadyForAccept(int sock) {
     desc.service->Event(event);
 }
 
+void SocketManager::SecurityStatus(int sock, int counter, bool allowed) {
+    auto &desc = m_socketDescriptionVector[sock];
+    if (!desc.isOpen()) {
+        LogDebug("Client from socket " << sock <<
+            " closed connection before cynara answer was received.");
+        return;
+    }
+
+    if (desc.counter != counter) {
+        LogDebug("Client from socket " << sock <<
+            " closed connection before cynara answer was received.");
+        return;
+    }
+
+    GenericSocketService::SecurityEvent event;
+    event.connectionID.sock = sock;
+    event.connectionID.counter = counter;
+    event.allowed = allowed;
+    desc.service->Event(event);
+}
+
 void SocketManager::ReadyForRead(int sock) {
-    if (m_socketDescriptionVector[sock].isListen) {
+    if (m_socketDescriptionVector[sock].isListen()) {
         ReadyForAccept(sock);
         return;
     }
 
+    if (m_socketDescriptionVector[sock].isCynara()) {
+        m_cynara->ProcessSocket();
+        return;
+    }
+
     GenericSocketService::ReadEvent event;
     event.connectionID.sock = sock;
     event.connectionID.counter = m_socketDescriptionVector[sock].counter;
@@ -285,7 +327,12 @@ void SocketManager::ReadyForRead(int sock) {
     }
 }
 
-void SocketManager::ReadyForWriteBuffer(int sock) {
+void SocketManager::ReadyForWrite(int sock) {
+    if (m_socketDescriptionVector[sock].isCynara()) {
+        m_cynara->ProcessSocket();
+        return;
+    }
+
     auto &desc = m_socketDescriptionVector[sock];
     size_t size = desc.rawBuffer.size();
     ssize_t result = write(sock, &desc.rawBuffer[0], size);
@@ -321,10 +368,6 @@ void SocketManager::ReadyForWriteBuffer(int sock) {
     desc.service->Event(event);
 }
 
-void SocketManager::ReadyForWrite(int sock) {
-    ReadyForWriteBuffer(sock);
-}
-
 void SocketManager::MainLoop() {
     // remove evironment values passed by systemd
     sd_listen_fds(1);
@@ -383,9 +426,9 @@ void SocketManager::MainLoop() {
 
             auto &desc = m_socketDescriptionVector[pqTimeout.sock];
 
-            if (!desc.isTimeout || !desc.isOpen) {
+            if (!desc.isTimeout() || !desc.isOpen()) {
                 // Connection was closed. Timeout is useless...
-                desc.isTimeout = false;
+                desc.setTimeout(false);
                 continue;
             }
 
@@ -400,7 +443,7 @@ void SocketManager::MainLoop() {
             // timeout from m_timeoutQueue matches with socket.timeout
             // and connection is open. Time to close it!
             // Putting new timeout in queue here is pointless.
-            desc.isTimeout = false;
+            desc.setTimeout(false);
             CloseSocket(pqTimeout.sock);
 
             // All done. Now we should process next select ;-)
@@ -488,12 +531,12 @@ int SocketManager::CreateDomainSocketHelp(
     }
 
     if (smack_check()) {
-        LogInfo("Set up smack label: " << desc.smackLabel);
+        LogInfo("Set up smack label: " << desc.privilege);
 
-        if (0 != smack_fsetlabel(sockfd, desc.smackLabel.c_str(), SMACK_LABEL_IPIN)) {
-            LogError("Error in smack_fsetlabel");
-            ThrowMsg(Exception::InitFailed, "Error in smack_fsetlabel");
-        }
+//        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!");
     }
@@ -547,9 +590,10 @@ void SocketManager::CreateDomainSocket(
 
     auto &description = CreateDefaultReadSocketDescription(sockfd, false);
 
-    description.isListen = true;
+    description.setListen(true);
     description.interfaceID = desc.interfaceID;
     description.service = service;
+    description.cynaraPrivilege = desc.privilege;
 
     LogDebug("Listen on socket: " << sockfd <<
         " Handler: " << desc.serviceHandlerPath.c_str());
@@ -566,9 +610,9 @@ void SocketManager::RegisterSocketService(GenericSocketService *service) {
         for (int i =0; i < (int)m_socketDescriptionVector.size(); ++i)
         {
             auto &desc = m_socketDescriptionVector[i];
-            if (desc.service == service && desc.isOpen) {
+            if (desc.service == service && desc.isOpen()) {
                 close(i);
-                desc.isOpen = false;
+                desc.setOpen(false);
             }
         }
         ReThrow(Exception::Base);
@@ -576,20 +620,28 @@ void SocketManager::RegisterSocketService(GenericSocketService *service) {
 }
 
 void SocketManager::Close(ConnectionID connectionID) {
-    {
-        std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
-        m_closeQueue.push(connectionID);
-    }
-    NotifyMe();
+    CloseEvent event;
+    event.sock = connectionID.sock;
+    event.counter = connectionID.counter;
+    AddEvent(event);
 }
 
 void SocketManager::Write(ConnectionID connectionID, const RawBuffer &rawBuffer) {
-    WriteBuffer buffer;
-    buffer.connectionID = connectionID;
-    buffer.rawBuffer = rawBuffer;
+    WriteEvent event{connectionID, rawBuffer};
+    AddEvent(event);
+}
+
+void SocketManager::SecurityCheck(ConnectionID connectionID) {
+    SecurityEvent event;
+    event.sock = connectionID.sock;
+    event.counter = connectionID.counter;
+    AddEvent(event);
+}
+
+void SocketManager::CreateEvent(EventFunction fun) {
     {
         std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
-        m_writeBufferQueue.push(buffer);
+        m_eventQueue.push(std::move(fun));
     }
     NotifyMe();
 }
@@ -599,60 +651,74 @@ void SocketManager::NotifyMe() {
 }
 
 void SocketManager::ProcessQueue() {
-    WriteBuffer buffer;
-    {
-        std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
-        while (!m_writeBufferQueue.empty()) {
-            buffer = m_writeBufferQueue.front();
-            m_writeBufferQueue.pop();
+    while(1) {
+        EventFunction fun;
+        {
+            std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
+            if (m_eventQueue.empty())
+                return;
+            fun = std::move(m_eventQueue.front());
+            m_eventQueue.pop();
+        }
+        fun();
+    }
+}
 
-            auto &desc = m_socketDescriptionVector[buffer.connectionID.sock];
+void SocketManager::Handle(const WriteEvent &event) {
+    auto &desc = m_socketDescriptionVector[event.connectionID.sock];
 
-            if (!desc.isOpen) {
-                LogDebug("Received packet for write but connection is closed. Packet ignored!");
-                continue;
-            }
+    if (!desc.isOpen()) {
+        LogDebug("Received packet for write but connection is closed. Packet ignored!");
+        return;
+    }
 
-            if (desc.counter != buffer.connectionID.counter)
-            {
-                LogDebug("Received packet for write but counter is broken. Packet ignored!");
-                continue;
-            }
+    if (desc.counter != event.connectionID.counter)
+    {
+        LogDebug("Received packet for write but counter is broken. Packet ignored!");
+        return;
+    }
 
-            std::copy(
-                buffer.rawBuffer.begin(),
-                buffer.rawBuffer.end(),
-                std::back_inserter(desc.rawBuffer));
+    std::copy(
+        event.rawBuffer.begin(),
+        event.rawBuffer.end(),
+        std::back_inserter(desc.rawBuffer));
 
-            FD_SET(buffer.connectionID.sock, &m_writeSet);
-        }
+    FD_SET(event.connectionID.sock, &m_writeSet);
+}
 
-    }
+void SocketManager::Handle(const CloseEvent &event) {
+    if (!m_socketDescriptionVector[event.sock].isOpen())
+        return;
 
-    while (1) {
-        ConnectionID connection;
-        {
-            std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
-            if (m_closeQueue.empty())
-                return;
-            connection = m_closeQueue.front();
-            m_closeQueue.pop();
-        }
+    if (event.counter != m_socketDescriptionVector[event.sock].counter)
+        return;
 
-        if (!m_socketDescriptionVector[connection.sock].isOpen)
-            continue;
+    CloseSocket(event.sock);
+}
 
-        if (connection.counter != m_socketDescriptionVector[connection.sock].counter)
-            continue;
+void SocketManager::Handle(const SecurityEvent &event) {
+    auto& desc = m_socketDescriptionVector[event.sock];
+    if (!desc.isOpen())
+        return;
 
-        CloseSocket(connection.sock);
-    }
+    if (event.counter != desc.counter)
+        return;
+
+    std::string session = std::to_string(desc.counter);
+
+    m_cynara->Request(desc.cynaraUser,
+                      desc.cynaraClient,
+                      session,
+                      desc.cynaraPrivilege,
+                      [this, event](bool allowed) {
+                          this->SecurityStatus(event.sock, event.counter, allowed);
+                      });
 }
 
 void SocketManager::CloseSocket(int sock) {
     auto &desc = m_socketDescriptionVector[sock];
 
-    if (!(desc.isOpen)) {
+    if (!(desc.isOpen())) {
         // This may happend when some information was waiting for write to the
         // socket and in the same time socket was closed by the client.
         LogError("Socket " << sock << " is not open. Nothing to do!");
@@ -664,7 +730,7 @@ void SocketManager::CloseSocket(int sock) {
     event.connectionID.counter = desc.counter;
     auto service = desc.service;
 
-    desc.isOpen = false;
+    desc.setOpen(false);
     desc.service = NULL;
     desc.interfaceID = -1;
     desc.rawBuffer.clear();
@@ -679,4 +745,31 @@ void SocketManager::CloseSocket(int sock) {
     FD_CLR(sock, &m_writeSet);
 }
 
+void SocketManager::CynaraSocket(int oldFd, int newFd, bool isRW) {
+    if (newFd != oldFd) {
+        if (newFd >= 0) {
+            auto &desc = CreateDefaultReadSocketDescription(newFd, false);
+            desc.service = nullptr;
+            desc.setCynara(true);
+        }
+
+        if (oldFd >= 0) {
+            auto &old = m_socketDescriptionVector[oldFd];
+            old.setOpen(false);
+            old.setCynara(false);
+            FD_CLR(oldFd, &m_writeSet);
+            FD_CLR(oldFd, &m_readSet);
+        }
+    }
+
+    if (newFd >= 0) {
+        FD_SET(newFd, &m_readSet);
+
+        if (isRW)
+            FD_SET(newFd, &m_writeSet);
+        else
+            FD_CLR(newFd, &m_writeSet);
+    }
+}
+
 } // namespace CKM
index 5dbffdc..522e79c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Contact: Bumjin Im <bj.im@samsung.com>
  *
@@ -31,6 +31,7 @@
 #include <string>
 #include <mutex>
 #include <thread>
+#include <functional>
 
 #include <dpl/exception.h>
 
@@ -39,6 +40,8 @@
 
 namespace CKM {
 
+class Cynara;
+
 class SocketManager : public GenericSocketManager {
 public:
     class Exception {
@@ -46,14 +49,20 @@ public:
         DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
         DECLARE_EXCEPTION_TYPE(Base, InitFailed)
     };
+
+
     SocketManager();
     virtual ~SocketManager();
     virtual void MainLoop();
     virtual void MainLoopStop();
 
+    virtual void CynaraSocket(int oldFd, int newFd, bool isRW);
+    void SecurityStatus(int sock, int counter, bool allowed);
+
     virtual void RegisterSocketService(GenericSocketService *service);
     virtual void Close(ConnectionID connectionID);
     virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer);
+    virtual void SecurityCheck(ConnectionID connectionID);
 
 protected:
     void CreateDomainSocket(
@@ -66,41 +75,68 @@ protected:
 
     void ReadyForRead(int sock);
     void ReadyForWrite(int sock);
-    void ReadyForWriteBuffer(int sock);
-    void ReadyForSendMsg(int sock);
     void ReadyForAccept(int sock);
     void ProcessQueue(void);
     void NotifyMe(void);
     void CloseSocket(int sock);
 
     struct SocketDescription {
-        bool isListen;
-        bool isOpen;
-        bool isTimeout;
+        bool isOpen() { return m_flags & OPEN; }
+        bool isListen() { return m_flags & LISTEN; }
+        bool isCynara() { return m_flags & CYNARA; }
+        bool isTimeout() { return m_flags & TIMEOUT; }
+        void setOpen(bool isSet) { isSet ? m_flags |= OPEN : m_flags &= ~OPEN; }
+        void setListen(bool isSet) { isSet ? m_flags |= LISTEN : m_flags &= ~LISTEN; }
+        void setCynara(bool isSet) { isSet ? m_flags |= CYNARA : m_flags &= ~CYNARA; }
+        void setTimeout(bool isSet) { isSet ? m_flags |= TIMEOUT : m_flags &= ~TIMEOUT; }
+
         InterfaceID interfaceID;
         GenericSocketService *service;
         time_t timeout;
         RawBuffer rawBuffer;
         int counter;
+        std::string cynaraPrivilege;
+        std::string cynaraUser;
+        std::string cynaraClient;
 
         SocketDescription()
-          : isListen(false)
-          , isOpen(false)
-          , isTimeout(false)
-          , interfaceID(-1)
+          : interfaceID(-1)
           , service(NULL)
+          , m_flags(0)
         {}
+    private:
+        static const char LISTEN  = 1 << 0;
+        static const char OPEN    = 1 << 1;
+        static const char CYNARA  = 1 << 2;
+        static const char TIMEOUT = 1 << 3;
+        int m_flags;
     };
 
     SocketDescription& CreateDefaultReadSocketDescription(int sock, bool timeout);
 
     typedef std::vector<SocketDescription> SocketDescriptionVector;
 
-    struct WriteBuffer {
+    // support for generic event Queue
+    typedef std::function<void(void)> EventFunction;
+    template <typename E>
+    void AddEvent(E event) {
+        CreateEvent([this, event]() {this->Handle(event);});
+    }
+    void CreateEvent(EventFunction fun);
+
+    struct WriteEvent {
         ConnectionID connectionID;
         RawBuffer rawBuffer;
     };
 
+    struct CloseEvent : public ConnectionID {};
+    struct SecurityEvent : public ConnectionID {};
+
+    void Handle(const WriteEvent &event);
+    void Handle(const CloseEvent &event);
+    void Handle(const SecurityEvent &event);
+    // support for generic event Queue
+
     struct Timeout {
         time_t time;
         int sock;
@@ -115,12 +151,12 @@ protected:
     int m_maxDesc;
     bool m_working;
     std::mutex m_eventQueueMutex;
-    std::queue<WriteBuffer> m_writeBufferQueue;
-    std::queue<ConnectionID> m_closeQueue;
+    std::queue<EventFunction> m_eventQueue;
     int m_notifyMe[2];
     int m_counter;
     std::priority_queue<Timeout> m_timeoutQueue;
     CommMgr m_commMgr;
+    std::unique_ptr<Cynara> m_cynara;
 };
 
 } // namespace CKM
index 6d84999..9f744b5 100644 (file)
@@ -47,7 +47,15 @@ void ThreadService::Handle(const ReadEvent &event) {
     LogDebug("Read event");
     auto &info = m_connectionInfoMap[event.connectionID.counter];
     info.buffer.Push(event.rawBuffer);
-    while(ProcessOne(event.connectionID, info));
+
+    if (!info.buffer.Ready())
+        return;
+
+    if (info.checkInProgress)
+        return;
+
+    info.checkInProgress = true;
+    m_serviceManager->SecurityCheck(event.connectionID);
 }
 
 void ThreadService::Handle(const CloseEvent &event) {
@@ -55,4 +63,27 @@ void ThreadService::Handle(const CloseEvent &event) {
     m_connectionInfoMap.erase(event.connectionID.counter);
 }
 
+void ThreadService::Handle(const SecurityEvent &event) {
+    LogDebug("Security event");
+    auto it = m_connectionInfoMap.find(event.connectionID.counter);
+
+    if (it == m_connectionInfoMap.end()) {
+        LogDebug("Connection has been closed already");
+        return;
+    }
+    auto &info = it->second;
+
+    if (!info.checkInProgress) {
+        LogDebug("Wrong status in info.checkInProgress. Expected: true.");
+        return;
+    }
+
+    ProcessOne(event.connectionID, info, event.allowed);
+
+    if (info.buffer.Ready())
+        m_serviceManager->SecurityCheck(event.connectionID);
+    else
+        info.checkInProgress = false;
+}
+
 } /* namespace CKM */
index e8f0ac6..219bfc0 100644 (file)
@@ -28,7 +28,7 @@
 
 namespace CKM {
 
-class ThreadService: public CKM::GenericSocketService, public CKM::ServiceThread
+class ThreadService: public GenericSocketService, public ServiceThread
 {
 public:
     ThreadService();
@@ -39,21 +39,23 @@ public:
     void Event(const WriteEvent& event) { ThreadEvent(event); }
     void Event(const ReadEvent& event) { ThreadEvent(event); }
     void Event(const CloseEvent& event) { ThreadEvent(event); }
+    void Event(const SecurityEvent &event) { ThreadEvent(event); }
 
 protected:
     virtual bool ProcessOne(const ConnectionID &conn,
-                            ConnectionInfo &info) = 0;
+                            ConnectionInfo &info,
+                            bool allowed) = 0;
 
     template <typename E>
     void ThreadEvent(const E& event) {
         CreateEvent([this, event]() { this->Handle(event); });
     }
-private:
 
     void Handle(const AcceptEvent &event);
     void Handle(const WriteEvent &event);
     void Handle(const ReadEvent &event);
     void Handle(const CloseEvent &event);
+    void Handle(const SecurityEvent &event);
 
     ConnectionInfoMap m_connectionInfoMap;
 };
index da200ba..132e6a8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -54,8 +54,8 @@ void CKMService::Stop() {
 GenericSocketService::ServiceDescriptionVector CKMService::GetServiceDescription()
 {
     return ServiceDescriptionVector {
-        {SERVICE_SOCKET_CKM_CONTROL, "key-manager::api-control", SOCKET_ID_CONTROL},
-        {SERVICE_SOCKET_CKM_STORAGE, "key-manager::api-storage", SOCKET_ID_STORAGE}
+        {SERVICE_SOCKET_CKM_CONTROL, "http://tizen.org/privilege/keymanager.admin", SOCKET_ID_CONTROL},
+        {SERVICE_SOCKET_CKM_STORAGE, "http://tizen.org/privilege/keymanager", SOCKET_ID_STORAGE}
     };
 }
 
@@ -65,9 +65,12 @@ void CKMService::SetCommManager(CommMgr *manager)
     Register(*manager);
 }
 
+// CKMService does not support security check
+// so 3rd parameter is not used
 bool CKMService::ProcessOne(
     const ConnectionID &conn,
-    ConnectionInfo &info)
+    ConnectionInfo &info,
+    bool /*allowed*/)
 {
     LogDebug ("process One");
     RawBuffer response;
@@ -409,5 +412,16 @@ void CKMService::ProcessMessage(MsgKeyRequest msg)
     }
 }
 
+void CKMService::CustomHandle(const ReadEvent &event) {
+    LogDebug("Read event");
+    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    info.buffer.Push(event.rawBuffer);
+    while(ProcessOne(event.connectionID, info, true));
+}
+
+void CKMService::CustomHandle(const SecurityEvent & /*event*/) {
+    LogError("This should not happend! SecurityEvent was called on CKMService!");
+}
+
 } // namespace CKM
 
index 5bc7230..5b6221e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -39,6 +39,16 @@ public:
     CKMService& operator=(const CKMService &) = delete;
     CKMService& operator=(CKMService &&) = delete;
 
+    // Custom add custom support for ReadEvent and SecurityEvent
+    // because we want to bypass security check in CKMService
+    virtual void Event(const ReadEvent &event) {
+        CreateEvent([this, event]() { this->CustomHandle(event); });
+    }
+
+    virtual void Event(const SecurityEvent &event) {
+        CreateEvent([this, event]() { this->CustomHandle(event); });
+    }
+
     virtual void Start(void);
     virtual void Stop(void);
 
@@ -46,6 +56,11 @@ public:
 
     ServiceDescriptionVector GetServiceDescription();
 
+protected:
+    // CustomHandle is used to bypass security check
+    void CustomHandle(const ReadEvent &event);
+    void CustomHandle(const SecurityEvent &event);
+
 private:
     virtual void SetCommManager(CommMgr *manager);
 
@@ -57,7 +72,8 @@ private:
 
     bool ProcessOne(
         const ConnectionID &conn,
-        ConnectionInfo &info);
+        ConnectionInfo &info,
+        bool allowed);
 
     RawBuffer ProcessControl(
         MessageBuffer &buffer);
index f08dbfa..f5de271 100644 (file)
@@ -64,7 +64,7 @@ void EncryptionService::RequestKey(const CryptoRequest& request)
 GenericSocketService::ServiceDescriptionVector EncryptionService::GetServiceDescription()
 {
     return ServiceDescriptionVector {
-        {SERVICE_SOCKET_ENCRYPTION, "key-manager::api-encryption", SOCKET_ID_ENCRYPTION}
+        {SERVICE_SOCKET_ENCRYPTION, "http://tizen.org/privilege/keymanager", SOCKET_ID_ENCRYPTION}
     };
 }
 
@@ -82,9 +82,12 @@ void EncryptionService::SetCommManager(CommMgr *manager)
     Register(*manager);
 }
 
+// Encryption Service does not support any kind of security-check
+// and 3rd parameter is not required
 bool EncryptionService::ProcessOne(
     const ConnectionID &conn,
-    ConnectionInfo &info)
+    ConnectionInfo &info,
+    bool /*allowed*/)
 {
     LogDebug ("process One");
     try {
@@ -127,4 +130,15 @@ void EncryptionService::ProcessEncryption(const ConnectionID &conn,
     m_logic.Crypt(req);
 }
 
+void EncryptionService::CustomHandle(const ReadEvent &event) {
+    LogDebug("Read event");
+    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    info.buffer.Push(event.rawBuffer);
+    while(ProcessOne(event.connectionID, info, true));
+}
+
+void EncryptionService::CustomHandle(const SecurityEvent &/*event*/) {
+    LogError("This should not happend! SecurityEvent was called on EncryptionService!");
+}
+
 } /* namespace CKM */
index 73140b7..e93c87f 100644 (file)
@@ -39,13 +39,28 @@ public:
     // from ThreadService
     ServiceDescriptionVector GetServiceDescription();
 
+    // Custom add custom support for ReadEvent and SecurityEvent
+    // because we want to bypass security check in EncryptionService
+    virtual void Event(const ReadEvent &event) {
+        CreateEvent([this, event]() { this->CustomHandle(event); });
+    }
+
+    virtual void Event(const SecurityEvent &event) {
+        CreateEvent([this, event]() { this->CustomHandle(event); });
+    }
+
     void Start();
     void Stop();
 
+protected:
+    // CustomHandle is used to bypass security check
+    void CustomHandle(const ReadEvent &event);
+    void CustomHandle(const SecurityEvent &event);
+
 private:
     virtual void SetCommManager(CommMgr *manager);
 
-    bool ProcessOne(const ConnectionID &conn, ConnectionInfo &info);
+    bool ProcessOne(const ConnectionID &conn, ConnectionInfo &info, bool allowed);
     void ProcessMessage(MsgKeyResponse msg);
     void ProcessEncryption(const ConnectionID &conn,
                            const Credentials &cred,
index e5b2b11..5e28d19 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2014 Samsung Electronics Co.
+ *  Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -76,7 +76,7 @@ void OCSPLogic::setNetAvailable()
     m_isNetAvailable = false;
 }
 
-RawBuffer OCSPLogic::ocspCheck(int commandId, const RawBufferVector &rawChain) {
+RawBuffer OCSPLogic::ocspCheck(int commandId, const RawBufferVector &rawChain, bool allowed) {
     CertificateImplVector certChain;
     OCSPModule ocsp;
     int retCode = CKM_API_SUCCESS;
@@ -89,18 +89,18 @@ RawBuffer OCSPLogic::ocspCheck(int commandId, const RawBufferVector &rawChain) {
 
     if (!m_isNetAvailable) {
         retCode = CKM_API_ERROR_NOT_SUPPORTED;
+    } else if (!allowed) {
+        retCode = CKM_API_ERROR_ACCESS_DENIED;
+    } else if(rawChain.size() < 2) {
+        LogError("Certificate chain should contain at least 2 certificates");
+        retCode = CKM_API_ERROR_INPUT_PARAM;
     } else {
-        if (rawChain.size() < 2) {
-            LogError("Certificate chain should contain at least 2 certificates");
-            retCode = CKM_API_ERROR_INPUT_PARAM;
-        } else {
-            for (auto &e: rawChain) {
-                certChain.push_back(CertificateImpl(e, DataFormat::FORM_DER));
-                if (certChain.rbegin()->empty()) {
-                    LogDebug("Error in parsing certificates!");
-                    retCode = CKM_API_ERROR_INPUT_PARAM;
-                    break;
-                }
+        for (auto &e: rawChain) {
+            certChain.push_back(CertificateImpl(e, DataFormat::FORM_DER));
+            if (certChain.rbegin()->empty()) {
+                LogDebug("Error in parsing certificates!");
+                retCode = CKM_API_ERROR_INPUT_PARAM;
+                break;
             }
         }
     }
index 386aec8..6a065c1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2014 Samsung Electronics Co.
+ *  Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ public:
     OCSPLogic& operator=(const OCSPLogic &) = delete;
     OCSPLogic& operator=(OCSPLogic &&) = delete;
 
-    RawBuffer ocspCheck(int commandId, const RawBufferVector &rawChain);
+    RawBuffer ocspCheck(int commandId, const RawBufferVector &rawChain, bool allowed);
     virtual ~OCSPLogic(){}
 private:
     void setNetAvailable();
index c2a6a23..e65114d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2014 Samsung Electronics Co.
+ *  Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -53,13 +53,14 @@ void OCSPService::Stop() {
 GenericSocketService::ServiceDescriptionVector OCSPService::GetServiceDescription()
 {
     return ServiceDescriptionVector {
-        {SERVICE_SOCKET_OCSP, "key-manager::api-ocsp", SOCKET_ID_OCSP}
+        {SERVICE_SOCKET_OCSP, "http://tizen.org/privilege/internet", SOCKET_ID_OCSP}
     };
 }
 
 bool OCSPService::ProcessOne(
     const ConnectionID &conn,
-    ConnectionInfo &info)
+    ConnectionInfo &info,
+    bool allowed)
 {
     LogDebug ("process One");
 
@@ -73,7 +74,7 @@ bool OCSPService::ProcessOne(
         RawBufferVector chainVector;
         buffer.Deserialize(commandId, chainVector);
 
-        RawBuffer response = m_logic->ocspCheck(commandId, chainVector);
+        RawBuffer response = m_logic->ocspCheck(commandId, chainVector, allowed);
         m_serviceManager->Write(conn, response);
 
         return true;
index 16121ec..a8453ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2014 Samsung Electronics Co.
+ *  Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -47,7 +47,8 @@ public:
 private:
     bool ProcessOne(
         const ConnectionID &conn,
-        ConnectionInfo &info);
+        ConnectionInfo &info,
+        bool allowed);
 
     OCSPLogic *m_logic;
 };
index 065fafe..a2fd9db 100644 (file)
@@ -10,6 +10,8 @@ PKG_CHECK_MODULES(CKM_DB_TOOL_DEP
     capi-system-info
     vconf
     libxml-2.0
+    cynara-client-async
+    cynara-creds-socket
     )
 
 FIND_PACKAGE(Threads REQUIRED)
@@ -33,6 +35,7 @@ SET(CKM_DB_TOOL_SOURCES
     ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/db-crypto-ext.cpp
     ${PROJECT_SOURCE_DIR}/tools/ckm_db_tool/ckm-logic-ext.cpp
 
+    ${KEY_MANAGER_PATH}/main/cynara.cpp
     ${KEY_MANAGER_PATH}/main/generic-socket-manager.cpp
     ${KEY_MANAGER_PATH}/main/socket-manager.cpp
     ${KEY_MANAGER_PATH}/main/smack-check.cpp