diff --git a/sources/ui-socket.c b/sources/ui-socket.c new file mode 100644 index 0000000..7f774e3 --- /dev/null +++ b/sources/ui-socket.c @@ -0,0 +1,104 @@ +#include "ui-socket.h" +#include +#include +#include +#include +#include +#include +#include + +static int socket_fd = -1; +static pthread_mutex_t socket_mutex = PTHREAD_MUTEX_INITIALIZER; + +int init_ui_socket(const char *filename) { + struct sockaddr_un addr; + int fd; + + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + perror("socket"); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, filename, sizeof(addr.sun_path) - 1); + + if (unlink(filename) == -1 && errno != ENOENT) { + perror("unlink"); + close(fd); + return -1; + } + + if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { + perror("bind"); + close(fd); + return -1; + } + + if (listen(fd, 5) == -1) { + perror("listen"); + close(fd); + return -1; + } + + socket_fd = fd; + return 0; +} + +int ask_access(const char *filename, struct process_info pi) { + int client_fd; + struct sockaddr_un client_addr; + socklen_t client_len = sizeof(client_addr); + char request[1024]; + char response[4]; + ssize_t bytes_sent, bytes_received; + + // Accept a connection from the GUI + if ((client_fd = accept(socket_fd, (struct sockaddr *)&client_addr, + &client_len)) == -1) { + perror("accept"); + return -1; + } + + // Construct the request message + snprintf(request, sizeof(request), "r%s;%d;%s;%d\0", filename, pi.PID, + pi.name, pi.UID); + + // Lock the socket to ensure thread safety + pthread_mutex_lock(&socket_mutex); + + // Send the request message to the GUI + bytes_sent = send(client_fd, request, strlen(request), 0); + if (bytes_sent == -1) { + perror("send"); + pthread_mutex_unlock(&socket_mutex); + close(client_fd); + return -1; + } + + // Receive the response from the GUI + bytes_received = recv(client_fd, response, sizeof(response) - 1, 0); + if (bytes_received == -1) { + perror("recv"); + pthread_mutex_unlock(&socket_mutex); + close(client_fd); + return -1; + } + response[bytes_received] = '\0'; + + // Unlock the socket + pthread_mutex_unlock(&socket_mutex); + + // Close the client socket + close(client_fd); + + // Check the response + if (response[0] == 'a' && response[1] == 'y' && response[2] == '\0') { + return 0; // Access granted + } else if (response[0] == 'a' && response[1] == 'n' && response[2] == '\0') { + return 1; // Access denied + } else { + // fprintf(stderr, "Invalid response from GUI: %s\n", response); + return -1; // Invalid response + } +} diff --git a/sources/ui-socket.h b/sources/ui-socket.h index 198d86b..00db77e 100644 --- a/sources/ui-socket.h +++ b/sources/ui-socket.h @@ -6,14 +6,19 @@ #ifndef UI_SOCKET_H #define UI_SOCKET_H +#include + struct process_info { - // TODO: define some fields + pid_t PID; + const char *name; + uid_t UID; }; -int init_ui_socket(); +// For default socket location, set socket_path = NULL. +int init_ui_socket(const char *socket_path); // TODO: design an interface for asking user for permission. -int ask_access(const char *filename, process_info pi); +int ask_access(const char *filename, struct process_info pi); #endif // !UI_SOCKET_H