/* Copyright (c) 2020, 2024, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is designed to work with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have either included with the program or referenced in the documentation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SSL_ACCEPTOR_CONTEXT_OPERATOR #define SSL_ACCEPTOR_CONTEXT_OPERATOR #include /* MyRcuLock */ #include "sql/ssl_acceptor_context_data.h" /** Ssl_acceptor_context_data */ /* Types of supported contexts */ enum class Ssl_acceptor_context_type { context_server_main = 0, context_server_admin, context_last }; class Lock_and_access_ssl_acceptor_context; class TLS_channel; /** TLS context access protector */ class Ssl_acceptor_context_container { protected: Ssl_acceptor_context_container(Ssl_acceptor_context_data *data); ~Ssl_acceptor_context_container(); void switch_data(Ssl_acceptor_context_data *new_data); using Ssl_acceptor_context_data_lock = MyRcuLock; Ssl_acceptor_context_data_lock *lock_; /* F.R.I.E.N.D.S. */ friend class Lock_and_access_ssl_acceptor_context; friend class TLS_channel; }; extern Ssl_acceptor_context_container *mysql_main; extern Ssl_acceptor_context_container *mysql_admin; /** TLS context manager */ class TLS_channel { public: /** Initialize the single instance of the acceptor @param [out] out Object initialized by the function @param [in] channel Name of the channel @param [in] callbacks Handle to the initialization callback object @param [in] db_init Whether database is being initialized or not @returns Initialization status @retval true failure to init @retval false initialized ok */ static bool singleton_init(Ssl_acceptor_context_container **out, std::string channel, Ssl_init_callback *callbacks, bool db_init); /** De-initialize the single instance of the acceptor @param [in] container TLS acceptor context object */ static void singleton_deinit(Ssl_acceptor_context_container *container); /** Re-initialize the single instance of the acceptor @param [in,out] container TLS acceptor context object @param [in] channel Name of the channel @param [in] callbacks Handle to the initialization callback object @param [out] error SSL Error information @param [in] force Activate the SSL settings even if this will lead to disabling SSL */ static void singleton_flush(Ssl_acceptor_context_container *container, std::string channel, Ssl_init_callback *callbacks, enum enum_ssl_init_error *error, bool force); }; using Ssl_acceptor_context_data_lock = MyRcuLock; /** TLS context access wrapper for ease of use */ class Lock_and_access_ssl_acceptor_context { public: Lock_and_access_ssl_acceptor_context(Ssl_acceptor_context_container *context) : read_lock_(context->lock_) {} ~Lock_and_access_ssl_acceptor_context() = default; /** Access protected @ref Ssl_acceptor_context_data */ operator const Ssl_acceptor_context_data *() { const Ssl_acceptor_context_data *c = read_lock_; return c; } /** Access to the SSL_CTX from the protected @ref Ssl_acceptor_context_data */ operator SSL_CTX *() { const Ssl_acceptor_context_data *c = read_lock_; return c->ssl_acceptor_fd_->ssl_context; } /** Access to the SSL from the protected @ref Ssl_acceptor_context_data */ operator SSL *() { const Ssl_acceptor_context_data *c = read_lock_; return c->acceptor_; } /** Access to st_VioSSLFd from the protected @ref Ssl_acceptor_context_data */ operator struct st_VioSSLFd *() { const Ssl_acceptor_context_data *c = read_lock_; return c->ssl_acceptor_fd_; } /** Fetch given property from underlying TLS context @param [in] property_type Property to be fetched @returns Value of property for given context. Empty in case of failure. */ std::string show_property(Ssl_acceptor_context_property_type property_type); /** Fetch channel name @returns Name of underlying channel */ std::string channel_name(); /** TLS context validity @returns Validity of TLS context @retval true Valid @retval false Invalid */ bool have_ssl(); private: /** Read lock over TLS context */ Ssl_acceptor_context_data_lock::ReadLock read_lock_; }; bool have_ssl(); #endif // SSL_ACCEPTOR_CONTEXT_OPERATOR