Reputation: 4058
I'm writing a C++ client application connecting to a MariaDB server with a MariaDB C connector. This code works:
this->mysql = mysql_init(0);
int timeout_sec = 10;
int ret = mysql_options(this->mysql, MYSQL_OPT_CONNECT_TIMEOUT, &timeout_sec);
assert(ret == 0);
auto ret_mysql = mysql_real_connect(this->mysql,
this->host.c_str(),
this->username.c_str(),
this->password.c_str(),
this->db_name.c_str(),
this->port,
nullptr,
0);
if (ret_mysql == nullptr) {
// An error occurred.
throw MyException("Database",mysql_error(this->mysql));
}
However, I would like to enable SSL and, because I'm using a server with a self-signed certificate, I need to add the CA file, therefore I added (before the connect):
int ret;
ret = mysql_options(this->pimpl->mysql, MYSQL_OPT_SSL_CA, ca_file.c_str());
assert(ret == 0);
However, if I add these lines, the mysql_real_connect then fails with a "Connection timeout".
Extra notes:
The server works fine with SSL with other clients
The certificate path/file is OK
If I increase the timeout values to 20, then I get a "Connection reset by peer"
I tried to use the deprecated mysql_ssl_set()
with no success (same result)
I tried to also set MYSQL_OPT_SSL_ENFORCE
/ MYSQL_OPT_SSL_VERIFY_SERVER_CERT
with no success
The server logs show:
[Warning] Aborted connection 12345 to db: 'unconnected' user: 'unauthenticated' host: '<ip_address>' (This connection closed normally without authentication)
Any idea what can be the problem? Perhaps, there is some other function to call before the connect?
--EDIT--
Apparently the problem was a SSL error due to a certificate common name mismatch. I fixed the issue and now it works. However, why if there is a problem with SSL it generates a timeout/connection reset by peer rather than returning an error as expected?
Upvotes: 0
Views: 163
Reputation: 874
I'll try an answer to the updated question, guessing some details that aren't in your post.
The list of "Errors" documented for mysql_real_connect()
doesn't include one for "TLS/SSL error: Validation of SSL server certificate failed". I guess you're getting a CR_SERVER_LOST
("If connect_timeout > 0 and it took longer than connect_timeout seconds to connect to the server or if the server died while executing the init-command.") This error is directly related to the MYSQL_OPT_CONNECT_TIMEOUT
you're actually using. I think the server is just ignoring your call when the certificate is invalid, and that results in a timeout at the client (ie. the client aborts after waiting too much for a response).
I can't explain why you get a "Connection reset by peer" when you increase the timeout, but this error is signaled/detected by the client network layer after the server explicitly closes the communication channel (before the client times out).
The command-line 'mysql' client may be using an explicit call to MYSQL_OPT_SSL_MODE
option with a value of SSL_MODE_VERIFY_CA
. You could do the same using mysql_options()
. Please check https://dev.mysql.com/doc/refman/8.0/en/connection-options.html#option_general_ssl-mode.
Upvotes: 0