From 6710c240aabdb9e75779b74cd5e6de44e12d40df Mon Sep 17 00:00:00 2001 From: CJ Cobb Date: Thu, 17 Jun 2021 01:30:30 +0000 Subject: [PATCH] ssl certs are optional --- server/listener.h | 194 +++++++++++++++--------------- server/websocket_server_async.cpp | 50 ++------ 2 files changed, 110 insertions(+), 134 deletions(-) diff --git a/server/listener.h b/server/listener.h index 45480a3bc..ba1fe0ff1 100644 --- a/server/listener.h +++ b/server/listener.h @@ -24,8 +24,8 @@ #include #include #include -#include #include +#include #include #include @@ -34,13 +34,15 @@ class SubscriptionManager; template -class Detector : public std::enable_shared_from_this> +class Detector + : public std::enable_shared_from_this> { - using std::enable_shared_from_this>::shared_from_this; + using std::enable_shared_from_this< + Detector>::shared_from_this; boost::beast::tcp_stream stream_; - ssl::context& ctx_; - std::shared_ptr backend_; + std::optional> ctx_; + std::shared_ptr backend_; std::shared_ptr subscriptions_; std::shared_ptr balancer_; DOSGuard& dosGuard_; @@ -49,7 +51,7 @@ class Detector : public std::enable_shared_from_this> ctx, std::shared_ptr backend, std::shared_ptr subscriptions, std::shared_ptr balancer, @@ -68,33 +70,36 @@ public: run() { // Set the timeout. - boost::beast::get_lowest_layer(stream_).expires_after(std::chrono::seconds(30)); + boost::beast::get_lowest_layer(stream_).expires_after( + std::chrono::seconds(30)); // Detect a TLS handshake async_detect_ssl( stream_, buffer_, boost::beast::bind_front_handler( - &Detector::on_detect, - shared_from_this())); + &Detector::on_detect, shared_from_this())); } void on_detect(boost::beast::error_code ec, bool result) { - if(ec) + if (ec) return httpFail(ec, "detect"); - if(result) + if (result) { + if (!ctx_) + return httpFail(ec, "ssl not supported by this server"); // Launch SSL session std::make_shared( stream_.release_socket(), - ctx_, + *ctx_, backend_, subscriptions_, balancer_, dosGuard_, - std::move(buffer_))->run(); + std::move(buffer_)) + ->run(); return; } @@ -105,17 +110,20 @@ public: subscriptions_, balancer_, dosGuard_, - std::move(buffer_))->run(); + std::move(buffer_)) + ->run(); } }; template -class Listener : public std::enable_shared_from_this> +class Listener + : public std::enable_shared_from_this> { - using std::enable_shared_from_this>::shared_from_this; + using std::enable_shared_from_this< + Listener>::shared_from_this; net::io_context& ioc_; - ssl::context& ctx_; + std::optional> ctx_; tcp::acceptor acceptor_; std::shared_ptr backend_; std::shared_ptr subscriptions_; @@ -125,7 +133,7 @@ class Listener : public std::enable_shared_from_this> ctx, tcp::endpoint endpoint, std::shared_ptr backend, std::shared_ptr subscriptions, @@ -143,7 +151,7 @@ public: // Open the acceptor acceptor_.open(endpoint.protocol(), ec); - if(ec) + if (ec) { httpFail(ec, "open"); return; @@ -151,7 +159,7 @@ public: // Allow address reuse acceptor_.set_option(net::socket_base::reuse_address(true), ec); - if(ec) + if (ec) { httpFail(ec, "set_option"); return; @@ -159,16 +167,15 @@ public: // Bind to the server address acceptor_.bind(endpoint, ec); - if(ec) + if (ec) { httpFail(ec, "bind"); return; } // Start listening for connections - acceptor_.listen( - net::socket_base::max_listen_connections, ec); - if(ec) + acceptor_.listen(net::socket_base::max_listen_connections, ec); + if (ec) { httpFail(ec, "listen"); return; @@ -190,14 +197,13 @@ private: acceptor_.async_accept( net::make_strand(ioc_), boost::beast::bind_front_handler( - &Listener::on_accept, - shared_from_this())); + &Listener::on_accept, shared_from_this())); } void on_accept(boost::beast::error_code ec, tcp::socket socket) { - if(ec) + if (ec) { httpFail(ec, "listener_accept"); } @@ -210,7 +216,8 @@ private: backend_, subscriptions_, balancer_, - dosGuard_)->run(); + dosGuard_) + ->run(); } // Accept another connection @@ -218,76 +225,75 @@ private: } }; -namespace Server +namespace Server { +using WebsocketServer = Listener; +using HttpServer = Listener; + +static std::shared_ptr +make_WebSocketServer( + boost::json::object const& config, + boost::asio::io_context& ioc, + std::optional> ctx, + std::shared_ptr backend, + std::shared_ptr subscriptions, + std::shared_ptr balancer, + DOSGuard& dosGuard) { - using WebsocketServer = Listener; - using HttpServer = Listener; + if (!config.contains("websocket_public")) + return nullptr; - static std::shared_ptr - make_WebSocketServer( - boost::json::object const& config, - boost::asio::io_context& ioc, - ssl::context& ctx, - std::shared_ptr backend, - std::shared_ptr subscriptions, - std::shared_ptr balancer, - DOSGuard& dosGuard) - { - if (!config.contains("websocket_public")) - return nullptr; + auto const& wsConfig = config.at("websocket_public").as_object(); - auto const& wsConfig = config.at("websocket_public").as_object(); + auto const address = + boost::asio::ip::make_address(wsConfig.at("ip").as_string().c_str()); + auto const port = + static_cast(wsConfig.at("port").as_int64()); - auto const address = - boost::asio::ip::make_address(wsConfig.at("ip").as_string().c_str()); - auto const port = - static_cast(wsConfig.at("port").as_int64()); + auto server = std::make_shared( + ioc, + ctx, + boost::asio::ip::tcp::endpoint{address, port}, + backend, + subscriptions, + balancer, + dosGuard); - auto server = std::make_shared( - ioc, - ctx, - boost::asio::ip::tcp::endpoint{address, port}, - backend, - subscriptions, - balancer, - dosGuard); - - server->run(); - return server; - } - - static std::shared_ptr - make_HttpServer( - boost::json::object const& config, - boost::asio::io_context& ioc, - ssl::context& ctx, - std::shared_ptr backend, - std::shared_ptr subscriptions, - std::shared_ptr balancer, - DOSGuard& dosGuard) - { - if (!config.contains("http_public")) - return nullptr; - - auto const& httpConfig = config.at("http_public").as_object(); - - auto const address = - boost::asio::ip::make_address(httpConfig.at("ip").as_string().c_str()); - auto const port = - static_cast(httpConfig.at("port").as_int64()); - - auto server = std::make_shared( - ioc, - ctx, - boost::asio::ip::tcp::endpoint{address, port}, - backend, - subscriptions, - balancer, - dosGuard); - - server->run(); - return server; - } + server->run(); + return server; } -#endif // LISTENER_H \ No newline at end of file +static std::shared_ptr +make_HttpServer( + boost::json::object const& config, + boost::asio::io_context& ioc, + std::optional> ctx, + std::shared_ptr backend, + std::shared_ptr subscriptions, + std::shared_ptr balancer, + DOSGuard& dosGuard) +{ + if (!config.contains("http_public")) + return nullptr; + + auto const& httpConfig = config.at("http_public").as_object(); + + auto const address = + boost::asio::ip::make_address(httpConfig.at("ip").as_string().c_str()); + auto const port = + static_cast(httpConfig.at("port").as_int64()); + + auto server = std::make_shared( + ioc, + ctx, + boost::asio::ip::tcp::endpoint{address, port}, + backend, + subscriptions, + balancer, + dosGuard); + + server->run(); + return server; +} +} // namespace Server + +#endif // LISTENER_H diff --git a/server/websocket_server_async.cpp b/server/websocket_server_async.cpp index ff2a0f214..7911e24d2 100644 --- a/server/websocket_server_async.cpp +++ b/server/websocket_server_async.cpp @@ -28,8 +28,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -71,7 +70,7 @@ parse_certs(const char* certFilename, const char* keyFilename) std::string cert = contents.str(); std::ifstream readKey(keyFilename, std::ios::in | std::ios::binary); - if(!readKey) + if (!readKey) return {}; contents.str(""); @@ -85,8 +84,7 @@ parse_certs(const char* certFilename, const char* keyFilename) boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2); - ctx.use_certificate_chain( - boost::asio::buffer(cert.data(), cert.size())); + ctx.use_certificate_chain(boost::asio::buffer(cert.data(), cert.size())); ctx.use_private_key( boost::asio::buffer(key.data(), key.size()), @@ -95,7 +93,6 @@ parse_certs(const char* certFilename, const char* keyFilename) return ctx; } - void initLogLevel(int level) { @@ -159,6 +156,9 @@ main(int argc, char* argv[]) auto const threads = std::max(1, std::atoi(argv[1])); auto const config = parse_config(argv[2]); auto ctx = parse_certs(argv[3], argv[4]); + auto ctxRef = ctx + ? std::optional>{ctx.value()} + : std::nullopt; if (argc > 5) { @@ -174,11 +174,6 @@ main(int argc, char* argv[]) std::cerr << "Ccouldnt parse config. Exiting..." << std::endl; return EXIT_FAILURE; } - if (!ctx) - { - std::cerr << "Couldn't parse SSL certificates" << std::endl; - return EXIT_FAILURE; - } boost::asio::io_context ioc{threads}; @@ -193,41 +188,16 @@ main(int argc, char* argv[]) NetworkValidatedLedgers::make_ValidatedLedgers()}; auto balancer = ETLLoadBalancer::make_ETLLoadBalancer( - *config, - ioc, - backend, - subscriptions, - ledgers - ); + *config, ioc, backend, subscriptions, ledgers); auto etl = ReportingETL::make_ReportingETL( - *config, - ioc, - backend, - subscriptions, - balancer, - ledgers - ); + *config, ioc, backend, subscriptions, balancer, ledgers); auto wsServer = Server::make_WebSocketServer( - *config, - ioc, - *ctx, - backend, - subscriptions, - balancer, - dosGuard - ); + *config, ioc, ctxRef, backend, subscriptions, balancer, dosGuard); auto httpServer = Server::make_HttpServer( - *config, - ioc, - *ctx, - backend, - subscriptions, - balancer, - dosGuard - ); + *config, ioc, ctxRef, backend, subscriptions, balancer, dosGuard); // Blocks until stopped. // When stopped, shared_ptrs fall out of scope