summaryrefslogtreecommitdiff
path: root/sql/mini_client.cc
diff options
context:
space:
mode:
authorunknown <peter@mysql.com>2002-11-24 17:07:53 +0300
committerunknown <peter@mysql.com>2002-11-24 17:07:53 +0300
commit8c8b97fdf4756a699346ae1688136624d76713bc (patch)
treedb7cb82e2166048d043214a331a5ad63bc7d0621 /sql/mini_client.cc
parent85bbdcf016dadf31335ad9ee98c3c8acfc167e2f (diff)
downloadmariadb-git-8c8b97fdf4756a699346ae1688136624d76713bc.tar.gz
SCRUM: Main change for Secure connection handling. Still needs some more coding. Commit
done for merge with newer version of code. client/mysqladmin.c: Support for new password format include/mysql.h: Increase buffer as new scramble is larger include/mysql_com.h: Add new prototypes for new auth handling libmysql/libmysql.c: New handshake handling code mysql-test/install_test_db.sh: Extend password length to handle new passwords mysql-test/t/rpl000017-slave.sh: Adjust test to work with longer password scripts/mysql_fix_privilege_tables.sh: Increase password length at priv table convertion scripts/mysql_install_db.sh: Longer passwords sql/item_strfunc.cc: New password generation function needs seed for password generation sql/mini_client.cc: Change MiniClient to handle new auth in replication sql/mysqld.cc: Remove unneeded flag (was added earlier for same change) sql/password.c: A lot of changes to handle new authentication and doccumentation sql/sql_acl.cc: Password handling function adjustment sql/sql_acl.h: Change prototype sql/sql_class.h: Extend scramble length sql/sql_parse.cc: Handling server side of new authentication sql/sql_yacc.yy: Adjustment for new prototypes
Diffstat (limited to 'sql/mini_client.cc')
-rw-r--r--sql/mini_client.cc90
1 files changed, 83 insertions, 7 deletions
diff --git a/sql/mini_client.cc b/sql/mini_client.cc
index aa84a52eb0b..52725f2acc0 100644
--- a/sql/mini_client.cc
+++ b/sql/mini_client.cc
@@ -87,7 +87,9 @@ static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
-#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
+#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \
+ CLIENT_LOCAL_FILES | CLIENT_SECURE_CONNECTION)
+
#if defined(MSDOS) || defined(__WIN__)
#define perror(A)
@@ -488,6 +490,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
uint net_read_timeout)
{
char buff[NAME_LEN+USERNAME_LENGTH+100],*end,*host_info;
+ char password_hash[20];
my_socket sock;
ulong ip_addr;
struct sockaddr_in sock_addr;
@@ -510,7 +513,6 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
user ? user : "(Null)",
net_read_timeout,
(uint) slave_net_timeout));
-
net->vio = 0; /* If something goes wrong */
mysql->charset=default_charset_info; /* Set character set */
if (!port)
@@ -799,22 +801,96 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
}
DBUG_PRINT("info",("user: %s",buff+5));
- end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd,
- (my_bool) (mysql->protocol_version == 9));
- if (db)
+
+ /*
+ We always start with old type handshake the only difference is message sent
+ If server handles secure connection type we'll not send the real scramble
+ */
+ if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
+ {
+ if (passwd[0])
+ {
+ /* Use something for not empty password not to match it against empty one */
+ end=scramble(strend(buff+5)+1, mysql->scramble_buff,"~MySQL#!",
+ (my_bool) (mysql->protocol_version == 9));
+ }
+ else /* For empty password*/
+ {
+ end=strend(buff+5)+1;
+ *end=0; /* Store zero length scramble */
+ }
+ }
+ /* Real scramble is sent only for old servers. This is to be blocked by option */
+ else
+ end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd,
+ (my_bool) (mysql->protocol_version == 9));
+
+ /* Add database if needed */
+ if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{
end=strmake(end+1,db,NAME_LEN);
mysql->db=my_strdup(db,MYF(MY_WME));
db=0;
}
+ /* Write authentication package */
if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
{
net->last_errno= CR_SERVER_LOST;
- strmov(net->last_error,ER(net->last_errno));
+ strmov(net->last_error,ER(net->last_errno));
goto error;
}
- if (mc_net_safe_read(mysql) == packet_error)
+
+ /* We shall only query sever if it expect us to do so */
+
+ if ( (pkt_length=mc_net_safe_read(mysql)) == packet_error)
goto error;
+
+ if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
+ {
+ /* This should basically always happen with new server unless empty password */
+ if (pkt_length==24) /* We have new hash back */
+ {
+ /* Old passwords will have zero at the first byte of hash */
+ if (net->read_pos[0])
+ {
+ /* Build full password hash as it is required to decode scramble */
+ password_hash_stage1(buff, passwd);
+ /* Store copy as we'll need it later */
+ memcpy(password_hash,buff,20);
+ /* Finally hash complete password using hash we got from server */
+ password_hash_stage2(password_hash,(char*)net->read_pos);
+ /* Decypt and store scramble 4 = hash for stage2 */
+ password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,20);
+ mysql->scramble_buff[20]=0;
+ /* Encode scramble with password. Recycle buffer */
+ password_crypt(mysql->scramble_buff,buff,buff,20);
+ }
+ else
+ {
+ /* Create password to decode scramble */
+ create_key_from_old_password(passwd,password_hash);
+ /* Decypt and store scramble 4 = hash for stage2 */
+ password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,20);
+ mysql->scramble_buff[20]=0;
+ /* Finally scramble decoded scramble with password */
+ scramble(buff, mysql->scramble_buff, passwd,
+ (my_bool) (mysql->protocol_version == 9));
+ }
+ /* Write second package of authentication */
+ if (my_net_write(net,buff,20) || net_flush(net))
+ {
+ net->last_errno= CR_SERVER_LOST;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
+ }
+ /* Read What server thinks about out new auth message report */
+ if (mc_net_safe_read(mysql) == packet_error)
+ goto error;
+ }
+ }
+
+ /* End of authentication part of handshake */
+
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
net->compress=1;
DBUG_PRINT("exit",("Mysql handler: %lx",mysql));