CVE-2015-3152: Improper Certificate Validation (CWE-295)
value: Oracle MySQL before 5.7.3, Oracle MySQL Connector/C (aka libmysqlclient) before 6.1.3, and MariaDB before 5.5.44 use the --ssl option to mean that SSL is optional, which allows man-in-the-middle attackers to spoof servers via a cleartext-downgrade attack, aka a "BACKRONYM" attack.
CWE description: The product does not validate, or incorrectly validates, a certificate.
CVSS v3 base score: 5.9
Published: 2016-05-16T10:59Z
Repository: https://github.com/mysql/mysql-server
Language: C
Files changed: client/mysql.cc, client/mysql_secure_installation.cc, client/mysql_upgrade.c, client/mysqladmin.cc, client/mysqlbinlog.cc, client/mysqlcheck.c, client/mysqldump.c, client/mysqlimport.c, client/mysqlshow.c, client/mysqlslap.c, client/mysqltest.cc, cmake/mysql_version.cmake, include/mysql.h, include/mysql.h.pp, include/sql_common.h, include/sslopt-case.h, include/sslopt-longopts.h, include/sslopt-vars.h, mysql-test/r/mysql_ssl.result, mysql-test/r/plugin_auth_sha256_server_default_tls.result, mysql-test/r/ssl_cipher.result, mysql-test/t/mysql_ssl-master.opt, mysql-test/t/mysql_ssl.test, mysql-test/t/plugin_auth_sha256_server_default_tls.test, mysql-test/t/ssl_cipher.test, sql-common/client.c, sql-common/client_authentication.cc, sql/rpl_slave.cc, tests/mysql_client_test.c
Commit date: 2013-10-31 11:35:15 +0200
Commit message: WL#6791 : Redefine client --ssl option to imply enforced encryption

# Changed the meaning of the --ssl=1 option of all client binaries
to mean force ssl, not try ssl and fail over to eunecrypted
# Added a new MYSQL_OPT_SSL_ENFORCE mysql_options()
option to specify that an ssl connection is required.
# Added a new macro SSL_SET_OPTIONS() to the client
SSL handling headers that sets all the relevant SSL options at 
once.
# Revamped all of the current native clients to use the new macro
# Removed some Windows line endings.
# Added proper handling of the new option into the ssl helper
headers.
# If SSL is mandatory assume that the media is secure enough 
for the sha256 plugin to do unencrypted password exchange even
before establishing a connection.
# Set the default ssl cipher to DHE-RSA-AES256-SHA if none is 
specified.
# updated test cases that require a non-default cipher to spawn 
a mysql command line tool binary since mysqltest has no support
for specifying ciphers.
# updated the replication slave connection code to always enforce
SSL if any of the SSL config options is present.
# test cases added and updated.
# added a mysql_get_option() API to return mysql_options() 
values. Used the new API inside the sha256 plugin.
# Fixed compilation warnings because of unused variables.
# Fixed test failures (mysql_ssl and bug13115401)
# Fixed whitespace issues.
# Fully implemented the mysql_get_option() function.
# Added a test case for mysql_get_option()
# fixed some trailing whitespace issues
# fixed some uint/int warnings in mysql_client_test.c
# removed shared memory option from non-windows get_options
 tests
# moved MYSQL_OPT_LOCAL_INFILE to the uint options
Diff: diff --git a/client/mysql.cc b/client/mysql.cc
index e99fe6bd2d..a503b79f78 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -4951,21 +4951,11 @@ init_connection_options(MYSQL *mysql)
     mysql_options(mysql, MYSQL_SECURE_AUTH, (char *) &opt_secure_auth);
 
   if (using_opt_local_infile)
     mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, (char*) &opt_local_infile);
 
