Rewriting client socket privilige part and adding exec path service
authorZofia Abramowska <z.abramowska@samsung.com>
Tue, 16 Jul 2013 10:01:42 +0000 (12:01 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 6 Feb 2014 16:13:21 +0000 (17:13 +0100)
[Issue#] SSDWSSP-367
[Bug/Feature] N/A
[Cause] Rewriting client API and security-server socket privilige checks
functionality to match recently written security-server services
[Solution] Rewriting client API to use new implementation of sockets,
adding new service for get execution path request
[Verification] Successful build.
        Run test 'security-server-test-client-smack'
        with 'regexp=sock' argument and check dlog logs whether
        execution path is being properly send
        (This functionality is not in ss API, so no tests for
        this specific service are available)

Change-Id: I49031860de14986f73899cb8c99f061241ede39b

14 files changed:
packaging/security-server.spec
src/CMakeLists.txt
src/client/security-server-client.c
src/include/security-server-comm.h
src/server/security-server-main.c
src/server2/client/client-socket-privilege.cpp [new file with mode: 0644]
src/server2/common/protocols.cpp
src/server2/common/protocols.h
src/server2/main/server2-main.cpp
src/server2/service/exec-path.cpp [new file with mode: 0644]
src/server2/service/exec-path.h [new file with mode: 0644]
systemd/CMakeLists.txt
systemd/security-server-exec-path.socket [new file with mode: 0644]
systemd/security-server.service

index c1b2e22..64d0394 100644 (file)
@@ -81,6 +81,7 @@ ln -s ../security-server.socket %{buildroot}/usr/lib/systemd/system/sockets.targ
 ln -s ../security-server-data-share.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-data-share.socket
 ln -s ../security-server-get-gid.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-get-gid.socket
 ln -s ../security-server-privilege-by-pid.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-privilege-by-pid.socket
+ln -s ../security-server-exec-path.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-exec-path.socket
 
 %clean
 rm -rf %{buildroot}
@@ -117,6 +118,8 @@ systemctl daemon-reload
 %attr(-,root,root) /usr/lib/systemd/system/security-server-get-gid.socket
 %attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-privilege-by-pid.socket
 %attr(-,root,root) /usr/lib/systemd/system/security-server-privilege-by-pid.socket
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-exec-path.socket
+%attr(-,root,root) /usr/lib/systemd/system/security-server-exec-path.socket
 
 %{_datadir}/license/%{name}
 
index e6dd979..297c245 100644 (file)
@@ -23,6 +23,7 @@ SET(SECURITY_SERVER_SOURCES
     ${SERVER2_PATH}/service/echo.cpp
     ${SERVER2_PATH}/service/get-gid.cpp
     ${SERVER2_PATH}/service/privilege-by-pid.cpp
+    ${SERVER2_PATH}/service/exec-path.cpp
     )
 
 SET_SOURCE_FILES_PROPERTIES(
@@ -65,6 +66,7 @@ SET(SECURITY_CLIENT_SOURCES
     ${SECURITY_SERVER_PATH}/server2/client/client-shared-memory.cpp
     ${SECURITY_SERVER_PATH}/server2/client/client-get-gid.cpp
     ${SECURITY_SERVER_PATH}/server2/client/client-privilege-by-pid.cpp
+    ${SECURITY_SERVER_PATH}/server2/client/client-socket-privilege.cpp
     ${SECURITY_SERVER_PATH}/client/security-server-client.c
     ${SECURITY_SERVER_PATH}/communication/security-server-comm.c
     ${SECURITY_SERVER_PATH}/util/smack-check.c
index 032c04c..8d35de0 100644 (file)
@@ -105,139 +105,6 @@ int convert_to_public_error_code(int err_code)
     return err_code;
 }
 
-static int send_exec_path_request(int sock_fd, pid_t pid)
-{
-    basic_header hdr;
-    int retval;
-    unsigned char buf[sizeof(hdr) + sizeof(pid)];
-
-    /* Assemble header */
-    hdr.version = SECURITY_SERVER_MSG_VERSION;
-    hdr.msg_id = SECURITY_SERVER_MSG_TYPE_EXE_PATH_REQUEST;
-    hdr.msg_len = sizeof(pid);
-
-    memcpy(buf, &hdr, sizeof(hdr));
-    memcpy(buf + sizeof(hdr), &pid, sizeof(pid));
-
-    /* Check poll */
-    retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
-    if (retval == SECURITY_SERVER_ERROR_POLL)
-    {
-        SEC_SVR_ERR("%s", "poll() error");
-        return SECURITY_SERVER_ERROR_SEND_FAILED;
-    }
-    if (retval == SECURITY_SERVER_ERROR_TIMEOUT)
-    {
-        SEC_SVR_ERR("%s", "poll() timeout");
-        return SECURITY_SERVER_ERROR_SEND_FAILED;
-    }
-
-    /* Send to server */
-    retval = TEMP_FAILURE_RETRY(write(sock_fd, buf, sizeof(buf)));
-    if (retval < (ssize_t)sizeof(buf))
-    {
-        /* Write error */
-        SEC_SVR_ERR("Error on write(): %d", retval);
-        return SECURITY_SERVER_ERROR_SEND_FAILED;
-    }
-    return SECURITY_SERVER_SUCCESS;
-}
-
-static int recv_exec_path_response(int sockfd, response_header *hdr, char **path)
-{
-    size_t size = 0;
-    char *buf = NULL;
-    int retval;
-
-    if (*path)
-    {
-        SEC_SVR_ERR("path should be NULL");
-        return SECURITY_SERVER_ERROR_INPUT_PARAM;
-    }
-
-    retval = recv_generic_response(sockfd, hdr);
-    if (retval != SECURITY_SERVER_SUCCESS)
-    {
-        SEC_SVR_ERR("Failed to get response: %d", retval);
-        return return_code_to_error_code(hdr->return_code);
-    }
-
-    retval = TEMP_FAILURE_RETRY(read(sockfd, &size, sizeof(size_t)));
-    if (retval < (ssize_t)sizeof(size_t) || size == 0 || size > MESSAGE_MAX_LEN)
-    {
-        /* Error on socket */
-        SEC_SVR_ERR("read() failed: %d", retval);
-        return SECURITY_SERVER_ERROR_RECV_FAILED;
-    }
-    buf = (char*)malloc((size + 1) * sizeof(char));
-    if (!buf)
-    {
-        SEC_SVR_ERR("malloc() failed. Size requested: %d", size * sizeof(char));
-        return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
-    }
-
-    retval = TEMP_FAILURE_RETRY(read(sockfd, buf, size));
-    if (retval < (ssize_t)size)
-    {
-        /* Error on socket */
-        SEC_SVR_ERR("read() failed: %d", retval);
-        free(buf);
-        return SECURITY_SERVER_ERROR_RECV_FAILED;
-    }
-    // terminate string
-    buf[size] = '\0';
-
-    *path = buf;
-    return SECURITY_SERVER_SUCCESS;
-}
-
-static int get_exec_path(pid_t pid, char **exe)
-{
-    int sockfd = -1;
-    int ret = 0;
-    char *path = NULL;
-    response_header hdr;
-    if (SECURITY_SERVER_SUCCESS != connect_to_server(&sockfd))
-        goto out;
-
-    ret = send_exec_path_request(sockfd, pid);
-    if (ret != SECURITY_SERVER_SUCCESS)
-    {
-        /* Error on socket */
-        SEC_SVR_ERR("Client: Send failed: %d", ret);
-        goto out;
-    }
-
-    ret = recv_exec_path_response(sockfd, &hdr, &path);
-    if (ret != SECURITY_SERVER_SUCCESS)
-    {
-        SEC_SVR_ERR("Client: Recv failed: %d", ret);
-        goto out;
-    }
-
-    ret = return_code_to_error_code(hdr.return_code);
-    if (hdr.basic_hdr.msg_id == SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE)
-        SEC_SVR_ERR("Client: Error has been received. return code:%d", hdr.return_code);
-    else if (hdr.basic_hdr.msg_id != SECURITY_SERVER_MSG_TYPE_EXE_PATH_RESPONSE)
-    {
-        SEC_SVR_ERR("Client: Wrong response type.");
-        ret = SECURITY_SERVER_ERROR_BAD_RESPONSE;
-    }
-
-out:
-    if (sockfd != -1)
-        close(sockfd);
-
-    if (ret == SECURITY_SERVER_SUCCESS)
-    {
-        *exe = path;
-        path = NULL;
-    }
-    free(path);
-    return ret;
-}
-
-
 // SECURITY_SERVER_API
 // int security_server_get_gid(const char *object)
 // {
@@ -324,9 +191,6 @@ out:
 //     return retval;
 // }
 
-
-
-
 SECURITY_SERVER_API
 int security_server_get_object_name(gid_t gid, char *object, size_t max_object_size)
 {
@@ -584,75 +448,12 @@ error:
 }
 
 SECURITY_SERVER_API
-int security_server_check_privilege_by_sockfd(int sockfd,
-                                              const char *object,
-                                              const char *access_rights)
-{
-    char *subject;
-    int ret;
-    char *path = NULL;
-
-    //for get socket options
-    struct ucred cr;
-    unsigned int len = sizeof(cr);
-
-    //SMACK runtime check
-    if (!smack_runtime_check())
-    {
-        SEC_SVR_DBG("%s","No SMACK support on device");
-        return SECURITY_SERVER_API_SUCCESS;
-    }
-
-    ret = smack_new_label_from_socket(sockfd, &subject);
-    if (ret != 0)
-        return SECURITY_SERVER_API_ERROR_SERVER_ERROR;
-
-    len = sizeof(cr);
-    ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
-    if (ret < 0) {
-        SEC_SVR_ERR("Error in getsockopt(). Errno: %s", strerror(errno));
-        ret = 0;
-        goto err;
-    }
-    ret = get_exec_path(cr.pid, &path);
-    if (SECURITY_SERVER_SUCCESS != ret)
-        SEC_SVR_ERR("Failed to read executable path for process %d", cr.pid);
-
-    ret = security_server_check_privilege_by_pid(cr.pid, object, access_rights);
-    if (ret == SECURITY_SERVER_RETURN_CODE_SUCCESS)
-        ret = 1;
-    else
-        ret = 0;
-
-err:
-
-    SECURE_SLOGD("security_server_check_privilege_by_pid returned %d", ret);
-    if (ret > 0)
-        SECURE_SLOGD("SS_SMACK: caller_pid=%d, subject=%s, object=%s, access=%s, result=%d, caller_path=%s", cr.pid, subject, object, access_rights, ret, path);
-    else
-        SECURE_SLOGW("SS_SMACK: caller_pid=%d, subject=%s, object=%s, access=%s, result=%d, caller_path=%s", cr.pid, subject, object, access_rights, ret, path);
-
-    free(path);
-    free(subject);
-    if (ret == 1)
-    {
-        return SECURITY_SERVER_API_SUCCESS;
-    }
-    else
-    {
-        return SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
-    }
-}
-
-
-SECURITY_SERVER_API
 int security_server_get_cookie_size(void)
 {
     return SECURITY_SERVER_COOKIE_LEN;
 }
 
 
-
 SECURITY_SERVER_API
 int security_server_get_cookie_pid(const char *cookie)
 {
@@ -1264,27 +1065,6 @@ error:
     return NULL;
 }
 
-SECURITY_SERVER_API
-char *security_server_get_smacklabel_sockfd(int fd)
-{
-    char *label = NULL;
-
-    if (!smack_check())
-    {
-        SEC_SVR_DBG("%s","No SMACK support on device");
-        label = (char*) malloc(1);
-        if (label) label[0] = '\0';
-        return label;
-    }
-
-    if (smack_new_label_from_socket(fd, &label) != 0)
-    {
-        SEC_SVR_ERR("Client ERROR: Unable to get socket SMACK label");
-        return NULL;
-    }
-
-    return label;
-}
 
 #ifdef USE_SEC_SRV1_FOR_CHECK_PRIVILEGE_BY_PID
 SECURITY_SERVER_API
index ebd428a..8bf4a10 100644 (file)
@@ -73,8 +73,6 @@ typedef struct
 #define SECURITY_SERVER_MSG_TYPE_CHECK_PID_PRIVILEGE_REQUEST    0x21
 #define SECURITY_SERVER_MSG_TYPE_CHECK_PID_PRIVILEGE_RESPONSE   0x22
 #endif
-#define SECURITY_SERVER_MSG_TYPE_EXE_PATH_REQUEST               0x23
-#define SECURITY_SERVER_MSG_TYPE_EXE_PATH_RESPONSE              0x24
 #define SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE               0xff
 
 /* Return code */
index db02bc6..0b615c1 100644 (file)
@@ -1153,133 +1153,6 @@ error:
 }
 
 
-/* Send exe path response to client
- *
- * Get exe path response packet format
- *  0                   1                   2                   3
- *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * |---------------------------------------------------------------|
- * | version=0x01  |MessageID=0x24 |Message Length = 4+path length |
- * |---------------------------------------------------------------|
- * |  return code  |  Path length  |             Path              |
- * |---------------------------------------------------------------|
-
-*/
-int send_exe_path_response(int sockfd, const char *path)
-{
-    response_header hdr;
-    unsigned char *msg = NULL;
-    unsigned char *ptr = NULL;
-    int ret;
-    size_t path_len = 0;
-    unsigned short msg_len = 0;
-
-    if (!path) {
-        SEC_SVR_ERR("Path is NULL");
-        return SECURITY_SERVER_ERROR_INPUT_PARAM;
-    }
-
-    path_len = strlen(path);
-    msg_len = sizeof(hdr) + sizeof(size_t) + path_len;
-    msg = (unsigned char*)malloc(msg_len * sizeof(unsigned char));
-    if (!msg) {
-        SEC_SVR_ERR("malloc failed");
-        return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
-    }
-
-    /* Assemble header */
-    hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
-    hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_EXE_PATH_RESPONSE;
-    hdr.basic_hdr.msg_len = sizeof(size_t) + path_len;
-    hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
-
-    /* Prepare packet */
-    ptr = msg;
-    memcpy(ptr, &hdr, sizeof(hdr));
-    ptr += sizeof(hdr);
-    memcpy(ptr, &path_len, sizeof(size_t));
-    ptr += sizeof(size_t);
-    memcpy(ptr, path, path_len);
-
-    /* Check poll */
-    ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
-    if (ret == SECURITY_SERVER_ERROR_POLL)
-    {
-        SEC_SVR_ERR("%s", "poll() error");
-        ret = SECURITY_SERVER_ERROR_SEND_FAILED;
-        goto out;
-    }
-    if (ret == SECURITY_SERVER_ERROR_TIMEOUT)
-    {
-        SEC_SVR_ERR("%s", "poll() timeout");
-        ret = SECURITY_SERVER_ERROR_SEND_FAILED;
-        goto out;
-    }
-
-    /* Send it */
-    ret = TEMP_FAILURE_RETRY(write(sockfd, msg, msg_len));
-    if (ret < msg_len)
-    {
-        SEC_SVR_ERR("Error on write(): %d", ret);
-        ret = SECURITY_SERVER_ERROR_SEND_FAILED;
-        goto out;
-    }
-    ret = SECURITY_SERVER_SUCCESS;
-
-out:
-    free(msg);
-    return ret;
-}
-
-
-int process_exe_path_request(int sockfd)
-{
-    pid_t pid;
-    int retval;
-    char *exe = NULL;
-
-    // read pid
-    retval = TEMP_FAILURE_RETRY(read(sockfd, &pid, sizeof(pid_t)));
-    if (retval < (ssize_t) sizeof(pid_t))
-    {
-        SEC_SVR_ERR("Server Error: recieve failed: %d", retval);
-        retval = send_generic_response(
-            sockfd,
-            SECURITY_SERVER_MSG_TYPE_EXE_PATH_RESPONSE,
-            SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
-
-        if (retval != SECURITY_SERVER_SUCCESS)
-            SEC_SVR_ERR("Server ERROR: Cannot send generic response: %d", retval);
-        goto error;
-    }
-
-    SEC_SVR_DBG("Server: Get exe path request for pid %d", pid);
-
-    // get executable path
-    exe = read_exe_path_from_proc(pid);
-    if (!exe)
-    {
-        SEC_SVR_ERR("Server: Failed to read executable path for pid %d", pid);
-        retval = send_generic_response(
-            sockfd,
-            SECURITY_SERVER_MSG_TYPE_EXE_PATH_RESPONSE,
-            SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
-
-        if (retval != SECURITY_SERVER_SUCCESS)
-            SEC_SVR_ERR("Server ERROR: Cannot send generic response: %d", retval);
-        goto error;
-    }
-
-    // send response
-    retval = send_exe_path_response(sockfd, exe);
-    if (retval != SECURITY_SERVER_SUCCESS)
-        SEC_SVR_ERR("ERROR: Cannot send exe path response: %d", retval);
-
-error:
-    free(exe);
-    return retval;
-}
-
 int client_has_access(int sockfd, const char *object)
 {
     char *label = NULL;
@@ -1462,11 +1335,6 @@ void *security_server_thread(void *param)
             process_set_pwd_validity_request(client_sockfd);
             break;
 
-        case SECURITY_SERVER_MSG_TYPE_EXE_PATH_REQUEST:
-            SEC_SVR_DBG("Server: get executable path by pid request received");
-            process_exe_path_request(client_sockfd);
-            break;
-
         /************************************************************************************************/
         /* Just for test. This code must be removed on release */
         case SECURITY_SERVER_MSG_TYPE_GET_ALL_COOKIES_REQUEST:
diff --git a/src/server2/client/client-socket-privilege.cpp b/src/server2/client/client-socket-privilege.cpp
new file mode 100644 (file)
index 0000000..2ac617e
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ *  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-socket-privilege.cpp
+ * @author      Zofia Abramowska (z.abramowska@samsung.com)
+ * @version     1.0
+ * @brief       This file constains implementation of socket privilege api.
+ */
+#include <memory>
+
+#include <sys/socket.h>
+#include <sys/smack.h>
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <socket-buffer.h>
+#include <client-common.h>
+#include <protocols.h>
+#include <smack-check.h>
+
+#include <security-server.h>
+#include <security-server-common.h>
+
+static int get_exec_path(pid_t pid, std::string &exe)
+{
+    using namespace SecurityServer;
+
+    try{
+        SocketBuffer send, recv;
+        Serialization ser;
+        ser.Serialize(send, pid);
+
+        int result = sendToServer(
+                SERVICE_SOCKET_EXEC_PATH,
+                send.Pop(),
+                recv);
+        if(result != SECURITY_SERVER_API_SUCCESS)
+            return result;
+
+        Deserialization des;
+        des.Deserialize(recv, result);
+        if(result != SECURITY_SERVER_API_SUCCESS)
+            return result;
+
+        des.Deserialize(recv, exe);
+        return result;
+    } catch (SocketBuffer::Exception::Base &e) {
+        LogDebug("SecurityServer::SocketBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogDebug("STD exception " << e.what());
+    } catch (...) {
+        LogDebug("Unknown exception occured");
+    }
+    return SECURITY_SERVER_API_ERROR_UNKNOWN;
+}
+
+SECURITY_SERVER_API
+int security_server_check_privilege_by_sockfd(int sockfd,
+                                              const char *object,
+                                              const char *access_rights)
+{
+    char *subject;
+    int ret;
+    std::string path;
+    std::unique_ptr<char> subject_p;
+
+    //for get socket options
+    struct ucred cr;
+    unsigned int len = sizeof(struct ucred);
+
+    //SMACK runtime check
+    if (!smack_runtime_check())
+    {
+        LogDebug("No SMACK support on device");
+        return SECURITY_SERVER_API_SUCCESS;
+    }
+
+    ret = smack_new_label_from_socket(sockfd, &subject);
+    if (ret == 0) {
+        //after allocation we move ownership to smart pointer to let it do the cleanup
+        subject_p.reset(subject);
+
+    } else {
+        ret = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+        goto exit;
+    }
+
+    ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
+    if (ret < 0) {
+        LogError("Error in getsockopt(). Errno: " << strerror(errno));
+        ret = SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
+        goto exit;
+    }
+
+    ret = security_server_check_privilege_by_pid(cr.pid, object, access_rights);
+
+    SECURE_LOGD("security_server_check_privilege_by_pid returned %d", ret);
+
+exit:
+    //Getting path for logs
+    if (SECURITY_SERVER_API_SUCCESS != get_exec_path(cr.pid, path))
+        //If this is only for logs, do we want to log it as error?
+        LogError("Failed to read executable path for process " << cr.pid);
+    if (ret == SECURITY_SERVER_API_SUCCESS)
+        SECURE_LOGD("SS_SMACK: caller_pid=%d, subject=%s, object=%s, access=%s, result=%d, caller_path=%s",
+                cr.pid, subject_p.get() ? subject_p.get() : "NULL", object, access_rights, ret, path.c_str());
+    else
+        SECURE_LOGW("SS_SMACK: caller_pid=%d, subject=%s, object=%s, access=%s, result=%d, caller_path=%s",
+                cr.pid, subject_p.get() ? subject_p.get() : "NULL", object, access_rights, ret, path.c_str());
+
+    return ret;
+}
+
+SECURITY_SERVER_API
+char *security_server_get_smacklabel_sockfd(int fd)
+{
+    char *label = NULL;
+
+    if (!smack_check())
+    {
+        LogDebug("No SMACK support on device");
+        label = (char*) malloc(1);
+        if (label) label[0] = '\0';
+        return label;
+    }
+
+    if (smack_new_label_from_socket(fd, &label) != 0)
+    {
+        LogError("Client ERROR: Unable to get socket SMACK label");
+        return NULL;
+    }
+
+    return label;
+}
index 28ee009..dc579f1 100644 (file)
@@ -34,5 +34,8 @@ char const * const SERVICE_SOCKET_GET_GID =
     "/tmp/.security-server-api-get-gid.sock";
 char const * const SERVICE_SOCKET_PRIVILEGE_BY_PID =
     "/tmp/.security-server-api-privilege-by-pid";
+char const * const SERVICE_SOCKET_EXEC_PATH =
+    "/tmp/.security-server-api-exec-path.sock";
+
 } // namespace SecurityServer
 
index 9938bf5..3ed74d7 100644 (file)
@@ -31,6 +31,7 @@ extern char const * const SERVICE_SOCKET_SHARED_MEMORY;
 extern char const * const SERVICE_SOCKET_ECHO;
 extern char const * const SERVICE_SOCKET_GET_GID;
 extern char const * const SERVICE_SOCKET_PRIVILEGE_BY_PID;
+extern char const * const SERVICE_SOCKET_EXEC_PATH;
 
 } // namespace SecuritySever
 
index 29281d3..289ac76 100644 (file)
@@ -34,6 +34,7 @@
 #include <data-share.h>
 #include <get-gid.h>
 #include <privilege-by-pid.h>
+#include <exec-path.h>
 #include <echo.h>
 
 IMPLEMENT_SAFE_SINGLETON(SecurityServer::Log::LogSystem);
@@ -61,6 +62,10 @@ int server2(void) {
         SecurityServer::PrivilegeByPidService *privByPidService = new SecurityServer::PrivilegeByPidService;
         privByPidService->Create();
         manager.RegisterSocketService(privByPidService);
+        
+        SecurityServer::ExecPathService *execService = new SecurityServer::ExecPathService;
+        execService->Create();
+        manager.RegisterSocketService(execService);
 
         manager.MainLoop();
     }
diff --git a/src/server2/service/exec-path.cpp b/src/server2/service/exec-path.cpp
new file mode 100644 (file)
index 0000000..4ecb2b3
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ *  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        exec-path.cpp
+ * @author      Zofia Abramowska (z.abramowska@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of api-exec-path service.
+ */
+
+#include <string>
+
+#include <unistd.h>
+#include <sys/smack.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <protocols.h>
+#include <exec-path.h>
+#include <security-server.h>
+#include <security-server-util.h>
+#include <smack-check.h>
+
+namespace {
+// Service may open more than one socket.
+// These ID's will be assigned to sockets
+// and will be used only by service.
+// When new connection arrives, AcceptEvent
+// will be generated with proper ID to inform
+// service about input socket.
+//
+// Please note: SocketManaged does not use it and
+// does not check it in any way.
+//
+// If your service require only one socket
+// (uses only one socket labeled with smack)
+// you may ignore this ID (just pass 0)
+const int SERVICE_SOCKET_ID = 0;
+
+} // namespace anonymous
+
+namespace SecurityServer {
+
+GenericSocketService::ServiceDescriptionVector ExecPathService::GetServiceDescription() {
+    ServiceDescription sd = {
+        "security-server",
+        SERVICE_SOCKET_ID,
+        SERVICE_SOCKET_EXEC_PATH
+    };
+    ServiceDescriptionVector v;
+    v.push_back(sd);
+    return v;
+}
+
+void ExecPathService::accept(const AcceptEvent &event) {
+    LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
+        << " ConnectionID.counter: " << event.connectionID.counter
+        << " ServiceID: " << event.interfaceID);
+}
+
+void ExecPathService::write(const WriteEvent &event) {
+    LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
+        " Size: " << event.size << " Left: " << event.left);
+    if (event.left == 0)
+        m_serviceManager->Close(event.connectionID);
+}
+
+bool ExecPathService::processOne(const ConnectionID &conn, SocketBuffer &buffer) {
+    LogDebug("Processing message");
+
+    int pid = 0;
+    char *exe;
+
+    if (!buffer.Ready()) {
+        LogDebug("Got part of message. Service is waiting for the rest.");
+        return false;
+    }
+
+    Try {
+        SecurityServer::Deserialization des;
+        des.Deserialize(buffer, pid);
+     } Catch (SocketBuffer::Exception::Base) {
+        LogDebug("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }
+
+    SecurityServer::Serialization ser;
+    SocketBuffer sendBuffer;
+    int retVal;
+
+    // get executable path
+    exe = read_exe_path_from_proc(pid);
+    // quickly getting rid of allocated memory
+    // when read_exe_path_from_proc will rewritten this won't be required
+    std::string exec_path(exe ? exe : "");
+    free(exe);
+
+    if (exec_path.empty())
+    {
+         LogError("Server: Failed to read executable path for pid " << pid);
+         retVal = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+         ser.Serialize(sendBuffer, retVal);
+         m_serviceManager->Write(conn, sendBuffer.Pop());
+         return true;
+    }
+
+    retVal = SECURITY_SERVER_API_SUCCESS;
+    ser.Serialize(sendBuffer, retVal);
+    ser.Serialize(sendBuffer, exec_path);
+    m_serviceManager->Write(conn, sendBuffer.Pop());
+    return true;
+}
+
+void ExecPathService::read(const ReadEvent &event) {
+    LogDebug("Read event for counter: " << event.connectionID.counter);
+    auto &buffer = m_socketBufferMap[event.connectionID.counter];
+    buffer.Push(event.rawBuffer);
+
+    LogDebug("Pushed to buffer ptr: " << (void*)&buffer);
+    // We can get several requests in one package.
+    // Extract and process them all
+    while(processOne(event.connectionID, buffer));
+}
+
+void ExecPathService::close(const CloseEvent &event) {
+    LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+    m_socketBufferMap.erase(event.connectionID.counter);
+}
+
+void ExecPathService::error(const ErrorEvent &event) {
+    LogDebug("ErrorEvent. ConnectionID: " << event.connectionID.sock);
+    m_serviceManager->Close(event.connectionID);
+}
+
+} // namespace SecurityServer
+
diff --git a/src/server2/service/exec-path.h b/src/server2/service/exec-path.h
new file mode 100644 (file)
index 0000000..0832acb
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  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        exec-path.h
+ * @author      Zofia Abramowska (z.abramowska@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of api-exec-path
+ */
+
+#ifndef _SECURITY_SERVER_EXEC_PATH_
+#define _SECURITY_SERVER_EXEC_PATH_
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+
+#include <socket-buffer.h>
+
+namespace SecurityServer {
+
+class ExecPathService
+  : public SecurityServer::GenericSocketService
+  , public SecurityServer::ServiceThread<ExecPathService>
+{
+public:
+    typedef std::map<int, SocketBuffer> SocketBufferMap;
+
+    ServiceDescriptionVector GetServiceDescription();
+
+    DECLARE_THREAD_EVENT(AcceptEvent, accept)
+    DECLARE_THREAD_EVENT(WriteEvent, write)
+    DECLARE_THREAD_EVENT(ReadEvent, read)
+    DECLARE_THREAD_EVENT(CloseEvent, close)
+    DECLARE_THREAD_EVENT(ErrorEvent, error)
+
+    void accept(const AcceptEvent &event);
+    void write(const WriteEvent &event);
+    void read(const ReadEvent &event);
+    void close(const CloseEvent &event);
+    void error(const ErrorEvent &event);
+private:
+    bool processOne(const ConnectionID &conn, SocketBuffer &buffer);
+    SocketBufferMap m_socketBufferMap;
+};
+
+} // namespace SecurityServer
+
+#endif // _SECURITY_SERVER_EXEC_PATH_
index 8c15827..4f6e9ca 100644 (file)
@@ -4,6 +4,7 @@ INSTALL(FILES
     ${CMAKE_SOURCE_DIR}/systemd/security-server-data-share.socket
     ${CMAKE_SOURCE_DIR}/systemd/security-server-get-gid.socket
     ${CMAKE_SOURCE_DIR}/systemd/security-server-privilege-by-pid.socket
+    ${CMAKE_SOURCE_DIR}/systemd/security-server-exec-path.socket
     DESTINATION
     /usr/lib/systemd/system
 )
diff --git a/systemd/security-server-exec-path.socket b/systemd/security-server-exec-path.socket
new file mode 100644 (file)
index 0000000..933b93d
--- /dev/null
@@ -0,0 +1,10 @@
+[Socket]
+ListenStream=/tmp/.security-server-api-exec-path.sock
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+Service=security-server.service
+
+[Install]
+WantedBy=sockets.target
index 645da60..a7e230c 100644 (file)
@@ -8,6 +8,7 @@ Sockets=security-server.socket
 Sockets=security-server-data-share.socket
 Sockets=security-server-get-gid.socket
 Sockets=security-server-privilege-by-pid.socket
+Sockets=security-server-exec-path.socket
 
 [Install]
 WantedBy=multi-user.target