From 944d396ef0bca53f057d6eee49f9305d8d30e910 Mon Sep 17 00:00:00 2001 From: Enrique Date: Sat, 5 Apr 2025 01:25:13 +0200 Subject: [PATCH] a lotta changes --- src/ipc/ipc.c | 94 ++++++++++++++++++------------------------ src/ipc/ipc.h | 26 ++++++++---- src/main.c | 17 ++++---- src/net/net.c | 111 ++++++++++++++++++++++++++++++++++---------------- src/net/net.h | 10 ++--- src/worker.c | 78 ++++++++++++++++++++++++++++++----- 6 files changed, 216 insertions(+), 120 deletions(-) diff --git a/src/ipc/ipc.c b/src/ipc/ipc.c index 69def17..c23af9a 100755 --- a/src/ipc/ipc.c +++ b/src/ipc/ipc.c @@ -73,71 +73,57 @@ void destroy_ipc_listener(ipc_listener **il){ } } -void free_ipc_message(ipc_message im){ - free_str(&im.key); - free_str(&im.val); -} - -static inline str ipc_message_to_str(ipc_message msg){ - str smsg = dnstr(msg.key.len + msg.val.len + 2*sizeof(u32)); - memcpy(smsg.ptr+smsg.len, &msg.key.len, sizeof(msg.key.len)); - smsg.len += sizeof(msg.key.len); - copy_str(smsg, msg.key); - memcpy(smsg.ptr+smsg.len, &msg.val.len, sizeof(msg.val.len)); - smsg.len += sizeof(msg.val.len); - copy_str(smsg, msg.val); - return smsg; -} - -int send_ipc_message(int to, ipc_message msg){ - str smsg = ipc_message_to_str(msg); - if(send(to, smsg.ptr, smsg.len, 0) == -1){ - log_error("cant send message to socket %d: %s", to, strerror(errno)); - free_str(&smsg); +int send_ipc_message(int to, ipc_type type, str msg){ + if(send(to, &type, sizeof(uint8_t), 0) -1){ + log_error("Can't send message type to socket %d: %s", to, strerror(errno)); + return 1; + } + if(send(to, &msg.len, sizeof(msg.len), 0) == -1){ + log_error("Can't send message length to socket %d: %s", to, strerror(errno)); + return 1; + } + if(send(to, msg.ptr, msg.len, 0) == -1){ + log_error("Can't send message to socket %d: %s", to, strerror(errno)); return 1; } - free_str(&smsg); - char buf[2]; - if(recv(to, buf, 2, 0) == -1){ - log_error("receiving OK from listener"); + char ack[3]; + if(recv(to, ack, 3, 0) == -1){ + log_error("Receiving ACK from listener"); return 1; } - if(strncmp(buf, "OK", 2) != 0){ - log_error("received '%s' from listener instead of 'OK'", buf); + if(strncmp(ack, "ACK", 2) != 0){ + log_error("Received '%.3s' from listener instead of 'ACK'", ack); return 1; } return 0; } -static inline ipc_message str_to_ipc_message(str smsg){ - struct ipc_message msg; - u32 l; - memcpy(&l, smsg.ptr, sizeof(l)); - smsg.ptr += sizeof(l); - msg.key = dnstr(l); - msg.key.len = l; - memcpy(msg.key.ptr, smsg.ptr, l); - smsg.ptr += l; - memcpy(&l, smsg.ptr, sizeof(l)); - smsg.ptr += sizeof(l); - msg.val = dnstr(l); - msg.val.len = l; - memcpy(msg.val.ptr, smsg.ptr, l); +ipc_msg receive_ipc_message(ipc_listener *il){ + ipc_msg msg = {0}; + if(recv(il->csocket, &msg.type, sizeof(uint8_t), 0) == -1){ + log_error("Can't receive message type from socket %d: %s", il->csocket, strerror(errno)); + goto end; + } + if(recv(il->csocket, &msg.msg.len, sizeof(msg.msg.len), 0) == -1){ + log_error("Can't receive message length from socket %d: %s", il->csocket, strerror(errno)); + goto end; + } + msg.msg.cap = msg.msg.len; + msg.msg.ptr = calloc(msg.msg.len, sizeof(char)); + if(recv(il->csocket, msg.msg.ptr, msg.msg.len, 0) == -1){ + log_error("Can't receive message from socket %d: %s", il->csocket, strerror(errno)); + free_ipc_message(&msg); + goto end; + } +end: + if(send(il->csocket, "ACK", slen("ACK"), 0) == -1){ + log_error("Sending 'ACK' to sender"); + } return msg; } -ipc_message receive_ipc_message(ipc_listener *il){ - str smsg = dnstr(MAX_IPC_MSG_LEN); // we are gonna have to poll btw - ipc_message msg = {0}; - smsg.len = recv(il->csocket, smsg.ptr, smsg.cap, 0); - if(smsg.len == -1){ - log_error("cant receive message from socket %d: %s", il->csocket, strerror(errno)); - }else{ - msg = str_to_ipc_message(smsg); - } - if(send(il->csocket, "OK", slen("OK"), 0) == -1){ - log_error("sending 'OK' to sender"); - } - return msg; +void free_ipc_message(ipc_msg *msg){ + msg->type = NONE; + free_str(&msg->msg); } diff --git a/src/ipc/ipc.h b/src/ipc/ipc.h index a122bc5..b275fbd 100755 --- a/src/ipc/ipc.h +++ b/src/ipc/ipc.h @@ -23,11 +23,23 @@ typedef struct ipc_listener { int csocket; } ipc_listener; +typedef enum ipc_type { + NONE, + SOCKET, REWRITES, // do away with these? + CERT, KEY, + RESTART, + RELOAD, + HTTP, + HTTPS, + LOG, + UNLOG, +} ipc_type; + #define MAX_IPC_MSG_LEN 1024 -typedef struct ipc_message { - str key; - str val; -} ipc_message; +typedef struct ipc_msg { + ipc_type type; + str msg; +} ipc_msg; ipc_sender *setup_ipc_sender(str addr, int backlog); void destroy_ipc_sender(ipc_sender **is); @@ -35,8 +47,8 @@ void destroy_ipc_sender(ipc_sender **is); ipc_listener *setup_ipc_listener(str saddr); void destroy_ipc_listener(ipc_listener **il); -void free_ipc_message(ipc_message im); -int send_ipc_message(int to, ipc_message msg); -ipc_message receive_ipc_message(ipc_listener *il); +int send_ipc_message(int to, ipc_type type, str msg); +ipc_msg receive_ipc_message(ipc_listener *il); +void free_ipc_message(ipc_msg *im); #endif diff --git a/src/main.c b/src/main.c index 071588a..7140256 100755 --- a/src/main.c +++ b/src/main.c @@ -97,7 +97,8 @@ int main(int argc, char *argv[]){ #ifdef SHOW_IP system("curl -s http://ipinfo.io/ip && echo"); #endif - + + /* sqlite3 *db = setupDatabase("src/db/db.db"); if(db == NULL){ @@ -115,7 +116,7 @@ int main(int argc, char *argv[]){ } */ - + // TODO: lookup shutdown() for sockets printf("press h for help\n"); bool end = false; while(!end){ @@ -131,11 +132,13 @@ int main(int argc, char *argv[]){ } struct worker w = { .pid = nw, .wsocket = accept(sender->ssocket, NULL, NULL) }; list_push(workers, w); - ipc_message msg = { .key = sstr("socket"), .val = utostr(server->ssocket, 10) }; - send_ipc_message(w.wsocket, msg); - free_ipc_message(msg); - msg = (ipc_message){ .key = sstr("rewrites"), .val = sstr("urirewrites") }; - send_ipc_message(w.wsocket, msg); + log_debug("erm"); + log_debug("1st send returned %d", + send_ipc_message(w.wsocket, SOCKET, utostr(server->ssocket, 10)) + ); + log_debug("2nd send returned %d", + send_ipc_message(w.wsocket, REWRITES, sstr("urirewrites")) + ); break; case 's': case 'S': kill(0, SIGUSR1); diff --git a/src/net/net.c b/src/net/net.c index cae3963..6379c2d 100755 --- a/src/net/net.c +++ b/src/net/net.c @@ -20,6 +20,7 @@ struct { {.fmt = sstr("bmp"), .type = sstr("image/bmp")}, {.fmt = sstr("css"), .type = sstr("text/css")}, {.fmt = sstr("csv"), .type = sstr("text/csv")}, + {.fmt = sstr("eot"), .type = sstr("application/vnd.ms-fontobject")}, {.fmt = sstr("gz"), .type = sstr("application/gzip")}, {.fmt = sstr("gif"), .type = sstr("image/gif")}, {.fmt = sstr("html"), .type = sstr("text/html")}, @@ -36,13 +37,17 @@ struct { {.fmt = sstr("pdf"), .type = sstr("application/pdf")}, {.fmt = sstr("php"), .type = sstr("application/x-httpd-php")}, {.fmt = sstr("rar"), .type = sstr("application/vnd.rar")}, + {.fmt = sstr("svg"), .type = sstr("image/svg+xml")}, {.fmt = sstr("tiff"), .type = sstr("image/tiff")}, {.fmt = sstr("ts"), .type = sstr("video/mp2t")}, + {.fmt = sstr("ttf"), .type = sstr("font/ttf")}, {.fmt = sstr("txt"), .type = sstr("text/plain")}, {.fmt = sstr("wav"), .type = sstr("audio/wav")}, {.fmt = sstr("weba"), .type = sstr("audio/webm")}, {.fmt = sstr("webm"), .type = sstr("video/webm")}, {.fmt = sstr("webp"), .type = sstr("image/webp")}, + {.fmt = sstr("woff"), .type = sstr("font/woff")}, + {.fmt = sstr("woff2"), .type = sstr("font/woff2")}, {.fmt = sstr("xml"), .type = sstr("application/xml")}, {.fmt = sstr("zip"), .type = sstr("application/zip")}, {.fmt = sstr("7z"), .type = sstr("application/x-7z-compressed")}, @@ -128,62 +133,98 @@ http_worker *setup_http_worker(int ssocket, int secure, str certfile, str keyfil hw->ssocket = ssocket; hw->csocket = -1; hw->secure = secure; - hw->receive = recv; - hw->ssl_receive = SSL_read; - SSL_library_init(); + if(secure){ + if(setup_https(hw, certfile, keyfile) != 0){ + log_error("Setting up HTTPS"); + terminate_https(hw); + destroy_http_worker(&hw); + } + } + + return hw; +} + +void destroy_http_worker(http_worker **hw){ + if(*hw != NULL){ + (*hw)->ssocket = -1; + close((*hw)->csocket); + (*hw)->csocket = -1; + (*hw)->secure = 0; + terminate_https(*hw); + free(*hw); + *hw = NULL; + } +} + +int setup_https(http_worker *hw, str certfile, str keyfile){ + if(certfile.len == 0){ + log_error("Missing certificate file"); + return 1; + } + if(keyfile.len == 0){ + log_error("Missing private key file"); + return 1; + } + + if(hw->ssl != NULL){ + SSL_free(hw->ssl); + } + if(hw->ssl_ctx != NULL){ + SSL_CTX_free(hw->ssl_ctx); + } + hw->ssl_ctx = SSL_CTX_new(TLS_server_method()); // need to compile openssl with ktls on for this (v) to work - SSL_CTX_set_options(hw->ssl_ctx, SSL_OP_ENABLE_KTLS); + SSL_CTX_set_options(hw->ssl_ctx, SSL_OP_ENABLE_KTLS | SSL_OP_IGNORE_UNEXPECTED_EOF); if(hw->ssl_ctx == NULL){ - goto error; + return 1; } //SSL_CTX_set_verify(hw->ssl_ctx, SSL_VERIFY_PEER, NULL); if(SSL_CTX_load_verify_locations(hw->ssl_ctx, "ssl/mkarchive.net/ca_bundle.crt", NULL) <= 0){ - log_error("ca_bundle.crt"); - goto error; + log_error("Verifying certificate locations"); + return 1; } if(SSL_CTX_use_certificate_file(hw->ssl_ctx, certfile.ptr, SSL_FILETYPE_PEM) <= 0){ - log_error("worker_cert"); - goto error; + log_error("Using certificate file"); + return 1; } if(SSL_CTX_use_PrivateKey_file(hw->ssl_ctx, keyfile.ptr, SSL_FILETYPE_PEM) <= 0 ){ - log_error("worker: key"); - goto error; + log_error("Using private key file"); + return 1; } hw->ssl = SSL_new(hw->ssl_ctx); - SSL_set_accept_state(hw->ssl); if(hw->ssl == NULL){ - goto error; - } - - if(0){ -error: - destroy_http_worker(&hw); + log_error("Creating SSL*"); + return 1; } + SSL_set_accept_state(hw->ssl); - return hw; + return 0; } -void destroy_http_worker(http_worker **hw){ - if(*hw != NULL){ - (*hw)->ssocket = -1; - close((*hw)->csocket); - (*hw)->secure = 0; - SSL_free((*hw)->ssl); - SSL_CTX_free((*hw)->ssl_ctx); - (*hw)->receive = NULL; - (*hw)->ssl_receive = NULL; - free(*hw); - *hw = NULL; +void reset_https(http_worker *hw){ + if(hw != NULL){ + close(hw->csocket); + if(hw->ssl != NULL){ + SSL_free(hw->ssl); + } + hw->ssl = SSL_new(hw->ssl_ctx); + SSL_set_accept_state(hw->ssl); } } -void reset_worker_ssl(http_worker *hw){ - close(hw->csocket); - SSL_free(hw->ssl); - hw->ssl = SSL_new(hw->ssl_ctx); - SSL_set_accept_state(hw->ssl); +void terminate_https(http_worker *hw){ + if(hw != NULL){ + if(hw->ssl != NULL){ + SSL_free(hw->ssl); + hw->ssl = NULL; + } + if(hw->ssl_ctx != NULL){ + SSL_CTX_free(hw->ssl_ctx); + hw->ssl_ctx = NULL; + } + } } int accept_connection(http_worker *hw, char ip[INET_ADDRSTRLEN]){ diff --git a/src/net/net.h b/src/net/net.h index dc3d021..55ffe44 100755 --- a/src/net/net.h +++ b/src/net/net.h @@ -86,16 +86,12 @@ typedef struct http_server { int ssocket; } http_server; -typedef ssize_t (*recv_func)(int,void*,size_t,int); -typedef int (*ssl_recv_func)(SSL*,void*,int); typedef struct http_worker { int ssocket; int csocket; int secure; SSL_CTX *ssl_ctx; SSL *ssl; - recv_func receive; - ssl_recv_func ssl_receive; } http_worker; #define MAX_RESPONSE_SIZE 0x0FFFFFFF @@ -106,14 +102,14 @@ typedef struct http_worker { http_server *setup_http_server(str port, int backlog); - void destroy_http_server(http_server **hs); http_worker *setup_http_worker(int ssocket, int secure, str certfile, str keyfile); - void destroy_http_worker(http_worker **hw); -void reset_worker_ssl(http_worker *hw); +int setup_https(http_worker *hw, str certfile, str keyfile); +void reset_https(http_worker *hw); +void terminate_https(http_worker *hw); int accept_connection(http_worker *hw, char ip[INET_ADDRSTRLEN]); diff --git a/src/worker.c b/src/worker.c index 45cc807..51ff976 100755 --- a/src/worker.c +++ b/src/worker.c @@ -8,9 +8,56 @@ ipc_listener *listener; http_worker *worker; +int secure; str rewritesfile; - - +str certfile; +str keyfile; + + +void handle_message(ipc_msg im){ + switch(im.type){ + case NONE: break; + case SOCKET: + if(worker != NULL){ + destroy_http_worker(&worker); + } + int ssocket = strtou(im.msg); + worker = setup_http_worker(ssocket, secure, certfile, keyfile); + break; + case REWRITES: + break; + case CERT: + free_str(&certfile); + certfile = dup_str(im.msg); + break; + case KEY: + free_str(&keyfile); + keyfile = dup_str(im.msg); + break; + case RESTART: + char *args[] = {"./worker.exe", listener.saddr.ptr, NULL}; + execv("./worker.exe", args); + log_error("Cannot restart worker: %s", strerror(errno)); + return 1; + break; + case RELOAD: + // re-reads config + break; + case HTTP: + secure = 0; + terminate_https(worker); + break; + case HTTPS: + secure = 1; + setup_https(worker, certfile, keyfile); + case LOG: + break; + case UNLOG: + break; + default: + break; + } +} int init(char *argv[]){ // replace signals with unix sockets // reinit @@ -26,9 +73,13 @@ int init(char *argv[]){ } // check key for value maybe idk - ipc_message msg = receive_ipc_message(listener); - int ssocket = strtou(msg.val); - free_ipc_message(msg); // v configurable certificate locations? + ipc_msg msg = receive_ipc_message(listener); + if(msg.type != SOCKET){ + log_error("uh oh"); + return 1; + } + int ssocket = strtou(msg.msg); + free_ipc_message(&msg); // v configurable certificate locations? worker = setup_http_worker(ssocket, 1, sstr("ssl/mkarchive.net/certificate.crt"), sstr("ssl/mkarchive.net/private.key")); if(worker == NULL){ log_error("setting up http worker"); @@ -36,8 +87,12 @@ int init(char *argv[]){ } // this is disgusting and should be done elsewhere msg = receive_ipc_message(listener); // check for value - rewritesfile = dup_str(msg.val); - free_ipc_message(msg); + if(msg.type != REWRITES){ + log_error("uh oh 2"); + return 1; + } + rewritesfile = dup_str(msg.msg); + free_ipc_message(&msg); int fsize = get_file_size(rewritesfile.ptr); int fd = open(rewritesfile.ptr, O_RDONLY | O_NONBLOCK); char *rewrites = mmap(NULL, fsize, PROT_READ, MAP_SHARED, fd, 0); @@ -50,6 +105,7 @@ int init(char *argv[]){ return 1; } munmap(rewritesfile.ptr, fsize); + close(fd); return 0; } @@ -81,7 +137,7 @@ int main(int argc, char **argv){ case -1: // couldnt accept, do something ig continue; case SSL_ERROR_SSL: - reset_worker_ssl(worker); + reset_https(worker); log_info("continuing\n"); continue; } @@ -91,7 +147,7 @@ int main(int argc, char **argv){ case -1: // couldnt accept, do something ig continue; case SSL_ERROR_SSL: - reset_worker_ssl(worker); + reset_https(worker); log_info("continuing\n"); continue; } @@ -119,7 +175,9 @@ int main(int argc, char **argv){ case PUT: break; case DELETE: - break; + break; + default: + break; } free_str(&suri.path); free_str(&suri.query); -- 2.39.5