From ab9010d945f88bc997f11a14e5b3fdfba72f77eb Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Fri, 29 Apr 2022 16:26:29 -0400 Subject: [PATCH] Add authorization --- src/auth/auth.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/auth/auth.hpp | 31 +++++++++++++++++++++++++++++++ src/main.cpp | 8 ++++++++ src/opt/parseopt.cpp | 6 ++++++ src/opt/parseopt.hpp | 3 ++- src/routes.cpp | 36 +++++++++++++++++++++++++++++------- src/routes.hpp | 2 ++ 7 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 src/auth/auth.cpp create mode 100644 src/auth/auth.hpp diff --git a/src/auth/auth.cpp b/src/auth/auth.cpp new file mode 100644 index 0000000..bcfb0e4 --- /dev/null +++ b/src/auth/auth.cpp @@ -0,0 +1,37 @@ +/////////////////////////////////////////////////////////////////////////////// +// Tyler Perkins +// 29-4-22 +// Auth definition +// + +#include "auth.hpp" + +bool auth::checkAuth(const crow::request& req){ + if(auth::auth_check::checker == nullptr) + return true; + else + return auth::auth_check::checker->checkAuth(req); +} + +auth::auth_check::auth_check(std::string& path){ + std::ifstream f (path); + + if(f.is_open()){ + std::string line; + while(std::getline(f, line)){ + tokens.insert(line); + } + } + f.close(); +} + +auth::auth_check::~auth_check(){ + //nothing to clean up +} + +bool auth::auth_check::checkAuth(const crow::request& req) const { + if(tokens.find(req.get_header_value(AUTH_HEADER)) != tokens.end()) + return true; + else + return false; +} diff --git a/src/auth/auth.hpp b/src/auth/auth.hpp new file mode 100644 index 0000000..4e5097b --- /dev/null +++ b/src/auth/auth.hpp @@ -0,0 +1,31 @@ +/////////////////////////////////////////////////////////////////////////////// +// Tyler Perkins +// 29-4-22 +// Auth definition +// + +#pragma once + +#include +#include +#include +#include + +constexpr char AUTH_HEADER[] = "Authorization"; + +namespace auth{ + class auth_check { + public: + auth_check(std::string&); + ~auth_check(); + + static auth_check* checker; + + bool checkAuth(const crow::request&) const; + + private: + std::unordered_set tokens; + }; + + bool checkAuth(const crow::request&); +} diff --git a/src/main.cpp b/src/main.cpp index d73abe5..5d814fd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,9 @@ #include #include #include "opt/parseopt.hpp" +#include "auth/auth.hpp" + +auth::auth_check* auth::auth_check::checker; #include "routes.hpp" @@ -14,6 +17,11 @@ int main(int argc, char** argv){ option_flags* flags = parse_options(argc, argv); + if(!flags->auth_path.empty()){ + auth::auth_check::checker = new auth::auth_check(flags->auth_path); + CROW_LOG_INFO << "Added authorization using authfile " << flags->auth_path; + } + crow::SimpleApp app; setRoutes(app); diff --git a/src/opt/parseopt.cpp b/src/opt/parseopt.cpp index e0741b0..16870ef 100644 --- a/src/opt/parseopt.cpp +++ b/src/opt/parseopt.cpp @@ -11,6 +11,8 @@ void help(char* progName){ std::cout << "Options:\n"; std::cout << " [-p PORT] Port to listen on (Default 5000)\n"; std::cout << " [-n NAME] Server name (Default \"proc-api\")\n"; + std::cout << " [-a PATH] Path to file containing authorization tokens\n"; + std::cout << " If the -a flag is not passed, no authorization is used\n"; std::cout << " [-h] Display this help message\n\n"; exit(1); } @@ -22,6 +24,7 @@ option_flags* parse_options(int argc, char** argv){ ret->port = 5000; ret->name = "proc-api"; + ret->auth_path = ""; while((c = getopt(argc, argv, optarg_string)) != -1){ switch(c){ @@ -31,6 +34,9 @@ option_flags* parse_options(int argc, char** argv){ case 'n': ret->name = std::string(optarg); break; + case 'a': + ret->auth_path = std::string(optarg); + break; case '?': std::cerr << "Unkown option: " << (char)optopt << "\n"; case 'h': diff --git a/src/opt/parseopt.hpp b/src/opt/parseopt.hpp index 3994c46..53beb6f 100644 --- a/src/opt/parseopt.hpp +++ b/src/opt/parseopt.hpp @@ -12,11 +12,12 @@ /////////////////////////////////////// // cli options -constexpr char optarg_string[] = "n:p:h"; +constexpr char optarg_string[] = "n:p:a:h"; struct option_flags { uint16_t port; std::string name; + std::string auth_path; }; void help(char*); diff --git a/src/routes.cpp b/src/routes.cpp index 50101c5..5df8bbe 100644 --- a/src/routes.cpp +++ b/src/routes.cpp @@ -8,6 +8,9 @@ void setRoutes(crow::SimpleApp& app){ CROW_ROUTE(app, "/proc/meminfo")([](const crow::request& req){ + if(!auth::checkAuth(req)) + return crow::response(403, "Authentication required"); + bool status; std::string accept = req.get_header_value("Accept"); @@ -24,7 +27,9 @@ void setRoutes(crow::SimpleApp& app){ } }); - CROW_ROUTE(app, "/mem")([](){ + CROW_ROUTE(app, "/mem")([](const crow::request& req){ + if(!auth::checkAuth(req)) + return crow::response(403, "Authentication required"); bool status; crow::json::wvalue json; @@ -34,6 +39,8 @@ void setRoutes(crow::SimpleApp& app){ }); CROW_ROUTE(app, "/proc/uptime")([](const crow::request& req){ + if(!auth::checkAuth(req)) + return crow::response(403, "Authentication required"); bool status; std::string accept = req.get_header_value("Accept"); @@ -50,13 +57,17 @@ void setRoutes(crow::SimpleApp& app){ } }); - CROW_ROUTE(app, "/uptime")([](){ + CROW_ROUTE(app, "/uptime")([](const crow::request& req){ + if(!auth::checkAuth(req)) + return crow::response(403, "Authentication required"); crow::response ret; ret.moved_perm("/proc/uptime"); return ret; }); CROW_ROUTE(app, "/proc/loadavg")([](const crow::request& req){ + if(!auth::checkAuth(req)) + return crow::response(403, "Authentication required"); bool status; std::string accept = req.get_header_value("Accept"); @@ -73,13 +84,17 @@ void setRoutes(crow::SimpleApp& app){ } }); - CROW_ROUTE(app, "/load")([](){ + CROW_ROUTE(app, "/load")([](const crow::request& req){ + if(!auth::checkAuth(req)) + return crow::response(403, "Authentication required"); crow::response ret; ret.moved_perm("/proc/loadavg"); return ret; }); CROW_ROUTE(app, "/proc/sys/kernel/hostname")([](const crow::request& req){ + if(!auth::checkAuth(req)) + return crow::response(403, "Authentication required"); bool status; std::string accept = req.get_header_value("Accept"); @@ -96,20 +111,27 @@ void setRoutes(crow::SimpleApp& app){ } }); - CROW_ROUTE(app, "/hostname")([](){ + CROW_ROUTE(app, "/hostname")([](const crow::request& req){ + if(!auth::checkAuth(req)) + return crow::response(403, "Authentication required"); crow::response ret; ret.moved_perm("/proc/sys/kernel/hostname"); return ret; }); - CROW_ROUTE(app, "/up")([](){ + CROW_ROUTE(app, "/up")([](const crow::request& req){ + if(!auth::checkAuth(req)) + return crow::response(403, "Authentication required"); + crow::json::wvalue ret; ret["message"] = "Alive and well!"; - return ret; + return crow::response(200, ret.dump()); }); //catchall route - CROW_CATCHALL_ROUTE(app)([](){ + CROW_CATCHALL_ROUTE(app)([](const crow::request& req){ + if(!auth::checkAuth(req)) + return crow::response(403, "Authentication required"); crow::json::wvalue ret; ret["message"] = "Route not understood. Please refer to the documentation"; diff --git a/src/routes.hpp b/src/routes.hpp index 6e68bb2..8563b61 100644 --- a/src/routes.hpp +++ b/src/routes.hpp @@ -13,4 +13,6 @@ #include "components/memory.hpp" #include "components/state.hpp" +#include "auth/auth.hpp" + void setRoutes(crow::SimpleApp&);