diff options
-rw-r--r-- | config/bmcweb_config.h.in | 2 | ||||
-rw-r--r-- | config/meson.build | 4 | ||||
-rw-r--r-- | http/app.hpp | 88 | ||||
-rw-r--r-- | http/http_server.hpp | 52 | ||||
-rw-r--r-- | http/routing/baserule.hpp | 4 | ||||
-rw-r--r-- | http/routing/sserule.hpp | 3 | ||||
-rw-r--r-- | http/routing/websocketrule.hpp | 4 | ||||
-rw-r--r-- | http/websocket.hpp | 5 | ||||
-rw-r--r-- | include/hostname_monitor.hpp | 2 | ||||
-rw-r--r-- | src/webserver_run.cpp | 43 |
10 files changed, 77 insertions, 130 deletions
diff --git a/config/bmcweb_config.h.in b/config/bmcweb_config.h.in index 476379645f..d3b174c470 100644 --- a/config/bmcweb_config.h.in +++ b/config/bmcweb_config.h.in @@ -21,5 +21,7 @@ constexpr const bool bmcwebEnableMultiHost = @BMCWEB_ENABLE_MULTI_HOST@ == 1; constexpr const bool bmcwebEnableHTTP2 = @BMCWEB_ENABLE_HTTP2@ == 1; +constexpr const bool bmcwebEnableTLS = @BMCWEB_ENABLE_TLS@ == 1; + constexpr const bool bmcwebMTLSCommonNameParsingMeta = @BMCWEB_ENABLE_MTLS_COMMON_NAME_PARSING_META@ == 1; // clang-format on diff --git a/config/meson.build b/config/meson.build index 21da40e077..1c6f78a999 100644 --- a/config/meson.build +++ b/config/meson.build @@ -19,6 +19,10 @@ enable_multi_host = get_option('experimental-redfish-multi-computer-system') conf_data.set10('BMCWEB_ENABLE_MULTI_HOST', enable_multi_host.allowed()) enable_http2 = get_option('experimental-http2') conf_data.set10('BMCWEB_ENABLE_HTTP2', enable_http2.allowed()) + +enable_tls = get_option('insecure-disable-ssl') +conf_data.set10('BMCWEB_ENABLE_TLS', enable_tls.disabled()) + conf_data.set10( 'BMCWEB_ENABLE_MTLS_COMMON_NAME_PARSING_META', get_option('mutual-tls-common-name-parsing') == 'meta', diff --git a/http/app.hpp b/http/app.hpp index eeb331ea96..d7863f6b17 100644 --- a/http/app.hpp +++ b/http/app.hpp @@ -8,6 +8,8 @@ #include "routing.hpp" #include "utility.hpp" +#include <systemd/sd-daemon.h> + #include <boost/asio/io_context.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/asio/ssl/context.hpp> @@ -31,9 +33,11 @@ class App { public: using ssl_socket_t = boost::beast::ssl_stream<boost::asio::ip::tcp::socket>; - using ssl_server_t = Server<App, ssl_socket_t>; - using socket_t = boost::asio::ip::tcp::socket; - using server_t = Server<App, socket_t>; + using raw_socket_t = boost::asio::ip::tcp::socket; + + using socket_type = + std::conditional_t<bmcwebEnableTLS, ssl_socket_t, raw_socket_t>; + using server_type = Server<App, socket_type>; explicit App(std::shared_ptr<boost::asio::io_context> ioIn = std::make_shared<boost::asio::io_context>()) : @@ -74,52 +78,53 @@ class App return router.newRuleTagged<Tag>(std::move(rule)); } - App& socket(int existingSocket) - { - socketFd = existingSocket; - return *this; - } - - App& port(std::uint16_t port) - { - portUint = port; - return *this; - } - void validate() { router.validate(); } - void run() + std::optional<boost::asio::ip::tcp::acceptor> setupSocket() { - validate(); -#ifdef BMCWEB_ENABLE_SSL - if (-1 == socketFd) + if (io == nullptr) { - sslServer = std::make_unique<ssl_server_t>(this, portUint, - sslContext, io); + BMCWEB_LOG_CRITICAL("IO was nullptr?"); + return std::nullopt; } - else + constexpr int defaultPort = 18080; + int listenFd = sd_listen_fds(0); + if (listenFd == 1) { - sslServer = std::make_unique<ssl_server_t>(this, socketFd, - sslContext, io); + BMCWEB_LOG_INFO("attempting systemd socket activation"); + if (sd_is_socket_inet(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_STREAM, + 1, 0) != 0) + { + BMCWEB_LOG_INFO("Starting webserver on socket handle {}", + SD_LISTEN_FDS_START); + return boost::asio::ip::tcp::acceptor( + *io, boost::asio::ip::tcp::v6(), SD_LISTEN_FDS_START); + } + BMCWEB_LOG_ERROR( + "bad incoming socket, starting webserver on port {}", + defaultPort); } - sslServer->run(); + BMCWEB_LOG_INFO("Starting webserver on port {}", defaultPort); + return boost::asio::ip::tcp::acceptor( + *io, boost::asio::ip::tcp::endpoint( + boost::asio::ip::make_address("0.0.0.0"), defaultPort)); + } -#else + void run() + { + validate(); - if (-1 == socketFd) + std::optional<boost::asio::ip::tcp::acceptor> acceptor = setupSocket(); + if (!acceptor) { - server = std::make_unique<server_t>(this, portUint, nullptr, io); - } - else - { - server = std::make_unique<server_t>(this, socketFd, nullptr, io); + BMCWEB_LOG_CRITICAL("Couldn't start server"); + return; } + server.emplace(this, std::move(*acceptor), sslContext, io); server->run(); - -#endif } void stop() @@ -160,19 +165,10 @@ class App private: std::shared_ptr<boost::asio::io_context> io; -#ifdef BMCWEB_ENABLE_SSL - uint16_t portUint = 443; -#else - uint16_t portUint = 80; -#endif - int socketFd = -1; - Router router; -#ifdef BMCWEB_ENABLE_SSL - std::unique_ptr<ssl_server_t> sslServer; -#else - std::unique_ptr<server_t> server; -#endif + std::optional<server_type> server; + + Router router; }; } // namespace crow using App = crow::App; diff --git a/http/http_server.hpp b/http/http_server.hpp index 2a6bd9f4aa..da73b107db 100644 --- a/http/http_server.hpp +++ b/http/http_server.hpp @@ -27,38 +27,15 @@ template <typename Handler, typename Adaptor = boost::asio::ip::tcp::socket> class Server { public: - Server(Handler* handlerIn, - std::unique_ptr<boost::asio::ip::tcp::acceptor>&& acceptorIn, + Server(Handler* handlerIn, boost::asio::ip::tcp::acceptor&& acceptorIn, std::shared_ptr<boost::asio::ssl::context> adaptorCtxIn, - std::shared_ptr<boost::asio::io_context> io = - std::make_shared<boost::asio::io_context>()) : + std::shared_ptr<boost::asio::io_context> io) : ioService(std::move(io)), acceptor(std::move(acceptorIn)), signals(*ioService, SIGINT, SIGTERM, SIGHUP), handler(handlerIn), adaptorCtx(std::move(adaptorCtxIn)) {} - Server(Handler* handlerIn, uint16_t port, - const std::shared_ptr<boost::asio::ssl::context>& adaptorCtxIn, - const std::shared_ptr<boost::asio::io_context>& io = - std::make_shared<boost::asio::io_context>()) : - Server(handlerIn, - std::make_unique<boost::asio::ip::tcp::acceptor>( - *io, boost::asio::ip::tcp::endpoint( - boost::asio::ip::make_address("0.0.0.0"), port)), - adaptorCtxIn, io) - {} - - Server(Handler* handlerIn, int existingSocket, - const std::shared_ptr<boost::asio::ssl::context>& adaptorCtxIn, - const std::shared_ptr<boost::asio::io_context>& io = - std::make_shared<boost::asio::io_context>()) : - Server(handlerIn, - std::make_unique<boost::asio::ip::tcp::acceptor>( - *io, boost::asio::ip::tcp::v6(), existingSocket), - adaptorCtxIn, io) - {} - void updateDateStr() { time_t lastTimeT = time(nullptr); @@ -90,14 +67,17 @@ class Server }; BMCWEB_LOG_INFO("bmcweb server is running, local endpoint {}", - acceptor->local_endpoint().address().to_string()); + acceptor.local_endpoint().address().to_string()); startAsyncWaitForSignal(); doAccept(); } void loadCertificate() { -#ifdef BMCWEB_ENABLE_SSL + if constexpr (!bmcwebEnableTLS) + { + return; + } namespace fs = std::filesystem; // Cleanup older certificate file existing in the system fs::path oldCert = "/home/root/server.pem"; @@ -121,7 +101,6 @@ class Server ensuressl::getSslContext(sslPemFile); adaptorCtx = sslContext; handler->ssl(std::move(sslContext)); -#endif } void startAsyncWaitForSignal() @@ -139,7 +118,7 @@ class Server BMCWEB_LOG_INFO("Receivied reload signal"); loadCertificate(); boost::system::error_code ec2; - acceptor->cancel(ec2); + acceptor.cancel(ec2); if (ec2) { BMCWEB_LOG_ERROR( @@ -163,12 +142,23 @@ class Server void doAccept() { + if (ioService == nullptr) + { + BMCWEB_LOG_CRITICAL("IoService was null"); + return; + } boost::asio::steady_timer timer(*ioService); std::shared_ptr<Connection<Adaptor, Handler>> connection; if constexpr (std::is_same<Adaptor, boost::beast::ssl_stream< boost::asio::ip::tcp::socket>>::value) { + if (adaptorCtx == nullptr) + { + BMCWEB_LOG_CRITICAL( + "Asked to lauch TLS socket but no context available"); + return; + } connection = std::make_shared<Connection<Adaptor, Handler>>( handler, std::move(timer), getCachedDateStr, Adaptor(*ioService, *adaptorCtx)); @@ -179,7 +169,7 @@ class Server handler, std::move(timer), getCachedDateStr, Adaptor(*ioService)); } - acceptor->async_accept( + acceptor.async_accept( boost::beast::get_lowest_layer(connection->socket()), [this, connection](const boost::system::error_code& ec) { if (!ec) @@ -194,7 +184,7 @@ class Server private: std::shared_ptr<boost::asio::io_context> ioService; std::function<std::string()> getCachedDateStr; - std::unique_ptr<boost::asio::ip::tcp::acceptor> acceptor; + boost::asio::ip::tcp::acceptor acceptor; boost::asio::signal_set signals; std::string dateStr; diff --git a/http/routing/baserule.hpp b/http/routing/baserule.hpp index 0913020935..f99e16ecf3 100644 --- a/http/routing/baserule.hpp +++ b/http/routing/baserule.hpp @@ -37,7 +37,6 @@ class BaseRule virtual void handle(const Request& /*req*/, const std::shared_ptr<bmcweb::AsyncResp>&, const std::vector<std::string>&) = 0; -#ifndef BMCWEB_ENABLE_SSL virtual void handleUpgrade(const Request& /*req*/, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, @@ -45,7 +44,7 @@ class BaseRule { asyncResp->res.result(boost::beast::http::status::not_found); } -#else + virtual void handleUpgrade( const Request& /*req*/, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, @@ -53,7 +52,6 @@ class BaseRule { asyncResp->res.result(boost::beast::http::status::not_found); } -#endif size_t getMethods() const { diff --git a/http/routing/sserule.hpp b/http/routing/sserule.hpp index c0a4e504b3..ad05bafbe2 100644 --- a/http/routing/sserule.hpp +++ b/http/routing/sserule.hpp @@ -30,7 +30,6 @@ class SseSocketRule : public BaseRule asyncResp->res.result(boost::beast::http::status::not_found); } -#ifndef BMCWEB_ENABLE_SSL void handleUpgrade(const Request& /*req*/, const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/, boost::asio::ip::tcp::socket&& adaptor) override @@ -42,7 +41,6 @@ class SseSocketRule : public BaseRule std::move(adaptor), openHandler, closeHandler); myConnection->start(); } -#else void handleUpgrade(const Request& /*req*/, const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/, boost::beast::ssl_stream<boost::asio::ip::tcp::socket>&& @@ -55,7 +53,6 @@ class SseSocketRule : public BaseRule std::move(adaptor), openHandler, closeHandler); myConnection->start(); } -#endif template <typename Func> self_t& onopen(Func f) diff --git a/http/routing/websocketrule.hpp b/http/routing/websocketrule.hpp index bf6daad6d0..b52d9ec9a7 100644 --- a/http/routing/websocketrule.hpp +++ b/http/routing/websocketrule.hpp @@ -27,7 +27,6 @@ class WebSocketRule : public BaseRule asyncResp->res.result(boost::beast::http::status::not_found); } -#ifndef BMCWEB_ENABLE_SSL void handleUpgrade(const Request& req, const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/, boost::asio::ip::tcp::socket&& adaptor) override @@ -41,7 +40,7 @@ class WebSocketRule : public BaseRule messageHandler, messageExHandler, closeHandler, errorHandler); myConnection->start(req); } -#else + void handleUpgrade(const Request& req, const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/, boost::beast::ssl_stream<boost::asio::ip::tcp::socket>&& @@ -56,7 +55,6 @@ class WebSocketRule : public BaseRule messageHandler, messageExHandler, closeHandler, errorHandler); myConnection->start(req); } -#endif template <typename Func> self_t& onopen(Func f) diff --git a/http/websocket.hpp b/http/websocket.hpp index 4262c70a5c..e669ffa611 100644 --- a/http/websocket.hpp +++ b/http/websocket.hpp @@ -6,14 +6,11 @@ #include <boost/asio/buffer.hpp> #include <boost/beast/core/multi_buffer.hpp> #include <boost/beast/websocket.hpp> +#include <boost/beast/websocket/ssl.hpp> #include <array> #include <functional> -#ifdef BMCWEB_ENABLE_SSL -#include <boost/beast/websocket/ssl.hpp> -#endif - namespace crow { namespace websocket diff --git a/include/hostname_monitor.hpp b/include/hostname_monitor.hpp index 188deff564..bb6998798a 100644 --- a/include/hostname_monitor.hpp +++ b/include/hostname_monitor.hpp @@ -1,5 +1,4 @@ #pragma once -#ifdef BMCWEB_ENABLE_SSL #include "dbus_singleton.hpp" #include "dbus_utility.hpp" #include "include/dbus_utility.hpp" @@ -148,4 +147,3 @@ inline void registerHostnameSignal() } } // namespace hostname_monitor } // namespace crow -#endif diff --git a/src/webserver_run.cpp b/src/webserver_run.cpp index e5d272ead8..2f28e16818 100644 --- a/src/webserver_run.cpp +++ b/src/webserver_run.cpp @@ -24,43 +24,11 @@ #include "vm_websocket.hpp" #include "webassets.hpp" -#include <systemd/sd-daemon.h> - #include <boost/asio/io_context.hpp> #include <sdbusplus/asio/connection.hpp> #include <sdbusplus/bus.hpp> #include <sdbusplus/server.hpp> -constexpr int defaultPort = 18080; - -static void setupSocket(crow::App& app) -{ - int listenFd = sd_listen_fds(0); - if (1 == listenFd) - { - BMCWEB_LOG_INFO("attempting systemd socket activation"); - if (sd_is_socket_inet(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_STREAM, 1, - 0) != 0) - { - BMCWEB_LOG_INFO("Starting webserver on socket handle {}", - SD_LISTEN_FDS_START); - app.socket(SD_LISTEN_FDS_START); - } - else - { - BMCWEB_LOG_INFO( - "bad incoming socket, starting webserver on port {}", - defaultPort); - app.port(defaultPort); - } - } - else - { - BMCWEB_LOG_INFO("Starting webserver on port {}", defaultPort); - app.port(defaultPort); - } -} - int run() { auto io = std::make_shared<boost::asio::io_context>(); @@ -122,8 +90,6 @@ int run() crow::login_routes::requestRoutes(app); - setupSocket(app); - #ifdef BMCWEB_ENABLE_VM_NBDPROXY crow::nbd_proxy::requestRoutes(app); #endif @@ -137,10 +103,11 @@ int run() } #endif -#ifdef BMCWEB_ENABLE_SSL - BMCWEB_LOG_INFO("Start Hostname Monitor Service..."); - crow::hostname_monitor::registerHostnameSignal(); -#endif + if constexpr (bmcwebEnableTLS) + { + BMCWEB_LOG_INFO("Start Hostname Monitor Service..."); + crow::hostname_monitor::registerHostnameSignal(); + } bmcweb::registerUserRemovedSignal(); |