24 changes: 21 additions & 3 deletions include/sslopt-vars.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,34 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */

#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
static my_bool opt_use_ssl = 0;
/* Always try to use SSL per default */
static my_bool opt_use_ssl = TRUE;
/* Fall back on unencrypted connections per default */
static my_bool opt_ssl_enforce= FALSE;
static char *opt_ssl_ca = 0;
static char *opt_ssl_capath = 0;
static char *opt_ssl_cert = 0;
static char *opt_ssl_cipher = 0;
static char *opt_ssl_key = 0;
static char *opt_ssl_crl = 0;
static char *opt_ssl_crlpath = 0;
#ifdef MYSQL_CLIENT
static my_bool opt_ssl_verify_server_cert= 0;
#ifndef MYSQL_CLIENT
#error This header is supposed to be used only in the client
#endif
#define SSL_SET_OPTIONS(mysql) \
if (opt_use_ssl) \
{ \
mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, \
opt_ssl_capath, opt_ssl_cipher); \
mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl); \
mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); \
mysql_options(mysql, MYSQL_OPT_SSL_ENFORCE, &opt_ssl_enforce); \
} \
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, \
(char*)&opt_ssl_verify_server_cert)

static my_bool opt_ssl_verify_server_cert= 0;
#else
#define SSL_SET_OPTIONS(mysql) do { } while(0)
#endif
#endif /* SSLOPT_VARS_INCLUDED */
5 changes: 5 additions & 0 deletions mysql-test/r/mysql_ssl.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# WL#6791 Redefine client --ssl option to imply enforced encryption
#
# verify that --ssl makes SSL required against a no-ssl server
End of 5.7 tests
7 changes: 2 additions & 5 deletions mysql-test/r/plugin_auth_sha256_server_default_tls.result
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ SELECT USER(),CURRENT_USER();
USER() CURRENT_USER()
kristofer2@localhost kristofer2@localhost
**** Client default_auth=sha_256_password and server default auth=sha256_password
#### Test is disabled because it requires RSA-keys and this only works
#### with OpenSSL. The reason is that the current client library
#### framework can't know if SSL was attempted or not when the default
#### client auth is switched and hence it will only report that the
#### connection is unencrypted.
user() current_user()
kristofer@localhost kristofer@localhost
**** Client default_auth=native and server default auth=sha256_password
user() current_user()
kristofer@localhost kristofer@localhost
Expand Down
4 changes: 2 additions & 2 deletions mysql-test/r/ssl_cipher.result
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#
# BUG#11760210 - SSL_CIPHER_LIST NOT SET OR RETURNED FOR "SHOW STATUS LIKE 'SSL_CIPHER_LIST'"
#
SHOW STATUS LIKE 'Ssl_cipher';
# must return AES128-SHA
Variable_name Value
Ssl_cipher AES128-SHA
SHOW STATUS LIKE 'Ssl_cipher_list';
Variable_name Value
Ssl_cipher_list AES128-SHA
# must fail since the default SSL cipher is not compatible
1 change: 1 addition & 0 deletions mysql-test/t/mysql_ssl-master.opt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--skip-ssl
26 changes: 26 additions & 0 deletions mysql-test/t/mysql_ssl.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#Want to skip this test from daily Valgrind execution
--source include/no_valgrind_without_big.inc

# This test should work in embedded server after we fix mysqltest
-- source include/not_embedded.inc

# Save the initial number of concurrent sessions
--source include/count_sessions.inc

--echo #
--echo # WL#6791 Redefine client --ssl option to imply enforced encryption
--echo #

--echo # verify that --ssl makes SSL required against a no-ssl server
--error 1
--exec $MYSQL --ssl -e "SHOW STATUS like 'Ssl_cipher'"


--echo End of 5.7 tests


# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc

