Add new functions to security-server API.
authorPawel Polawski <p.polawski@partner.samsung.com>
Fri, 25 Jan 2013 10:52:21 +0000 (11:52 +0100)
committerPawel Polawski <p.polawski@partner.samsung.com>
Thu, 31 Jan 2013 15:23:53 +0000 (16:23 +0100)
[Issue#]        SSDWSSP-45
[Cause]         Implement new APIs for getting SMACK label
                of peer in security-server
[Problem]       Two new function needed in API. Both returns
                SMACK labels but ttaking another parameters.
                First uses cookie, second socked descriptor.
[Solution]      New functions added
[Verification]  Tests should not fail

Change-Id: I4ca044230f1cba1174b61abae6b7641e1bbfcdbc

src/security-srv/client/security-server-client.c
src/security-srv/communication/security-server-comm.c
src/security-srv/include/security-server-comm.h
src/security-srv/include/security-server.h
src/security-srv/server/security-server-main.c

index e934df11c49862f4bc02946917e086eaccc7be7b..68e83a0b607db97d70a0402d6d84b63c3f46b14c 100644 (file)
@@ -27,6 +27,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <sys/smack.h>
+#include <fcntl.h>
 
 #include "security-server.h"
 #include "security-server-common.h"
@@ -1018,3 +1019,93 @@ error:
        retval = convert_to_public_error_code(retval);
        return retval;
 }
+
+SECURITY_SERVER_API
+char * security_server_get_smacklabel_cookie(const char * cookie)
+{
+    char * label = NULL;
+    int sockfd = -1, retval, pid = -1;
+    response_header hdr;
+
+    if(cookie == NULL)
+    {
+        retval = SECURITY_SERVER_ERROR_INPUT_PARAM;
+        goto error;
+    }
+
+    retval = connect_to_server(&sockfd);
+    if(retval != SECURITY_SERVER_SUCCESS)
+    {
+        /* Error on socket */
+        goto error;
+    }
+
+    /* make request packet */
+    retval = send_smack_request(sockfd, cookie);
+    if(retval != SECURITY_SERVER_SUCCESS)
+    {
+        /* Error on socket */
+        SEC_SVR_DBG("Client: Send failed: %d", retval);
+        goto error;
+    }
+
+    //allocating buffer for storing SMACK label received from server
+    label = calloc(SMACK_LABEL_LEN + 1, 1);
+    if(NULL == label)
+    {
+        SEC_SVR_DBG("Client ERROR: Memory allocation error");
+        goto error;
+    }
+
+    retval = recv_smack_response(sockfd, &hdr, label);
+
+    retval = return_code_to_error_code(hdr.return_code);
+    if(hdr.basic_hdr.msg_id != SECURITY_SERVER_MSG_TYPE_SMACK_RESPONSE)        /* Wrong response */
+    {
+        if(hdr.basic_hdr.msg_id == SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE)
+        {
+            /* There must be some error */
+            SEC_SVR_DBG("Client: Error has been received. return code:%d", hdr.return_code);
+        }
+        else
+        {
+            /* Something wrong with response */
+            SEC_SVR_DBG("Client ERROR: Unexpected error occurred:%d", retval);
+            retval = SECURITY_SERVER_ERROR_BAD_RESPONSE;
+        }
+        goto error;
+    }
+    if(hdr.return_code == SECURITY_SERVER_RETURN_CODE_NO_SUCH_COOKIE)
+    {
+        SEC_SVR_DBG("%s"," Client: There is no such cookie exist");
+    }
+
+error:
+    if(sockfd > 0)
+        close(sockfd);
+
+    retval = convert_to_public_error_code(retval);
+    if(retval == 0)
+        return label;
+
+    if(NULL != label)
+        free(label);
+
+    return NULL;
+}
+
+       SECURITY_SERVER_API
+char * security_server_get_smacklabel_sockfd(int fd)
+{
+       char * label = NULL;
+
+       if(smack_new_label_from_socket(fd, &label) != 0)
+       {
+               SEC_SVR_DBG("Client ERROR: Unable to get socket SMACK label");
+               return NULL;
+       }
+
+       return label;
+}
+
+
index 1ae8acd63bf533e1c7802d13d68fd312618e9726..d0a1e5a1a34c4cdbbe40db6470f996a3234072f8 100644 (file)
@@ -731,6 +731,64 @@ int send_pid(int sockfd, int pid)
        return SECURITY_SERVER_SUCCESS;
 }
 
