Raw copy client-common.cpp from security-server repository
authorLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Thu, 26 Jun 2014 23:20:15 +0000 (01:20 +0200)
committerRafal Krypa <r.krypa@samsung.com>
Thu, 3 Jul 2014 12:19:10 +0000 (14:19 +0200)
Source of code:
    repository: tizen.org/platform/core/security/security-server
    patch:      210758dc04b639fbc87df8c1ef6fba7e86b41875

Added file needs adaptation to Cynara. Due to many dependencies
it won't compile. That is why it is not added to CMakeLists yet.

Verification : Because of above patch doesn't need verification.

Change-Id: Ie826567c11ff827cf45043911b54b24275a0ffe7

src/client/sockets/client-common.cpp [new file with mode: 0644]

diff --git a/src/client/sockets/client-common.cpp b/src/client/sockets/client-common.cpp
new file mode 100644 (file)
index 0000000..00f099f
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@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        client-common.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This file is implementation of client-common functions.
+ */
+
+#include <fcntl.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+#include <dpl/singleton.h>
+#include <dpl/singleton_safe_impl.h>
+
+#include <message-buffer.h>
+
+#include <security-server.h>
+
+IMPLEMENT_SAFE_SINGLETON(SecurityServer::Log::LogSystem);
+
+namespace {
+
+const int POLL_TIMEOUT = 2000;
+
+void securityClientEnableLogSystem(void) {
+    SecurityServer::Singleton<SecurityServer::Log::LogSystem>::Instance().SetTag("SECURITY_SERVER_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_SERVER_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_SERVER_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_SERVER_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_SERVER_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_SERVER_API_ERROR_SOCKET;
+            }
+
+            if (error == EACCES) {
+                LogError("Access denied");
+                return SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
+            }
+
+            if (error != 0) {
+                LogError("Error in connect: " << strerror(error));
+                return SECURITY_SERVER_API_ERROR_SOCKET;
+            }
+
+            return SECURITY_SERVER_API_SUCCESS;
+        }
+
+        if (-1 == retval) {
+            int err = errno;
+            LogError("Error connecting socket: " << strerror(err));
+            if (err == EACCES)
+                return SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
+            if (err == ENOTSOCK)
+                return SECURITY_SERVER_API_ERROR_NO_SUCH_SERVICE;
+            return SECURITY_SERVER_API_ERROR_SOCKET;
+        }
+
+        return SECURITY_SERVER_API_SUCCESS;
+    }
+
+    int Get() {
+        return m_sock;
+    }
+
+private:
+    int m_sock;
+};
+
+} // namespace anonymous
+
+namespace SecurityServer {
+
+
+int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) {
+    int ret;
+    SockRAII sock;
+    ssize_t done = 0;
+    char buffer[2048];
+
+    if (SECURITY_SERVER_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_SERVER_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_SERVER_API_ERROR_SOCKET;
+        }
+        done += temp;
+    }
+
+    do {
+        if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
+            LogError("Error in poll(POLLIN)");
+            return SECURITY_SERVER_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_SERVER_API_ERROR_SOCKET;
+        }
+
+        if (0 == temp) {
+            LogError("Read return 0/Connection closed by server(?)");
+            return SECURITY_SERVER_API_ERROR_SOCKET;
+        }
+
+        RawBuffer raw(buffer, buffer+temp);
+        recv.Push(raw);
+    } while(!recv.Ready());
+    return SECURITY_SERVER_API_SUCCESS;
+}
+
+int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr) {
+    int ret;
+    SockRAII sock;
+    ssize_t done = 0;
+
+    if (SECURITY_SERVER_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_SERVER_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_SERVER_API_ERROR_SOCKET;
+        }
+        done += temp;
+    }
+
+    if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
+        LogError("Error in poll(POLLIN)");
+        return SECURITY_SERVER_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_SERVER_API_ERROR_SOCKET;
+    }
+
+    if (0 == temp) {
+        LogError("Read return 0/Connection closed by server(?)");
+        return SECURITY_SERVER_API_ERROR_SOCKET;
+    }
+
+    return SECURITY_SERVER_API_SUCCESS;
+}
+
+int try_catch(const std::function<int()>& func)
+{
+    try {
+        return func();
+    } catch (MessageBuffer::Exception::Base &e) {
+        LogError("SecurityServer::MessageBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogError("STD exception " << e.what());
+    } catch (...) {
+        LogError("Unknown exception occured");
+    }
+    return SECURITY_SERVER_API_ERROR_UNKNOWN;
+}
+
+} // namespace SecurityServer
+
+static void init_lib(void) __attribute__ ((constructor));
+static void init_lib(void)
+{
+    securityClientEnableLogSystem();
+}
+
+static void fini_lib(void) __attribute__ ((destructor));
+static void fini_lib(void)
+{
+
+}
+