#include <unistd.h>
#include <string.h>
#include <sys/smack.h>
+#include <fcntl.h>
#include "security-server.h"
#include "security-server-common.h"
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;
+}
+
+
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
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
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[])
{
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;
#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 */
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[]);
*/
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
#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"
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");
}
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);
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)
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;
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);