+/* Send SMACK label to client with lenght N
+ *  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=0x1e |  Message Length = SMACK_LABEL_LEN + 1
+ * |---------------------------------------------------------------|
+ * |  return code  |           SMACK label byte 0                  |
+ * |---------------------------------------------------------------|
+ * |                      ..................                       |
+ * |---------------------------------------------------------------|
+ * |                      SMACK label byte N                       |
+ * |---------------------------------------------------------------|
+*/
+int send_smack(int sockfd, char * label)
+{
+       response_header hdr;
+    //added 1 to the size is for NULL terminating label
+    int LABEL_SIZE = SMACK_LABEL_LEN + 1;
+    int PACKET_SIZE = sizeof(hdr) + LABEL_SIZE;
+       unsigned char msg[PACKET_SIZE];
+       int ret;
+
+       /* Assemble header */
+       hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
+       hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_SMACK_RESPONSE;
+       hdr.basic_hdr.msg_len = LABEL_SIZE;
+       hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
+
+       /* Perpare packet */
+       memcpy(msg, &hdr, sizeof(hdr));
+       memcpy(msg + sizeof(hdr), label, LABEL_SIZE);
+    memset(msg + sizeof(hdr) + SMACK_LABEL_LEN, 0x00, 1); //adding NULL ad the label end
+
+       /* Check poll */
+       ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
+       if(ret == SECURITY_SERVER_ERROR_POLL)
+       {
+               SEC_SVR_DBG("%s", "poll() error");
+               return SECURITY_SERVER_ERROR_SEND_FAILED;
+       }
+       if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
+       {
+               SEC_SVR_DBG("%s", "poll() timeout");
+               return SECURITY_SERVER_ERROR_SEND_FAILED;
+       }
+
+       /* Send it */
+       ret = write(sockfd, msg, PACKET_SIZE);
+       if(ret <  PACKET_SIZE)
+       {
+               /* Error on writing */
+               SEC_SVR_DBG("Error on write(): %d", ret);
+               ret = SECURITY_SERVER_ERROR_SEND_FAILED;
+               return ret;
+       }
+       return SECURITY_SERVER_SUCCESS;
+}
+
 /* Send Check password response to client
  *
  * Check password response packet format
@@ -1079,6 +1137,58 @@ int send_privilege_check_new_request(int sock_fd,
        return SECURITY_SERVER_SUCCESS;
 }
 
+/* Send SMACK request message to security server *
+ *
+ * Message format
+ *  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=0x1d |      Message Length = 20      |
+ * |---------------------------------------------------------------|
+ * |                                                               |
+ * |                                                               |
+ * |                      Cookie (20bytes)                         |
+ * |                                                               |
+ * |                                                               |
+ * |---------------------------------------------------------------|
+ */
+int send_smack_request(int sock_fd, const char * cookie)
+{
+       basic_header hdr;
+       int retval;
+       unsigned char buf[sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN];
+
+       /* Assemble header */
+       hdr.version = SECURITY_SERVER_MSG_VERSION;
+       hdr.msg_id = SECURITY_SERVER_MSG_TYPE_SMACK_REQUEST;
+       hdr.msg_len = SECURITY_SERVER_COOKIE_LEN;
+
+       memcpy(buf, &hdr, sizeof(hdr));
+       memcpy(buf + sizeof(hdr), cookie, SECURITY_SERVER_COOKIE_LEN);
+
+       /* Check poll */
+       retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
+       if(retval == SECURITY_SERVER_ERROR_POLL)
+       {
+               SEC_SVR_DBG("%s", "poll() error");
+               return SECURITY_SERVER_ERROR_SEND_FAILED;
+       }
+       if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
+       {
+               SEC_SVR_DBG("%s", "poll() timeout");
+               return SECURITY_SERVER_ERROR_SEND_FAILED;
+       }
+
+       /* Send to server */
+       retval = write(sock_fd, buf, sizeof(buf));
+       if(retval < sizeof(buf))
+       {
+               /* Write error */
+               SEC_SVR_DBG("Error on write(): %d", retval);
+               return SECURITY_SERVER_ERROR_SEND_FAILED;
+       }
+       return SECURITY_SERVER_SUCCESS;
+}
+
 /* Send PID check request message to security server *
  *
  * Message format
@@ -1863,6 +1973,19 @@ int recv_pid_request(int sockfd, unsigned char *requested_cookie)
        return SECURITY_SERVER_SUCCESS;
 }
 
+/* receiving cookie from package */
+int recv_smack_request(int sockfd, unsigned char *requested_cookie)
+{
+       int retval;
+       retval = read(sockfd, requested_cookie, SECURITY_SERVER_COOKIE_LEN);
+       if(retval < SECURITY_SERVER_COOKIE_LEN)
+       {
+               SEC_SVR_DBG("Received cookie size is too small: %d", retval);
+               return SECURITY_SERVER_ERROR_RECV_FAILED;
+       }
+       return SECURITY_SERVER_SUCCESS;
+}
+
 /* Receive pid request packet body */
 int recv_launch_tool_request(int sockfd, int argc, char *argv[])
 {
@@ -2072,6 +2195,24 @@ int recv_privilege_check_new_response(int sockfd, response_header *hdr)
        return SECURITY_SERVER_SUCCESS;
 }
 
