From: Pawel Polawski Date: Fri, 25 Jan 2013 10:52:21 +0000 (+0100) Subject: Add new functions to security-server API. X-Git-Tag: submit/tizen_2.1/20130424.233001~5^2~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e751d050febd183016497eeb6d4ef2a558bb3669;p=platform%2Fcore%2Fsecurity%2Fsecurity-server.git Add new functions to security-server API. [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 --- diff --git a/src/security-srv/client/security-server-client.c b/src/security-srv/client/security-server-client.c index e934df1..68e83a0 100644 --- a/src/security-srv/client/security-server-client.c +++ b/src/security-srv/client/security-server-client.c @@ -27,6 +27,7 @@ #include #include #include +#include #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; +} + + diff --git a/src/security-srv/communication/security-server-comm.c b/src/security-srv/communication/security-server-comm.c index 1ae8acd..d0a1e5a 100644 --- a/src/security-srv/communication/security-server-comm.c +++ b/src/security-srv/communication/security-server-comm.c @@ -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; diff --git a/src/security-srv/include/security-server-comm.h b/src/security-srv/include/security-server-comm.h index ed87222..b132caf 100644 --- a/src/security-srv/include/security-server-comm.h +++ b/src/security-srv/include/security-server-comm.h @@ -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[]); diff --git a/src/security-srv/include/security-server.h b/src/security-srv/include/security-server.h index bf2201b..b927c89 100644 --- a/src/security-srv/include/security-server.h +++ b/src/security-srv/include/security-server.h @@ -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 diff --git a/src/security-srv/server/security-server-main.c b/src/security-srv/server/security-server-main.c index ecb9a1b..7838050 100644 --- a/src/security-srv/server/security-server-main.c +++ b/src/security-srv/server/security-server-main.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #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//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);