#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <sys/poll.h>
#include "smack-check.h"
#include "security-server.h"
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)
+ {
+ /* 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
ret = smack_new_label_from_socket(sockfd, &subject);
if (ret != 0)
- {
return SECURITY_SERVER_API_ERROR_SERVER_ERROR;
- }
ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
if (ret < 0) {
ret = 0;
goto err;
}
- path = read_exe_path_from_proc(cr.pid);
+ 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)
err:
- SEC_SVR_DBG("SMACK have access returned %d", ret);
+ SEC_SVR_DBG("security_server_check_privilege_by_pid returned %d", ret);
if (ret > 0)
SEC_SVR_DBG("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
SEC_SVR_ERR("SS_SMACK: caller_pid=%d, subject=%s, object=%s, access=%s, result=%d, caller_path=%s", cr.pid, subject, object, access_rights, ret, path);
- if (path != NULL)
- free(path);
+ free(path);
free(subject);
if (ret == 1)
{
#include <sys/stat.h>
#include <limits.h>
#include <ctype.h>
-#include <stdint.h>
#include "security-server-common.h"
#include "security-server-comm.h"
printf("\n");
}
-char *read_exe_path_from_proc(pid_t pid)
-{
- char link[32];
- char *exe = NULL;
- size_t size = 64;
- ssize_t cnt = 0;
-
- // get link to executable
- snprintf(link, sizeof(link), "/proc/%d/exe", pid);
-
- for (;;)
- {
- exe = malloc(size);
- if (exe == NULL) {
- SEC_SVR_ERR("Out of memory");
- return NULL;
- }
-
- // read link target
- cnt = readlink(link, exe, size);
-
- // error
- if (cnt < 0 || (size_t)cnt > size) {
- SEC_SVR_ERR("Can't locate process binary for pid[%d]", pid);
- free(exe);
- return NULL;
- }
-
- // read less than requested
- if ((size_t)cnt < size)
- break;
-
- // read exactly the number of bytes requested
- free(exe);
- if (size > (SIZE_MAX >> 1)) {
- SEC_SVR_ERR("Exe path too long (more than %d characters)", size);
- return NULL;
- }
- size <<= 1;
- }
- // readlink does not append null byte to buffer.
- exe[cnt] = '\0';
- return exe;
-}
-
/* Return code in packet is positive integer *
* We need to convert them to error code which are negative integer */
int return_code_to_error_code(int ret_code)
return ret;
}
-/* Authenticate the application is middleware daemon
- * The middleware must run as root and the cmd line must be pre listed */
-int authenticate_developer_shell(int sockfd)
-{
- int retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
- struct ucred cr;
- unsigned int cl = sizeof(cr);
- char *exe = NULL;
-
- /* get PID of socket peer */
- if(getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) != 0)
- {
- retval = SECURITY_SERVER_ERROR_SOCKET;
- SEC_SVR_ERR("%s", "Error on getsockopt");
- goto error;
- }
-
- /* All middlewares will run as root */
- if(cr.uid != SECURITY_SERVER_DEVELOPER_UID)
- {
- retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
- SEC_SVR_ERR("Non root process has called API: %d", cr.uid);
- goto error;
- }
-
- /* Read executable path of the PID from proc fs */
- exe = read_exe_path_from_proc(cr.pid);
- if(exe == NULL)
- {
- /* It's weired. no file in proc file system, */
- retval = SECURITY_SERVER_ERROR_FILE_OPERATION;
- SEC_SVR_ERR("Error on opening /proc/%d/exe", cr.pid);
- goto error;
- }
-
- /* Search exe of the peer that is really debug tool */
- if(strcmp(exe, SECURITY_SERVER_DEBUG_TOOL_PATH) != 0)
- {
- SEC_SVR_ERR("Error: Wrong exe path [%s]", exe);
- retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
- goto error;
- }
- retval = SECURITY_SERVER_SUCCESS;
- SEC_SVR_DBG("%s", "Client Authenticated");
-
-error:
- if(exe != NULL)
- free(exe);
-
- return retval;
-}
-
int free_argv(char **argv, int argc)
{
int i;
free(buff);
return retval;
}
-
#define SECURITY_SERVER_MSG_TYPE_SMACK_RESPONSE 0x1e
#define SECURITY_SERVER_MSG_TYPE_APP_GIVE_ACCESS_REQUEST 0x1f
#define SECURITY_SERVER_MSG_TYPE_APP_GIVE_ACCESS_RESPONSE 0x20
+#define SECURITY_SERVER_MSG_TYPE_CHECK_PID_PRIVILEGE_REQUEST 0x21
+#define SECURITY_SERVER_MSG_TYPE_CHECK_PID_PRIVILEGE_RESPONSE 0x22
+#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 */
int authenticate_client_middleware(int sockfd, int *pid);
int get_client_gid_list(int sockfd, int ** privileges);
int authenticate_developer_shell(int sockfd);
-char *read_exe_path_from_proc(pid_t pid);
int send_generic_response (int sockfd, unsigned char msgid, unsigned char return_code);
int send_cookie(int sockfd, unsigned char *cookie);
int send_object_name(int sockfd, char *obj);
#include <sys/wait.h>
#include <poll.h>
#include <grp.h>
+#include <stdint.h>
#include <privilege-control.h>
#include <security-server-system-observer.h>
}
#endif
+char *read_exe_path_from_proc(pid_t pid)
+{
+ char link[32];
+ char *exe = NULL;
+ size_t size = 64;
+ ssize_t cnt = 0;
+
+ // get link to executable
+ snprintf(link, sizeof(link), "/proc/%d/exe", pid);
+
+ for (;;)
+ {
+ exe = malloc(size);
+ if (exe == NULL )
+ {
+ SEC_SVR_ERR("Out of memory");
+ return NULL ;
+ }
+
+ // read link target
+ cnt = readlink(link, exe, size);
+
+ // error
+ if (cnt < 0 || (size_t) cnt > size)
+ {
+ SEC_SVR_ERR("Can't locate process binary for pid[%d]", pid);
+ free(exe);
+ return NULL ;
+ }
+
+ // read less than requested
+ if ((size_t) cnt < size)
+ break;
+
+ // read exactly the number of bytes requested
+ free(exe);
+ if (size > (SIZE_MAX >> 1))
+ {
+ SEC_SVR_ERR("Exe path too long (more than %d characters)", size);
+ return NULL ;
+ }
+ size <<= 1;
+ }
+ // readlink does not append null byte to buffer.
+ exe[cnt] = '\0';
+ return exe;
+}
+
+
/* Object name is actually name of a Group ID *
* This function opens /etc/group file and search group ID and
* returns the string */
return SECURITY_SERVER_SUCCESS;
}
+/* Authenticate the application is middleware daemon
+ * The middleware must run as root and the cmd line must be pre listed */
+int authenticate_developer_shell(int sockfd)
+{
+ int retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
+ struct ucred cr;
+ unsigned int cl = sizeof(cr);
+ char *exe = NULL;
+
+ /* get PID of socket peer */
+ if(getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) != 0)
+ {
+ retval = SECURITY_SERVER_ERROR_SOCKET;
+ SEC_SVR_ERR("%s", "Error on getsockopt");
+ goto error;
+ }
+
+ /* All middlewares will run as root */
+ if(cr.uid != SECURITY_SERVER_DEVELOPER_UID)
+ {
+ retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
+ SEC_SVR_ERR("Non root process has called API: %d", cr.uid);
+ goto error;
+ }
+
+ /* Read executable path of the PID from proc fs */
+ exe = read_exe_path_from_proc(cr.pid);
+ if(exe == NULL)
+ {
+ /* It's weired. no file in proc file system, */
+ retval = SECURITY_SERVER_ERROR_FILE_OPERATION;
+ SEC_SVR_ERR("Error on opening /proc/%d/exe", cr.pid);
+ goto error;
+ }
+
+ /* Search exe of the peer that is really debug tool */
+ if(strcmp(exe, SECURITY_SERVER_DEBUG_TOOL_PATH) != 0)
+ {
+ SEC_SVR_ERR("Error: Wrong exe path [%s]", exe);
+ retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
+ goto error;
+ }
+ retval = SECURITY_SERVER_SUCCESS;
+ SEC_SVR_DBG("%s", "Client Authenticated");
+
+error:
+ if(exe != NULL)
+ free(exe);
+
+ return retval;
+}
+
int process_cookie_request(int sockfd)
{
int retval, client_pid, client_uid;
return retval;
}
+
+/* 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;
int ret = 0;
SEC_SVR_DBG("%s", "Server: app give access requset received");
process_app_get_access_request(client_sockfd, basic_hdr.msg_len - sizeof(basic_hdr));
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: