This repository has been archived on 2024-07-05. You can view files and clone it, but cannot push or open issues or pull requests.
Infinitum/server/main.c

176 lines
3.9 KiB
C
Raw Normal View History

#include "httpd.h"
#include <sys/stat.h>
#include <openssl/evp.h>
#define CHUNK_SIZE 1024 // read 1024 bytes at a time
// Public directory settings
#define PUBLIC_DIR "./public"
#define INDEX_HTML "/index.html"
#define NOT_FOUND_HTML "/404.html"
typedef struct {
char *key;
char *value;
} KeyValuePair;
// Function to create key-value pair
KeyValuePair* createKeyValuePair(const char *key, const char *value) {
KeyValuePair *pair = malloc(sizeof(KeyValuePair));
if (pair != NULL) {
pair->key = strdup(key);
pair->value = strdup(value);
}
return pair;
}
// Function to free memory occupied by a key-value pair
void freeKeyValuePair(KeyValuePair *pair) {
if (pair != NULL) {
free(pair->key);
free(pair->value);
free(pair);
}
}
void sha512_hash_string(const char *input, char outputBuffer[129]) {
EVP_MD_CTX *mdctx;
const EVP_MD *md;
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int hashLen;
md = EVP_sha512();
mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, input, strlen(input));
EVP_DigestFinal_ex(mdctx, hash, &hashLen);
EVP_MD_CTX_free(mdctx);
for (int i = 0; i < hashLen; i++) {
sprintf(&outputBuffer[i * 2], "%02x", hash[i]);
}
outputBuffer[hashLen * 2] = '\0';
}
void parsePasswordPostData(const char *postData) {
char *dataCopy = strdup(postData); // Make a copy to avoid modifying the original string
char *token = strtok(dataCopy, "&");
while (token != NULL) {
char *keyValuePair = strdup(token);
char *key = strtok(keyValuePair, "=");
char *value = strtok(NULL, "=");
if (key != NULL && value != NULL) {
//printf("Key: %s, Value: %s\n", key, value);
// Here, you can store or process the key and value as needed
if(*key == 'p') {
char localHashOutput[129];
sha512_hash_string(value, localHashOutput);
//printf("Hashed");
printf("Input password is: %s\nHashed password is: %s\n", value, localHashOutput);
}
}
free(keyValuePair);
token = strtok(NULL, "&");
}
free(dataCopy);
}
int main(int c, char **v) {
char *port = c == 1 ? "8000" : v[1];
serve_forever(port);
return 0;
}
int file_exists(const char *file_name) {
struct stat buffer;
int exists;
exists = (stat(file_name, &buffer) == 0);
return exists;
}
int read_file(const char *file_name) {
char buf[CHUNK_SIZE];
FILE *file;
size_t nread;
int err = 1;
file = fopen(file_name, "r");
if (file) {
while ((nread = fread(buf, 1, sizeof buf, file)) > 0)
fwrite(buf, 1, nread, stdout);
err = ferror(file);
fclose(file);
}
return err;
}
void route() {
ROUTE_START()
GET("/") {
char index_html[20];
sprintf(index_html, "%s%s", PUBLIC_DIR, INDEX_HTML);
HTTP_200;
if (file_exists(index_html)) {
read_file(index_html);
} else {
printf("Hello! You are using %s\n\n", request_header("User-Agent"));
}
}
POST("/hash") {
HTTP_201;
if(payload_size > 0){
parsePasswordPostData(payload);
}
}
GET("/test") {
HTTP_200;
printf("List of request headers:\n\n");
header_t *h = request_headers();
while (h->name) {
printf("%s: %s\n", h->name, h->value);
h++;
}
}
POST("/") {
HTTP_201;
printf("Wow, seems that you POSTed %d bytes.\n", payload_size);
printf("Fetch the data using `payload` variable.\n");
if (payload_size > 0)
printf("Request body: %s", payload);
}
GET(uri) {
char file_name[255];
sprintf(file_name, "%s%s", PUBLIC_DIR, uri);
if (file_exists(file_name)) {
HTTP_200;
read_file(file_name);
} else {
HTTP_404;
sprintf(file_name, "%s%s", PUBLIC_DIR, NOT_FOUND_HTML);
if (file_exists(file_name))
read_file(file_name);
}
}
ROUTE_END()
}