From fb8aa42d5a989441ee5affbdb9428fd12d4dd70e Mon Sep 17 00:00:00 2001 From: badaix Date: Sat, 11 May 2024 12:37:21 +0200 Subject: [PATCH] Make key password configurable --- server/control_server.cpp | 56 +++++++++++++++++++++++++------------- server/control_server.hpp | 1 + server/etc/snapserver.conf | 1 + server/server_settings.hpp | 1 + server/snapserver.cpp | 1 + 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/server/control_server.cpp b/server/control_server.cpp index 208efccc..b28fce01 100644 --- a/server/control_server.cpp +++ b/server/control_server.cpp @@ -40,19 +40,34 @@ static constexpr auto LOG_TAG = "ControlServer"; ControlServer::ControlServer(boost::asio::io_context& io_context, const ServerSettings& settings, ControlMessageReceiver* controlMessageReceiver) : io_context_(io_context), ssl_context_(boost::asio::ssl::context::sslv23), tcp_settings_(settings.tcp), http_settings_(settings.http), - controlMessageReceiver_(controlMessageReceiver) + controlMessageReceiver_(controlMessageReceiver), ssl_enabled_(true) { const ServerSettings::Ssl& ssl = settings.ssl; - ssl_context_.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use); - ssl_context_.set_password_callback( - [](size_t max_length, boost::asio::ssl::context_base::password_purpose purpose) -> string + if (ssl.certificate.empty() || ssl.private_key.empty()) + { + LOG(INFO, LOG_TAG) << "SSL disabled, to enable SSL, please configure a certificate and private key file in PEM format\n"; + ssl_enabled_ = false; + } + if (ssl_enabled_) + { + ssl_context_.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | + boost::asio::ssl::context::single_dh_use); + if (!ssl.key_password.empty()) { - LOG(DEBUG, LOG_TAG) << "getPassword, purpose: " << purpose << ", max length: " << max_length << "\n"; - return "test"; - }); - ssl_context_.use_certificate_chain_file(ssl.certificate); - ssl_context_.use_private_key_file(ssl.private_key, boost::asio::ssl::context::pem); - // ssl_context_.use_tmp_dh_file("dh4096.pem"); + ssl_context_.set_password_callback( + [pw = ssl.key_password](size_t max_length, boost::asio::ssl::context_base::password_purpose purpose) -> string + { + LOG(DEBUG, LOG_TAG) << "getPassword, purpose: " << purpose << ", max length: " << max_length << "\n"; + return pw; + }); + } + if (!ssl.certificate.empty() && !ssl.private_key.empty()) + { + ssl_context_.use_certificate_chain_file(ssl.certificate); + ssl_context_.use_private_key_file(ssl.private_key, boost::asio::ssl::context::pem); + } + // ssl_context_.use_tmp_dh_file("dh4096.pem"); + } } @@ -193,17 +208,20 @@ void ControlServer::start() } } - for (const auto& address : http_settings_.ssl_bind_to_address) + if (ssl_enabled_) { - try - { - LOG(INFO, LOG_TAG) << "Creating HTTPS acceptor for address: " << address << ", port: " << http_settings_.ssl_port << "\n"; - acceptor_.emplace_back(make_unique(boost::asio::make_strand(io_context_.get_executor()), - tcp::endpoint(boost::asio::ip::address::from_string(address), http_settings_.ssl_port))); - } - catch (const boost::system::system_error& e) + for (const auto& address : http_settings_.ssl_bind_to_address) { - LOG(ERROR, LOG_TAG) << "error creating HTTP acceptor: " << e.what() << ", code: " << e.code() << "\n"; + try + { + LOG(INFO, LOG_TAG) << "Creating HTTPS acceptor for address: " << address << ", port: " << http_settings_.ssl_port << "\n"; + acceptor_.emplace_back(make_unique(boost::asio::make_strand(io_context_.get_executor()), + tcp::endpoint(boost::asio::ip::address::from_string(address), http_settings_.ssl_port))); + } + catch (const boost::system::system_error& e) + { + LOG(ERROR, LOG_TAG) << "error creating HTTP acceptor: " << e.what() << ", code: " << e.code() << "\n"; + } } } } diff --git a/server/control_server.hpp b/server/control_server.hpp index 7e770f39..7181798b 100644 --- a/server/control_server.hpp +++ b/server/control_server.hpp @@ -72,4 +72,5 @@ class ControlServer : public ControlMessageReceiver ServerSettings::Tcp tcp_settings_; ServerSettings::Http http_settings_; ControlMessageReceiver* controlMessageReceiver_; + bool ssl_enabled_; }; diff --git a/server/etc/snapserver.conf b/server/etc/snapserver.conf index e6a7b218..0223ea36 100644 --- a/server/etc/snapserver.conf +++ b/server/etc/snapserver.conf @@ -54,6 +54,7 @@ # https://gist.github.com/fntlnz/cf14feb5a46b2eda428e000157447309 certificate = certs/snapserver.crt private_key = certs/snapserver.key +key_password = # ############################################################################### diff --git a/server/server_settings.hpp b/server/server_settings.hpp index 747dd076..1d481953 100644 --- a/server/server_settings.hpp +++ b/server/server_settings.hpp @@ -42,6 +42,7 @@ struct ServerSettings { std::string certificate{""}; std::string private_key{""}; + std::string key_password{""}; }; struct Http diff --git a/server/snapserver.cpp b/server/snapserver.cpp index 9f1a3599..e37b33d4 100644 --- a/server/snapserver.cpp +++ b/server/snapserver.cpp @@ -83,6 +83,7 @@ int main(int argc, char* argv[]) // SSL settings conf.add>("", "ssl.certificate", "certificate file (PEM format)", settings.ssl.certificate, &settings.ssl.certificate); conf.add>("", "ssl.private_key", "private key file (PEM format)", settings.ssl.private_key, &settings.ssl.private_key); + conf.add>("", "ssl.key_password", "key password (for encrypted private key)", settings.ssl.key_password, &settings.ssl.key_password); // HTTP RPC settings conf.add>("", "http.enabled", "enable HTTP Json RPC (HTTP POST and websockets)", settings.http.enabled, &settings.http.enabled);