## This test file is for testing encrypted communication only, not other
## encryption routines that the SSL library happens to provide!
15 changes: 9 additions & 6 deletions mysql-test/t/plugin_auth_sha256_server_default_tls.test
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,15 @@ SELECT USER(),CURRENT_USER();
connection default;
disconnect con2;
--echo **** Client default_auth=sha_256_password and server default auth=sha256_password
--echo #### Test is disabled because it requires RSA-keys and this only works
--echo #### with OpenSSL. The reason is that the current client library
--echo #### framework can't know if SSL was attempted or not when the default
--echo #### client auth is switched and hence it will only report that the
--echo #### connection is unencrypted.
# --exec xterm -e gdb --args $MYSQL -ukristofer -psecret2 --default_auth=sha256_password --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem -e "select user(), current_user()"
# Why using sha256_password requires --ssl=1 ?
# The current client library can't know if SSL was attempted or not
# when the default client auth is switched and hence it will only report
# that the connection is unencrypted forcing the client to ask for RSA keys.
# However, it is possible to inform the client library to enforce SSL using
# MYSQL_OPT_ENFORCE_SSL (or --ssl=1) and this will be enough for the
# sha256_password plugin to safely assume a secure connection despite it hasn't
# really been established yet.
--exec $MYSQL -ukristofer -psecret2 --default_auth=sha256_password --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem --ssl -e "select user(), current_user()"
--echo **** Client default_auth=native and server default auth=sha256_password
--exec $MYSQL -ukristofer -psecret2 --default_auth=mysql_native_password --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem -e "select user(), current_user()"

Expand Down
14 changes: 8 additions & 6 deletions mysql-test/t/ssl_cipher.test
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#but needs to be kept for tests that would need MyISAM in future.
--source include/force_myisam_default.inc

--source include/not_embedded.inc

# Turn on ssl between the client and server
# and run a number of tests

Expand All @@ -15,14 +17,14 @@
# Save the initial number of concurrent sessions
--source include/count_sessions.inc

connect (ssl_con,localhost,root,,,,,SSL);
--echo # must return AES128-SHA
# need to use mysql since mysqltest doesn't support --ssl-cipher
--exec $MYSQL --host=localhost -e "SHOW STATUS LIKE 'Ssl_cipher'; SHOW STATUS LIKE 'Ssl_cipher_list'" --ssl --ssl-cipher=AES128-SHA

# Check Cipher Name and Cipher List
SHOW STATUS LIKE 'Ssl_cipher';
SHOW STATUS LIKE 'Ssl_cipher_list';

connection default;
disconnect ssl_con;
--echo # must fail since the default SSL cipher is not compatible
--error 1
--exec $MYSQL --host=localhost -e "SHOW STATUS LIKE 'Ssl_cipher'; SHOW STATUS LIKE 'Ssl_cipher_list'" --ssl

# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
258 changes: 246 additions & 12 deletions sql-common/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ void init_client_psi_keys(void)

#endif /* HAVE_PSI_INTERFACE */

const char *default_ssl_cipher= "DHE-RSA-AES256-SHA";
uint mysql_port=0;
char *mysql_unix_port= 0;
const char *unknown_sqlstate= "HY000";
Expand Down Expand Up @@ -1248,19 +1249,28 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd)
(STR), MYF(MY_WME)) : NULL; \
} while (0)

#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
#define SET_SSL_OPTION(opt_var,arg) \
#define SET_OPTION(opt_var,arg) \
do { \
if (mysql->options.opt_var) \
my_free(mysql->options.opt_var); \
mysql->options.opt_var= arg ? my_strdup(key_memory_mysql_options, arg, MYF(MY_WME)) : NULL; \
mysql->options.opt_var = arg ? my_strdup(key_memory_mysql_options, arg, MYF(MY_WME)) : NULL; \
} while (0)


#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
#define SET_SSL_OPTION(opt_var,arg) \
do { \
SET_OPTION(opt_var, arg); \
if (mysql->options.opt_var) \
mysql->options.use_ssl= 1
mysql->options.use_ssl = TRUE; \
} while (0)