+int recv_smack_response(int sockfd, response_header *hdr, char * label)
+{
+       int retval;
+
+       retval = recv_generic_response(sockfd, hdr);
+       if(retval != SECURITY_SERVER_SUCCESS)
+               return return_code_to_error_code(hdr->return_code);
+
+       retval = read(sockfd, label, SMACK_LABEL_LEN + 1);
+       if(retval < sizeof(int))
+       {
+               /* Error on socket */
+               SEC_SVR_DBG("Client: Receive failed %d", retval);
+               return  SECURITY_SERVER_ERROR_RECV_FAILED;
+       }
+       return SECURITY_SERVER_SUCCESS;
+}
+
 int recv_pid_response(int sockfd, response_header *hdr, int *pid)
 {
        int retval;
index ed87222079b05dc49ddcb300b09933ba1eefa24b..b132cafe15ff114065b782f285af54c7ee312da6 100644 (file)
@@ -67,6 +67,8 @@ typedef struct
 #define SECURITY_SERVER_MSG_TYPE_SET_PWD_MAX_CHALLENGE_RESPONSE  0x1a
 #define SECURITY_SERVER_MSG_TYPE_SET_PWD_VALIDITY_REQUEST    0x1b
 #define SECURITY_SERVER_MSG_TYPE_SET_PWD_VALIDITY_RESPONSE   0x1c
+#define SECURITY_SERVER_MSG_TYPE_SMACK_REQUEST         0x1d
+#define SECURITY_SERVER_MSG_TYPE_SMACK_RESPONSE        0x1e
 #define SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE      0xff
 
 /* Return code */
@@ -122,6 +124,10 @@ int send_pid_request(int sock_fd, const char*cookie);
 int recv_pid_response(int sockfd, response_header *hdr, int *pid);
 int recv_pid_request(int sockfd, unsigned char *requested_cookie);
 int send_pid(int sockfd, int pid);
+int send_smack_request(int sockfd, const char * cookie);
+int recv_smack_response(int sockfd, response_header *hdr, char * label);
+int recv_smack_request(int sockfd, unsigned char *requested_cookie);
+int send_smack(int sockfd, char * label);
 int send_launch_tool_request(int sock_fd, int argc, const char **argv);
 int recv_generic_response(int sockfd, response_header *hdr);
 int recv_launch_tool_request(int sockfd, int argc, char *argv[]);
index bf2201b46618407e2e3ee51d8c068a26d98fbacb..b927c89e8d9bf97e5f4215c5d2b2bdda75756859 100644 (file)
@@ -984,6 +984,34 @@ int security_server_set_pwd_history(int number_of_history);
 */
 int security_server_launch_debug_tool(int argc, const char **argv);
 
+/*
+ * This function allows to get process SMACK label by passing cookie assigned
+ * to process. Function returns pointer to allocated buffer with label.
+ * User has to free the buffer after using.
+ *
+ * \param[in] Pointer to cookie
+ *
+ * \return Pointer to SMACK label or NULL
+ *
+ * \par For free label use free(), label allocated by calloc()
+ *      User responsibility is to free resource.
+ */
+char * security_server_get_smacklabel_cookie(const char *cookie);
+
+/*
+ * This function allows to get process SMACK label by passing socket descriptor.
+ * Function returns pointer to allocated buffer with label.
+ * User has to free the buffer after using.
+ *
+ * \param[in] Socket descriptor
+ *
+ * \return Pointer to SMACK label or NULL
+ *
+ * \par For free label use free(), label allocated by calloc().
+ *      User responsibility is to free resource.
+ */
+char * security_server_get_smacklabel_sockfd(int fd);
+
 #ifdef __cplusplus
 }
 #endif
