#pragma once #include "config.h" #if USE_SSL #include #include #include #include #include #include #include #include #include #include namespace DB { /// The CertificateReloader singleton performs 2 functions: /// 1. Dynamic reloading of TLS key-pair when requested by server: /// Server config reloader notifies CertificateReloader when the config changes. /// On changed config, CertificateReloader reloads certs from disk. /// 2. Implement `SSL_CTX_set_cert_cb` to set certificate for a new connection: /// OpenSSL invokes a callback to setup a connection. class CertificateReloader { public: using stat_t = struct stat; /// Singleton CertificateReloader(CertificateReloader const &) = delete; void operator=(CertificateReloader const &) = delete; static CertificateReloader & instance() { static CertificateReloader instance; return instance; } /// Initialize the callback and perform the initial cert loading void init(); /// Handle configuration reload void tryLoad(const Poco::Util::AbstractConfiguration & config); /// A callback for OpenSSL int setCertificate(SSL * ssl); private: CertificateReloader() = default; LoggerPtr log = getLogger("CertificateReloader"); struct File { const char * description; explicit File(const char * description_) : description(description_) {} std::string path; std::filesystem::file_time_type modification_time; bool changeIfModified(std::string new_path, LoggerPtr logger); }; File cert_file{"certificate"}; File key_file{"key"}; struct Data { Poco::Crypto::X509Certificate::List certs_chain; Poco::Crypto::EVPPKey key; Data(std::string cert_path, std::string key_path, std::string pass_phrase); }; MultiVersion data; bool init_was_not_made = true; }; } #endif