From 22a7b5b3fc31998d17495fcb701d96ebef689c22 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Mon, 21 Nov 2022 21:02:33 +0100 Subject: [PATCH] feat: added secure random URL option --- landerctl | 29 ++++++++-- src/main.cpp | 109 ++++++++++++++++++++++-------------- tries/include/ternarytrie.h | 6 +- tries/src/ternarytrie.c | 9 +-- 4 files changed, 101 insertions(+), 52 deletions(-) diff --git a/landerctl b/landerctl index c9a2c12..52b0dcc 100755 --- a/landerctl +++ b/landerctl @@ -3,16 +3,35 @@ API_KEY=test URL=http://localhost:18080 -if [ "$1" = add ]; then +if [ "$1" = g ]; then + curl -is "$URL/$2" | + sed -En 's/^[lL]ocation: (.*)/\1/p' + +elif [ "$1" = s ]; then curl \ -XPOST \ -d "$2" \ -H "X-Api-Key: $API_KEY" \ "$URL/s/$3" -elif [ "$1" = get ]; then - curl -is "$URL/$2" | sed -En 's/^[lL]ocation: (.*)/\1/p' +elif [ "$1" = sl ]; then + curl \ + -XPOST \ + -d "$2" \ + -H "X-Api-Key: $API_KEY" \ + "$URL/sl/$3" -elif [ "$1" = paste ]; then - curl --data-binary @"$2" -XPOST -H "X-Api-Key: $API_KEY" "$URL/p/$3" +elif [ "$1" = p ]; then + curl \ + -XPOST \ + -H "X-Api-Key: $API_KEY" \ + --data-binary @"$2" \ + "$URL/p/$3" + +elif [ "$1" = pl ]; then + curl \ + -XPOST \ + -H "X-Api-Key: $API_KEY" \ + --data-binary @"$2" \ + "$URL/pl/$3" fi diff --git a/src/main.cpp b/src/main.cpp index 35c1c82..9812e27 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,55 @@ extern "C" { return crow::response(crow::status::UNAUTHORIZED); \ } +crow::response add_redirect(std::string base_url, TernaryTrie *trie, + const char *url, bool secure) { + Entry *new_entry = entry_new(Redirect, url); + char *key = ternarytrie_add_random(trie, new_entry, secure); + + if (key == NULL) { + return crow::response(crow::status::INTERNAL_SERVER_ERROR); + } + + std::string res = base_url + key; + free(key); + + return crow::response(res); +} + +bool store_paste(const char *key, const char *body) { + // Write paste contents to file + std::fstream file; + file.open(std::string("pastes/") + key, std::ios_base::out); + + if (!file.is_open()) { + return false; + } + + file << body; + file.close(); + + return true; +} + +crow::response add_paste(std::string base_url, TernaryTrie *trie, + const char *body, bool secure) { + Entry *new_entry = entry_new(Paste, ""); + char *key = ternarytrie_add_random(trie, new_entry, secure); + + if (key == NULL) { + return crow::response(crow::status::INTERNAL_SERVER_ERROR); + } + + if (!store_paste(key, body)) { + return crow::response(crow::status::INTERNAL_SERVER_ERROR); + } + + std::string res = base_url + key; + free(key); + + return crow::response(res); +} + int main() { // Initialize random seed for generating URLs srand(time(NULL)); @@ -72,23 +121,22 @@ int main() { res.end(); }); - // Add a new Redirect with a randomly generated key + // Add a new Redirect with a short randomly generated key CROW_ROUTE(app, "/s/") .methods(crow::HTTPMethod::Post)( [api_key, base_url, trie](const crow::request req) { AUTH(); - Entry *new_entry = entry_new(Redirect, req.body.c_str()); - char *key = ternarytrie_add_random(trie, new_entry); + return add_redirect(base_url, trie, req.body.c_str(), false); + }); - if (key == NULL) { - return crow::response(crow::status::INTERNAL_SERVER_ERROR); - } + // Add a new Redirect with a long randomly generated key + CROW_ROUTE(app, "/sl/") + .methods(crow::HTTPMethod::Post)( + [api_key, base_url, trie](const crow::request req) { + AUTH(); - std::string res = base_url + key; - free(key); - - return crow::response(res); + return add_redirect(base_url, trie, req.body.c_str(), true); }); // Add a new Redirect with a given key @@ -108,35 +156,22 @@ int main() { return crow::response(base_url + key); }); - // Add a new Paste with a randomly generated key + // Add a new Paste with a short randomly generated key CROW_ROUTE(app, "/p/") .methods(crow::HTTPMethod::Post)( [api_key, base_url, trie](const crow::request &req) { AUTH(); - Entry *new_entry = entry_new(Paste, ""); - char *key = ternarytrie_add_random(trie, new_entry); + return add_paste(base_url, trie, req.body.c_str(), false); + }); - if (key == NULL) { - return crow::response(crow::status::INTERNAL_SERVER_ERROR); - } + // Add a new Paste with a long randomly generated key + CROW_ROUTE(app, "/pl/") + .methods(crow::HTTPMethod::Post)( + [api_key, base_url, trie](const crow::request &req) { + AUTH(); - // Write paste contents to file - std::fstream file; - file.open(std::string("pastes/") + key, std::ios_base::out); - - if (!file.is_open()) { - free(key); - return crow::response(crow::status::INTERNAL_SERVER_ERROR); - } - - file << req.body; - file.close(); - - std::string res = base_url + key; - free(key); - - return crow::response(res); + return add_paste(base_url, trie, req.body.c_str(), true); }); // Add a paste with a given key @@ -146,24 +181,16 @@ int main() { AUTH(); Entry *new_entry = entry_new(Paste, ""); - bool added = ternarytrie_add(trie, key.c_str(), new_entry); if (!added) { return crow::response(crow::status::CONFLICT); } - // Write paste contents to file - std::fstream file; - file.open(std::string("pastes/") + key, std::ios_base::out); - - if (!file.is_open()) { + if (!store_paste(key.c_str(), req.body.c_str())) { return crow::response(crow::status::INTERNAL_SERVER_ERROR); } - file << req.body; - file.close(); - return crow::response(base_url + key); }); app.port(18080).multithreaded().run(); diff --git a/tries/include/ternarytrie.h b/tries/include/ternarytrie.h index 42773a0..0634aaa 100644 --- a/tries/include/ternarytrie.h +++ b/tries/include/ternarytrie.h @@ -14,7 +14,8 @@ static const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW static const size_t charset_len = sizeof(charset) - 1; // Length of randomly generated keys -#define RANDOM_KEY_LENGTH 4 +#define RANDOM_KEY_LENGTH_SHORT 4 +#define RANDOM_KEY_LENGTH_LONG 16 /** * Type definition for the struct representing the current Trie. @@ -83,9 +84,10 @@ bool ternarytrie_add(TernaryTrie* trie, const char* key, Entry *entry); * * @param trie * @param entry entry to add + * @param secure whether to generate a longer, more secure random key * @return the generated key */ -char *ternarytrie_add_random(TernaryTrie *trie, Entry *entry); +char *ternarytrie_add_random(TernaryTrie *trie, Entry *entry, bool secure); /** * Remove an entry from this trie given its key. diff --git a/tries/src/ternarytrie.c b/tries/src/ternarytrie.c index f65b165..9cebfcc 100644 --- a/tries/src/ternarytrie.c +++ b/tries/src/ternarytrie.c @@ -333,19 +333,20 @@ bool ternarytrie_add(TernaryTrie *trie, const char *key, Entry *entry) { return return_value; } -char* ternarytrie_add_random(TernaryTrie *trie, Entry *entry) { +char* ternarytrie_add_random(TernaryTrie *trie, Entry *entry, bool secure) { pthread_rwlock_wrlock(&trie->lock); // Generate random key bool ok = false; - char *key = malloc(RANDOM_KEY_LENGTH + 1); - key[RANDOM_KEY_LENGTH] = '\0'; + int key_length = secure ? RANDOM_KEY_LENGTH_LONG : RANDOM_KEY_LENGTH_SHORT; + char *key = malloc(key_length + 1); + key[key_length] = '\0'; // We naively generate new keys until we find a key that isn't in the trie // yet. With charset_len ** RANDOM_KEY_LENGTH sufficiently large, this isn't a // problem, because the chances of collisions are extremely small. while (!ok) { - for (int i = 0; i < RANDOM_KEY_LENGTH; i++) { + for (int i = 0; i < key_length; i++) { key[i] = charset[rand() % charset_len]; }