From cb72b2a5cc4687abca86079dfcb842884fd414e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 21 May 2019 11:15:36 +0300 Subject: [PATCH] MXS-2483: Move SSL functionality into SSLProvider The class is intended to be inherited by objects that need an SSL context and a configuration. In practice this will be servers and listeners. The SSLContext is stored in a rworker_local shared_ptr that makes it possible to update safely. As the copying is always done behind a lock the cached local value always holds a valid SSLContext instance for the duration of all function calls. Using the pImpl idiom, the routingworker.hh header is not exposed in the ssl.hh header. This allows the SSLProvider class to be inherited more easily. --- include/maxscale/ssl.hh | 18 ++++++++++++ server/core/ssl.cc | 65 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/include/maxscale/ssl.hh b/include/maxscale/ssl.hh index 5d6ad9668..a597feadf 100644 --- a/include/maxscale/ssl.hh +++ b/include/maxscale/ssl.hh @@ -58,6 +58,9 @@ ssl_method_type_t string_to_ssl_method_type(const char* str); extern const MXS_ENUM_VALUE ssl_version_values[]; +// The concrete implementation of the SSLProvider class (hides the dependency on routingworker.hh) +class SSLProviderImp; + namespace maxscale { @@ -134,4 +137,19 @@ private: SSLContext(const SSLConfig& cfg); bool init(); }; + +// A SSL connection provider (incoming or outgoing). Used by servers and listeners. +class SSLProvider +{ +public: + const mxs::SSLConfig& config() const; + mxs::SSLContext* context() const; + void set_context(std::unique_ptr ssl); + + SSLProvider(std::unique_ptr&& context); + ~SSLProvider(); + +private: + std::unique_ptr m_imp; +}; } diff --git a/server/core/ssl.cc b/server/core/ssl.cc index 1c6c08fca..61d99b24f 100644 --- a/server/core/ssl.cc +++ b/server/core/ssl.cc @@ -33,6 +33,7 @@ #include #include #include +#include static RSA* rsa_512 = NULL; static RSA* rsa_1024 = NULL; @@ -196,10 +197,48 @@ static const char* get_ssl_errors() return ssl_errbuf->c_str(); } +class SSLProviderImp +{ +public: + const mxs::SSLConfig& config() const; + mxs::SSLContext* context() const; + void set_context(std::unique_ptr ssl); + + SSLProviderImp(std::unique_ptr&& context); + +private: + mxs::rworker_local> m_context; /**< SSL context */ + mxs::SSLConfig m_config; /**< SSL configuration */ +}; + +const mxs::SSLConfig& SSLProviderImp::config() const +{ + return m_config; +} + +mxs::SSLContext* SSLProviderImp::context() const +{ + mxb_assert_message(mxs::RoutingWorker::get_current(), "Must be used on a RoutingWorker"); + return m_context->get(); +} + +void SSLProviderImp::set_context(std::unique_ptr ssl) +{ + mxb_assert_message(mxs::RoutingWorker::get_current() + == mxs::RoutingWorker::get(mxs::RoutingWorker::MAIN), + "Must be only set on the main RoutingWorker"); + m_config = ssl ? ssl->config() : mxs::SSLConfig {}; + m_context.assign(std::move(ssl)); +} + +SSLProviderImp::SSLProviderImp(std::unique_ptr&& context) + : m_context {std::move(context)} +{ +} + namespace maxscale { - SSLConfig::SSLConfig(const MXS_CONFIG_PARAMETER& params) : key(params.get_string(CN_SSL_KEY)) , cert(params.get_string(CN_SSL_CERT)) @@ -413,4 +452,28 @@ SSLContext::~SSLContext() { SSL_CTX_free(m_ctx); } + +SSLProvider::SSLProvider(std::unique_ptr&& ssl) + : m_imp(new SSLProviderImp(std::move(ssl))) +{ +} + +SSLProvider::~SSLProvider() +{ +} + +mxs::SSLContext* SSLProvider::context() const +{ + return m_imp->context(); +} + +const mxs::SSLConfig& SSLProvider::config() const +{ + return m_imp->config(); +} + +void SSLProvider::set_context(std::unique_ptr ssl) +{ + m_imp->set_context(std::move(ssl)); +} }