diff --git a/src/webfuse/ws/server_handler.cpp b/src/webfuse/ws/server_handler.cpp index c56216c..a6ae89c 100644 --- a/src/webfuse/ws/server_handler.cpp +++ b/src/webfuse/ws/server_handler.cpp @@ -1,8 +1,11 @@ #include "webfuse/ws/server_handler.hpp" #include "webfuse/util/authenticator.hpp" +#include +#include #include + namespace { std::string get_auth_token_of_known_header(lws * wsi, lws_token_indexes header) @@ -48,6 +51,7 @@ namespace webfuse server_handler::server_handler(std::string const & auth_app, std::string const & auth_hdr) : connection(nullptr) , id(0) +, is_authenticated(false) , authenticator(auth_app) , auth_header(auth_hdr) { @@ -146,6 +150,7 @@ void server_handler::on_closed(lws * wsi) if (wsi == connection) { connection = nullptr; + is_authenticated = false; } } @@ -169,17 +174,28 @@ void server_handler::poll() std::future server_handler::perform(messagewriter writer) { - std::future result; + std::promise p; + std::future result = p.get_future(); + if (is_authenticated) { - std::promise p; - result = p.get_future(); - std::lock_guard lock(mut); uint32_t id = next_id(); writer.set_id(id); requests.emplace(std::move(writer)); pending_responses.emplace(id, std::move(p)); } + else + { + try + { + throw std::runtime_error("unauthenticated"); + } + catch(std::exception const &ex) + { + p.set_exception(std::current_exception()); + } + + } return result; @@ -188,21 +204,32 @@ std::future server_handler::perform(messagewriter writer) int server_handler::authenticate_via_header(lws * wsi) { - int result = 0; - if ((!authenticator.empty()) && (!auth_header.empty())) + // authentication is disabled + if (authenticator.empty()) { - std::string token = get_auth_token(wsi); - if (!token.empty()) - { - webfuse::authenticator auth(authenticator); - result = auth.authenticate(token) ? 0 : -1; - } - else - { - result = -1; - } + is_authenticated = true; + return 0; + } + + // authentication is enabled, but not via HTTP header + if (auth_header.empty()) + { + is_authenticated = false; + return 0; + } + + // delay authentication if HTTP header is not provided + std::string token = get_auth_token(wsi); + if (token.empty()) + { + is_authenticated = false; + return 0; } + // close connection, when authentication fails + webfuse::authenticator auth(authenticator); + int const result = auth.authenticate(token) ? 0 : -1; + is_authenticated = (result == 0); return result; } diff --git a/src/webfuse/ws/server_handler.hpp b/src/webfuse/ws/server_handler.hpp index bfc21d0..d8a3249 100644 --- a/src/webfuse/ws/server_handler.hpp +++ b/src/webfuse/ws/server_handler.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace webfuse { @@ -38,6 +39,7 @@ private: struct lws * connection; uint32_t id; + std::atomic is_authenticated; std::string authenticator; std::string auth_header;