diff options
author | unknown <peter@mysql.com> | 2002-11-24 17:07:53 +0300 |
---|---|---|
committer | unknown <peter@mysql.com> | 2002-11-24 17:07:53 +0300 |
commit | 8c8b97fdf4756a699346ae1688136624d76713bc (patch) | |
tree | db7cb82e2166048d043214a331a5ad63bc7d0621 /sql/mini_client.cc | |
parent | 85bbdcf016dadf31335ad9ee98c3c8acfc167e2f (diff) | |
download | mariadb-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.cc | 90 |
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)); |