diff --git a/README.md b/README.md index 869b112..a472198 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ A UNIX local messaging service - Once messages are retrieved, `djumbai-dequeue` sends them to the `djumbai-send` process. This process operates with root privileges. 6. **Receiving and Delivery:** - - `djumbai-send` spawns a process named `djumbai-client-receive`, which operates under the context of the user intended to receive the message. + - `djumbai-send` spawns a process named `djumbai-client-receive`, which operates under the context of the user/group intended to receive the message. - `djumbai-client-receive` writes the received message to the recipient's message-box. 7. **Message Retrieval by User:** @@ -32,11 +32,11 @@ This structured breakdown elucidates the sequential steps involved in the Unix m ## Cenas concretas -Mail queue - FIFO em /opt/djumbai/fifos/message_queue e so pode ser acedida por users do grupo djumbai-queue, que contem djumbai-enqueue e djumbai-dequeue +Mail queue - FIFO em /opt/djumbai/fifos/message_queue e so pode ser acedida por users do grupo djumbai_queue, que contem djumbai_enqueue e djumbai_dequeue -Send FIFO - FIFO em /opt/djumbai/fifos/send_fifo e so pode ser acedida por users do grupo djumbai-send, que contem djumbai-dequeue e djumbai-send +Send FIFO - FIFO em /opt/djumbai/fifos/send_fifo e so pode ser acedida por users do grupo djumbai_send, que contem djumbai_dequeue e djumbai_send -Mailbox pessoal - Diretoria em /opt/djumbai/user/$uid/mailbox, que so pode ser acedida pelo user com UID $uid +Mailbox pessoal _ Diretoria em /opt/djumbai/user/$uid/mailbox, que so pode ser acedida pelo user com UID $uid SentBox pessoal - Diretoria em /opt/djumbai/user/$uid/sentbox, que so pode ser acedida pelo user com UID $uid diff --git a/src/client/client.c b/src/client/client.c index d234b97..0332483 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -35,7 +35,7 @@ int send_message(unsigned int sender, unsigned int receiver) { fgets(content, MAX_CONTENT_SIZE, stdin); message msg; - if (new_message(&msg, sender, receiver, content) != 0) { + if (new_message(&msg, sender, 0, receiver, content) != 0) { printf("Error when creating new message\n"); } diff --git a/src/djumbai_client_receive/djumbai_client_receive.c b/src/djumbai_client_receive/djumbai_client_receive.c index bc2486d..7513880 100644 --- a/src/djumbai_client_receive/djumbai_client_receive.c +++ b/src/djumbai_client_receive/djumbai_client_receive.c @@ -1,3 +1,62 @@ -int main(){ +#include "../../libs/communication/communication.h" +#include "../../libs/protocol/protocol.h" +#include +#include +#include +#include +#include +int main() { + + unsigned char buffer[MESSAGE_SIZE]; + read(0, buffer, MESSAGE_SIZE); + message msg; + deserialize_message(buffer, MESSAGE_SIZE, &msg); + + if (msg.header.isgroup) { + const char *directory_format = "/opt/djumbai/group/%d/"; + char group_path[50]; + sprintf(group_path, directory_format, msg.header.receiver); + char message_box_path[70]; + sprintf(message_box_path, group_path, "message_box/"); + + struct stat st; + if (stat(group_path, &st) == -1) { + // Directory doesn't exist, so create it + if (mkdir(group_path, 0070) == -1) { + perror("mkdir"); + return EXIT_FAILURE; + } + } + if (stat(message_box_path, &st) == -1) { + // Directory doesn't exist, so create it + if (mkdir(message_box_path, 0070) == -1) { + perror("mkdir"); + return EXIT_FAILURE; + } + } + chroot(message_box_path); + //Do the rest + } else { + + // struct stat st; + // if (stat(user_path, &st) == -1) { + // // Directory doesn't exist, so create it + // if (mkdir(user_path, 0700) == -1) { + // perror("mkdir"); + // return EXIT_FAILURE; + // } + // } + // if (stat(message_box_path, &st) == -1) { + // // Directory doesn't exist, so create it + // if (mkdir(message_box_path, 0700) == -1) { + // perror("mkdir"); + // return EXIT_FAILURE; + // } + // } + // chroot(message_box_path); + // + // Message receiver is a user + // Write to the user's mailbox + } } diff --git a/src/djumbai_send/djumbai_send.c b/src/djumbai_send/djumbai_send.c index 9bbbf0c..cc842fd 100644 --- a/src/djumbai_send/djumbai_send.c +++ b/src/djumbai_send/djumbai_send.c @@ -1,6 +1,8 @@ +#include "../../libs/communication/communication.h" #include "../../libs/protocol/protocol.h" #include #include +#include #include #include #include @@ -38,16 +40,90 @@ int main() { } } - unsigned char buffer[MESSAGE_SIZE]; while (1) { + // Read message from the send_fifo + unsigned char buffer[MESSAGE_SIZE]; read(send_fifo_fd, buffer, MESSAGE_SIZE); + // Deserialize the message + message msg; + deserialize_message(buffer, MESSAGE_SIZE, &msg); - // SPAWN THE CHILD PROCESS TO PUT THE MESSAGE IN THE USER'S QUEUE - // CHECK IF THE MESSAGE IS DESTINED TO A GROUP - // IF IT IS DESTINED TO A GROUP, START THE CHILD PROCESS WITH THE UID OF THE SENDER AND GID OF THE GROUP - // THE SENDER MUST BE PART OF THE GROUP + int pipe_to_child[2]; - memset(buffer, 0, MESSAGE_SIZE); + if (pipe(pipe_to_child) == -1) { + perror("pipe"); + exit(EXIT_FAILURE); + } + + pid_t pid = fork(); + if (pid == -1) { + perror("fork"); + exit(EXIT_FAILURE); + } + + if (pid == 0) { // Child process + close(pipe_to_child[1]); // Close write end of pipe + + if (msg.header.isgroup) { + // Message receiver is a group + // Get the UID of the nobody user. + const char *nobody_username = "nobody"; + + struct passwd *pw = getpwnam(nobody_username); + if (pw == NULL) { + fprintf(stderr, "User %s not found\n", nobody_username); + exit(EXIT_FAILURE); + } + // Set UID to nobody + if (setuid(pw->pw_uid) == -1) { + perror("setuid"); + exit(EXIT_FAILURE); + } + + // Set gid to receiver + if (setgid(msg.header.receiver) == -1) { + perror("setgid"); + exit(EXIT_FAILURE); + } + } else { + // Message receiver is a user + // Change UID receiver + if (setuid(msg.header.receiver) == -1) { + perror("setuid"); + exit(EXIT_FAILURE); + } + + struct passwd *pw = getpwuid(msg.header.receiver); + if (pw == NULL) { + fprintf(stderr, "User with uid %d not found\n", msg.header.receiver); + exit(EXIT_FAILURE); + } + + if (setgid(pw->pw_gid) == -1) { + perror("setgid"); + exit(EXIT_FAILURE); + } + } + + // Redirect stdin to read from pipe_to_child + dup2(pipe_to_child[0], STDIN_FILENO); + + execlp("./bin/djumbai_client_receive", "djumbai_client_receive", NULL); + + // If execlp fails + perror("execlp"); + close(pipe_to_child[0]); + exit(EXIT_FAILURE); + } else { // Parent process + close(pipe_to_child[0]); // Close read end of pipe + + write(pipe_to_child[1], buffer, sizeof(buffer)); + + // Close the write end of the pipe + close(pipe_to_child[1]); + // Wait for the child process to finish + wait(NULL); + } } close(send_fifo_fd); unlink(send_fifo_path);