summaryrefslogtreecommitdiff
path: root/sql-common
diff options
context:
space:
mode:
authorRamil Kalimullin <ramil.kalimullin@oracle.com>2017-03-10 01:19:50 +0400
committerRamil Kalimullin <ramil.kalimullin@oracle.com>2017-03-10 01:19:50 +0400
commit2531c8dcd152bedeeebfe07d5e4a29bd84357c27 (patch)
tree25a818224d40ca50d38e8971c504b64475929d8b /sql-common
parentec2a6b6035ed842e39bcecc2c62c39758bda02fb (diff)
downloadmariadb-git-2531c8dcd152bedeeebfe07d5e4a29bd84357c27.tar.gz
BUG#25575605: SETTING --SSL-MODE=REQUIRED SENDS CREDENTIALS BEFORE VERIFYING SSL CONNECTION
MYSQL_OPT_SSL_MODE option introduced. It is set in case of --ssl-mode=REQUIRED and permits only SSL connection.
Diffstat (limited to 'sql-common')
-rw-r--r--sql-common/client.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/sql-common/client.c b/sql-common/client.c
index 3a6e205d384..759d95117cb 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1137,7 +1137,7 @@ static const char *default_options[]=
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
"multi-results", "multi-statements", "multi-queries", "secure-auth",
"report-data-truncation", "plugin-dir", "default-auth",
- "enable-cleartext-plugin",
+ "enable-cleartext-plugin", "ssl-mode",
NullS
};
enum option_id {
@@ -1149,7 +1149,7 @@ enum option_id {
OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name,
OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth,
OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth,
- OPT_enable_cleartext_plugin,
+ OPT_enable_cleartext_plugin, OPT_ssl_mode,
OPT_keep_this_one_last
};
@@ -1338,12 +1338,26 @@ void mysql_read_default_options(struct st_mysql_options *options,
my_free(options->ssl_cipher);
options->ssl_cipher= my_strdup(opt_arg, MYF(MY_WME));
break;
+ case OPT_ssl_mode:
+ if (opt_arg &&
+ !my_strcasecmp(&my_charset_latin1, opt_arg, "required"))
+ {
+ ENSURE_EXTENSIONS_PRESENT(options);
+ options->extension->ssl_mode= SSL_MODE_REQUIRED;
+ }
+ else
+ {
+ fprintf(stderr, "Unknown option to ssl-mode: %s\n", opt_arg);
+ exit(1);
+ }
+ break;
#else
case OPT_ssl_key:
case OPT_ssl_cert:
case OPT_ssl_ca:
case OPT_ssl_capath:
case OPT_ssl_cipher:
+ case OPT_ssl_mode:
break;
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
case OPT_character_sets_dir:
@@ -1850,6 +1864,10 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
mysql->options.ssl_capath = 0;
mysql->options.ssl_cipher= 0;
mysql->options.use_ssl = FALSE;
+ if (mysql->options.extension)
+ {
+ mysql->options.extension->ssl_mode= 0;
+ }
mysql->connector_fd = 0;
DBUG_VOID_RETURN;
}
@@ -2596,6 +2614,31 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
end= buff+5;
}
#ifdef HAVE_OPENSSL
+ /*
+ If SSL connection is required we'll:
+ 1. check if the server supports SSL;
+ 2. check if the client is properly configured;
+ 3. try to use SSL no matter the other options given.
+ */
+ if (mysql->options.extension &&
+ mysql->options.extension->ssl_mode == SSL_MODE_REQUIRED)
+ {
+ if (!(mysql->server_capabilities & CLIENT_SSL))
+ {
+ set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
+ ER(CR_SSL_CONNECTION_ERROR),
+ "Server doesn't support SSL");
+ goto error;
+ }
+ if (!mysql->options.use_ssl)
+ {
+ set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
+ ER(CR_SSL_CONNECTION_ERROR),
+ "Client is not configured to use SSL");
+ goto error;
+ }
+ mysql->client_flag|= CLIENT_SSL;
+ }
if (mysql->client_flag & CLIENT_SSL)
{
/* Do the SSL layering. */
@@ -4242,6 +4285,13 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
mysql->options.extension->enable_cleartext_plugin=
(*(my_bool*) arg) ? TRUE : FALSE;
break;
+ case MYSQL_OPT_SSL_MODE:
+ if (*(uint *) arg == SSL_MODE_REQUIRED)
+ {
+ ENSURE_EXTENSIONS_PRESENT(&mysql->options);
+ mysql->options.extension->ssl_mode= SSL_MODE_REQUIRED;
+ }
+ break;
default:
DBUG_RETURN(1);
}