#define EXTENSION_SET_SSL_STRING(OPTS, X, STR) \
do { \
EXTENSION_SET_STRING(OPTS, X, STR); \
if ((OPTS)->extension->X) \
(OPTS)->use_ssl= 1


(OPTS)->use_ssl = TRUE; \
} while (0)
#else
#define SET_SSL_OPTION(opt_var,arg) \
do { \
Expand Down Expand Up @@ -2808,14 +2818,16 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
mysql->client_flag|= CLIENT_MULTI_RESULTS;

#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
/* consider SSL if any of the SSL mysql_options() is issued */
if (mysql->options.ssl_key || mysql->options.ssl_cert ||
mysql->options.ssl_ca || mysql->options.ssl_capath ||
mysql->options.ssl_cipher ||
(mysql->options.extension && mysql->options.extension->ssl_crl) ||
(mysql->options.extension && mysql->options.extension->ssl_crlpath))
mysql->options.use_ssl= 1;
(mysql->options.extension && mysql->options.extension->ssl_crl) ||
(mysql->options.extension && mysql->options.extension->ssl_crlpath) ||
(mysql->options.extension && mysql->options.extension->ssl_enforce))
mysql->options.use_ssl = TRUE;
if (mysql->options.use_ssl)
mysql->client_flag|= CLIENT_SSL;
mysql->client_flag |= CLIENT_SSL;
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY*/
if (mpvio->db)
mysql->client_flag|= CLIENT_CONNECT_WITH_DB;
Expand Down Expand Up @@ -2847,7 +2859,37 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
end= buff+5;
}
#ifdef HAVE_OPENSSL
if (mysql->client_flag & CLIENT_SSL)

if (mysql->options.extension && mysql->options.extension->ssl_enforce)
{
/*
ssl_enforce=1 means enforce ssl
Don't fallback on unencrypted connection.
*/
/* can't turn enforce on without turning on use_ssl too */
DBUG_ASSERT(mysql->options.use_ssl);
/* enforce=true takes precendence over use=false */
if (!(mysql->server_capabilities & CLIENT_SSL))
{
set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
ER(CR_SSL_CONNECTION_ERROR),
"SSL is required but the server doesn't "
"support it"
);
goto error;
}
}

/*
use_ssl=0 => Disable ssl and connect using unencrypted channel if server
allows it
use_ssl=1, ssl_enforce=0 (default) => attempt ssl connection if possible but
fallback on unencrypted connection if possible.
*/
if ((mysql->server_capabilities & CLIENT_SSL) && mysql->options.use_ssl)
{
/* Do the SSL layering. */
struct st_mysql_options *options= &mysql->options;
Expand All @@ -2856,6 +2898,11 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
const char *cert_error;
unsigned long ssl_error;

if (!mysql->options.ssl_cipher)
{
SET_OPTION(ssl_cipher, default_ssl_cipher);
}

/*
Send mysql->client_flag, max_packet_size - unencrypted otherwise
the server does not know we want to do SSL
Expand Down Expand Up @@ -2918,6 +2965,7 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
MYSQL_TRACE(SSL_CONNECTED, mysql, ());
MYSQL_TRACE_STAGE(mysql, AUTHENTICATE);
}

#endif /* HAVE_OPENSSL */

DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
Expand Down Expand Up @@ -4728,6 +4776,11 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
case MYSQL_OPT_SSL_CRLPATH: EXTENSION_SET_SSL_STRING(&mysql->options,
ssl_crlpath, arg);
break;
case MYSQL_OPT_SSL_ENFORCE: ENSURE_EXTENSIONS_PRESENT(&mysql->options);
mysql->options.extension->ssl_enforce=
(*(my_bool *) arg) ? TRUE : FALSE;
mysql->options.use_ssl= TRUE;
break;
case MYSQL_SERVER_PUBLIC_KEY:
EXTENSION_SET_STRING(&mysql->options, server_public_key_path, arg);
break;
Expand Down Expand Up @@ -4788,6 +4841,187 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
}


/**
Return the current values for the options settable through mysql_options()
Returns the current values for all of the connection options.
Callers should not manipulate the returned data !
Data are valid at the time of returning them until the next C API CALL
arg should always be a pointer to a variable of the appropriate type.
type of variable, based on the parameter:
uint
MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT,
MYSQL_OPT_PROTOCOL
my_bool
MYSQL_OPT_COMPRESS, MYSQL_OPT_LOCAL_INFILE, MYSQL_OPT_USE_REMOTE_CONNECTION,
MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_GUESS_CONNECTION,
MYSQL_SECURE_AUTH, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_OPT_SSL_ENFORCE,
MYSQL_ENABLE_CLEARTEXT_PLUGIN, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
const char *
MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_SHARED_MEMORY_BASE_NAME,
MYSQL_SET_CLIENT_IP, MYSQL_OPT_BIND, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH,
MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CERT, MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH,
MYSQL_OPT_SSL_CIPHER, MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,
MYSQL_SERVER_PUBLIC_KEY
<none, error returned>
MYSQL_OPT_NAMED_PIPE, MYSQL_OPT_CONNECT_ATTR_RESET,
MYSQL_OPT_CONNECT_ATTR_DELETE, MYSQL_INIT_COMMAND
@param mysql The MYSQL connection to operate on
@param option The option to return the value for
@param out arg Must be non-null. Receives the current value.
@return status
@retval 0 SUCCESS
*/

