1
0
mirror of https://github.com/MariaDB/server.git synced 2025-06-12 01:53:02 +03:00

SCRUM: Secure auth

Implement mysql_change_user
Get rid of double user search at authentication
Some cleanups


client/mysqladmin.c:
  Fix long line
include/mysql_com.h:
  Fix long lines
libmysql/libmysql.c:
  mysql_change_user() for new auth + some fixes
sql/password.c:
  Add author info so who is guilty in errors would be known :)
sql/sql_acl.cc:
  Move class definitions to .h
sql/sql_acl.h:
  Add class definitions
sql/sql_parse.cc:
  Get rid of double user search. Implement mysql_change_user
This commit is contained in:
unknown
2002-11-30 16:31:58 +03:00
parent 14754ce141
commit 05ba93c279
7 changed files with 437 additions and 237 deletions

View File

@ -2220,7 +2220,7 @@ Try also with PIPE or TCP/IP
#include "_cust_libmysql.h";
#endif
DBUG_PRINT("info",("user: %s",buff+5));
/*
/*
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
*/
@ -2228,10 +2228,10 @@ Try also with PIPE or TCP/IP
{
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));
}
/* Use something for not empty password not to match against empty one */
end=scramble(strend(buff+5)+1, mysql->scramble_buff,"\1~MySQL#!\2",
(my_bool) (mysql->protocol_version == 9));
}
else /* For empty password*/
{
end=strend(buff+5)+1;
@ -2242,11 +2242,11 @@ Try also with PIPE or TCP/IP
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);
end=strmake(end+1,db,NAME_LEN);
mysql->db=my_strdup(db,MYF(MY_WME));
db=0;
}
@ -2409,21 +2409,96 @@ static my_bool mysql_reconnect(MYSQL *mysql)
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db)
{
char buff[512],*pos=buff;
char buff[512],*end=buff;
ulong pkt_length;
char password_hash[20]; /* Used for tmp storage of stage1 hash */
NET *net= &mysql->net;
DBUG_ENTER("mysql_change_user");
if (!user)
user="";
if (!passwd)
passwd="";
/* Store user into the buffer */
end=strmov(end,user)+1;
/*
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(end, mysql->scramble_buff,"\1~MySQL#!\2",
(my_bool) (mysql->protocol_version == 9));
}
else /* For empty password*/
*end=0; /* Store zero length scramble */
}
/* Real scramble is sent only for servers. This is to be blocked by option */
else
end=scramble(end, mysql->scramble_buff, passwd,
(my_bool) (mysql->protocol_version == 9));
/* Add database if needed */
end=strmov(end+1,db ? db : "");
/* Write authentication package */
simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1);
/* We shall only query sever if it expect us to do so */
if ( (pkt_length=net_safe_read(mysql)) == packet_error)
goto error;
pos=strmov(pos,user)+1;
pos=scramble(pos, mysql->scramble_buff, passwd,
(my_bool) (mysql->protocol_version == 9));
pos=strmov(pos+1,db ? db : "");
if (simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (pos-buff),0))
DBUG_RETURN(1);
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,net->read_pos);
/* Decypt and store scramble 4 = hash for stage2 */
password_crypt(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(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 (net_safe_read(mysql) == packet_error)
goto error;
}
}
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
@ -2432,6 +2507,10 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
mysql->passwd=my_strdup(passwd,MYF(MY_WME));
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
DBUG_RETURN(0);
error:
DBUG_RETURN(1);
}