From fbe58d57d6c6c8aa7d7e8d4a459a97513ba35f34 Mon Sep 17 00:00:00 2001 From: Pin Date: Sat, 12 Mar 2022 23:08:47 -0500 Subject: [PATCH] finishing additions --- README.md | 4 ++-- cmd/server.c | 38 +++++++++++++++++++++++++++++++------- src/requestHandlers.c | 18 ++++++++++++++++++ src/returnRequest.c | 9 ++++++++- src/socketHelp.c | 9 +++++++-- src/utils.c | 15 ++++++++++++++- 6 files changed, 80 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index fe15e29..7012d38 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ It is recommended to run this application using Docker. For a deployment running the application without HTTPS run `make dockerTestDeploy`, this will open a socket on port 8080. For a deployment running the application with HTTPS run `make dockerReleaseDeploy`, this will also open a socket on port 8080. Running `make killTestDocker` will kill the running instance of seaweb:latest running in Docker. -To view logs within the running container run `docker exec -it $(docker ps | grep "seaweb:latest" | grep -o '[^ ]*$') tail -f /var/log/seaweb/log`, or manually view the `/var/log/seaweb/log` file. +To view logs within the running container run `docker exec -it $(docker ps | grep "seaweb:latest" | grep -o '[^ ]*$') tail -f /var/log/seaweb/log`, or manually view the `/var/log/seaweb/log` file within the container. If you run this application without Docker please ensure the OpenSSL development headers are installed onto your system, this will be important if running with HTTPS. -To build this application outside of Docker run `make`, and the binary will be build into `./bin`. +To build this application outside of Docker run `make`, and the binary will be built into `./bin`. Running `./bin/seaweb --help` or `./bin/seaweb -h` will show you the help message for the application showing all possible options. By default the application is compiled to utilize `/var/www/html` as the WEB root, and will output logs to `/var/log/seaweb/log`; if running the application outside of Docker please ensure this is setup with correct permissions to run. diff --git a/cmd/server.c b/cmd/server.c index 9a35bb4..69f28df 100644 --- a/cmd/server.c +++ b/cmd/server.c @@ -27,6 +27,10 @@ char *WEB_ROOT_DIR = NULL; static int timeout = 0; +/* + * Used to print debug messages to the screen + * when the --verbose flag is passed + */ int printDebug(char message[]) { if (verbose_flag == 1) { printf("[Debug] %s\n", message); @@ -34,6 +38,12 @@ int printDebug(char message[]) { return 0; } +/* + * This function handles incoming requests and stores + * the parsed data into the HTTPRequest struct passed + * into the function. If any errors are encountered + * during this process a negative number will be returned + */ int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) { char temp[1]; // Used to check newlines char *token = calloc(8, sizeof(char)); @@ -45,6 +55,8 @@ int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) { char * varCheck; // Creating empty requestBody + // Setting values to 0 helps if variable is not + // set and determining that later on in handling r->requestBody = malloc(sizeof(char)); r->requestBodyLen = 0; r->requestVars = malloc(sizeof(char)); @@ -129,11 +141,13 @@ int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) { } line++; } else { + // Appending char to checkLine strcat((char *)checkLine, temp); checkLineLen++; } } + // Return error if request type is not set if (strlen(r->requestType) == 0) { free(logLine); free(checkLine); @@ -145,6 +159,10 @@ int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) { return 0; } +/* + * This function is the entry point for all new requests; this + * function will always return 0 regardless of outcome + */ int handleRequest(unsigned char buffer[], int socket, SSL *ssl) { struct HTTPRequest r; // Holds relevant HTTP request information r.requestConLen = malloc(sizeof(char)); @@ -189,6 +207,10 @@ int handleRequest(unsigned char buffer[], int socket, SSL *ssl) { return 0; } +/* + * This function is used as a signal to kill child processes that + * are triggered by the corresponding alarm + */ void timeoutChild(int sig) { timeout = 1; } @@ -229,6 +251,7 @@ int main(int argc, char **argv) { {0, 0, 0, 0} }; + // Define help message const char* usage = "Usage: seaweb [options]\n\n" " -h --help\t\t\tShows this message\n" @@ -241,6 +264,7 @@ int main(int argc, char **argv) { " --verbose\t\t\tPrints debug messages\n" "\n"; + // Parsing options int c; while (1) { int option_index = 0; @@ -293,14 +317,14 @@ int main(int argc, char **argv) { enableHTTPS = 1; } - if ( enableHTTPS == 1 ) { + if ( enableHTTPS == 1 ) { // Open secure socket printf("Opening secure socket on port: %d\n", port); checkerr = createSecureSocket(port, &server_fd, &address, &addrlen, listenAddrNum, &ctx, certFile, privKeyFile); if ( ctx == NULL ) { printf("Error creating ctx\n"); } - } else { + } else { // Open socket printf("Opening socket on port: %d\n", port); checkerr = createSocket(port, &server_fd, &address, &addrlen, listenAddrNum); } @@ -321,11 +345,11 @@ int main(int argc, char **argv) { pid_t pid; pid = fork(); - if (pid == 0) { + if (pid == 0) { // Child process handles sessions pid_t pid2; pid2 = fork(); - if (pid2 == 0) { + if (pid2 == 0) { // Child child process reads requests and handles return bufSize = BUFF_READ; if ( enableHTTPS ) { size_t buffCont = 1; @@ -362,14 +386,14 @@ int main(int argc, char **argv) { exit(EXIT_SUCCESS); } else if (pid2 < 0) { printDebug("Error forking supervisor..."); - } else { + } else { // Parent process waits to see if child timeout is triggered int status; signal(SIGALRM, timeoutChild); alarm(2); pause(); if (timeout) { status = waitpid(pid, NULL, WNOHANG); - if (status == 0) { + if (status == 0) { // If status is not 0 kill child process printDebug("Killing child"); kill(pid2, 9); wait(NULL); @@ -380,7 +404,7 @@ int main(int argc, char **argv) { close(new_socket); } else if (pid < 0) { printDebug("Error forking..."); - } else { + } else { // Ignore exit status of spawned child (proc is not a zombie) signal(SIGCHLD, SIG_IGN); close(new_socket); continue; diff --git a/src/requestHandlers.c b/src/requestHandlers.c index 203069f..11e7da0 100644 --- a/src/requestHandlers.c +++ b/src/requestHandlers.c @@ -10,6 +10,10 @@ #include "server.h" #include "utils.h" +/* + * This funcion handles all GET requests and checks + * to see if a php file is being requested + */ int handleGetRequest(int socket, struct HTTPRequest *r, SSL *ssl) { char errResponse[256]; char ch; @@ -19,6 +23,7 @@ int handleGetRequest(int socket, struct HTTPRequest *r, SSL *ssl) { FILE *fp; char *workingReqDir; + // Checking for php extension char *phpReturn = NULL; char phpEnd[5] = ".php"; bool endsWithPhp = false; @@ -49,6 +54,7 @@ int handleGetRequest(int socket, struct HTTPRequest *r, SSL *ssl) { } char *reqDir = calloc((strlen(WEB_ROOT_DIR) + strlen(workingReqDir) + 1), sizeof(char)); + // Creating absolute path from web root sprintf(reqDir, "%s%s", WEB_ROOT_DIR, workingReqDir); fp = fopen(reqDir, "r"); @@ -77,6 +83,10 @@ int handleGetRequest(int socket, struct HTTPRequest *r, SSL *ssl) { return 0; } +/* + * This function handles all PUT requests and attempts to create + * a fill with the requested content at the web root plus passed path + */ int handlePUTRequest(int socket, struct HTTPRequest *r, SSL *ssl) { FILE *fp; char *reqDir; @@ -106,6 +116,10 @@ int handlePUTRequest(int socket, struct HTTPRequest *r, SSL *ssl) { return return201Request(socket, r->requestBody, ssl); } +/* + * This function handles all DELETE requests and attempts to delete + * the requested file + */ int handleDELETERequest(int socket, struct HTTPRequest *r, SSL *ssl) { char *reqDir; char * workingReqDir; @@ -136,6 +150,10 @@ int handleDELETERequest(int socket, struct HTTPRequest *r, SSL *ssl) { return 0; } +/* + * This function handles all POST requests and checks to see + * if the file extension is .php + */ int handlePOSTRequest(int socket, struct HTTPRequest *r, SSL *ssl) { char *phpReturn = NULL; // Supported data types application/x-www-form-urlencoded application/json diff --git a/src/returnRequest.c b/src/returnRequest.c index c6e9b08..6e3b424 100644 --- a/src/returnRequest.c +++ b/src/returnRequest.c @@ -6,6 +6,9 @@ #include "server.h" +/* + * This function returns the requested request's response data + */ int returnRequest(int socket, char *message, int status, SSL *ssl) { if ( enableHTTPS ) { SSL_write(ssl, message, strlen(message)); @@ -20,7 +23,7 @@ int returnRequest(int socket, char *message, int status, SSL *ssl) { int return200Request(int socket, unsigned char *content, SSL *ssl) { char *message = ""; - if (content != NULL) { + if (content != NULL) { // If content is passed add it to the return string message = calloc(strlen((char *)content) + 128, sizeof(char)); sprintf(message, "HTTP/1.1 200 OK\nContent-Length: %zu\nContent-Type: text/html\nConnection: close\n\n%s", strlen((char *)content), content); @@ -87,6 +90,10 @@ int return505Request(int socket, SSL *ssl) { return returnRequest(socket, message, 505, ssl); } +/* + * This function delete the first line of php-cgi return data + * and passes the resulting text into return200Request + */ int returnPHPRequest(int socket, char *content, SSL *ssl) { char *message = malloc(1024); memset(message, 0, 1024); diff --git a/src/socketHelp.c b/src/socketHelp.c index e755f3a..8929b35 100644 --- a/src/socketHelp.c +++ b/src/socketHelp.c @@ -9,6 +9,11 @@ #include "socketHelp.h" +/* + * This function turns a IPv4 four byte octet into + * an unsigned 32 bit integer which can be used when + * opening new socket connections + */ uint32_t addr2sin_addr(char *addr) { char *token; int i = 0; @@ -18,12 +23,12 @@ uint32_t addr2sin_addr(char *addr) { token = strtok(addr, "."); while(token != NULL) { addrTempNum = strtoul(token, NULL,10); - if ( addrTempNum > 255 ) { + if ( addrTempNum > 255 ) { // Check if octet is valid printf("Invalid IP octet: %ld\n", addrTempNum); free(token); return -1; - } + } // Adding value to addr number addrNum = addrNum + ( addrTempNum << (8*(3-i)) ); token = strtok(NULL, "."); diff --git a/src/utils.c b/src/utils.c index f440735..b128e79 100644 --- a/src/utils.c +++ b/src/utils.c @@ -16,6 +16,11 @@ static char supportedHTTPVersions[NUM_SUPPORTED_VERSIONS][16] = { "HTTP/1.0" }; +/* + * This function prints logs to the screen if the web root is not absolute, + * if web root is /var/www/html then it is assumed to be running in service mode + * which means it prints logs to /var/log/seaweb/log + */ int PrintLog(unsigned char *message) { time_t UTCTime; // Setting time in EPOC @@ -36,6 +41,10 @@ int PrintLog(unsigned char *message) { return 0; } +/* + * This function checks to see if the requested http version + * is with 1.1 or 1.0 + */ int checkHTTPVersion(char *version) { int supported = -1; // Default fail state char testVer[16]; @@ -48,6 +57,10 @@ int checkHTTPVersion(char *version) { return supported; } +/* + * This function executes php-cgi requests and returns + * the response + */ char *php_cgi(char *sPath, struct HTTPRequest *r) { int phpPipe[2]; char *buf = NULL; @@ -107,7 +120,7 @@ char *php_cgi(char *sPath, struct HTTPRequest *r) { dup2(phpPipe2[0], STDIN_FILENO); execl("/usr/bin/php-cgi", "php-cgi", NULL); } - } else { + } else { // GET request handlers does not require second fork putenv("REQUEST_METHOD=GET"); if (r->requestVars != NULL) { queryString = malloc(strlen(r->requestVars) + 24);