int STDCALL
mysql_get_option(MYSQL *mysql, enum mysql_option option, const void *arg)
{
DBUG_ENTER("mysql_option");
DBUG_PRINT("enter", ("option: %d", (int)option));

if (!arg)
DBUG_RETURN(1);

switch (option) {
case MYSQL_OPT_CONNECT_TIMEOUT:
*((uint *)arg) = mysql->options.connect_timeout;
break;
case MYSQL_OPT_READ_TIMEOUT:
*((uint *)arg)= mysql->options.read_timeout;
break;
case MYSQL_OPT_WRITE_TIMEOUT:
*((uint *)arg)= mysql->options.write_timeout;
break;
case MYSQL_OPT_COMPRESS:
*((my_bool *)arg) = mysql->options.compress ? TRUE : FALSE;
break;
case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
*((uint *)arg)= (mysql->options.client_flag & CLIENT_LOCAL_FILES) ?
TRUE : FALSE;
break;
case MYSQL_READ_DEFAULT_FILE:
*((char **)arg)= mysql->options.my_cnf_file;
break;
case MYSQL_READ_DEFAULT_GROUP:
*((char **)arg)= mysql->options.my_cnf_group;
break;
case MYSQL_SET_CHARSET_DIR:
*((char **)arg)= mysql->options.charset_dir;
break;
case MYSQL_SET_CHARSET_NAME:
*((char **)arg)= mysql->options.charset_name;
break;
case MYSQL_OPT_PROTOCOL:
*((uint *)arg)= mysql->options.protocol;
break;
case MYSQL_SHARED_MEMORY_BASE_NAME:
#if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
*((char **)arg)= mysql->options.shared_memory_base_name;
#else
*((const char **)arg)= "";
#endif
break;
case MYSQL_OPT_USE_REMOTE_CONNECTION:
*((my_bool *)arg)=
(mysql->options.methods_to_use == MYSQL_OPT_USE_REMOTE_CONNECTION) ?
TRUE : FALSE;
break;
case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
*((my_bool *)arg) =
(mysql->options.methods_to_use == MYSQL_OPT_USE_EMBEDDED_CONNECTION) ?
TRUE : FALSE;
break;
case MYSQL_OPT_GUESS_CONNECTION:
*((my_bool *)arg) =
(mysql->options.methods_to_use == MYSQL_OPT_GUESS_CONNECTION) ?
TRUE : FALSE;
break;
case MYSQL_SET_CLIENT_IP:
*((char **)arg) = mysql->options.ci.client_ip;
break;
case MYSQL_SECURE_AUTH:
*((my_bool *)arg)= mysql->options.secure_auth;
break;
case MYSQL_REPORT_DATA_TRUNCATION:
*((my_bool *)arg)= mysql->options.report_data_truncation;
break;
case MYSQL_OPT_RECONNECT:
*((my_bool *)arg)= mysql->reconnect;
break;
case MYSQL_OPT_BIND:
*((char **)arg)= mysql->options.ci.bind_address;
break;
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
*((my_bool *)arg) = (mysql->options.client_flag &
CLIENT_SSL_VERIFY_SERVER_CERT) ? TRUE : FALSE;
break;
case MYSQL_PLUGIN_DIR:
*((char **)arg)= mysql->options.extension ?
mysql->options.extension->plugin_dir : NULL;
break;
case MYSQL_DEFAULT_AUTH:
*((char **)arg)= mysql->options.extension ?
mysql->options.extension->default_auth : NULL;
break;
case MYSQL_OPT_SSL_KEY:
*((char **)arg)= mysql->options.ssl_key;
break;
case MYSQL_OPT_SSL_CERT:
*((char **)arg)= mysql->options.ssl_cert;
break;
case MYSQL_OPT_SSL_CA:
*((char **)arg)= mysql->options.ssl_ca;
break;
case MYSQL_OPT_SSL_CAPATH:
*((char **)arg)= mysql->options.ssl_capath;
break;
case MYSQL_OPT_SSL_CIPHER:
*((char **)arg)= mysql->options.ssl_cipher;
break;
case MYSQL_OPT_SSL_CRL:
*((char **)arg)= mysql->options.extension ?
mysql->options.extension->ssl_crl : NULL;
break;
case MYSQL_OPT_SSL_CRLPATH:
*((char **)arg)= mysql->options.extension ?
mysql->options.extension->ssl_crlpath : NULL;
break;
case MYSQL_OPT_SSL_ENFORCE:
*((my_bool *)arg)= (mysql->options.extension &&
mysql->options.extension->ssl_enforce) ? TRUE : FALSE;
break;
case MYSQL_SERVER_PUBLIC_KEY:
*((char **)arg)= mysql->options.extension ?
mysql->options.extension->server_public_key_path : NULL;
break;
case MYSQL_ENABLE_CLEARTEXT_PLUGIN:
*((my_bool *)arg)= (mysql->options.extension &&
mysql->options.extension->enable_cleartext_plugin) ?
TRUE : FALSE;
break;
case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS:
*((my_bool*)arg)= (mysql->options.client_flag &
CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS) ? TRUE : FALSE;
break;

case MYSQL_OPT_NAMED_PIPE: /* This option is depricated */
case MYSQL_INIT_COMMAND: /* Cumulative */
case MYSQL_OPT_CONNECT_ATTR_RESET: /* Cumulative */
case MYSQL_OPT_CONNECT_ATTR_DELETE: /* Cumulative */
default:
DBUG_RETURN(1);
}
DBUG_RETURN(0);
}