-#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
-  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_VERIFY_SERVER_CERT,
-                (char*) &opt_ssl_verify_server_cert);
-#endif
+  SSL_SET_OPTIONS(mysql);
 
   if (opt_protocol)
     mysql_options(mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
 
 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
diff --git a/client/mysql_secure_installation.cc b/client/mysql_secure_installation.cc
index 3b4985fd9e..e5b4d82fa3 100644
--- a/client/mysql_secure_installation.cc
+++ b/client/mysql_secure_installation.cc
@@ -156,21 +156,11 @@ my_arguments_get_one_option(int optid,
 
 /* Initialize options for the given connection handle. */
 static void
 init_connection_options(MYSQL *mysql)
 {
-#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
-  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_VERIFY_SERVER_CERT,
-                (char*) &opt_ssl_verify_server_cert);
-#endif
+  SSL_SET_OPTIONS(mysql);
 
   if (opt_protocol)
     mysql_options(mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
 
 #ifdef HAVE_SMEM
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index f5e689196d..51c4cfce01 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -286,11 +286,11 @@ get_one_option(int optid, const struct my_option *opt,
   case 'f': /* --force     */
   case 's':                                     /* --upgrade-system-tables */
   case OPT_WRITE_BINLOG:                        /* --write-binlog */
     add_option= FALSE;
     break;
-
+#include <sslopt-case.h>
   case 'h': /* --host */
   case 'W': /* --pipe */
   case 'P': /* --port */
   case 'S': /* --socket */
   case OPT_MYSQL_PROTOCOL: /* --protocol */
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 381e9c68ec..d70c8f742e 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -359,21 +359,11 @@ int main(int argc,char *argv[])
   if (opt_connect_timeout)
   {
     uint tmp=opt_connect_timeout;
     mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT, (char*) &tmp);
   }
-#ifdef HAVE_OPENSSL
-  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_VERIFY_SERVER_CERT,
-                (char*)&opt_ssl_verify_server_cert);
-#endif
+  SSL_SET_OPTIONS(&mysql);
   if (opt_protocol)
     mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
   if (shared_memory_base_name)
     mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index f89cb6234d..fdf795bfc7 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -1883,21 +1883,11 @@ static Exit_status safe_connect()
   {
     error("Failed on mysql_init.");
     return ERROR_STOP;
   }
 
-#ifdef HAVE_OPENSSL
-  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_VERIFY_SERVER_CERT,
-                (char*) &opt_ssl_verify_server_cert);
-#endif
+  SSL_SET_OPTIONS(mysql);
 
   if (opt_plugin_dir && *opt_plugin_dir)
     mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
 
   if (opt_default_auth && *opt_default_auth)
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index cb4cdb84c9..15791fa8c7 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -879,19 +879,11 @@ static int dbConnect(char *host, char *user, char *passwd)
     fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
   }
   mysql_init(&mysql_connection);
   if (opt_compress)
     mysql_options(&mysql_connection, MYSQL_OPT_COMPRESS, NullS);
-#ifdef HAVE_OPENSSL
-  if (opt_use_ssl)
-  {
-    mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
-		  opt_ssl_capath, opt_ssl_cipher);
-    mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
-    mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
-  }
-#endif
+  SSL_SET_OPTIONS(&mysql_connection);
   if (opt_protocol)
     mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
   if (opt_bind_addr)
     mysql_options(&mysql_connection, MYSQL_OPT_BIND, opt_bind_addr);
 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 71160afde9..4b776014f1 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -1593,21 +1593,11 @@ static int connect_to_db(char *host, char *user,char *passwd)
 
   verbose_msg("-- Connecting to %s...\n", host ? host : "localhost");
   mysql_init(&mysql_connection);
   if (opt_compress)
     mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
-#ifdef HAVE_OPENSSL
-  if (opt_use_ssl)
-  {
-    mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
-                  opt_ssl_capath, opt_ssl_cipher);
-    mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
-    mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
-  }
-  mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
-                (char*)&opt_ssl_verify_server_cert);
-#endif
+  SSL_SET_OPTIONS(&mysql_connection);
   if (opt_protocol)
     mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
   if (opt_bind_addr)
     mysql_options(&mysql_connection,MYSQL_OPT_BIND,opt_bind_addr);
 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index eebb89382d..3748fc1731 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -418,21 +418,11 @@ static MYSQL *db_connect(char *host, char *database,
   if (opt_compress)
     mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS);
   if (opt_local_file)
     mysql_options(mysql,MYSQL_OPT_LOCAL_INFILE,
 		  (char*) &opt_local_file);
-#ifdef HAVE_OPENSSL
-  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_VERIFY_SERVER_CERT,
-                (char*)&opt_ssl_verify_server_cert);
-#endif
+  SSL_SET_OPTIONS(mysql);
   if (opt_protocol)
     mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
   if (opt_bind_addr)
     mysql_options(mysql,MYSQL_OPT_BIND,opt_bind_addr);
 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index cf81588baf..c7756d0d19 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -115,21 +115,11 @@ int main(int argc, char **argv)
     exit(1);
   }
   mysql_init(&mysql);
   if (opt_compress)
     mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