index ecb9a1b4493e9437a15b2f88aac9e2af10fc48f6..783805079720dfa492d25f833d008fca18b0a1d4 100644 (file)
@@ -29,6 +29,8 @@
 #include <signal.h>
 #include <pthread.h>
 #include <limits.h>
+#include <fcntl.h>
+#include <sys/smack.h>
 
 #include "security-server-cookie.h"
 #include "security-server-common.h"
@@ -336,6 +338,7 @@ int process_cookie_request(int sockfd)
                goto error;
        }
        /* If client application is root process, just respond default cookie */
+    /*
        if( client_uid == 0)
        {
                SEC_SVR_DBG("%s", "Requested application is a root process");
@@ -348,6 +351,9 @@ int process_cookie_request(int sockfd)
        }
        else
        {
+    */
+        //TODO: Remove above code if there will be no crashes without it
+        //All process should be treaded the same
                /* Create a new cookie. or find existing one */
                pthread_mutex_lock(&cookie_mutex);
                created_cookie = create_cookie_item(client_pid, sockfd, c_list);
@@ -357,7 +363,7 @@ int process_cookie_request(int sockfd)
                        SEC_SVR_DBG("%s","Cannot create a cookie");
                        goto error;
                }
-       }
+       //}
        /* send cookie as response */
        retval = send_cookie(sockfd, created_cookie->cookie);
        if(retval != SECURITY_SERVER_SUCCESS)
@@ -764,6 +770,120 @@ error:
        return retval;
 }
 