/**
A function to return the key from a connection attribute
*/
Expand Down
20 changes: 19 additions & 1 deletion sql-common/client_authentication.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ int sha256_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
bool connection_is_secure= false;
unsigned char scramble_pkt[20];
unsigned char *pkt;
my_bool ssl_enforce= FALSE;


DBUG_ENTER("sha256_password_auth_client");
Expand All @@ -164,9 +165,26 @@ int sha256_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
*/
memcpy(scramble_pkt, pkt, SCRAMBLE_LENGTH);

if (mysql_get_option(mysql, MYSQL_OPT_SSL_ENFORCE, &ssl_enforce))
ssl_enforce= FALSE;

if (mysql_get_ssl_cipher(mysql) != NULL)
connection_is_secure= true;

/*
If set to the default plugin, then the client and server haven't
attempted a SSL connection yet and there is no way of knowing if this will
be successful later on when encryption is needed.
The only way to be sure that SSL will be established is to check if the
client enforce SSL.
If MYSQL_OPT_ENFORCE_SSL flag isn't set then SSL might be established but
the client will still expect RSA keys from the server and fail if those
aren't available.
*/
else if (ssl_enforce)
connection_is_secure= true; // Safely assume connection will be encrypted

/* If connection isn't secure attempt to get the RSA public key file */
if (!connection_is_secure)
{
Expand Down
7 changes: 5 additions & 2 deletions sql/rpl_slave.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6966,18 +6966,21 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
#ifdef HAVE_OPENSSL
if (mi->ssl)
{
const static my_bool ssl_enforce_true= TRUE;
mysql_ssl_set(mysql,
mi->ssl_key[0]?mi->ssl_key:0,
mi->ssl_cert[0]?mi->ssl_cert:0,
mi->ssl_ca[0]?mi->ssl_ca:0,
mi->ssl_capath[0]?mi->ssl_capath:0,
mi->ssl_cipher[0]?mi->ssl_cipher:0);
mysql_options(mysql, MYSQL_OPT_SSL_CRL,
mysql_options(mysql, MYSQL_OPT_SSL_CRL,
mi->ssl_crl[0] ? mi->ssl_crl : 0);
mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH,
mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH,
mi->ssl_crlpath[0] ? mi->ssl_crlpath : 0);
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
&mi->ssl_verify_server_cert);
/* we always enforce SSL if SSL is turned on */
mysql_options(mysql, MYSQL_OPT_SSL_ENFORCE, &ssl_enforce_true);
}
#endif

Expand Down
109 changes: 109 additions & 0 deletions tests/mysql_client_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -19514,6 +19514,114 @@ static void test_wl6797()
mysql_stmt_close(stmt);
}


