summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Feist <james.feist@linux.intel.com>2020-04-03 20:58:55 +0300
committerJames Feist <james.feist@linux.intel.com>2020-07-16 04:02:55 +0300
commit3909dc82a003893812f598434d6c4558107afa28 (patch)
treeb5c39fbb7d66ad9134a4f0fcecaa12c9346c5752
parente7808c93f01081ca12e1b4769691b5ae673f9017 (diff)
downloadbmcweb-3909dc82a003893812f598434d6c4558107afa28.tar.xz
Rework Authorization flow
Currently we parse the whole message before authenticating, allowing an attacker the ability to upload a large image, or keep a connection open for the max amount of time easier than it should be. This moves the authentication to the earliest point possible, and restricts unauthenticated users timeouts and max upload sizes. It also makes it so that unauthenticated users cannot keep the connection alive forever by refusing to close the connection. Tested: - login/logout - firmware update - large POST when unauthenticated - timeouts when unauthenticated - slowhttptest Change-Id: Ifa02d8db04eac1821e8950eb85e71634a9e6d265 Signed-off-by: James Feist <james.feist@linux.intel.com>
-rw-r--r--http/http_connection.h138
-rw-r--r--http/timer_queue.h3
-rw-r--r--include/authorization.hpp267
-rw-r--r--include/login_routes.hpp (renamed from include/token_authorization_middleware.hpp)268
-rw-r--r--include/persistent_data_middleware.hpp2
-rw-r--r--include/redfish_v1.hpp1
-rw-r--r--include/webassets.hpp8
-rw-r--r--include/webroutes.hpp13
-rw-r--r--include/webserver_common.hpp5
-rw-r--r--redfish-core/include/node.hpp1
-rw-r--r--src/webserver_main.cpp4
11 files changed, 394 insertions, 316 deletions
diff --git a/http/http_connection.h b/http/http_connection.h
index 5f4681f2a4..c413990921 100644
--- a/http/http_connection.h
+++ b/http/http_connection.h
@@ -7,6 +7,7 @@
#include "timer_queue.h"
#include "utility.h"
+#include "authorization.hpp"
#include "http_utility.hpp"
#include <boost/algorithm/string.hpp>
@@ -248,6 +249,18 @@ static std::atomic<int> connectionCount;
constexpr unsigned int httpReqBodyLimit =
1024 * 1024 * BMCWEB_HTTP_REQ_BODY_LIMIT_MB;
+constexpr uint64_t loggedOutPostBodyLimit = 4096;
+
+constexpr uint32_t httpHeaderLimit = 8192;
+
+// drop all connections after 1 minute, this time limit was chosen
+// arbitrarily and can be adjusted later if needed
+static constexpr const size_t loggedInAttempts =
+ (60 / timerQueueTimeoutSeconds);
+
+static constexpr const size_t loggedOutAttempts =
+ (15 / timerQueueTimeoutSeconds);
+
template <typename Adaptor, typename Handler, typename... Middlewares>
class Connection :
public std::enable_shared_from_this<
@@ -265,10 +278,8 @@ class Connection :
timerQueue(timerQueueIn)
{
parser.emplace(std::piecewise_construct, std::make_tuple());
- // Temporarily set by the BMCWEB_HTTP_REQ_BODY_LIMIT_MB variable; Need
- // to modify uploading/authentication mechanism to a better method that
- // disallows a DOS attack based on a large file size.
parser->body_limit(httpReqBodyLimit);
+ parser->header_limit(httpHeaderLimit);
req.emplace(parser->get());
#ifdef BMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION
@@ -472,7 +483,7 @@ class Connection :
void start()
{
- startDeadline();
+ startDeadline(0);
// TODO(ed) Abstract this to a more clever class with the idea of an
// asynchronous "start"
if constexpr (std::is_same_v<Adaptor,
@@ -498,6 +509,7 @@ class Connection :
void handle()
{
cancelDeadlineTimer();
+
bool isInvalidRequest = false;
// Check for HTTP version 1.1.
@@ -647,6 +659,8 @@ class Connection :
decltype(ctx),
decltype(*middlewares)>(
*middlewares, ctx, *req, res);
+
+ crow::authorization::cleanupTempSession(*req);
}
if (!isAlive())
@@ -731,14 +745,21 @@ class Connection :
}
}
+ cancelDeadlineTimer();
+
if (errorWhileReading)
{
- cancelDeadlineTimer();
close();
BMCWEB_LOG_DEBUG << this << " from read(1)";
return;
}
+ if (!req)
+ {
+ close();
+ return;
+ }
+
// Compute the url parameters for the request
req->url = req->target();
std::size_t index = req->url.find("?");
@@ -746,7 +767,32 @@ class Connection :
{
req->url = req->url.substr(0, index);
}
- req->urlParams = QueryString(std::string(req->target()));
+ crow::authorization::authenticate(*req, res);
+
+ bool loggedIn = req && req->session;
+ if (loggedIn)
+ {
+ startDeadline(loggedInAttempts);
+ BMCWEB_LOG_DEBUG << "Starting slow deadline";
+
+ req->urlParams = QueryString(std::string(req->target()));
+ }
+ else
+ {
+ const boost::optional<uint64_t> contentLength =
+ parser->content_length();
+ if (contentLength &&
+ *contentLength > loggedOutPostBodyLimit)
+ {
+ BMCWEB_LOG_DEBUG << "Content length greater than limit "
+ << *contentLength;
+ close();
+ return;
+ }
+
+ startDeadline(loggedOutAttempts);
+ BMCWEB_LOG_DEBUG << "Starting quick deadline";
+ }
doRead();
});
}
@@ -772,7 +818,20 @@ class Connection :
}
else
{
- if (!isAlive())
+ if (isAlive())
+ {
+ cancelDeadlineTimer();
+ bool loggedIn = req && req->session;
+ if (loggedIn)
+ {
+ startDeadline(loggedInAttempts);
+ }
+ else
+ {
+ startDeadline(loggedOutAttempts);
+ }
+ }
+ else
{
errorWhileReading = true;
}
@@ -790,6 +849,15 @@ class Connection :
void doWrite()
{
+ bool loggedIn = req && req->session;
+ if (loggedIn)
+ {
+ startDeadline(loggedInAttempts);
+ }
+ else
+ {
+ startDeadline(loggedOutAttempts);
+ }
BMCWEB_LOG_DEBUG << this << " doWrite";
res.preparePayload();
serializer.emplace(*res.stringResponse);
@@ -817,8 +885,6 @@ class Connection :
BMCWEB_LOG_DEBUG << this << " Clearing response";
res.clear();
parser.emplace(std::piecewise_construct, std::make_tuple());
- parser->body_limit(httpReqBodyLimit); // reset body limit for
- // newly created parser
buffer.consume(buffer.size());
req.emplace(parser->get());
@@ -837,39 +903,37 @@ class Connection :
}
}
- void startDeadline(size_t timerIterations = 0)
+ void startDeadline(size_t timerIterations)
{
- // drop all connections after 1 minute, this time limit was chosen
- // arbitrarily and can be adjusted later if needed
- constexpr const size_t maxReadAttempts =
- (60 / detail::timerQueueTimeoutSeconds);
-
cancelDeadlineTimer();
- timerCancelKey = timerQueue.add([this, self(shared_from_this()),
- readCount{parser->get().body().size()},
- timerIterations{timerIterations + 1}] {
- // Mark timer as not active to avoid canceling it during
- // Connection destructor which leads to double free issue
- timerCancelKey.reset();
- if (!isAlive())
- {
- return;
- }
+ if (timerIterations)
+ {
+ timerIterations--;
+ }
- // Restart timer if read is in progress.
- // With threshold can be used to drop slow connections
- // to protect against slow-rate DoS attack
- if ((parser->get().body().size() > readCount) &&
- (timerIterations < maxReadAttempts))
- {
- BMCWEB_LOG_DEBUG << this << " restart timer - read in progress";
- startDeadline(timerIterations);
- return;
- }
+ timerCancelKey =
+ timerQueue.add([self(shared_from_this()), timerIterations] {
+ // Mark timer as not active to avoid canceling it during
+ // Connection destructor which leads to double free issue
+ self->timerCancelKey.reset();
+ if (!self->isAlive())
+ {
+ return;
+ }
- close();
- });
+ // Threshold can be used to drop slow connections
+ // to protect against slow-rate DoS attack
+ if (timerIterations)
+ {
+ BMCWEB_LOG_DEBUG << self.get()
+ << " restart timer - read in progress";
+ self->startDeadline(timerIterations);
+ return;
+ }
+
+ self->close();
+ });
if (!timerCancelKey)
{
diff --git a/http/timer_queue.h b/http/timer_queue.h
index d83cd0e229..85791eab89 100644
--- a/http/timer_queue.h
+++ b/http/timer_queue.h
@@ -10,10 +10,11 @@
namespace crow
{
+
+constexpr const size_t timerQueueTimeoutSeconds = 5;
namespace detail
{
-constexpr const size_t timerQueueTimeoutSeconds = 5;
constexpr const size_t maxSize = 100;
// fast timer queue for fixed tick value.
class TimerQueue
diff --git a/include/authorization.hpp b/include/authorization.hpp
new file mode 100644
index 0000000000..9074377b83
--- /dev/null
+++ b/include/authorization.hpp
@@ -0,0 +1,267 @@
+#pragma once
+
+#include "webroutes.hpp"
+
+#include <app.h>
+#include <common.h>
+#include <http_request.h>
+#include <http_response.h>
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/container/flat_set.hpp>
+#include <http_utility.hpp>
+#include <pam_authenticate.hpp>
+#include <persistent_data_middleware.hpp>
+
+#include <random>
+
+namespace crow
+{
+
+namespace authorization
+{
+
+static void cleanupTempSession(Request& req)
+{
+ // TODO(ed) THis should really be handled by the persistent data
+ // middleware, but because it is upstream, it doesn't have access to the
+ // session information. Should the data middleware persist the current
+ // user session?
+ if (req.session != nullptr &&
+ req.session->persistence ==
+ crow::persistent_data::PersistenceType::SINGLE_REQUEST)
+ {
+ persistent_data::SessionStore::getInstance().removeSession(req.session);
+ }
+}
+
+static const std::shared_ptr<crow::persistent_data::UserSession>
+ performBasicAuth(std::string_view auth_header)
+{
+ BMCWEB_LOG_DEBUG << "[AuthMiddleware] Basic authentication";
+
+ std::string authData;
+ std::string_view param = auth_header.substr(strlen("Basic "));
+ if (!crow::utility::base64Decode(param, authData))
+ {
+ return nullptr;
+ }
+ std::size_t separator = authData.find(':');
+ if (separator == std::string::npos)
+ {
+ return nullptr;
+ }
+
+ std::string user = authData.substr(0, separator);
+ separator += 1;
+ if (separator > authData.size())
+ {
+ return nullptr;
+ }
+ std::string pass = authData.substr(separator);
+
+ BMCWEB_LOG_DEBUG << "[AuthMiddleware] Authenticating user: " << user;
+
+ int pamrc = pamAuthenticateUser(user, pass);
+ bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
+ if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
+ {
+ return nullptr;
+ }
+
+ // TODO(ed) generateUserSession is a little expensive for basic
+ // auth, as it generates some random identifiers that will never be
+ // used. This should have a "fast" path for when user tokens aren't
+ // needed.
+ // This whole flow needs to be revisited anyway, as we can't be
+ // calling directly into pam for every request
+ return persistent_data::SessionStore::getInstance().generateUserSession(
+ user, crow::persistent_data::PersistenceType::SINGLE_REQUEST,
+ isConfigureSelfOnly);
+}
+
+static const std::shared_ptr<crow::persistent_data::UserSession>
+ performTokenAuth(std::string_view auth_header)
+{
+ BMCWEB_LOG_DEBUG << "[AuthMiddleware] Token authentication";
+
+ std::string_view token = auth_header.substr(strlen("Token "));
+ auto session =
+ persistent_data::SessionStore::getInstance().loginSessionByToken(token);
+ return session;
+}
+
+static const std::shared_ptr<crow::persistent_data::UserSession>
+ performXtokenAuth(const crow::Request& req)
+{
+ BMCWEB_LOG_DEBUG << "[AuthMiddleware] X-Auth-Token authentication";
+
+ std::string_view token = req.getHeaderValue("X-Auth-Token");
+ if (token.empty())
+ {
+ return nullptr;
+ }
+ auto session =
+ persistent_data::SessionStore::getInstance().loginSessionByToken(token);
+ return session;
+}
+
+static const std::shared_ptr<crow::persistent_data::UserSession>
+ performCookieAuth(const crow::Request& req)
+{
+ BMCWEB_LOG_DEBUG << "[AuthMiddleware] Cookie authentication";
+
+ std::string_view cookieValue = req.getHeaderValue("Cookie");
+ if (cookieValue.empty())
+ {
+ return nullptr;
+ }
+
+ auto startIndex = cookieValue.find("SESSION=");
+ if (startIndex == std::string::npos)
+ {
+ return nullptr;
+ }
+ startIndex += sizeof("SESSION=") - 1;
+ auto endIndex = cookieValue.find(";", startIndex);
+ if (endIndex == std::string::npos)
+ {
+ endIndex = cookieValue.size();
+ }
+ std::string_view authKey =
+ cookieValue.substr(startIndex, endIndex - startIndex);
+
+ const std::shared_ptr<crow::persistent_data::UserSession> session =
+ persistent_data::SessionStore::getInstance().loginSessionByToken(
+ authKey);
+ if (session == nullptr)
+ {
+ return nullptr;
+ }
+#ifndef BMCWEB_INSECURE_DISABLE_CSRF_PREVENTION
+ // RFC7231 defines methods that need csrf protection
+ if (req.method() != "GET"_method)
+ {
+ std::string_view csrf = req.getHeaderValue("X-XSRF-TOKEN");
+ // Make sure both tokens are filled
+ if (csrf.empty() || session->csrfToken.empty())
+ {
+ return nullptr;
+ }
+
+ if (csrf.size() != crow::persistent_data::sessionTokenSize)
+ {
+ return nullptr;
+ }
+ // Reject if csrf token not available
+ if (!crow::utility::constantTimeStringCompare(csrf, session->csrfToken))
+ {
+ return nullptr;
+ }
+ }
+#endif
+ return session;
+}
+
+// checks if request can be forwarded without authentication
+static bool isOnWhitelist(const crow::Request& req)
+{
+ // it's allowed to GET root node without authentication
+ if ("GET"_method == req.method())
+ {
+ if (req.url == "/redfish/v1" || req.url == "/redfish/v1/" ||
+ req.url == "/redfish" || req.url == "/redfish/" ||
+ req.url == "/redfish/v1/odata" || req.url == "/redfish/v1/odata/")
+ {
+ return true;
+ }
+ else if (crow::webroutes::routes.find(std::string(req.url)) !=
+ crow::webroutes::routes.end())
+ {
+ return true;
+ }
+ }
+
+ // it's allowed to POST on session collection & login without
+ // authentication
+ if ("POST"_method == req.method())
+ {
+ if ((req.url == "/redfish/v1/SessionService/Sessions") ||
+ (req.url == "/redfish/v1/SessionService/Sessions/") ||
+ (req.url == "/login"))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void authenticate(crow::Request& req, Response& res)
+{
+ if (isOnWhitelist(req))
+ {
+ return;
+ }
+
+ const crow::persistent_data::AuthConfigMethods& authMethodsConfig =
+ crow::persistent_data::SessionStore::getInstance()
+ .getAuthMethodsConfig();
+
+ if (req.session == nullptr && authMethodsConfig.xtoken)
+ {
+ req.session = performXtokenAuth(req);
+ }
+ if (req.session == nullptr && authMethodsConfig.cookie)
+ {
+ req.session = performCookieAuth(req);
+ }
+ if (req.session == nullptr)
+ {
+ std::string_view authHeader = req.getHeaderValue("Authorization");
+ if (!authHeader.empty())
+ {
+ // Reject any kind of auth other than basic or token
+ if (boost::starts_with(authHeader, "Token ") &&
+ authMethodsConfig.sessionToken)
+ {
+ req.session = performTokenAuth(authHeader);
+ }
+ else if (boost::starts_with(authHeader, "Basic ") &&
+ authMethodsConfig.basic)
+ {
+ req.session = performBasicAuth(authHeader);
+ }
+ }
+ }
+
+ if (req.session == nullptr)
+ {
+ BMCWEB_LOG_WARNING << "[AuthMiddleware] authorization failed";
+
+ // If it's a browser connecting, don't send the HTTP authenticate
+ // header, to avoid possible CSRF attacks with basic auth
+ if (http_helpers::requestPrefersHtml(req))
+ {
+ res.result(boost::beast::http::status::temporary_redirect);
+ res.addHeader("Location",
+ "/#/login?next=" + http_helpers::urlEncode(req.url));
+ }
+ else
+ {
+ res.result(boost::beast::http::status::unauthorized);
+ // only send the WWW-authenticate header if this isn't a xhr
+ // from the browser. most scripts,
+ if (req.getHeaderValue("User-Agent").empty())
+ {
+ res.addHeader("WWW-Authenticate", "Basic");
+ }
+ }
+
+ res.end();
+ return;
+ }
+}
+
+} // namespace authorization
+} // namespace crow
diff --git a/include/token_authorization_middleware.hpp b/include/login_routes.hpp
index a455926851..346ab89de8 100644
--- a/include/token_authorization_middleware.hpp
+++ b/include/login_routes.hpp
@@ -15,273 +15,9 @@
namespace crow
{
-namespace token_authorization
+namespace login_routes
{
-class Middleware
-{
- public:
- struct Context
- {};
-
- void beforeHandle(crow::Request& req, Response& res, Context& ctx)
- {
- if (isOnWhitelist(req))
- {
- return;
- }
-
- const crow::persistent_data::AuthConfigMethods& authMethodsConfig =
- crow::persistent_data::SessionStore::getInstance()
- .getAuthMethodsConfig();
-
- if (req.session == nullptr && authMethodsConfig.xtoken)
- {
- req.session = performXtokenAuth(req);
- }
- if (req.session == nullptr && authMethodsConfig.cookie)
- {
- req.session = performCookieAuth(req);
- }
- if (req.session == nullptr)
- {
- std::string_view authHeader = req.getHeaderValue("Authorization");
- if (!authHeader.empty())
- {
- // Reject any kind of auth other than basic or token
- if (boost::starts_with(authHeader, "Token ") &&
- authMethodsConfig.sessionToken)
- {
- req.session = performTokenAuth(authHeader);
- }
- else if (boost::starts_with(authHeader, "Basic ") &&
- authMethodsConfig.basic)
- {
- req.session = performBasicAuth(authHeader);
- }
- }
- }
-
- if (req.session == nullptr)
- {
- BMCWEB_LOG_WARNING << "[AuthMiddleware] authorization failed";
-
- // If it's a browser connecting, don't send the HTTP authenticate
- // header, to avoid possible CSRF attacks with basic auth
- if (http_helpers::requestPrefersHtml(req))
- {
- res.result(boost::beast::http::status::temporary_redirect);
- res.addHeader("Location", "/#/login?next=" +
- http_helpers::urlEncode(req.url));
- }
- else
- {
- res.result(boost::beast::http::status::unauthorized);
- // only send the WWW-authenticate header if this isn't a xhr
- // from the browser. most scripts,
- if (req.getHeaderValue("User-Agent").empty())
- {
- res.addHeader("WWW-Authenticate", "Basic");
- }
- }
-
- res.end();
- return;
- }
-
- // TODO get user privileges here and propagate it via MW Context
- // else let the request continue unharmed
- }
-
- template <typename AllContext>
- void afterHandle(Request& req, Response& res, Context& ctx,
- AllContext& allctx)
- {
- // TODO(ed) THis should really be handled by the persistent data
- // middleware, but because it is upstream, it doesn't have access to the
- // session information. Should the data middleware persist the current
- // user session?
- if (req.session != nullptr &&
- req.session->persistence ==
- crow::persistent_data::PersistenceType::SINGLE_REQUEST)
- {
- persistent_data::SessionStore::getInstance().removeSession(
- req.session);
- }
- }
-
- private:
- const std::shared_ptr<crow::persistent_data::UserSession>
- performBasicAuth(std::string_view auth_header) const
- {
- BMCWEB_LOG_DEBUG << "[AuthMiddleware] Basic authentication";
-
- std::string authData;
- std::string_view param = auth_header.substr(strlen("Basic "));
- if (!crow::utility::base64Decode(param, authData))
- {
- return nullptr;
- }
- std::size_t separator = authData.find(':');
- if (separator == std::string::npos)
- {
- return nullptr;
- }
-
- std::string user = authData.substr(0, separator);
- separator += 1;
- if (separator > authData.size())
- {
- return nullptr;
- }
- std::string pass = authData.substr(separator);
-
- BMCWEB_LOG_DEBUG << "[AuthMiddleware] Authenticating user: " << user;
-
- int pamrc = pamAuthenticateUser(user, pass);
- bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
- if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
- {
- return nullptr;
- }
-
- // TODO(ed) generateUserSession is a little expensive for basic
- // auth, as it generates some random identifiers that will never be
- // used. This should have a "fast" path for when user tokens aren't
- // needed.
- // This whole flow needs to be revisited anyway, as we can't be
- // calling directly into pam for every request
- return persistent_data::SessionStore::getInstance().generateUserSession(
- user, crow::persistent_data::PersistenceType::SINGLE_REQUEST,
- isConfigureSelfOnly);
- }
-
- const std::shared_ptr<crow::persistent_data::UserSession>
- performTokenAuth(std::string_view auth_header) const
- {
- BMCWEB_LOG_DEBUG << "[AuthMiddleware] Token authentication";
-
- std::string_view token = auth_header.substr(strlen("Token "));
- auto session =
- persistent_data::SessionStore::getInstance().loginSessionByToken(
- token);
- return session;
- }
-
- const std::shared_ptr<crow::persistent_data::UserSession>
- performXtokenAuth(const crow::Request& req) const
- {
- BMCWEB_LOG_DEBUG << "[AuthMiddleware] X-Auth-Token authentication";
-
- std::string_view token = req.getHeaderValue("X-Auth-Token");
- if (token.empty())
- {
- return nullptr;
- }
- auto session =
- persistent_data::SessionStore::getInstance().loginSessionByToken(
- token);
- return session;
- }
-
- const std::shared_ptr<crow::persistent_data::UserSession>
- performCookieAuth(const crow::Request& req) const
- {
- BMCWEB_LOG_DEBUG << "[AuthMiddleware] Cookie authentication";
-
- std::string_view cookieValue = req.getHeaderValue("Cookie");
- if (cookieValue.empty())
- {
- return nullptr;
- }
-
- auto startIndex = cookieValue.find("SESSION=");
- if (startIndex == std::string::npos)
- {
- return nullptr;
- }
- startIndex += sizeof("SESSION=") - 1;
- auto endIndex = cookieValue.find(";", startIndex);
- if (endIndex == std::string::npos)
- {
- endIndex = cookieValue.size();
- }
- std::string_view authKey =
- cookieValue.substr(startIndex, endIndex - startIndex);
-
- const std::shared_ptr<crow::persistent_data::UserSession> session =
- persistent_data::SessionStore::getInstance().loginSessionByToken(
- authKey);
- if (session == nullptr)
- {
- return nullptr;
- }
-#ifndef BMCWEB_INSECURE_DISABLE_CSRF_PREVENTION
- // RFC7231 defines methods that need csrf protection
- if (req.method() != "GET"_method)
- {
- std::string_view csrf = req.getHeaderValue("X-XSRF-TOKEN");
- // Make sure both tokens are filled
- if (csrf.empty() || session->csrfToken.empty())
- {
- return nullptr;
- }
-
- if (csrf.size() != crow::persistent_data::sessionTokenSize)
- {
- return nullptr;
- }
- // Reject if csrf token not available
- if (!crow::utility::constantTimeStringCompare(csrf,
- session->csrfToken))
- {
- return nullptr;
- }
- }
-#endif
- session->cookieAuth = true;
- return session;
- }
-
- // checks if request can be forwarded without authentication
- bool isOnWhitelist(const crow::Request& req) const
- {
- // it's allowed to GET root node without authentica tion
- if ("GET"_method == req.method())
- {
- if (req.url == "/redfish/v1" || req.url == "/redfish/v1/" ||
- req.url == "/redfish" || req.url == "/redfish/" ||
- req.url == "/redfish/v1/odata" ||
- req.url == "/redfish/v1/odata/")
- {
- return true;
- }
- else if (crow::webassets::routes.find(std::string(req.url)) !=
- crow::webassets::routes.end())
- {
- return true;
- }
- }
-
- // it's allowed to POST on session collection & login without
- // authentication
- if ("POST"_method == req.method())
- {
- if ((req.url == "/redfish/v1/SessionService/Sessions") ||
- (req.url == "/redfish/v1/SessionService/Sessions/") ||
- (req.url == "/login"))
- {
- return true;
- }
- }
-
- return false;
- }
-};
-
-// TODO(ed) see if there is a better way to allow middlewares to request
-// routes.
-// Possibly an init function on first construction?
template <typename... Middlewares>
void requestRoutes(Crow<Middlewares...>& app)
{
@@ -477,5 +213,5 @@ void requestRoutes(Crow<Middlewares...>& app)
return;
});
}
-} // namespace token_authorization
+} // namespace login_routes
} // namespace crow
diff --git a/include/persistent_data_middleware.hpp b/include/persistent_data_middleware.hpp
index de3a6ba5bb..819d69d89f 100644
--- a/include/persistent_data_middleware.hpp
+++ b/include/persistent_data_middleware.hpp
@@ -11,9 +11,9 @@
#include <nlohmann/json.hpp>
#include <pam_authenticate.hpp>
#include <sessions.hpp>
-#include <webassets.hpp>
#include <filesystem>
+#include <fstream>
#include <random>
namespace crow
diff --git a/include/redfish_v1.hpp b/include/redfish_v1.hpp
index d77d893cae..3a4b9f5228 100644
--- a/include/redfish_v1.hpp
+++ b/include/redfish_v1.hpp
@@ -5,7 +5,6 @@
#include <boost/algorithm/string.hpp>
#include <dbus_singleton.hpp>
#include <persistent_data_middleware.hpp>
-#include <token_authorization_middleware.hpp>
#include <fstream>
#include <streambuf>
diff --git a/include/webassets.hpp b/include/webassets.hpp
index fc58d3730f..92cf4aa826 100644
--- a/include/webassets.hpp
+++ b/include/webassets.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "webroutes.hpp"
+
#include <app.h>
#include <http_request.h>
#include <http_response.h>
@@ -27,8 +29,6 @@ struct CmpStr
}
};
-static boost::container::flat_set<std::string> routes;
-
template <typename... Middlewares>
void requestRoutes(Crow<Middlewares...>& app)
{
@@ -100,13 +100,13 @@ void requestRoutes(Crow<Middlewares...>& app)
webpath.string().back() != '/')
{
// insert the non-directory version of this path
- routes.insert(webpath);
+ webroutes::routes.insert(webpath);
webpath += "/";
}
}
std::pair<boost::container::flat_set<std::string>::iterator, bool>
- inserted = routes.insert(webpath);
+ inserted = webroutes::routes.insert(webpath);
if (!inserted.second)
{
diff --git a/include/webroutes.hpp b/include/webroutes.hpp
new file mode 100644
index 0000000000..757a272d23
--- /dev/null
+++ b/include/webroutes.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <boost/container/flat_set.hpp>
+namespace crow
+{
+namespace webroutes
+{
+
+static boost::container::flat_set<std::string> routes;
+
+} // namespace webroutes
+
+} // namespace crow
diff --git a/include/webserver_common.hpp b/include/webserver_common.hpp
index 079b17a96f..d8876d473b 100644
--- a/include/webserver_common.hpp
+++ b/include/webserver_common.hpp
@@ -15,9 +15,8 @@
*/
#pragma once
+#include "persistent_data_middleware.hpp"
#include "security_headers_middleware.hpp"
-#include "token_authorization_middleware.hpp"
using CrowApp = crow::App<crow::SecurityHeadersMiddleware,
- crow::persistent_data::Middleware,
- crow::token_authorization::Middleware>;
+ crow::persistent_data::Middleware>;
diff --git a/redfish-core/include/node.hpp b/redfish-core/include/node.hpp
index c2c10d5d1d..2f4cb6b3dd 100644
--- a/redfish-core/include/node.hpp
+++ b/redfish-core/include/node.hpp
@@ -19,7 +19,6 @@
#include "http_response.h"
#include "privileges.hpp"
-#include "token_authorization_middleware.hpp"
#include "webserver_common.hpp"
#include <error_messages.hpp>
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 11e8e925a8..036db5479a 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -6,6 +6,7 @@
#include <dbus_singleton.hpp>
#include <image_upload.hpp>
#include <kvm_websocket.hpp>
+#include <login_routes.hpp>
#include <obmc_console.hpp>
#include <openbmc_dbus_rest.hpp>
@@ -21,7 +22,6 @@
#include <sdbusplus/server.hpp>
#include <security_headers_middleware.hpp>
#include <ssl_key_handler.hpp>
-#include <token_authorization_middleware.hpp>
#include <vm_websocket.hpp>
#include <webassets.hpp>
#include <webserver_common.hpp>
@@ -104,7 +104,7 @@ int main(int argc, char** argv)
crow::ibm_mc_lock::Lock::getInstance();
#endif
- crow::token_authorization::requestRoutes(app);
+ crow::login_routes::requestRoutes(app);
BMCWEB_LOG_INFO << "bmcweb (" << __DATE__ << ": " << __TIME__ << ')';
setupSocket(app);