+int process_smack_request(int sockfd)
+{
+       int retval, client_pid;
+       unsigned char requested_cookie[SECURITY_SERVER_COOKIE_LEN];
+       cookie_list *search_result = NULL;
+    //handler for SMACK label
+    char * label = NULL;
+    //buffer for storing file path
+    const int BUFFSIZE = 30;
+    char path[BUFFSIZE];
+    int fd;
+
+       /* Authenticate client */
+       retval = authenticate_client_middleware(sockfd, &client_pid);
+       if(retval != SECURITY_SERVER_SUCCESS)
+       {
+               SEC_SVR_DBG("%s", "Client Authentication Failed");
+               retval = send_generic_response(sockfd,
+                               SECURITY_SERVER_MSG_TYPE_SMACK_RESPONSE,
+                               SECURITY_SERVER_RETURN_CODE_AUTHENTICATION_FAILED);
+               if(retval != SECURITY_SERVER_SUCCESS)
+               {
+                       SEC_SVR_DBG("ERROR: Cannot send generic response: %d", retval);
+               }
+               goto error;
+       }
+
+       retval = recv_smack_request(sockfd, requested_cookie);
+       if(retval == SECURITY_SERVER_ERROR_RECV_FAILED)
+       {
+               SEC_SVR_DBG("%s", "Receiving request failed");
+               retval = send_generic_response(sockfd,
+                               SECURITY_SERVER_MSG_TYPE_SMACK_RESPONSE,
+                               SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
+               if(retval != SECURITY_SERVER_SUCCESS)
+               {
+                       SEC_SVR_DBG("ERROR: Cannot send generic response: %d", retval);
+               }
+               goto error;
+       }
+
+       /* Search cookie list */
+       pthread_mutex_lock(&cookie_mutex);
+       search_result = search_cookie(c_list, requested_cookie, 0);
+       pthread_mutex_unlock(&cookie_mutex);
+       if(search_result != NULL)
+       {
+               /* We found */
+               SEC_SVR_DBG("We found the cookie and pid:%d", search_result->pid);
+               SEC_SVR_DBG("%s", "Cookie comparison succeeded. Access granted.");
+
+        //clearing buffer
+        memset(path, 0x00, BUFFSIZE);
+
+        //preparing file path
+        snprintf(path, BUFFSIZE, "/proc/%d/attr/current", search_result->pid);
+        SEC_SVR_DBG("Path to file: %s\n", path);
+
+        //allocation place for label
+        label = calloc(SMACK_LABEL_LEN, 1);
+        if(NULL == label)
+        {
+            SEC_SVR_DBG("Client ERROR: Memory allocation error");
+            goto error;
+        }
+
+        //clearing buffer for label
+        memset(label, 0x00, SMACK_LABEL_LEN);
+
+        //opening file /proc/<pid>/attr/curent with SMACK label
+        fd = open(path, O_RDONLY);
+        if(fd < 0)
+        {
+            SEC_SVR_DBG("Client ERROR: Unable to open file in /proc");
+            goto error;
+        }
+
+        //reading label from file, it is NOT NULL TERMINATED
+        retval = read(fd, label, SMACK_LABEL_LEN);
+        close(fd);
+        if(retval < 0)
+        {
+            SEC_SVR_DBG("Client ERROR: Unable to read from file");
+            goto error;
+        }
+
+        SEC_SVR_DBG("Readed label is: %s\n", label);
+
+               retval = send_smack(sockfd, label);
+
+               if(retval != SECURITY_SERVER_SUCCESS)
+               {
+                       SEC_SVR_DBG("ERROR: Cannot send generic response: %d", retval);
+               }
+       }
+       else
+       {
+               /* It's not exist */
+               SEC_SVR_DBG("%s", "Could not find the cookie");
+               retval = send_generic_response(sockfd,
+                               SECURITY_SERVER_MSG_TYPE_SMACK_RESPONSE,
+                               SECURITY_SERVER_RETURN_CODE_NO_SUCH_COOKIE);
+               if(retval != SECURITY_SERVER_SUCCESS)
+               {
+                       SEC_SVR_DBG("ERROR: Cannot send SMACK label response: %d", retval);
+               }
+       }
+error:
+    if(NULL != label)
+        free(label);
+
+       return retval;
+}
+
 int process_tool_request(int client_sockfd, int server_sockfd)
 {
        int retval, argcnum;
@@ -948,6 +1068,11 @@ void *security_server_thread(void *param)
                        process_pid_request(client_sockfd);
                        break;
 
+               case SECURITY_SERVER_MSG_TYPE_SMACK_REQUEST:
+                       SEC_SVR_DBG("%s", "SMACK label request received");
+                       process_smack_request(client_sockfd);
+                       break;
+
                case SECURITY_SERVER_MSG_TYPE_TOOL_REQUEST:
                        SEC_SVR_DBG("%s", "launch tool request received");
                        process_tool_request(client_sockfd, server_sockfd);