-#ifdef HAVE_OPENSSL
-  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_VERIFY_SERVER_CERT,
-                (char*)&opt_ssl_verify_server_cert);
-#endif
+  SSL_SET_OPTIONS(&mysql);
   if (opt_protocol)
     mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
   if (opt_bind_addr)
     mysql_options(&mysql,MYSQL_OPT_BIND,opt_bind_addr);
 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index a892806bc4..6cb9bb760e 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -142,12 +142,12 @@ static my_bool opt_compress= FALSE, tty_password= FALSE,
                auto_generate_sql_guid_primary= FALSE,
                auto_generate_sql= FALSE;
 const char *auto_generate_sql_type= "mixed";
 
 static unsigned long connect_flags= CLIENT_MULTI_RESULTS |
-                                    CLIENT_MULTI_STATEMENTS |
-                                    CLIENT_REMEMBER_OPTIONS;
+                                    CLIENT_MULTI_STATEMENTS |
+                                    CLIENT_REMEMBER_OPTIONS;
 
 
 static int verbose, delimiter_length;
 static uint commit_rate;
 static uint detach_rate;
@@ -333,19 +333,11 @@ int main(int argc, char **argv)
     exit(1);
   }
   mysql_init(&mysql);
   if (opt_compress)
     mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
-#ifdef HAVE_OPENSSL
-  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);
-  }
-#endif
+  SSL_SET_OPTIONS(&mysql);
   if (opt_protocol)
     mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
   if (shared_memory_base_name)
     mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index ff5aa9449e..2844868543 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -5505,10 +5505,13 @@ void do_connect(struct st_command *command)
   char *con_options;
   my_bool con_ssl= 0, con_compress= 0;
   my_bool con_pipe= 0, con_shm= 0, con_cleartext_enable= 0;
   my_bool con_secure_auth= 1;
   struct st_connection* con_slot;
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
+  my_bool save_opt_use_ssl= opt_use_ssl;
+#endif
 
   static DYNAMIC_STRING ds_connection_name;
   static DYNAMIC_STRING ds_host;
   static DYNAMIC_STRING ds_user;
   static DYNAMIC_STRING ds_password;
@@ -5639,27 +5642,26 @@ void do_connect(struct st_command *command)
                   opt_charsets_dir);
 
 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
   if (opt_use_ssl)
     con_ssl= 1;
-#endif
 
-  if (con_ssl)
+  opt_use_ssl= con_ssl;
+
+  if (opt_use_ssl)
   {
-#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
-    mysql_ssl_set(&con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
-		  opt_ssl_capath, opt_ssl_cipher);
-    mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
-    mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
-#if MYSQL_VERSION_ID >= 50000
     /* Turn on ssl_verify_server_cert only if host is "localhost" */
     opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost");
-    mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
-                  &opt_ssl_verify_server_cert);
+  }
+#else
+  /* keep the compiler happy about con_ssl */
+  con_ssl = con_ssl ? TRUE : FALSE;
 #endif
+  SSL_SET_OPTIONS(&con_slot->mysql);
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
+  opt_use_ssl= save_opt_use_ssl;
 #endif
