Add authorization

This commit is contained in:
Tyler Perkins 2022-04-29 16:26:29 -04:00
parent 0a9af99427
commit ab9010d945
7 changed files with 115 additions and 8 deletions

37
src/auth/auth.cpp Normal file
View File

@ -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;
}

31
src/auth/auth.hpp Normal file
View File

@ -0,0 +1,31 @@
///////////////////////////////////////////////////////////////////////////////
// Tyler Perkins
// 29-4-22
// Auth definition
//
#pragma once
#include <crow.h>
#include <unordered_set>
#include <string>
#include <fstream>
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<std::string> tokens;
};
bool checkAuth(const crow::request&);
}

View File

@ -7,6 +7,9 @@
#include <iostream> #include <iostream>
#include <crow.h> #include <crow.h>
#include "opt/parseopt.hpp" #include "opt/parseopt.hpp"
#include "auth/auth.hpp"
auth::auth_check* auth::auth_check::checker;
#include "routes.hpp" #include "routes.hpp"
@ -14,6 +17,11 @@ int main(int argc, char** argv){
option_flags* flags = parse_options(argc, 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; crow::SimpleApp app;
setRoutes(app); setRoutes(app);

View File

@ -11,6 +11,8 @@ void help(char* progName){
std::cout << "Options:\n"; std::cout << "Options:\n";
std::cout << " [-p PORT] Port to listen on (Default 5000)\n"; std::cout << " [-p PORT] Port to listen on (Default 5000)\n";
std::cout << " [-n NAME] Server name (Default \"proc-api\")\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"; std::cout << " [-h] Display this help message\n\n";
exit(1); exit(1);
} }
@ -22,6 +24,7 @@ option_flags* parse_options(int argc, char** argv){
ret->port = 5000; ret->port = 5000;
ret->name = "proc-api"; ret->name = "proc-api";
ret->auth_path = "";
while((c = getopt(argc, argv, optarg_string)) != -1){ while((c = getopt(argc, argv, optarg_string)) != -1){
switch(c){ switch(c){
@ -31,6 +34,9 @@ option_flags* parse_options(int argc, char** argv){
case 'n': case 'n':
ret->name = std::string(optarg); ret->name = std::string(optarg);
break; break;
case 'a':
ret->auth_path = std::string(optarg);
break;
case '?': case '?':
std::cerr << "Unkown option: " << (char)optopt << "\n"; std::cerr << "Unkown option: " << (char)optopt << "\n";
case 'h': case 'h':

View File

@ -12,11 +12,12 @@
/////////////////////////////////////// ///////////////////////////////////////
// cli options // cli options
constexpr char optarg_string[] = "n:p:h"; constexpr char optarg_string[] = "n:p:a:h";
struct option_flags { struct option_flags {
uint16_t port; uint16_t port;
std::string name; std::string name;
std::string auth_path;
}; };
void help(char*); void help(char*);

View File

@ -8,6 +8,9 @@
void setRoutes(crow::SimpleApp& app){ void setRoutes(crow::SimpleApp& app){
CROW_ROUTE(app, "/proc/meminfo")([](const crow::request& req){ CROW_ROUTE(app, "/proc/meminfo")([](const crow::request& req){
if(!auth::checkAuth(req))
return crow::response(403, "Authentication required");
bool status; bool status;
std::string accept = req.get_header_value("Accept"); 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; bool status;
crow::json::wvalue json; crow::json::wvalue json;
@ -34,6 +39,8 @@ void setRoutes(crow::SimpleApp& app){
}); });
CROW_ROUTE(app, "/proc/uptime")([](const crow::request& req){ CROW_ROUTE(app, "/proc/uptime")([](const crow::request& req){
if(!auth::checkAuth(req))
return crow::response(403, "Authentication required");
bool status; bool status;
std::string accept = req.get_header_value("Accept"); 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; crow::response ret;
ret.moved_perm("/proc/uptime"); ret.moved_perm("/proc/uptime");
return ret; return ret;
}); });
CROW_ROUTE(app, "/proc/loadavg")([](const crow::request& req){ CROW_ROUTE(app, "/proc/loadavg")([](const crow::request& req){
if(!auth::checkAuth(req))
return crow::response(403, "Authentication required");
bool status; bool status;
std::string accept = req.get_header_value("Accept"); 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; crow::response ret;
ret.moved_perm("/proc/loadavg"); ret.moved_perm("/proc/loadavg");
return ret; return ret;
}); });
CROW_ROUTE(app, "/proc/sys/kernel/hostname")([](const crow::request& req){ CROW_ROUTE(app, "/proc/sys/kernel/hostname")([](const crow::request& req){
if(!auth::checkAuth(req))
return crow::response(403, "Authentication required");
bool status; bool status;
std::string accept = req.get_header_value("Accept"); 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; crow::response ret;
ret.moved_perm("/proc/sys/kernel/hostname"); ret.moved_perm("/proc/sys/kernel/hostname");
return ret; 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; crow::json::wvalue ret;
ret["message"] = "Alive and well!"; ret["message"] = "Alive and well!";
return ret; return crow::response(200, ret.dump());
}); });
//catchall route //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; crow::json::wvalue ret;
ret["message"] = "Route not understood. Please refer to the documentation"; ret["message"] = "Route not understood. Please refer to the documentation";

View File

@ -13,4 +13,6 @@
#include "components/memory.hpp" #include "components/memory.hpp"
#include "components/state.hpp" #include "components/state.hpp"
#include "auth/auth.hpp"
void setRoutes(crow::SimpleApp&); void setRoutes(crow::SimpleApp&);