From da345fc42276f3101c35f5e8e911e72a9e927eae Mon Sep 17 00:00:00 2001 From: afonso Date: Sat, 11 May 2024 12:39:00 +0100 Subject: [PATCH] Done until djumbai-send --- README.md | 22 ++---- libs/protocol/protocol.c | 3 +- libs/protocol/protocol.h | 6 +- src/client/client.c | 12 ++-- src/djumbai_client_send/djumbai_client_send.c | 4 +- src/djumbai_dequeue/djumbai_dequeue.c | 69 +++++++++++++++++-- src/djumbai_enqueue/djumbai_enqueue.c | 2 +- src/djumbai_send/djumbai_send.c | 53 +++++++++++++- 8 files changed, 135 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 775940f..869b112 100644 --- a/README.md +++ b/README.md @@ -32,24 +32,12 @@ This structured breakdown elucidates the sequential steps involved in the Unix m ## Cenas concretas -Mail queue - FIFO em /opt/djumbai/queue/mailqueue 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 -Mailbox pessoal - Diretoria em /opt/djumbai/mailbox/user/$uid, que so pode ser acedida pelo user com UID $uid +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 grupo - Diretoria em /opt/djumbai/mailbox/group/$gid, que so pode ser acedida pelo grupo com GID $gid - -SentBox pessoal - Diretoria em /opt/djumbai/sentbox/user/$uid, que so pode ser acedida pelo user com UID $uid - -Repositorio de chaves publicas de utilizadores - Diretoria em /opt/djumbai/pub_keys/user/$uid que contem as chaves publicas de cada utilizador. Apenas o proprio user tem acesso de escrita no ficheiro da sua chave publica - -Repositorio de chaves publicas de grupos - Diretoria em /opt/djumbai/pub_keys/group/$gid que contem as chaves publicas de cada grupo. Apenas membros do proprio grupo tem acesso de escrita no ficheiro da sua chave publica - -Repositorio de chaves privadas de utilizadores - Diretoria em /opt/djumbai/priv_keys/user/$uid que contem as chaves privadas de cada utilizador. Apenas o proprio user tem acesso de leitura e escrita no ficheiro da sua chave publica - -Repositorio de chaves privadas de grupos - Diretoria em /opt/djumbai/priv_keys/group/$gid que contem as chaves privadas de cada grupo. Apenas membros do proprio grupo tem acesso de leitura e escrita no ficheiro da sua chave privada - -Envio de mensagem para utilizador - Mensagem assinada com chave privada do remetente e cifrada com a chave publica do destinatario. - -Envio de mensagem para grupo - Mensagem assinada com chave privada do remetente e cifrada com a chave publica do grupo. +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 +Mailbox grupo - Diretoria em /opt/djumbai/group/$gid/mailbox, que so pode ser acedida pelo grupo com GID $gid diff --git a/libs/protocol/protocol.c b/libs/protocol/protocol.c index a0e721e..420a495 100644 --- a/libs/protocol/protocol.c +++ b/libs/protocol/protocol.c @@ -1,11 +1,12 @@ #include "protocol.h" -int new_message(message *m, unsigned int sender, unsigned int receiver, char *content) { +int new_message(message *m, unsigned int sender, unsigned int isgroup, unsigned int receiver, char *content) { if (strlen(content) > MAX_CONTENT_SIZE) { return 1; } m->header.version = VERSION; m->header.sender = sender; + m->header.isgroup = isgroup; m->header.receiver = receiver; time(&m->header.timestamp); strncpy(m->content, content, MAX_CONTENT_SIZE); diff --git a/libs/protocol/protocol.h b/libs/protocol/protocol.h index e8c42c6..27f8b35 100644 --- a/libs/protocol/protocol.h +++ b/libs/protocol/protocol.h @@ -8,13 +8,15 @@ #define VERSION 1 #define MAX_CONTENT_SIZE (PIPE_BUF - sizeof(struct MessageHeader)) -#define MESSAGE_SIZE sizeof(struct Message) +#define MESSAGE_SIZE (sizeof(struct Message)) typedef struct MessageHeader { // The protocol's version unsigned int version; // The sender is a user unsigned int sender; + // Flag indicating if the receiver is a group + unsigned int isgroup; // The receiver is either a user or a group unsigned int receiver; // The message was sent at this timestamp @@ -29,6 +31,6 @@ typedef struct Message { } message; -int new_message(message *m, unsigned int sender, unsigned int receiver, char *content); +int new_message(message *m, unsigned int sender, unsigned int isgroup, unsigned int receiver, char *content); #endif // !PROTOCOL_H diff --git a/src/client/client.c b/src/client/client.c index 32e4b6b..d234b97 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -21,18 +21,16 @@ int send_message(unsigned int sender, unsigned int receiver) { // Redirect stdin to read from pipe_to_child dup2(pipe_to_child[0], STDIN_FILENO); - - // Execute a command, for example, a simple "cat" command execlp("./bin/djumbai_client_send/djumbai_client_send", "djumbai_client_send", NULL); + close(pipe_to_child[0]); // 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 - printf("Please enter your message (Max of %ld bytes):\n", MAX_CONTENT_SIZE); + printf("Please enter your message (Max of %ld bytes):\n", MAX_CONTENT_SIZE - 1); char content[MAX_CONTENT_SIZE]; fgets(content, MAX_CONTENT_SIZE, stdin); @@ -42,13 +40,13 @@ int send_message(unsigned int sender, unsigned int receiver) { } // Serialize the message - unsigned char buffer[sizeof(struct Message)]; - if (serialize_message(&msg, sizeof(struct Message), buffer) == -1) { + unsigned char buffer[MESSAGE_SIZE]; + if (serialize_message(&msg, MESSAGE_SIZE, buffer) == -1) { fprintf(stderr, "Error: Serialization failed\n"); return 1; } - write(pipe_to_child[1], buffer, sizeof(buffer)); + write(pipe_to_child[1], buffer, MESSAGE_SIZE); // Close the write end of the pipe close(pipe_to_child[1]); diff --git a/src/djumbai_client_send/djumbai_client_send.c b/src/djumbai_client_send/djumbai_client_send.c index fe645a3..c8f5dd7 100644 --- a/src/djumbai_client_send/djumbai_client_send.c +++ b/src/djumbai_client_send/djumbai_client_send.c @@ -33,8 +33,8 @@ int main() { } else { // Parent process close(pipe_to_child[0]); // Close read end of pipe - unsigned char buffer[sizeof(struct Message)]; - read(0, buffer, sizeof(struct Message)); + unsigned char buffer[MESSAGE_SIZE]; + read(0, buffer, MESSAGE_SIZE); write(pipe_to_child[1], buffer, sizeof(buffer)); // Close the write end of the pipe diff --git a/src/djumbai_dequeue/djumbai_dequeue.c b/src/djumbai_dequeue/djumbai_dequeue.c index 34638cb..4de5f06 100644 --- a/src/djumbai_dequeue/djumbai_dequeue.c +++ b/src/djumbai_dequeue/djumbai_dequeue.c @@ -1,8 +1,67 @@ +#include +#include +#include +#include +#include +#include #include +#include "../../libs/protocol/protocol.h" -int main(){ - //Make stdin the FIFO - //Read from FIFO - //Make stdout the output FIFO - //Write to another FIFO +int main() { + // Change the root of the process so it doesn't have access to anything else. + chroot("/opt/djumbai/"); + const char *message_queue_path = "fifos/message_queue"; + + if (access(message_queue_path, F_OK) != -1) { + // FIFO exists, delete it + if (unlink(message_queue_path) == -1) { + perror("unlink"); + exit(EXIT_FAILURE); + } + printf("Existing FIFO deleted.\n"); + } + + // Open the FIFO for reading + if (mkfifo(message_queue_path, 0420) == -1) { + perror("mkfifo"); + exit(EXIT_FAILURE); + } + int message_queue_fd; + message_queue_fd = open(message_queue_path, O_RDONLY); + if (message_queue_fd == -1) { + if (errno == ENOENT) { + // FIFO does not exist + printf("FIFO '%s' does not exist. Exiting...\n", message_queue_path); + return 1; + } else { + perror("open"); + return 1; + } + } + + // Open the FIFO for writing + const char *send_fifo_path = "fifos/send_fifo"; + int send_fifo_fd; + send_fifo_fd = open(send_fifo_path, O_WRONLY); + if (send_fifo_fd == -1) { + if (errno == ENOENT) { + // FIFO does not exist + printf("FIFO '%s' does not exist. Exiting...\n", send_fifo_path); + return 1; + } else { + perror("open"); + return 1; + } + } + + unsigned char buffer[MESSAGE_SIZE]; + while(1){ + read(message_queue_fd,buffer,MESSAGE_SIZE); + write(send_fifo_fd,buffer,MESSAGE_SIZE); + memset(buffer, 0, MESSAGE_SIZE); + } + + close(message_queue_fd); + unlink(message_queue_path); + close(send_fifo_fd); } diff --git a/src/djumbai_enqueue/djumbai_enqueue.c b/src/djumbai_enqueue/djumbai_enqueue.c index d63ca42..61c5bf0 100644 --- a/src/djumbai_enqueue/djumbai_enqueue.c +++ b/src/djumbai_enqueue/djumbai_enqueue.c @@ -4,7 +4,7 @@ int main() { //Change the root of the djumbai_enqueue process so it doesn't have access to anything else. chroot("/opt/djumbai/queue/"); const char *message_queue_path = - "mailqueue"; // Replace this with the path to your FIFO + "mailqueue"; // Open the FIFO for writing int queue_fd; diff --git a/src/djumbai_send/djumbai_send.c b/src/djumbai_send/djumbai_send.c index bc2486d..9bbbf0c 100644 --- a/src/djumbai_send/djumbai_send.c +++ b/src/djumbai_send/djumbai_send.c @@ -1,3 +1,54 @@ -int main(){ +#include "../../libs/protocol/protocol.h" +#include +#include +#include +#include +#include +#include +int main() { + + // Open the FIFO for writing + const char *send_fifo_path = "fifos/send_fifo"; + if (access(send_fifo_path, F_OK) != -1) { + // FIFO exists, delete it + if (unlink(send_fifo_path) == -1) { + perror("unlink"); + exit(EXIT_FAILURE); + } + printf("Existing FIFO deleted.\n"); + } + + // Open the FIFO for reading + if (mkfifo(send_fifo_path, 0420) == -1) { + perror("mkfifo"); + exit(EXIT_FAILURE); + } + + int send_fifo_fd; + send_fifo_fd = open(send_fifo_path, O_RDONLY); + if (send_fifo_fd == -1) { + if (errno == ENOENT) { + // FIFO does not exist + printf("FIFO '%s' does not exist. Exiting...\n", send_fifo_path); + return 1; + } else { + perror("open"); + return 1; + } + } + + unsigned char buffer[MESSAGE_SIZE]; + while (1) { + read(send_fifo_fd, buffer, MESSAGE_SIZE); + + // 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 + + memset(buffer, 0, MESSAGE_SIZE); + } + close(send_fifo_fd); + unlink(send_fifo_path); }