-  }
 
   if (con_pipe)
   {
 #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
     opt_protocol= MYSQL_PROTOCOL_PIPE;
@@ -8762,26 +8764,20 @@ int main(int argc, char **argv)
 #ifndef EMBEDDED_LIBRARY
   if (opt_protocol)
     mysql_options(&con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 #endif
 
-#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
 
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
   if (opt_use_ssl)
   {
-    mysql_ssl_set(&con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
-		  opt_ssl_capath, opt_ssl_cipher);
-    mysql_options(&con->mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
-    mysql_options(&con->mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
-#if MYSQL_VERSION_ID >= 50000
     /* Turn on ssl_verify_server_cert only if host is "localhost" */
     opt_ssl_verify_server_cert= opt_host && !strcmp(opt_host, "localhost");
-    mysql_options(&con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
-                  &opt_ssl_verify_server_cert);
-#endif
   }
 #endif
+  SSL_SET_OPTIONS(&con->mysql);
+
 
 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
   if (shared_memory_base_name)
     mysql_options(&con->mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
 #endif
diff --git a/cmake/mysql_version.cmake b/cmake/mysql_version.cmake
index c9631db1c2..0beab367fd 100644
--- a/cmake/mysql_version.cmake
+++ b/cmake/mysql_version.cmake
@@ -16,11 +16,11 @@
 #
 # Global constants, only to be changed between major releases.
 #
 
 SET(SHARED_LIB_MAJOR_VERSION "18")
-SET(SHARED_LIB_MINOR_VERSION "1")
+SET(SHARED_LIB_MINOR_VERSION "2")
 SET(PROTOCOL_VERSION "10")
 SET(DOT_FRM_VERSION "6")
 
 # Generate "something" to trigger cmake rerun when VERSION changes
 CONFIGURE_FILE(
diff --git a/include/mysql.h b/include/mysql.h
index 72b94b936c..689161cf71 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -157,11 +157,12 @@ enum mysql_option
   MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,
   MYSQL_OPT_CONNECT_ATTR_RESET, MYSQL_OPT_CONNECT_ATTR_ADD,
   MYSQL_OPT_CONNECT_ATTR_DELETE,
   MYSQL_SERVER_PUBLIC_KEY,
   MYSQL_ENABLE_CLEARTEXT_PLUGIN,
-  MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
+  MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,
+  MYSQL_OPT_SSL_ENFORCE
 };
 
 /**
   @todo remove the "extension", move st_mysql_options completely
   out of mysql.h
@@ -449,10 +450,12 @@ MYSQL_RES *	STDCALL mysql_list_tables(MYSQL *mysql,const char *wild);
 MYSQL_RES *	STDCALL mysql_list_processes(MYSQL *mysql);
 int		STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
 				      const void *arg);
 int		STDCALL mysql_options4(MYSQL *mysql,enum mysql_option option,
                                        const void *arg1, const void *arg2);
+int             STDCALL mysql_get_option(MYSQL *mysql, enum mysql_option option,
+                                         const void *arg);
 void		STDCALL mysql_free_result(MYSQL_RES *result);
 void		STDCALL mysql_data_seek(MYSQL_RES *result,
 					my_ulonglong offset);
 MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result,
 						MYSQL_ROW_OFFSET offset);
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index 220f68ebc5..82cb087e43 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -314,11 +314,12 @@ enum mysql_option
   MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,
   MYSQL_OPT_CONNECT_ATTR_RESET, MYSQL_OPT_CONNECT_ATTR_ADD,
   MYSQL_OPT_CONNECT_ATTR_DELETE,
   MYSQL_SERVER_PUBLIC_KEY,
   MYSQL_ENABLE_CLEARTEXT_PLUGIN,
-  MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
+  MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,
+  MYSQL_OPT_SSL_ENFORCE
 };
 struct st_mysql_options_extention;
 struct st_mysql_options {
   unsigned int connect_timeout, read_timeout, write_timeout;
   unsigned int port, protocol;
@@ -516,10 +517,12 @@ MYSQL_RES * mysql_list_tables(MYSQL *mysql,const char *wild);
 MYSQL_RES * mysql_list_processes(MYSQL *mysql);
 int mysql_options(MYSQL *mysql,enum mysql_option option,
           const void *arg);
 int mysql_options4(MYSQL *mysql,enum mysql_option option,
                                        const void *arg1, const void *arg2);
+int mysql_get_option(MYSQL *mysql, enum mysql_option option,
+                                         const void *arg);
 void mysql_free_result(MYSQL_RES *result);
 void mysql_data_seek(MYSQL_RES *result,
      my_ulonglong offset);
 MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result,
       MYSQL_ROW_OFFSET offset);
diff --git a/include/sql_common.h b/include/sql_common.h
index f99df2a74e..6d7545bb95 100644
--- a/include/sql_common.h
+++ b/include/sql_common.h
@@ -65,10 +65,12 @@ struct st_mysql_options_extention {
   char *ssl_crlpath;				/* PEM directory of CRL-s? */
   HASH connection_attributes;
   char *server_public_key_path;
   size_t connection_attributes_length;
   my_bool enable_cleartext_plugin;
+  /** false if it is possible to fall back on unencrypted connections */
+  my_bool ssl_enforce;
 };
 
 typedef struct st_mysql_methods
 {
   my_bool (*read_query_result)(MYSQL *mysql);
diff --git a/include/sslopt-case.h b/include/sslopt-case.h
index 25817587aa..fe2c42dd09 100644
--- a/include/sslopt-case.h
+++ b/include/sslopt-case.h
@@ -15,10 +15,21 @@
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
 
 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
+#ifdef MYSQL_CLIENT
+    case OPT_SSL_SSL:
+      /*
+        A client side --ssl option handling.
+        --ssl=1 means enforce (use=1, enforce=1)
+	--ssl=0 means can't enforce (use=0, enforce=0)
+	no --ssl means default : no enforce (use=1), just try (enforce=1)
+      */
+      opt_ssl_enforce= opt_use_ssl;
+      break;
+#endif
     case OPT_SSL_KEY:
     case OPT_SSL_CERT:
     case OPT_SSL_CA:
     case OPT_SSL_CAPATH:
     case OPT_SSL_CIPHER:
@@ -26,11 +37,11 @@
     case OPT_SSL_CRLPATH:
     /*
       Enable use of SSL if we are using any ssl option
       One can disable SSL later by using --skip-ssl or --ssl=0
     */
-      opt_use_ssl= 1;
+      opt_use_ssl= TRUE;
     /* crl has no effect in yaSSL */  
 #ifdef HAVE_YASSL
       opt_ssl_crl= NULL;
       opt_ssl_crlpath= NULL;
 #endif
diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h
index 8280f3b8f1..f295eea826 100644
--- a/include/sslopt-longopts.h
+++ b/include/sslopt-longopts.h
@@ -17,34 +17,36 @@
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
 
 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
 
   {"ssl", OPT_SSL_SSL,
-   "Enable SSL for connection (automatically enabled with other flags).",
+   "If set to ON, this option enforces that SSL is established before client "
+   "attempts to authenticate to the server. To disable client SSL capabilities "
+   "use --ssl=OFF.",
    &opt_use_ssl, &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
   {"ssl-ca", OPT_SSL_CA,
-   "CA file in PEM format (check OpenSSL docs, implies --ssl).",
+   "CA file in PEM format.",
    &opt_ssl_ca, &opt_ssl_ca, 0, GET_STR, REQUIRED_ARG,
    0, 0, 0, 0, 0, 0},
   {"ssl-capath", OPT_SSL_CAPATH,
-   "CA directory (check OpenSSL docs, implies --ssl).",
+   "CA directory.",
    &opt_ssl_capath, &opt_ssl_capath, 0, GET_STR, REQUIRED_ARG,
    0, 0, 0, 0, 0, 0},
-  {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format (implies --ssl).",
+  {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format.",
    &opt_ssl_cert, &opt_ssl_cert, 0, GET_STR, REQUIRED_ARG,
    0, 0, 0, 0, 0, 0},
-  {"ssl-cipher", OPT_SSL_CIPHER, "SSL cipher to use (implies --ssl).",
+  {"ssl-cipher", OPT_SSL_CIPHER, "SSL cipher to use.",
    &opt_ssl_cipher, &opt_ssl_cipher, 0, GET_STR, REQUIRED_ARG,
    0, 0, 0, 0, 0, 0},
-  {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl).",
+  {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format.",
    &opt_ssl_key, &opt_ssl_key, 0, GET_STR, REQUIRED_ARG,
    0, 0, 0, 0, 0, 0},
-  {"ssl-crl", OPT_SSL_CRL, "Certificate revocation list (implies --ssl).",
+  {"ssl-crl", OPT_SSL_CRL, "Certificate revocation list.",
    &opt_ssl_crl, &opt_ssl_crl, 0, GET_STR, REQUIRED_ARG,
    0, 0, 0, 0, 0, 0},
   {"ssl-crlpath", OPT_SSL_CRLPATH, 
-    "Certificate revocation list path (implies --ssl).",
+    "Certificate revocation list path.",
    &opt_ssl_crlpath, &opt_ssl_crlpath, 0, GET_STR, REQUIRED_ARG,
    0, 0, 0, 0, 0, 0},
 #ifdef MYSQL_CLIENT
   {"ssl-verify-server-cert", OPT_SSL_VERIFY_SERVER_CERT,
    "Verify server's \"Common Name\" in its cert against hostname used "
diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h
index 05a5f507a3..43900a4c3d 100644
--- a/include/sslopt-vars.h
+++ b/include/sslopt-vars.h
@@ -15,18 +15,36 @@
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    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 */
diff --git a/mysql-test/r/mysql_ssl.result b/mysql-test/r/mysql_ssl.result
new file mode 100644
index 0000000000..4b87cc2135
--- /dev/null
+++ b/mysql-test/r/mysql_ssl.result
@@ -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
diff --git a/mysql-test/r/plugin_auth_sha256_server_default_tls.result b/mysql-test/r/plugin_auth_sha256_server_default_tls.result
index 76ec29a1f6..b14692fe16 100644
--- a/mysql-test/r/plugin_auth_sha256_server_default_tls.result
+++ b/mysql-test/r/plugin_auth_sha256_server_default_tls.result
@@ -25,15 +25,12 @@ GRANT ALL PRIVILEGES ON *.* TO 'kristofer'@'localhost' IDENTIFIED BY PASSWORD '<
 Change user (should succeed)
 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
 DROP USER 'kristofer'@'localhost';
 DROP USER 'kristofer2'@'localhost';
diff --git a/mysql-test/r/ssl_cipher.result b/mysql-test/r/ssl_cipher.result
index 78081300b5..fb90fd4a4c 100644
--- a/mysql-test/r/ssl_cipher.result
+++ b/mysql-test/r/ssl_cipher.result
@@ -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
diff --git a/mysql-test/t/mysql_ssl-master.opt b/mysql-test/t/mysql_ssl-master.opt
new file mode 100644
index 0000000000..0ca403efdf
--- /dev/null
+++ b/mysql-test/t/mysql_ssl-master.opt
@@ -0,0 +1 @@
+--skip-ssl
diff --git a/mysql-test/t/mysql_ssl.test b/mysql-test/t/mysql_ssl.test
new file mode 100644
index 0000000000..dec815325a
--- /dev/null
+++ b/mysql-test/t/mysql_ssl.test
@@ -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!
diff --git a/mysql-test/t/plugin_auth_sha256_server_default_tls.test b/mysql-test/t/plugin_auth_sha256_server_default_tls.test
index a23c97ae0d..7b0c7cf500 100644
--- a/mysql-test/t/plugin_auth_sha256_server_default_tls.test
+++ b/mysql-test/t/plugin_auth_sha256_server_default_tls.test
@@ -34,16 +34,19 @@ change_user kristofer2,secret2;
 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()"
 
 DROP USER 'kristofer'@'localhost';
 DROP USER 'kristofer2'@'localhost';
diff --git a/mysql-test/t/ssl_cipher.test b/mysql-test/t/ssl_cipher.test
index 5b54703a52..7a6f1999bf 100644
--- a/mysql-test/t/ssl_cipher.test
+++ b/mysql-test/t/ssl_cipher.test
@@ -1,10 +1,12 @@
 # The include statement below is a temp one for tests that are yet to
 #be ported to run with InnoDB,
 #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
 
 --echo #
 --echo # BUG#11760210 - SSL_CIPHER_LIST NOT SET OR RETURNED FOR "SHOW STATUS LIKE 'SSL_CIPHER_LIST'"
@@ -13,16 +15,16 @@
 -- source include/have_ssl.inc
 
 # 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
diff --git a/sql-common/client.c b/sql-common/client.c
index 0ce55c65a2..d72ff19991 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -143,10 +143,11 @@ void init_client_psi_keys(void)
   mysql_memory_register(category, all_client_memory, count);
 }
 
 #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";
 const char	*not_error_sqlstate= "00000";
 const char	*cant_connect_sqlstate= "08001";
@@ -1246,23 +1247,32 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd)
       (OPTS)->extension->X= ((STR) != NULL) ?                    \
         my_strdup(key_memory_mysql_options,                      \
                   (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 { \
       ; \
     } while(0)
@@ -2806,18 +2816,20 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
 
   if (mysql->client_flag & CLIENT_MULTI_STATEMENTS)
     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;
   else
     mysql->client_flag&= ~CLIENT_CONNECT_WITH_DB;
@@ -2845,19 +2857,54 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
     int2store(buff, mysql->client_flag);
     int3store(buff+2, net->max_packet_size);
     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;
     struct st_VioSSLFd *ssl_fd;
     enum enum_ssl_init_error ssl_init_error;
     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
     */
     MYSQL_TRACE(SEND_SSL_REQUEST, mysql, (end - buff, (const unsigned char*)buff));
@@ -2916,10 +2963,11 @@ 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",
 		     mysql->server_version, mysql->server_capabilities,
 		     mysql->server_status, mysql->client_flag));
@@ -4726,10 +4774,15 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
                                                         ssl_crl, arg);
                                break;
   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;
 
   case MYSQL_OPT_CONNECT_ATTR_RESET:
@@ -4786,10 +4839,191 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
   }
   DBUG_RETURN(0);
 }
 
 
+/**
+  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
 */
 uchar *
 get_attr_key(LEX_STRING *part, size_t *length,
diff --git a/sql-common/client_authentication.cc b/sql-common/client_authentication.cc
index 8a69107889..2bd27c46f8 100644
--- a/sql-common/client_authentication.cc
+++ b/sql-common/client_authentication.cc
@@ -143,10 +143,11 @@ int sha256_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
   bool got_public_key_from_server= false;
 #endif
   bool connection_is_secure= false;
   unsigned char scramble_pkt[20];
   unsigned char *pkt;
+  my_bool ssl_enforce= FALSE;
 
 
   DBUG_ENTER("sha256_password_auth_client");
 
   /*
@@ -162,13 +163,30 @@ int sha256_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
     Copy the scramble to the stack or it will be lost on the next use of the 
     net buffer.
   */
   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)
   {
  #if !defined(HAVE_YASSL)
     public_key= rsa_init(mysql);
diff --git a/sql/rpl_slave.cc b/sql/rpl_slave.cc
index b0c904ad7a..c8fbbdbfad 100644
--- a/sql/rpl_slave.cc
+++ b/sql/rpl_slave.cc
@@ -6964,22 +6964,25 @@ 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
 
   mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset_info->csname);
   /* This one is not strictly needed but we have it here for completeness */
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 677bb140a2..f05939e671 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -19512,10 +19512,118 @@ static void test_wl6797()
   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
   mysql_query(mysql, "DROP TABLE IF EXISTS t2");
   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 },
   { "client_query", client_query },
   { "test_prepare_insert_update", test_prepare_insert_update},
@@ -19783,10 +19891,11 @@ static struct my_tests_st my_tests[]= {
   { "test_wl5968", test_wl5968 },
   { "test_wl5924", test_wl5924 },
   { "test_wl6587", test_wl6587 },
   { "test_wl5928", test_wl5928 },
   { "test_wl6797", test_wl6797 },
+  { "test_wl6791", test_wl6791 },
   { 0, 0 }
 };
 
 
 static struct my_tests_st *get_my_tests() { return my_tests; }

Vulnerable code: #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
  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_VERIFY_SERVER_CERT,
                (char*) &opt_ssl_verify_server_cert);
#endif
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
  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_VERIFY_SERVER_CERT,
                (char*) &opt_ssl_verify_server_cert);
#endif

#ifdef HAVE_OPENSSL
  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_VERIFY_SERVER_CERT,
                (char*)&opt_ssl_verify_server_cert);
#endif
#ifdef HAVE_OPENSSL
  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_VERIFY_SERVER_CERT,
                (char*) &opt_ssl_verify_server_cert);
