summaryrefslogtreecommitdiffhomepage
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
parentf1f4cbd996aa00b6e4d3d04d0223d02fd553dd96 (diff)
Authentication infrastructure
-rw-r--r--debian/changelog8
-rw-r--r--plugin_interface.h3
-rw-r--r--plugins/cgi/cgi.cpp4
-rw-r--r--plugins/cgi/cgi.h6
-rw-r--r--plugins/fcgi/fcgi.cpp5
-rw-r--r--plugins/fcgi/fcgi.h6
-rw-r--r--plugins/redirect/redirect.cpp5
-rw-r--r--plugins/redirect/redirect.h7
-rw-r--r--plugins/static-files/static-files.cpp5
-rw-r--r--plugins/static-files/static-files.h5
-rw-r--r--plugins/statistics/statistics.cpp5
-rw-r--r--plugins/statistics/statistics.h5
-rw-r--r--plugins/webbox/webbox.cpp4
-rw-r--r--plugins/webbox/webbox.h8
-rw-r--r--plugins/weblog/weblog.cpp4
-rw-r--r--plugins/weblog/weblog.h6
-rw-r--r--response.cpp81
17 files changed, 122 insertions, 45 deletions
diff --git a/debian/changelog b/debian/changelog
index 23a6097..eb9a600 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+webserver (1.8) unstable; urgency=medium
+
+ * Automatically reopen broken fcgi sockets
+ * Fix empty fcgi stderr messages
+ * Authorization: Default HTTP AUTH, except for webbox with own login page
+
+ -- Roland Reichwein <rr@antcom.de> Fri, 29 May 2020 10:23:06 +0200
+
webserver (1.7) unstable; urgency=medium
* Omit PEM file reload. Access to files is denied because of dropped privileges.
diff --git a/plugin_interface.h b/plugin_interface.h
index c0a95b9..830c44c 100644
--- a/plugin_interface.h
+++ b/plugin_interface.h
@@ -27,6 +27,9 @@ public:
std::function<void(const std::string& key, const std::string& value)>& SetResponseHeader // to be added to result string
) = 0;
+ // Plugin provides own authentication mechanism? Otherwise, webserver makes HTTP AUTH via status 401
+ virtual bool has_own_authentication() = 0;
+
virtual ~webserver_plugin_interface(){} // optional
};
diff --git a/plugins/cgi/cgi.cpp b/plugins/cgi/cgi.cpp
index 480ae9e..131855e 100644
--- a/plugins/cgi/cgi.cpp
+++ b/plugins/cgi/cgi.cpp
@@ -290,3 +290,7 @@ std::string cgi_plugin::generate_page(
}
}
+bool cgi_plugin::has_own_authentication()
+{
+ return false;
+}
diff --git a/plugins/cgi/cgi.h b/plugins/cgi/cgi.h
index 467a6c4..5093901 100644
--- a/plugins/cgi/cgi.h
+++ b/plugins/cgi/cgi.h
@@ -8,12 +8,14 @@ public:
cgi_plugin();
~cgi_plugin();
- std::string name();
+ std::string name() override;
std::string generate_page(
std::function<std::string(const std::string& key)>& GetServerParam,
std::function<std::string(const std::string& key)>& GetRequestParam, // request including body (POST...)
std::function<void(const std::string& key, const std::string& value)>& SetResponseHeader // to be added to result string
- );
+ ) override;
+
+ bool has_own_authentication() override;
};
diff --git a/plugins/fcgi/fcgi.cpp b/plugins/fcgi/fcgi.cpp
index 6f4ad1f..22a4d40 100644
--- a/plugins/fcgi/fcgi.cpp
+++ b/plugins/fcgi/fcgi.cpp
@@ -538,3 +538,8 @@ std::string fcgi_plugin::generate_page(
}
}
+bool fcgi_plugin::has_own_authentication()
+{
+ return false;
+}
+
diff --git a/plugins/fcgi/fcgi.h b/plugins/fcgi/fcgi.h
index 289c4d6..167a356 100644
--- a/plugins/fcgi/fcgi.h
+++ b/plugins/fcgi/fcgi.h
@@ -41,12 +41,14 @@ public:
fcgi_plugin();
~fcgi_plugin();
- std::string name();
+ std::string name() override;
std::string generate_page(
std::function<std::string(const std::string& key)>& GetServerParam,
std::function<std::string(const std::string& key)>& GetRequestParam, // request including body (POST...)
std::function<void(const std::string& key, const std::string& value)>& SetResponseHeader // to be added to result string
- );
+ ) override;
+
+ bool has_own_authentication() override;
std::string fcgiQuery(FCGIContext& context);
};
diff --git a/plugins/redirect/redirect.cpp b/plugins/redirect/redirect.cpp
index 91d5f64..796926d 100644
--- a/plugins/redirect/redirect.cpp
+++ b/plugins/redirect/redirect.cpp
@@ -62,3 +62,8 @@ std::string redirect_plugin::generate_page(
}
}
+bool redirect_plugin::has_own_authentication()
+{
+ return false;
+}
+
diff --git a/plugins/redirect/redirect.h b/plugins/redirect/redirect.h
index 403cc16..472f9f2 100644
--- a/plugins/redirect/redirect.h
+++ b/plugins/redirect/redirect.h
@@ -8,13 +8,14 @@ public:
redirect_plugin();
~redirect_plugin();
- std::string name();
+ std::string name() override;
std::string generate_page(
std::function<std::string(const std::string& key)>& GetServerParam,
std::function<std::string(const std::string& key)>& GetRequestParam, // request including body (POST...)
std::function<void(const std::string& key, const std::string& value)>& SetResponseHeader // to be added to result string
- );
-
+ ) override;
+
+ bool has_own_authentication() override;
};
extern "C" BOOST_SYMBOL_EXPORT redirect_plugin webserver_plugin;
diff --git a/plugins/static-files/static-files.cpp b/plugins/static-files/static-files.cpp
index 345cf56..b2dcdca 100644
--- a/plugins/static-files/static-files.cpp
+++ b/plugins/static-files/static-files.cpp
@@ -115,3 +115,8 @@ std::string static_files_plugin::generate_page(
}
}
+bool static_files_plugin::has_own_authentication()
+{
+ return false;
+}
+
diff --git a/plugins/static-files/static-files.h b/plugins/static-files/static-files.h
index ff35e92..a119387 100644
--- a/plugins/static-files/static-files.h
+++ b/plugins/static-files/static-files.h
@@ -8,13 +8,14 @@ public:
static_files_plugin();
~static_files_plugin();
- std::string name();
+ std::string name() override;
std::string generate_page(
std::function<std::string(const std::string& key)>& GetServerParam,
std::function<std::string(const std::string& key)>& GetRequestParam, // request including body (POST...)
std::function<void(const std::string& key, const std::string& value)>& SetResponseHeader // to be added to result string
- );
+ ) override;
+ bool has_own_authentication() override;
};
extern "C" BOOST_SYMBOL_EXPORT static_files_plugin webserver_plugin;
diff --git a/plugins/statistics/statistics.cpp b/plugins/statistics/statistics.cpp
index 6d3899e..3ebd301 100644
--- a/plugins/statistics/statistics.cpp
+++ b/plugins/statistics/statistics.cpp
@@ -132,3 +132,8 @@ std::string statistics_plugin::generate_page(
}
}
+bool statistics_plugin::has_own_authentication()
+{
+ return false;
+}
+
diff --git a/plugins/statistics/statistics.h b/plugins/statistics/statistics.h
index 5db309b..e998643 100644
--- a/plugins/statistics/statistics.h
+++ b/plugins/statistics/statistics.h
@@ -8,13 +8,14 @@ public:
statistics_plugin();
~statistics_plugin();
- std::string name();
+ std::string name() override;
std::string generate_page(
std::function<std::string(const std::string& key)>& GetServerParam,
std::function<std::string(const std::string& key)>& GetRequestParam, // request including body (POST...)
std::function<void(const std::string& key, const std::string& value)>& SetResponseHeader // to be added to result string
- );
+ ) override;
+ bool has_own_authentication() override;
};
extern "C" BOOST_SYMBOL_EXPORT statistics_plugin webserver_plugin;
diff --git a/plugins/webbox/webbox.cpp b/plugins/webbox/webbox.cpp
index 09ac7c5..de8df85 100644
--- a/plugins/webbox/webbox.cpp
+++ b/plugins/webbox/webbox.cpp
@@ -943,3 +943,7 @@ void webbox_plugin::registerCommand(std::shared_ptr<Command> command)
m_commands[command->getCommandName()] = command;
};
+bool webbox_plugin::has_own_authentication()
+{
+ return true;
+}
diff --git a/plugins/webbox/webbox.h b/plugins/webbox/webbox.h
index dd2fb93..cd4e21d 100644
--- a/plugins/webbox/webbox.h
+++ b/plugins/webbox/webbox.h
@@ -18,12 +18,16 @@ private:
public:
webbox_plugin();
~webbox_plugin();
- std::string name();
+
+ std::string name() override;
+
std::string generate_page(
std::function<std::string(const std::string& key)>& GetServerParam,
std::function<std::string(const std::string& key)>& GetRequestParam, // request including body (POST...)
std::function<void(const std::string& key, const std::string& value)>& SetResponseHeader // to be added to result string
- );
+ ) override;
+
+ bool has_own_authentication() override;
};
extern "C" BOOST_SYMBOL_EXPORT webbox_plugin webserver_plugin;
diff --git a/plugins/weblog/weblog.cpp b/plugins/weblog/weblog.cpp
index c18f120..1e1b6b2 100644
--- a/plugins/weblog/weblog.cpp
+++ b/plugins/weblog/weblog.cpp
@@ -441,3 +441,7 @@ std::string weblog_plugin::generate_page(
}
}
+bool weblog_plugin::has_own_authentication()
+{
+ return false;
+}
diff --git a/plugins/weblog/weblog.h b/plugins/weblog/weblog.h
index 28b4ab3..0994b91 100644
--- a/plugins/weblog/weblog.h
+++ b/plugins/weblog/weblog.h
@@ -8,13 +8,15 @@ public:
weblog_plugin();
~weblog_plugin();
- std::string name();
+ std::string name() override;
+
std::string generate_page(
std::function<std::string(const std::string& key)>& GetServerParam,
std::function<std::string(const std::string& key)>& GetRequestParam, // request including body (POST...)
std::function<void(const std::string& key, const std::string& value)>& SetResponseHeader // to be added to result string
- );
+ ) override;
+ bool has_own_authentication() override;
};
extern "C" BOOST_SYMBOL_EXPORT weblog_plugin webserver_plugin;
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()};