summaryrefslogtreecommitdiffhomepage
path: root/response.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-05-29 11:31:40 +0200
committerRoland Reichwein <mail@reichwein.it>2020-05-29 11:31:40 +0200
commite0451ef59a69eda29efa6bc22294b2bcf8b8b600 (patch)
treedc80766930ca36ef5394b648b3658d41c1cd0abc /response.cpp
parentf1f4cbd996aa00b6e4d3d04d0223d02fd553dd96 (diff)
Authentication infrastructure
Diffstat (limited to 'response.cpp')
-rw-r--r--response.cpp81
1 files changed, 51 insertions, 30 deletions
diff --git a/response.cpp b/response.cpp
index 5f4f3f2..9ee1977 100644
--- a/response.cpp
+++ b/response.cpp
@@ -69,7 +69,39 @@ public:
Server& GetServer() const {return m_server; }
const Socket& GetSocket() const {return m_server.GetSocket(); }
-};
+
+ // Returns error message, empty on auth success
+ std::string isAuthenticated()
+ {
+ auto& auth{m_path.auth};
+ if (auth.size() != 0) {
+ std::string authorization{m_req[http::field::authorization]};
+ if (authorization.substr(0, 6) != "Basic "s) {
+ return "Bad Authorization Type";
+ }
+
+ authorization = authorization.substr(6);
+ authorization = decode64(authorization);
+
+ size_t pos {authorization.find(':')};
+ if (pos == authorization.npos)
+ return "Bad Authorization Encoding";
+
+ std::string login{authorization.substr(0, pos)};
+ std::string password{authorization.substr(pos + 1)};
+
+ auto it {auth.find(login)};
+ // it.second contains crypted/hash
+ // password is plain text to validate against the hash
+ if (it == auth.end() || !Auth::validate(it->second, password)) {
+ return "Bad Authorization";
+ }
+ }
+
+ return "";
+ }
+
+}; // class RequestContext
std::string extend_index_html(std::string path)
{
@@ -106,6 +138,8 @@ std::string GetServerParam(const std::string& key, Server& server)
std::unordered_map<std::string, std::function<std::string(RequestContext&)>> GetRequestParamFunctions{
// following are the supported fields:
{"authorization", [](RequestContext& req_ctx) { return std::string{req_ctx.GetReq()[http::field::authorization]}; }},
+
+ {"is_authenticated", [](RequestContext& req_ctx) { return req_ctx.isAuthenticated() == ""s ? "1"s : "0"s;}},
{"body", [](RequestContext& req_ctx) { return req_ctx.GetReq().body(); }},
@@ -232,6 +266,19 @@ response_type HttpStatusAndStats(std::string status, std::string message, Reques
return std::move(res);
}
+response_type handleAuth(RequestContext& req_ctx, response_type& res)
+{
+ if (req_ctx.GetPlugin()->has_own_authentication() == false) {
+ std::string message { req_ctx.isAuthenticated() };
+ if (message != "") {
+ res.set(http::field::www_authenticate, "Basic realm=\"Reichwein.IT Webserver Login\"");
+ return HttpStatusAndStats("401", message, req_ctx, res);
+ }
+ }
+
+ return std::move(res);
+}
+
} // anonymous namespace
response_type generate_response(request_type& req, Server& server)
@@ -244,35 +291,9 @@ response_type generate_response(request_type& req, Server& server)
try {
RequestContext req_ctx{req, server}; // can throw std::out_of_range
- auto& auth{req_ctx.GetPath().auth};
- if (auth.size() != 0) {
- std::string authorization{req[http::field::authorization]};
- if (authorization.substr(0, 6) != "Basic "s)
- return HttpStatusAndStats("401", "Bad Authorization Type", req_ctx, res);
-
- authorization = authorization.substr(6);
- authorization = decode64(authorization);
-
- size_t pos {authorization.find(':')};
- if (pos == authorization.npos)
- return HttpStatusAndStats("401", "Bad Authorization Encoding", req_ctx, res);
-
- std::string login{authorization.substr(0, pos)};
- std::string password{authorization.substr(pos + 1)};
-
- auto it {auth.find(login)};
- // it.second contains crypted/hash
- // password is plain text to validate against the hash
- if (it == auth.end() || !Auth::validate(it->second, password)) {
-
- // For now, WWW-Authenticate: Basic realm="..." will only be generated for static-files.
- // All other plugins are expected to present their own login pages
- if (req_ctx.GetPluginName() == "static-files")
- res.set(http::field::www_authenticate, "Basic realm=\"Reichwein.IT Webserver Login\"");
-
- return HttpStatusAndStats("401", "Bad Authorization", req_ctx, res);
- }
- }
+ res = handleAuth(req_ctx, res);
+ if (res.result_int() / 100 == 4) // status 4xx
+ return res;
plugin_type plugin{req_ctx.GetPlugin()};