From 2e8cf31abc7bb1bb00eb9dbf93e3b8b253889fed Mon Sep 17 00:00:00 2001
From: "konstantin@oak.local" <>
Date: Fri, 28 Nov 2003 13:11:44 +0300
Subject: [PATCH] Second part of WL #519: Client option secure-auth deployed on
 all possible layers: - mysql client command-line and config file option -
 mysql_options option MYSQL_SECURE_AUTH - mysql_real_connect will
 automatically take into account that option if  
 mysql->options.my_cnf_file/my_cnf_group is set

---
 client/client_priv.h |  2 +-
 client/mysql.cc      |  7 ++++++-
 include/errmsg.h     |  1 +
 include/mysql.h      |  4 +++-
 libmysql/errmsg.c    |  9 ++++++---
 sql-common/client.c  | 24 +++++++++++++++++++++---
 6 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/client/client_priv.h b/client/client_priv.h
index d655619516..f6d766b7ef 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -40,4 +40,4 @@ enum options_client { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
 	       OPT_DELETE_MASTER_LOGS,
                OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL,
                OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION,
-               OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER };
+               OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH };
diff --git a/client/mysql.cc b/client/mysql.cc
index 059a1ad36f..9062b58d09 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -134,7 +134,7 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
 	       vertical=0, line_numbers=1, column_names=1,opt_html=0,
                opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0,
 	       tty_password= 0, opt_nobeep=0, opt_reconnect=1,
-	       default_charset_used= 0;
+	       default_charset_used= 0, opt_secure_auth= 0;
 static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
 static my_string opt_mysql_unix_port=0;
 static int connect_flag=CLIENT_INTERACTIVE;
@@ -623,6 +623,9 @@ static struct my_option my_long_options[] =
   {"max_join_size", OPT_MAX_JOIN_SIZE, "", (gptr*) &max_join_size,
    (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1,
    0},
+  {"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it"
+    " uses old (pre-4.1.1) protocol", (gptr*) &opt_secure_auth,
+    (gptr*) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
@@ -2553,6 +2556,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
   }
   if (opt_compress)
     mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
+  if (opt_secure_auth)
+    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);
 #ifdef HAVE_OPENSSL
diff --git a/include/errmsg.h b/include/errmsg.h
index a354c125e3..24326b1efe 100644
--- a/include/errmsg.h
+++ b/include/errmsg.h
@@ -87,3 +87,4 @@ extern const char *client_errors[];	/* Error messages */
 #define CR_CONN_UNKNOW_PROTOCOL 		2046
 #define CR_INVALID_CONN_HANDLE			2047
 #define CR_MYSQL_SERVER_INIT_MISSED             2048
+#define CR_SECURE_AUTH                          2049
diff --git a/include/mysql.h b/include/mysql.h
index 23d89fd531..fd0330b35d 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -145,7 +145,7 @@ enum mysql_option
   MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
   MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
   MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
-  MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP
+  MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH
 };
 
 struct st_mysql_options {
@@ -184,6 +184,8 @@ struct st_mysql_options {
 #endif
   enum mysql_option methods_to_use;
   char *client_ip;
+  /* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */
+  my_bool secure_auth;
 };
 
 enum mysql_status 
diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c
index 148625129b..4dfcfe6a1d 100644
--- a/libmysql/errmsg.c
+++ b/libmysql/errmsg.c
@@ -72,7 +72,8 @@ const char *client_errors[]=
   "Can't open shared memory. Can't send the request event to server (%lu)",
   "Wrong or unknown protocol",
   "Invalid connection handle",
-  "mysql_server_init wasn't called"
+  "mysql_server_init wasn't called",
+  "Connection using old (pre 4.1.1) authentication protocol refused (client option 'secure_auth' enabled)"
 };
 
 /* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
@@ -128,7 +129,8 @@ const char *client_errors[]=
   "Can't open shared memory. Can't send the request event to server (%lu)",
   "Wrong or unknown protocol",
   "Invalid connection handle",
-  "mysql_server_init wasn't called"
+  "mysql_server_init wasn't called",
+  "Connection using old (pre 4.1.1) authentication protocol refused (client option 'secure_auth' enabled)"
 };
 
 #else /* ENGLISH */
@@ -182,7 +184,8 @@ const char *client_errors[]=
   "Can't open shared memory. Can't send the request event to server (%lu)",
   "Wrong or unknown protocol",
   "Invalid connection handle",
-  "mysql_server_init wasn't called"
+  "mysql_server_init wasn't called",
+  "Connection using old (pre 4.1.1) authentication protocol refused (client option 'secure_auth' enabled)"
 };
 #endif
 
diff --git a/sql-common/client.c b/sql-common/client.c
index 878a8beacb..055aa5210b 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -783,7 +783,7 @@ static const char *default_options[]=
   "connect-timeout", "local-infile", "disable-local-infile",
   "replication-probe", "enable-reads-from-master", "repl-parse-query",
   "ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
-  "multi-results", "multi-queries",
+  "multi-results", "multi-queries", "secure-auth",
   NullS
 };
 
@@ -991,6 +991,9 @@ void mysql_read_default_options(struct st_mysql_options *options,
 	case 31:
 	  options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
 	  break;
+        case 32: /* secure-auth */
+          options->secure_auth= TRUE;
+          break;
 	default:
 	  DBUG_PRINT("warning",("unknown option: %s",option[0]));
 	}
@@ -1473,7 +1476,11 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
   if (!host || !host[0])
     host=mysql->options.host;
   if (!user || !user[0])
+  {
     user=mysql->options.user;
+    if (!user)
+      user= "";
+  }
   if (!passwd)
   {
     passwd=mysql->options.password;
@@ -1481,6 +1488,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
     if (!passwd)
       passwd=getenv("MYSQL_PWD");		/* get it from environment */
 #endif
+    if (!passwd)
+      passwd= "";
   }
   if (!db || !db[0])
     db=mysql->options.db;
@@ -1742,6 +1751,14 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
   else
     mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
 
+  if (mysql->options.secure_auth && passwd[0] &&
+      !(mysql->server_capabilities & CLIENT_SECURE_CONNECTION))
+  {
+    strmov(net->sqlstate, unknown_sqlstate);
+    strmov(net->last_error, ER(net->last_errno=CR_SECURE_AUTH));
+    goto error;
+  }
+
   charset_number= mysql->server_language;
 
   /* Set character set */
@@ -1793,8 +1810,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
   }
 
   /* Save connection information */
-  if (!user) user="";
-  if (!passwd) passwd="";
   if (!my_multi_malloc(MYF(0),
 		       &mysql->host_info, (uint) strlen(host_info)+1,
 		       &mysql->host,      (uint) strlen(host)+1,
@@ -2542,6 +2557,9 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
     break;
   case MYSQL_SET_CLIENT_IP:
     mysql->options.client_ip= my_strdup(arg, MYF(MY_WME));
+  case MYSQL_SECURE_AUTH:
+    mysql->options.secure_auth= *(my_bool *) arg;
+    break;
   default:
     DBUG_RETURN(1);
   }
-- 
2.30.9