MXS-2483: Move SSL configuration into SSLConfig
This way the configuration information can be accessed without the SSLContext.
This commit is contained in:
@ -517,6 +517,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void response_time_add(double ave, int num_samples);
|
void response_time_add(double ave, int num_samples);
|
||||||
|
|
||||||
|
const mxs::SSLConfig& ssl_config() const
|
||||||
|
{
|
||||||
|
return m_ssl_config;
|
||||||
|
}
|
||||||
|
|
||||||
mxs::SSLContext* ssl_context() const
|
mxs::SSLContext* ssl_context() const
|
||||||
{
|
{
|
||||||
return m_ssl_context.get();
|
return m_ssl_context.get();
|
||||||
@ -525,6 +530,7 @@ public:
|
|||||||
void set_ssl_context(std::unique_ptr<mxs::SSLContext> ssl)
|
void set_ssl_context(std::unique_ptr<mxs::SSLContext> ssl)
|
||||||
{
|
{
|
||||||
m_ssl_context.swap(ssl);
|
m_ssl_context.swap(ssl);
|
||||||
|
m_ssl_config = m_ssl_context->config();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -540,4 +546,5 @@ private:
|
|||||||
std::mutex m_average_write_mutex; /**< Protects response time from concurrent writing */
|
std::mutex m_average_write_mutex; /**< Protects response time from concurrent writing */
|
||||||
|
|
||||||
std::unique_ptr<mxs::SSLContext> m_ssl_context; /**< SSL context */
|
std::unique_ptr<mxs::SSLContext> m_ssl_context; /**< SSL context */
|
||||||
|
mxs::SSLConfig m_ssl_config; /**< SSL configuration */
|
||||||
};
|
};
|
||||||
|
@ -61,6 +61,26 @@ extern const MXS_ENUM_VALUE ssl_version_values[];
|
|||||||
namespace maxscale
|
namespace maxscale
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// SSL configuration
|
||||||
|
struct SSLConfig
|
||||||
|
{
|
||||||
|
SSLConfig() = default;
|
||||||
|
SSLConfig(const MXS_CONFIG_PARAMETER& params);
|
||||||
|
|
||||||
|
// CA must always be defined for non-empty configurations
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return ca.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string key; /**< SSL private key */
|
||||||
|
std::string cert; /**< SSL certificate */
|
||||||
|
std::string ca; /**< SSL CA certificate */
|
||||||
|
ssl_method_type_t version = SERVICE_SSL_TLS_MAX; /**< Which TLS version to use */
|
||||||
|
int verify_depth = 9; /**< SSL certificate verification depth */
|
||||||
|
bool verify_peer = true; /**< Enable peer certificate verification */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SSLContext is used to aggregate the SSL configuration and data for a particular object.
|
* The SSLContext is used to aggregate the SSL configuration and data for a particular object.
|
||||||
*/
|
*/
|
||||||
@ -91,22 +111,10 @@ public:
|
|||||||
return SSL_new(m_ctx);
|
return SSL_new(m_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private key
|
// SSL configuration
|
||||||
const std::string& ssl_key() const
|
const SSLConfig& config() const
|
||||||
{
|
{
|
||||||
return m_key;
|
return m_cfg;
|
||||||
}
|
|
||||||
|
|
||||||
// Public cert
|
|
||||||
const std::string& ssl_cert() const
|
|
||||||
{
|
|
||||||
return m_cert;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Certificate authority
|
|
||||||
const std::string& ssl_ca() const
|
|
||||||
{
|
|
||||||
return m_ca;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to JSON representation
|
// Convert to JSON representation
|
||||||
@ -121,16 +129,9 @@ private:
|
|||||||
SSL_CTX* m_ctx = nullptr;
|
SSL_CTX* m_ctx = nullptr;
|
||||||
SSL_METHOD* m_method = nullptr; /**< SSLv3 or TLS1.0/1.1/1.2 methods
|
SSL_METHOD* m_method = nullptr; /**< SSLv3 or TLS1.0/1.1/1.2 methods
|
||||||
* see: https://www.openssl.org/docs/ssl/SSL_CTX_new.html */
|
* see: https://www.openssl.org/docs/ssl/SSL_CTX_new.html */
|
||||||
|
SSLConfig m_cfg;
|
||||||
|
|
||||||
std::string m_key; /**< SSL private key */
|
SSLContext(const SSLConfig& cfg);
|
||||||
std::string m_cert; /**< SSL certificate */
|
|
||||||
std::string m_ca; /**< SSL CA certificate */
|
|
||||||
ssl_method_type_t m_version; /**< Which TLS version to use */
|
|
||||||
int m_verify_depth; /**< SSL certificate verification depth */
|
|
||||||
bool m_verify_peer; /**< Enable peer certificate verification */
|
|
||||||
|
|
||||||
SSLContext(const std::string& key, const std::string& cert, const std::string& ca,
|
|
||||||
ssl_method_type_t version, int verify_depth, bool verify_peer_cert);
|
|
||||||
bool init();
|
bool init();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -155,12 +155,11 @@ char* mxs_lestr_consume(uint8_t** c, size_t* size)
|
|||||||
|
|
||||||
MYSQL* mxs_mysql_real_connect(MYSQL* con, SERVER* server, const char* user, const char* passwd)
|
MYSQL* mxs_mysql_real_connect(MYSQL* con, SERVER* server, const char* user, const char* passwd)
|
||||||
{
|
{
|
||||||
mxs::SSLContext* ssl = server->ssl_context();
|
auto ssl = server->ssl_config();
|
||||||
|
|
||||||
if (ssl)
|
if (!ssl.empty())
|
||||||
{
|
{
|
||||||
mysql_ssl_set(con, ssl->ssl_key().c_str(), ssl->ssl_cert().c_str(), ssl->ssl_ca().c_str(),
|
mysql_ssl_set(con, ssl.key.c_str(), ssl.cert.c_str(), ssl.ca.c_str(), NULL, NULL);
|
||||||
NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char yes = 1;
|
char yes = 1;
|
||||||
@ -205,7 +204,7 @@ MYSQL* mxs_mysql_real_connect(MYSQL* con, SERVER* server, const char* user, cons
|
|||||||
mysql_get_character_set_info(mysql, &cs_info);
|
mysql_get_character_set_info(mysql, &cs_info);
|
||||||
server->charset = cs_info.number;
|
server->charset = cs_info.number;
|
||||||
|
|
||||||
if (ssl && mysql_get_ssl_cipher(con) == NULL)
|
if (!ssl.empty() && mysql_get_ssl_cipher(con) == NULL)
|
||||||
{
|
{
|
||||||
if (server->warn_ssl_not_enabled)
|
if (server->warn_ssl_not_enabled)
|
||||||
{
|
{
|
||||||
|
@ -199,6 +199,17 @@ static const char* get_ssl_errors()
|
|||||||
namespace maxscale
|
namespace maxscale
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
SSLConfig::SSLConfig(const MXS_CONFIG_PARAMETER& params)
|
||||||
|
: key(params.get_string(CN_SSL_KEY))
|
||||||
|
, cert(params.get_string(CN_SSL_CERT))
|
||||||
|
, ca(params.get_string(CN_SSL_CA_CERT))
|
||||||
|
, version((ssl_method_type_t)params.get_enum(CN_SSL_VERSION, ssl_version_values))
|
||||||
|
, verify_depth(params.get_integer(CN_SSL_CERT_VERIFY_DEPTH))
|
||||||
|
, verify_peer(params.get_bool(CN_SSL_VERIFY_PEER_CERTIFICATE))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
std::unique_ptr<SSLContext> SSLContext::create(const MXS_CONFIG_PARAMETER& params)
|
std::unique_ptr<SSLContext> SSLContext::create(const MXS_CONFIG_PARAMETER& params)
|
||||||
{
|
{
|
||||||
@ -208,13 +219,7 @@ std::unique_ptr<SSLContext> SSLContext::create(const MXS_CONFIG_PARAMETER& param
|
|||||||
mxb_assert(params.get_string(CN_SSL_KEY).empty()
|
mxb_assert(params.get_string(CN_SSL_KEY).empty()
|
||||||
|| access(params.get_string(CN_SSL_KEY).c_str(), F_OK) == 0);
|
|| access(params.get_string(CN_SSL_KEY).c_str(), F_OK) == 0);
|
||||||
|
|
||||||
std::unique_ptr<SSLContext> ssl(
|
std::unique_ptr<SSLContext> ssl(new(std::nothrow) SSLContext(SSLConfig(params)));
|
||||||
new(std::nothrow) SSLContext(params.get_string(CN_SSL_KEY),
|
|
||||||
params.get_string(CN_SSL_CERT),
|
|
||||||
params.get_string(CN_SSL_CA_CERT),
|
|
||||||
(ssl_method_type_t)params.get_enum(CN_SSL_VERSION, ssl_version_values),
|
|
||||||
params.get_integer(CN_SSL_CERT_VERIFY_DEPTH),
|
|
||||||
params.get_bool(CN_SSL_VERIFY_PEER_CERTIFICATE)));
|
|
||||||
|
|
||||||
if (ssl && !ssl->init())
|
if (ssl && !ssl->init())
|
||||||
{
|
{
|
||||||
@ -224,14 +229,8 @@ std::unique_ptr<SSLContext> SSLContext::create(const MXS_CONFIG_PARAMETER& param
|
|||||||
return ssl;
|
return ssl;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSLContext::SSLContext(const std::string& key, const std::string& cert, const std::string& ca,
|
SSLContext::SSLContext(const SSLConfig& cfg)
|
||||||
ssl_method_type_t version, int verify_depth, bool verify_peer)
|
: m_cfg(cfg)
|
||||||
: m_key(key)
|
|
||||||
, m_cert(cert)
|
|
||||||
, m_ca(ca)
|
|
||||||
, m_version(version)
|
|
||||||
, m_verify_depth(verify_depth)
|
|
||||||
, m_verify_peer(verify_peer)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,21 +239,21 @@ std::string SSLContext::serialize() const
|
|||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << "ssl=required\n";
|
ss << "ssl=required\n";
|
||||||
|
|
||||||
if (!m_cert.empty())
|
if (!m_cfg.cert.empty())
|
||||||
{
|
{
|
||||||
ss << "ssl_cert=" << m_cert << "\n";
|
ss << "ssl_cert=" << m_cfg.cert << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_key.empty())
|
if (!m_cfg.key.empty())
|
||||||
{
|
{
|
||||||
ss << "ssl_key=" << m_key << "\n";
|
ss << "ssl_key=" << m_cfg.key << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
mxb_assert(!m_ca.empty());
|
mxb_assert(!m_cfg.ca.empty());
|
||||||
ss << "ssl_ca_cert=" << m_ca << "\n";
|
ss << "ssl_ca_cert=" << m_cfg.ca << "\n";
|
||||||
ss << "ssl_version=" << ssl_method_type_to_string(m_version) << "\n";
|
ss << "ssl_version=" << ssl_method_type_to_string(m_cfg.version) << "\n";
|
||||||
ss << "ssl_cert_verify_depth=" << m_verify_depth << "\n";
|
ss << "ssl_cert_verify_depth=" << m_cfg.verify_depth << "\n";
|
||||||
ss << "ssl_verify_peer_certificate=" << (m_verify_peer ? "true" : "false") << "\n";
|
ss << "ssl_verify_peer_certificate=" << (m_cfg.verify_peer ? "true" : "false") << "\n";
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +261,7 @@ bool SSLContext::init()
|
|||||||
{
|
{
|
||||||
bool rval = true;
|
bool rval = true;
|
||||||
|
|
||||||
switch (m_version)
|
switch (m_cfg.version)
|
||||||
{
|
{
|
||||||
#ifndef OPENSSL_1_1
|
#ifndef OPENSSL_1_1
|
||||||
case SERVICE_TLS10:
|
case SERVICE_TLS10:
|
||||||
@ -337,26 +336,26 @@ bool SSLContext::init()
|
|||||||
SSL_CTX_set_tmp_rsa_callback(m_ctx, tmp_rsa_callback);
|
SSL_CTX_set_tmp_rsa_callback(m_ctx, tmp_rsa_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
mxb_assert(!m_ca.empty());
|
mxb_assert(!m_cfg.ca.empty());
|
||||||
|
|
||||||
/* Load the CA certificate into the SSL_CTX structure */
|
/* Load the CA certificate into the SSL_CTX structure */
|
||||||
if (!SSL_CTX_load_verify_locations(m_ctx, m_ca.c_str(), NULL))
|
if (!SSL_CTX_load_verify_locations(m_ctx, m_cfg.ca.c_str(), NULL))
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to set Certificate Authority file");
|
MXS_ERROR("Failed to set Certificate Authority file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_cert.empty() && !m_key.empty())
|
if (!m_cfg.cert.empty() && !m_cfg.key.empty())
|
||||||
{
|
{
|
||||||
/** Load the server certificate */
|
/** Load the server certificate */
|
||||||
if (SSL_CTX_use_certificate_chain_file(m_ctx, m_cert.c_str()) <= 0)
|
if (SSL_CTX_use_certificate_chain_file(m_ctx, m_cfg.cert.c_str()) <= 0)
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to set server SSL certificate: %s", get_ssl_errors());
|
MXS_ERROR("Failed to set server SSL certificate: %s", get_ssl_errors());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the private-key corresponding to the server certificate */
|
/* Load the private-key corresponding to the server certificate */
|
||||||
if (SSL_CTX_use_PrivateKey_file(m_ctx, m_key.c_str(), SSL_FILETYPE_PEM) <= 0)
|
if (SSL_CTX_use_PrivateKey_file(m_ctx, m_cfg.key.c_str(), SSL_FILETYPE_PEM) <= 0)
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to set server SSL key: %s", get_ssl_errors());
|
MXS_ERROR("Failed to set server SSL key: %s", get_ssl_errors());
|
||||||
return false;
|
return false;
|
||||||
@ -371,13 +370,13 @@ bool SSLContext::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set to require peer (client) certificate verification */
|
/* Set to require peer (client) certificate verification */
|
||||||
if (m_verify_peer)
|
if (m_cfg.verify_peer)
|
||||||
{
|
{
|
||||||
SSL_CTX_set_verify(m_ctx, SSL_VERIFY_PEER, NULL);
|
SSL_CTX_set_verify(m_ctx, SSL_VERIFY_PEER, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the verification depth */
|
/* Set the verification depth */
|
||||||
SSL_CTX_set_verify_depth(m_ctx, m_verify_depth);
|
SSL_CTX_set_verify_depth(m_ctx, m_cfg.verify_depth);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -385,12 +384,12 @@ bool SSLContext::init()
|
|||||||
json_t* SSLContext::to_json() const
|
json_t* SSLContext::to_json() const
|
||||||
{
|
{
|
||||||
json_t* ssl = json_object();
|
json_t* ssl = json_object();
|
||||||
const char* ssl_method = ssl_method_type_to_string(m_version);
|
const char* ssl_method = ssl_method_type_to_string(m_cfg.version);
|
||||||
|
|
||||||
json_object_set_new(ssl, "ssl_version", json_string(ssl_method));
|
json_object_set_new(ssl, "ssl_version", json_string(ssl_method));
|
||||||
json_object_set_new(ssl, "ssl_cert", json_string(m_cert.c_str()));
|
json_object_set_new(ssl, "ssl_cert", json_string(m_cfg.cert.c_str()));
|
||||||
json_object_set_new(ssl, "ssl_ca_cert", json_string(m_ca.c_str()));
|
json_object_set_new(ssl, "ssl_ca_cert", json_string(m_cfg.ca.c_str()));
|
||||||
json_object_set_new(ssl, "ssl_key", json_string(m_key.c_str()));
|
json_object_set_new(ssl, "ssl_key", json_string(m_cfg.key.c_str()));
|
||||||
|
|
||||||
return ssl;
|
return ssl;
|
||||||
}
|
}
|
||||||
@ -400,12 +399,12 @@ std::string SSLContext::to_string() const
|
|||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
|
|
||||||
ss << "\tSSL initialized: yes\n"
|
ss << "\tSSL initialized: yes\n"
|
||||||
<< "\tSSL method type: " << ssl_method_type_to_string(m_version) << "\n"
|
<< "\tSSL method type: " << ssl_method_type_to_string(m_cfg.version) << "\n"
|
||||||
<< "\tSSL certificate verification depth: " << m_verify_depth << "\n"
|
<< "\tSSL certificate verification depth: " << m_cfg.verify_depth << "\n"
|
||||||
<< "\tSSL peer verification : " << (m_verify_peer ? "true" : "false") << "\n"
|
<< "\tSSL peer verification : " << (m_cfg.verify_peer ? "true" : "false") << "\n"
|
||||||
<< "\tSSL certificate: " << m_cert << "\n"
|
<< "\tSSL certificate: " << m_cfg.cert << "\n"
|
||||||
<< "\tSSL key: " << m_key << "\n"
|
<< "\tSSL key: " << m_cfg.key << "\n"
|
||||||
<< "\tSSL CA certificate: " << m_ca << "\n";
|
<< "\tSSL CA certificate: " << m_cfg.ca << "\n";
|
||||||
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ static bool pam_backend_auth_extract(DCB* dcb, GWBUF* buffer)
|
|||||||
*/
|
*/
|
||||||
static bool pam_backend_auth_connectssl(DCB* dcb)
|
static bool pam_backend_auth_connectssl(DCB* dcb)
|
||||||
{
|
{
|
||||||
return dcb->server->ssl_context() != NULL;
|
return dcb->server->ssl_context();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -952,10 +952,8 @@ mxs_auth_state_t gw_send_backend_auth(DCB* dcb)
|
|||||||
mxs_auth_state_t rval = MXS_AUTH_STATE_FAILED;
|
mxs_auth_state_t rval = MXS_AUTH_STATE_FAILED;
|
||||||
|
|
||||||
if (dcb->session == NULL
|
if (dcb->session == NULL
|
||||||
|| (dcb->session->state != SESSION_STATE_CREATED
|
|| (dcb->session->state != SESSION_STATE_CREATED && dcb->session->state != SESSION_STATE_STARTED)
|
||||||
&& dcb->session->state != SESSION_STATE_STARTED)
|
|| (dcb->server->ssl_context() && dcb->ssl_state == SSL_HANDSHAKE_FAILED))
|
||||||
|| (dcb->server->ssl_context()
|
|
||||||
&& dcb->ssl_state == SSL_HANDSHAKE_FAILED))
|
|
||||||
{
|
{
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
@ -4850,24 +4850,26 @@ static void blr_master_get_config(ROUTER_INSTANCE* router, MasterServerConfig* c
|
|||||||
curr_master->password = router->password;
|
curr_master->password = router->password;
|
||||||
curr_master->filestem = router->fileroot;
|
curr_master->filestem = router->fileroot;
|
||||||
/* SSL options */
|
/* SSL options */
|
||||||
if (auto server_ssl = router->service->dbref->server->ssl_context())
|
auto server_ssl = router->service->dbref->server->ssl_config();
|
||||||
|
|
||||||
|
if (!server_ssl.empty())
|
||||||
{
|
{
|
||||||
curr_master->ssl_enabled = router->ssl_enabled;
|
curr_master->ssl_enabled = router->ssl_enabled;
|
||||||
if (router->ssl_version)
|
if (router->ssl_version)
|
||||||
{
|
{
|
||||||
curr_master->ssl_version = router->ssl_version;
|
curr_master->ssl_version = router->ssl_version;
|
||||||
}
|
}
|
||||||
if (!server_ssl->ssl_key().empty())
|
if (!server_ssl.key.empty())
|
||||||
{
|
{
|
||||||
curr_master->ssl_key = server_ssl->ssl_key();
|
curr_master->ssl_key = server_ssl.key;
|
||||||
}
|
}
|
||||||
if (!server_ssl->ssl_cert().empty())
|
if (!server_ssl.cert.empty())
|
||||||
{
|
{
|
||||||
curr_master->ssl_cert = server_ssl->ssl_cert();
|
curr_master->ssl_cert = server_ssl.cert;
|
||||||
}
|
}
|
||||||
if (!server_ssl->ssl_ca().empty())
|
if (!server_ssl.ca.empty())
|
||||||
{
|
{
|
||||||
curr_master->ssl_ca = server_ssl->ssl_ca();
|
curr_master->ssl_ca = server_ssl.ca;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Connect options */
|
/* Connect options */
|
||||||
|
Reference in New Issue
Block a user