Extract communication functions to common library 09/30809/16
authorLukasz Kostyra <l.kostyra@samsung.com>
Mon, 17 Nov 2014 11:48:55 +0000 (12:48 +0100)
committerRafal Krypa <r.krypa@samsung.com>
Tue, 31 Mar 2015 09:57:45 +0000 (11:57 +0200)
Since slave service will use the same functions as client library to send data,
these are extracted in this commit and will be used in the next change.

[Verification]  Build, install, run tests.

Change-Id: I4b9e11015c657066657f493e87d68958283bb947

src/client/client-common.cpp
src/client/client-offline.cpp
src/client/client-security-manager.cpp
src/client/include/client-common.h
src/common/CMakeLists.txt
src/common/connection.cpp [new file with mode: 0644]
src/common/include/connection.h [new file with mode: 0644]
src/server/service/service.cpp

index 883ab8d..3051cbc 100644 (file)
@@ -45,225 +45,14 @@ IMPLEMENT_SAFE_SINGLETON(SecurityManager::Log::LogSystem);
 
 namespace {
 
-const int POLL_TIMEOUT = -1;
-
 void securityClientEnableLogSystem(void) {
     SecurityManager::Singleton<SecurityManager::Log::LogSystem>::Instance().SetTag("SECURITY_MANAGER_CLIENT");
 }
 
-int waitForSocket(int sock, int event, int timeout) {
-    int retval;
-    pollfd desc[1];
-    desc[0].fd = sock;
-    desc[0].events = event;
-
-    while((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) {
-        timeout >>= 1;
-        errno = 0;
-    }
-
-    if (0 == retval) {
-        LogDebug("Poll timeout");
-    } else if (-1 == retval) {
-        int err = errno;
-        LogError("Error in poll: " << strerror(err));
-    }
-    return retval;
-}
-
-class SockRAII {
-public:
-    SockRAII()
-      : m_sock(-1)
-    {}
-
-    virtual ~SockRAII() {
-        if (m_sock > -1)
-            close(m_sock);
-    }
-
-    int Connect(char const * const interface) {
-        sockaddr_un clientAddr;
-        int flags;
-
-        if (m_sock != -1) // guard
-            close(m_sock);
-
-        m_sock = socket(AF_UNIX, SOCK_STREAM, 0);
-        if (m_sock < 0) {
-            int err = errno;
-            LogError("Error creating socket: " << strerror(err));
-            return SECURITY_MANAGER_API_ERROR_SOCKET;
-        }
-
-        if ((flags = fcntl(m_sock, F_GETFL, 0)) < 0 ||
-            fcntl(m_sock, F_SETFL, flags | O_NONBLOCK) < 0)
-        {
-            int err = errno;
-            LogError("Error in fcntl: " << strerror(err));
-            return SECURITY_MANAGER_API_ERROR_SOCKET;
-        }
-
-        memset(&clientAddr, 0, sizeof(clientAddr));
-
-        clientAddr.sun_family = AF_UNIX;
-
-        if (strlen(interface) >= sizeof(clientAddr.sun_path)) {
-            LogError("Error: interface name " << interface << "is too long. Max len is:" << sizeof(clientAddr.sun_path));
-            return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE;
-        }
-
-        strcpy(clientAddr.sun_path, interface);
-
-        LogDebug("ClientAddr.sun_path = " << interface);
-
-        int retval = TEMP_FAILURE_RETRY(connect(m_sock, (struct sockaddr*)&clientAddr, SUN_LEN(&clientAddr)));
-        if ((retval == -1) && (errno == EINPROGRESS)) {
-            if (0 >= waitForSocket(m_sock, POLLOUT, POLL_TIMEOUT)) {
-                LogError("Error in waitForSocket.");
-                return SECURITY_MANAGER_API_ERROR_SOCKET;
-            }
-            int error = 0;
-            socklen_t len = sizeof(error);
-            retval = getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &len);
-
-            if (-1 == retval) {
-                int err = errno;
-                LogError("Error in getsockopt: " << strerror(err));
-                return SECURITY_MANAGER_API_ERROR_SOCKET;
-            }
-
-            if (error == EACCES) {
-                LogError("Access denied");
-                return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED;
-            }
-
-            if (error != 0) {
-                LogError("Error in connect: " << strerror(error));
-                return SECURITY_MANAGER_API_ERROR_SOCKET;
-            }
-
-            return SECURITY_MANAGER_API_SUCCESS;
-        }
-
-        if (-1 == retval) {
-            int err = errno;
-            LogError("Error connecting socket: " << strerror(err));
-            if (err == EACCES)
-                return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED;
-            if (err == ENOTSOCK)
-                return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE;
-            return SECURITY_MANAGER_API_ERROR_SOCKET;
-        }
-
-        return SECURITY_MANAGER_API_SUCCESS;
-    }
-
-    int Get() {
-        return m_sock;
-    }
-
-private:
-    int m_sock;
-};
-
 } // namespace anonymous
 
 namespace SecurityManager {
 
-int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) {
-    int ret;
-    SockRAII sock;
-    ssize_t done = 0;
-    char buffer[2048];
-
-    if (SECURITY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) {
-        LogError("Error in SockRAII");
-        return ret;
-    }
-
-    while ((send.size() - done) > 0) {
-        if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) {
-            LogError("Error in poll(POLLOUT)");
-            return SECURITY_MANAGER_API_ERROR_SOCKET;
-        }
-        ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done));
-        if (-1 == temp) {
-            int err = errno;
-            LogError("Error in write: " << strerror(err));
-            return SECURITY_MANAGER_API_ERROR_SOCKET;
-        }
-        done += temp;
-    }
-
-    do {
-        if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
-            LogError("Error in poll(POLLIN)");
-            return SECURITY_MANAGER_API_ERROR_SOCKET;
-        }
-        ssize_t temp = TEMP_FAILURE_RETRY(read(sock.Get(), buffer, 2048));
-        if (-1 == temp) {
-            int err = errno;
-            LogError("Error in read: " << strerror(err));
-            return SECURITY_MANAGER_API_ERROR_SOCKET;
-        }
-
-        if (0 == temp) {
-            LogError("Read return 0/Connection closed by server(?)");
-            return SECURITY_MANAGER_API_ERROR_SOCKET;
-        }
-
-        RawBuffer raw(buffer, buffer+temp);
-        recv.Push(raw);
-    } while(!recv.Ready());
-    return SECURITY_MANAGER_API_SUCCESS;
-}
-
-int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr) {
-    int ret;
-    SockRAII sock;
-    ssize_t done = 0;
-
-    if (SECURITY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) {
-        LogError("Error in SockRAII");
-        return ret;
-    }
-
-    while ((send.size() - done) > 0) {
-        if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) {
-            LogError("Error in poll(POLLOUT)");
-            return SECURITY_MANAGER_API_ERROR_SOCKET;
-        }
-        ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done));
-        if (-1 == temp) {
-            int err = errno;
-            LogError("Error in write: " << strerror(err));
-            return SECURITY_MANAGER_API_ERROR_SOCKET;
-        }
-        done += temp;
-    }
-
-    if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
-        LogError("Error in poll(POLLIN)");
-        return SECURITY_MANAGER_API_ERROR_SOCKET;
-    }
-
-    ssize_t temp = TEMP_FAILURE_RETRY(recvmsg(sock.Get(), &hdr, MSG_CMSG_CLOEXEC));
-
-    if (temp < 0) {
-        int err = errno;
-        LogError("Error in recvmsg(): " << strerror(err) << " errno: " << err);
-        return SECURITY_MANAGER_API_ERROR_SOCKET;
-    }
-
-    if (0 == temp) {
-        LogError("Read return 0/Connection closed by server(?)");
-        return SECURITY_MANAGER_API_ERROR_SOCKET;
-    }
-
-    return SECURITY_MANAGER_API_SUCCESS;
-}
-
 int try_catch(const std::function<int()>& func)
 {
     try {
index e442c2f..d60911d 100644 (file)
  * @brief       Helper class for client "off-line" mode detection
  */
 
+#include <client-offline.h>
 #include <client-common.h>
 #include <message-buffer.h>
 #include <protocols.h>
+#include <connection.h>
 #include <dpl/serialization.h>
 #include <dpl/log/log.h>
-#include "client-offline.h"
 
 namespace SecurityManager {
 
index 74a6b30..4d6fecb 100644 (file)
@@ -44,6 +44,8 @@
 #include <client-common.h>
 #include <protocols.h>
 #include <service_impl.h>
+#include <connection.h>
+
 #include <security-manager.h>
 #include <client-offline.h>
 
index c7d18a4..b82f6a5 100644 (file)
 #ifndef _SECURITY_MANAGER_CLIENT_
 #define _SECURITY_MANAGER_CLIENT_
 
-#include <vector>
 #include <functional>
 
-#include <message-buffer.h>
-
 #define SECURITY_MANAGER_API __attribute__((visibility("default")))
 #define SECURITY_MANAGER_UNUSED __attribute__((unused))
 
-extern "C" {
-    struct msghdr;
-}
-
 namespace SecurityManager {
 
-typedef std::vector<unsigned char> RawBuffer;
-
-int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv);
-
-/*
- * sendToServerAncData is special case when we want to receive file descriptor
- * passed by Security Manager on behalf of calling process. We can't get it with
- * MessageBuffer.
- *
- * This function should be called _ONLY_ in this particular case.
- *
- */
-int sendToManagerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr);
-
 /*
  * Decorator function that performs frequently repeated exception handling in
  * SS client API functions. Accepts lambda expression as an argument.
index 2da9c3e..6571e64 100644 (file)
@@ -41,6 +41,7 @@ SET(COMMON_SOURCES
     ${DPL_PATH}/core/src/string.cpp
     ${DPL_PATH}/db/src/naive_synchronization_object.cpp
     ${DPL_PATH}/db/src/sql_connection.cpp
+    ${COMMON_PATH}/connection.cpp
     ${COMMON_PATH}/cynara.cpp
     ${COMMON_PATH}/file-lock.cpp
     ${COMMON_PATH}/protocols.cpp
diff --git a/src/common/connection.cpp b/src/common/connection.cpp
new file mode 100644 (file)
index 0000000..e4dc9ee
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ *  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        connection.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @author      Lukasz Kostyra (l.kostyra@samsung.com)
+ * @version     1.0
+ * @brief       This file is implementation of common connection functions.
+ */
+
+#include "connection.h"
+#include <fcntl.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/smack.h>
+#include <sys/xattr.h>
+#include <linux/xattr.h>
+#include <unistd.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <message-buffer.h>
+
+#include <protocols.h>
+
+namespace {
+
+const int POLL_TIMEOUT = -1;
+
+int waitForSocket(int sock, int event, int timeout) {
+    int retval;
+    pollfd desc[1];
+    desc[0].fd = sock;
+    desc[0].events = event;
+
+    while((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) {
+        timeout >>= 1;
+        errno = 0;
+    }
+
+    if (0 == retval) {
+        LogDebug("Poll timeout");
+    } else if (-1 == retval) {
+        int err = errno;
+        LogError("Error in poll: " << strerror(err));
+    }
+    return retval;
+}
+
+class SockRAII {
+public:
+    SockRAII()
+      : m_sock(-1)
+    {}
+
+    virtual ~SockRAII() {
+        if (m_sock > -1)
+            close(m_sock);
+    }
+
+    int Connect(char const * const interface) {
+        sockaddr_un clientAddr;
+        int flags;
+
+        if (m_sock != -1) // guard
+            close(m_sock);
+
+        m_sock = socket(AF_UNIX, SOCK_STREAM, 0);
+        if (m_sock < 0) {
+            int err = errno;
+            LogError("Error creating socket: " << strerror(err));
+            return SECURITY_MANAGER_API_ERROR_SOCKET;
+        }
+
+        if ((flags = fcntl(m_sock, F_GETFL, 0)) < 0 ||
+            fcntl(m_sock, F_SETFL, flags | O_NONBLOCK) < 0)
+        {
+            int err = errno;
+            LogError("Error in fcntl: " << strerror(err));
+            return SECURITY_MANAGER_API_ERROR_SOCKET;
+        }
+
+        memset(&clientAddr, 0, sizeof(clientAddr));
+
+        clientAddr.sun_family = AF_UNIX;
+
+        if (strlen(interface) >= sizeof(clientAddr.sun_path)) {
+            LogError("Error: interface name " << interface << "is too long. Max len is:" << sizeof(clientAddr.sun_path));
+            return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE;
+        }
+
+        strcpy(clientAddr.sun_path, interface);
+
+        LogDebug("ClientAddr.sun_path = " << interface);
+
+        int retval = TEMP_FAILURE_RETRY(connect(m_sock, (struct sockaddr*)&clientAddr, SUN_LEN(&clientAddr)));
+        if ((retval == -1) && (errno == EINPROGRESS)) {
+            if (0 >= waitForSocket(m_sock, POLLIN, POLL_TIMEOUT)) {
+                LogError("Error in waitForSocket.");
+                return SECURITY_MANAGER_API_ERROR_SOCKET;
+            }
+            int error = 0;
+            socklen_t len = sizeof(error);
+            retval = getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &len);
+
+            if (-1 == retval) {
+                int err = errno;
+                LogError("Error in getsockopt: " << strerror(err));
+                return SECURITY_MANAGER_API_ERROR_SOCKET;
+            }
+
+            if (error == EACCES) {
+                LogError("Access denied");
+                return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED;
+            }
+
+            if (error != 0) {
+                LogError("Error in connect: " << strerror(error));
+                return SECURITY_MANAGER_API_ERROR_SOCKET;
+            }
+
+            return SECURITY_MANAGER_API_SUCCESS;
+        }
+
+        if (-1 == retval) {
+            int err = errno;
+            LogError("Error connecting socket: " << strerror(err));
+            if (err == EACCES)
+                return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED;
+            if (err == ENOTSOCK)
+                return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE;
+            return SECURITY_MANAGER_API_ERROR_SOCKET;
+        }
+
+        return SECURITY_MANAGER_API_SUCCESS;
+    }
+
+    int Get() {
+        return m_sock;
+    }
+
+private:
+    int m_sock;
+};
+
+} // namespace anonymous
+
+namespace SecurityManager {
+
+int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) {
+    int ret;
+    SockRAII sock;
+    ssize_t done = 0;
+    char buffer[2048];
+
+    if (SECURITY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) {
+        LogError("Error in SockRAII");
+        return ret;
+    }
+
+    while ((send.size() - done) > 0) {
+        if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) {
+            LogError("Error in poll(POLLOUT)");
+            return SECURITY_MANAGER_API_ERROR_SOCKET;
+        }
+        ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done));
+        if (-1 == temp) {
+            int err = errno;
+            LogError("Error in write: " << strerror(err));
+            return SECURITY_MANAGER_API_ERROR_SOCKET;
+        }
+        done += temp;
+    }
+
+    do {
+        if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
+            LogError("Error in poll(POLLIN)");
+            return SECURITY_MANAGER_API_ERROR_SOCKET;
+        }
+        ssize_t temp = TEMP_FAILURE_RETRY(read(sock.Get(), buffer, 2048));
+        if (-1 == temp) {
+            int err = errno;
+            LogError("Error in read: " << strerror(err));
+            return SECURITY_MANAGER_API_ERROR_SOCKET;
+        }
+
+        if (0 == temp) {
+            LogError("Read return 0/Connection closed by server(?)");
+            return SECURITY_MANAGER_API_ERROR_SOCKET;
+        }
+
+        RawBuffer raw(buffer, buffer+temp);
+        recv.Push(raw);
+    } while(!recv.Ready());
+    return SECURITY_MANAGER_API_SUCCESS;
+}
+
+int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr) {
+    int ret;
+    SockRAII sock;
+    ssize_t done = 0;
+
+    if (SECURITY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) {
+        LogError("Error in SockRAII");
+        return ret;
+    }
+
+    while ((send.size() - done) > 0) {
+        if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) {
+            LogError("Error in poll(POLLOUT)");
+            return SECURITY_MANAGER_API_ERROR_SOCKET;
+        }
+        ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done));
+        if (-1 == temp) {
+            int err = errno;
+            LogError("Error in write: " << strerror(err));
+            return SECURITY_MANAGER_API_ERROR_SOCKET;
+        }
+        done += temp;
+    }
+
+    if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
+        LogError("Error in poll(POLLIN)");
+        return SECURITY_MANAGER_API_ERROR_SOCKET;
+    }
+
+    ssize_t temp = TEMP_FAILURE_RETRY(recvmsg(sock.Get(), &hdr, MSG_CMSG_CLOEXEC));
+
+    if (temp < 0) {
+        int err = errno;
+        LogError("Error in recvmsg(): " << strerror(err) << " errno: " << err);
+        return SECURITY_MANAGER_API_ERROR_SOCKET;
+    }
+
+    if (0 == temp) {
+        LogError("Read return 0/Connection closed by server(?)");
+        return SECURITY_MANAGER_API_ERROR_SOCKET;
+    }
+
+    return SECURITY_MANAGER_API_SUCCESS;
+}
+
+} // namespace SecurityManager
diff --git a/src/common/include/connection.h b/src/common/include/connection.h
new file mode 100644 (file)
index 0000000..77967c4
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ *  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        sock-raii.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @author      Lukasz Kostyra (l.kostyra@samsung.com)
+ * @version     1.0
+ * @brief       This file constains declarations of connection-related functions
+ *              used in security manager.
+ */
+
+#ifndef _SECURITY_MANAGER_CONNECTION_
+#define _SECURITY_MANAGER_CONNECTION_
+
+#include <vector>
+#include <functional>
+
+#include <message-buffer.h>
+
+extern "C" {
+    struct msghdr;
+}
+
+namespace SecurityManager {
+
+typedef std::vector<unsigned char> RawBuffer;
+
+int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv);
+
+/*
+ * sendToServerAncData is special case when we want to receive file descriptor
+ * passed by Security Manager on behalf of calling process. We can't get it with
+ * MessageBuffer.
+ *
+ * This function should be called _ONLY_ in this particular case.
+ *
+ */
+int sendToManagerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr);
+
+} // namespace SecurityManager
+
+#endif // _SECURITY_MANAGER_CONNECTION_
index 522356f..334ce19 100644 (file)
@@ -29,6 +29,7 @@
 #include <dpl/serialization.h>
 #include <sys/smack.h>
 
+#include "connection.h"
 #include "protocols.h"
 #include "service.h"
 #include "service_impl.h"