232 lines
5.0 KiB
C
232 lines
5.0 KiB
C
#include "httpd.h"
|
|
#include <sys/stat.h>
|
|
#include <openssl/evp.h>
|
|
#include <sqlite3.h>
|
|
#include <uuid/uuid.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 "/notfound/404.html"
|
|
|
|
/*
|
|
Key-value structure pairs
|
|
*/
|
|
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);
|
|
}
|
|
}
|
|
|
|
/*
|
|
SHA-512 Hash of string
|
|
*/
|
|
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';
|
|
}
|
|
|
|
/*
|
|
Process POST to /hash
|
|
*/
|
|
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);
|
|
}
|
|
|
|
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
|
|
int i;
|
|
for(i = 0; i<argc; i++){
|
|
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
|
}
|
|
printf("\n");
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Main Function
|
|
*/
|
|
int main(int c, char **v) {
|
|
sqlite3 *db;
|
|
char *err_msg = 0;
|
|
|
|
int rc = sqlite3_open("infinitum.db", &db);
|
|
if (rc != SQLITE_OK) {
|
|
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
|
|
sqlite3_close(db);
|
|
return 1;
|
|
}
|
|
|
|
char *sql;
|
|
sql = "CREATE TABLE IF NOT EXISTS Users ( \
|
|
UserID TEXT PRIMARY KEY, \
|
|
FirstName TEXT NOT NULL, \
|
|
LastName TEXT NOT NULL, \
|
|
Email TEXT NOT NULL UNIQUE, \
|
|
RegistrationDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, \
|
|
LastLoginDate TIMESTAMP, \
|
|
Notes TEXT \
|
|
);";
|
|
|
|
rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
|
|
|
|
if( rc != SQLITE_OK) {
|
|
fprintf(stderr, "Something happend during processing db tables");
|
|
sqlite3_free(&err_msg);
|
|
sqlite3_close(db);
|
|
return 1;
|
|
}
|
|
|
|
// idk
|
|
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;
|
|
}
|
|
|
|
/*
|
|
Route Handling
|
|
*/
|
|
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()
|
|
} |