#endif
#ifdef HAVE_OPENSSL
  if (opt_use_ssl)
  {
    mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
		  opt_ssl_capath, opt_ssl_cipher);
    mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
    mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
  }
#endif
#ifdef HAVE_OPENSSL
  if (opt_use_ssl)
  {
    mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
                  opt_ssl_capath, opt_ssl_cipher);
    mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
    mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
  }
  mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
                (char*)&opt_ssl_verify_server_cert);
#endif
#ifdef HAVE_OPENSSL
  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_VERIFY_SERVER_CERT,
                (char*)&opt_ssl_verify_server_cert);
#endif
#ifdef HAVE_OPENSSL
  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_VERIFY_SERVER_CERT,
                (char*)&opt_ssl_verify_server_cert);
#endif
                                    CLIENT_MULTI_STATEMENTS |
                                    CLIENT_REMEMBER_OPTIONS;
#ifdef HAVE_OPENSSL
  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);
  }
#endif
#endif
  if (con_ssl)
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
    mysql_ssl_set(&con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
		  opt_ssl_capath, opt_ssl_cipher);
    mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
    mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
#if MYSQL_VERSION_ID >= 50000
    mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
                  &opt_ssl_verify_server_cert);
  }
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
    mysql_ssl_set(&con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
		  opt_ssl_capath, opt_ssl_cipher);
    mysql_options(&con->mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
    mysql_options(&con->mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
#if MYSQL_VERSION_ID >= 50000
    mysql_options(&con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
                  &opt_ssl_verify_server_cert);
#endif
SET(SHARED_LIB_MINOR_VERSION "1")
  MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
  MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS
      opt_use_ssl= 1;
   "Enable SSL for connection (automatically enabled with other flags).",
   "CA file in PEM format (check OpenSSL docs, implies --ssl).",
   "CA directory (check OpenSSL docs, implies --ssl).",
  {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format (implies --ssl).",
  {"ssl-cipher", OPT_SSL_CIPHER, "SSL cipher to use (implies --ssl).",
  {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl).",
  {"ssl-crl", OPT_SSL_CRL, "Certificate revocation list (implies --ssl).",
    "Certificate revocation list path (implies --ssl).",
static my_bool opt_use_ssl   = 0;
#ifdef MYSQL_CLIENT
static my_bool opt_ssl_verify_server_cert= 0;
#### 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.
SHOW STATUS LIKE 'Ssl_cipher';
SHOW STATUS LIKE 'Ssl_cipher_list';
# --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()"
connect (ssl_con,localhost,root,,,,,SSL);
# Check Cipher Name and Cipher List
SHOW STATUS LIKE 'Ssl_cipher';
SHOW STATUS LIKE 'Ssl_cipher_list';
connection default;
disconnect ssl_con;
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
#define SET_SSL_OPTION(opt_var,arg) \
    mysql->options.opt_var= arg ? my_strdup(key_memory_mysql_options, arg, MYF(MY_WME)) : NULL; \
      mysql->options.use_ssl= 1
      (OPTS)->use_ssl= 1
    
    
      (mysql->options.extension && mysql->options.extension->ssl_crl) || 
      (mysql->options.extension && mysql->options.extension->ssl_crlpath))
    mysql->options.use_ssl= 1;
    mysql->client_flag|= CLIENT_SSL;
  if (mysql->client_flag & CLIENT_SSL)
  
    mysql_options(mysql, MYSQL_OPT_SSL_CRL, 
    mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, 
Fixed code:   SSL_SET_OPTIONS(mysql);
  SSL_SET_OPTIONS(mysql);
#include <sslopt-case.h>
  SSL_SET_OPTIONS(&mysql);
  SSL_SET_OPTIONS(mysql);
  SSL_SET_OPTIONS(&mysql_connection);
  SSL_SET_OPTIONS(&mysql_connection);
  SSL_SET_OPTIONS(mysql);
  SSL_SET_OPTIONS(&mysql);
                                    CLIENT_MULTI_STATEMENTS |
                                    CLIENT_REMEMBER_OPTIONS;
  SSL_SET_OPTIONS(&mysql);
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
  my_bool save_opt_use_ssl= opt_use_ssl;
#endif
  opt_use_ssl= con_ssl;

  if (opt_use_ssl)
  }
#else
  /* keep the compiler happy about con_ssl */
  con_ssl = con_ssl ? TRUE : FALSE;
  SSL_SET_OPTIONS(&con_slot->mysql);
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
  opt_use_ssl= save_opt_use_ssl;
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
  SSL_SET_OPTIONS(&con->mysql);

SET(SHARED_LIB_MINOR_VERSION "2")
  MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,
  MYSQL_OPT_SSL_ENFORCE
int             STDCALL mysql_get_option(MYSQL *mysql, enum mysql_option option,
                                         const void *arg);
  MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,
  MYSQL_OPT_SSL_ENFORCE
int mysql_get_option(MYSQL *mysql, enum mysql_option option,
                                         const void *arg);
  /** false if it is possible to fall back on unencrypted connections */
  my_bool ssl_enforce;
#ifdef MYSQL_CLIENT
    case OPT_SSL_SSL:
      /*
        A client side --ssl option handling.
        --ssl=1 means enforce (use=1, enforce=1)
	--ssl=0 means can't enforce (use=0, enforce=0)
	no --ssl means default : no enforce (use=1), just try (enforce=1)
      */
      opt_ssl_enforce= opt_use_ssl;
      break;
#endif
      opt_use_ssl= TRUE;
   "If set to ON, this option enforces that SSL is established before client "
   "attempts to authenticate to the server. To disable client SSL capabilities "
   "use --ssl=OFF.",
   "CA file in PEM format.",
   "CA directory.",
  {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format.",
  {"ssl-cipher", OPT_SSL_CIPHER, "SSL cipher to use.",
  {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format.",
  {"ssl-crl", OPT_SSL_CRL, "Certificate revocation list.",
    "Certificate revocation list path.",
/* 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;
#ifndef MYSQL_CLIENT
#error This header is supposed to be used only in the client
#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)
#
# 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
user()	current_user()
kristofer@localhost	kristofer@localhost
# must return AES128-SHA
# must fail since the default SSL cipher is not compatible
--skip-ssl
#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!
# 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()"
--source include/not_embedded.inc

--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
--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
const char      *default_ssl_cipher= "DHE-RSA-AES256-SHA";
#define SET_OPTION(opt_var,arg) \
  do { \
    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); \
      mysql->options.use_ssl = TRUE; \
  } while (0)

  do { \
      (OPTS)->use_ssl = TRUE; \
  } while (0)
  /* consider SSL if any of the SSL mysql_options() is issued */
      (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;
    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)
    if (!mysql->options.ssl_cipher)
    {
      SET_OPTION(ssl_cipher, default_ssl_cipher);
    }


  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;
/**
  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);
}


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

  /*
    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

    const static my_bool ssl_enforce_true= TRUE;
    mysql_options(mysql, MYSQL_OPT_SSL_CRL,
    mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH,
    /* we always enforce SSL if SSL is turned on */
    mysql_options(mysql, MYSQL_OPT_SSL_ENFORCE, &ssl_enforce_true);

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);
}


  { "test_wl6791", test_wl6791 },