static void test_wl6791()
{
int rc;
uint idx;
MYSQL *l_mysql;
enum mysql_option
uint_opts[] = {
MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT,
MYSQL_OPT_PROTOCOL, MYSQL_OPT_LOCAL_INFILE
},
my_bool_opts[] = {
MYSQL_OPT_COMPRESS, MYSQL_OPT_USE_REMOTE_CONNECTION,
MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_GUESS_CONNECTION,
MYSQL_SECURE_AUTH, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_OPT_SSL_ENFORCE,
MYSQL_ENABLE_CLEARTEXT_PLUGIN, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
},
const_char_opts[] = {
MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME,
#if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
/* mysql_options() is a no-op on non-supporting platforms. */
MYSQL_SHARED_MEMORY_BASE_NAME,
#endif
MYSQL_SET_CLIENT_IP, MYSQL_OPT_BIND, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH,
MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CERT, MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH,
MYSQL_OPT_SSL_CIPHER, MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,
MYSQL_SERVER_PUBLIC_KEY
},
err_opts[] = {
MYSQL_OPT_NAMED_PIPE, MYSQL_OPT_CONNECT_ATTR_RESET,
MYSQL_OPT_CONNECT_ATTR_DELETE, MYSQL_INIT_COMMAND
};

myheader("test_wl6791");

/* prepare the connection */
l_mysql = mysql_client_init(NULL);
DIE_UNLESS(l_mysql != NULL);

for (idx= 0; idx < sizeof(uint_opts) / sizeof(enum mysql_option); idx++)
{
uint opt_before= 1, opt_after= 0;

if (!opt_silent)
fprintf(stdout, "testing uint option #%d (%d)\n", idx,
(int) uint_opts[idx]);
rc= mysql_options(l_mysql, uint_opts[idx], &opt_before);
DIE_UNLESS(rc == 0);

rc = mysql_get_option(l_mysql, uint_opts[idx], &opt_after);
DIE_UNLESS(rc == 0);

DIE_UNLESS(opt_before == opt_after);
}

for (idx= 0; idx < sizeof(my_bool_opts) / sizeof(enum mysql_option); idx++)
{
my_bool opt_before = TRUE, opt_after = FALSE;

if (!opt_silent)
fprintf(stdout, "testing my_bool option #%d (%d)\n", idx,
(int)my_bool_opts[idx]);

rc = mysql_options(l_mysql, my_bool_opts[idx], &opt_before);
DIE_UNLESS(rc == 0);

rc = mysql_get_option(l_mysql, my_bool_opts[idx], &opt_after);
DIE_UNLESS(rc == 0);

DIE_UNLESS(opt_before == opt_after);
}

for (idx= 0; idx < sizeof(const_char_opts) / sizeof(enum mysql_option); idx++)
{
const char *opt_before = "TEST", *opt_after = NULL;

if (!opt_silent)
fprintf(stdout, "testing const char * option #%d (%d)\n", idx,
(int)const_char_opts[idx]);

rc = mysql_options(l_mysql, const_char_opts[idx], opt_before);
DIE_UNLESS(rc == 0);

rc = mysql_get_option(l_mysql, const_char_opts[idx], &opt_after);
DIE_UNLESS(rc == 0);

DIE_UNLESS(opt_before && opt_after &&
0 == strcmp(opt_before, opt_after));
}

for (idx= 0; idx < sizeof(err_opts) / sizeof(enum mysql_option); idx++)
{
void *dummy_arg;
if (!opt_silent)
fprintf(stdout, "testing invalid option #%d (%d)\n", idx,
(int)err_opts[idx]);

rc = mysql_get_option(l_mysql, err_opts[idx], &dummy_arg);
DIE_UNLESS(rc != 0);
}

/* clean up */
mysql_close(l_mysql);
}


static struct my_tests_st my_tests[]= {
{ "disable_query_logs", disable_query_logs },
{ "test_view_sp_list_fields", test_view_sp_list_fields },
Expand Down Expand Up @@ -19785,6 +19893,7 @@ static struct my_tests_st my_tests[]= {
{ "test_wl6587", test_wl6587 },
{ "test_wl5928", test_wl5928 },
{ "test_wl6797", test_wl6797 },
{ "test_wl6791", test_wl6791 },
{ 0, 0 }
};

Expand Down