Commit a2425837 authored by peter@mysql.com's avatar peter@mysql.com

SCRUM: Montymise code

       fix mysql_change_user() for old clients
parent 54ff0efe
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define LOCAL_HOST "localhost" #define LOCAL_HOST "localhost"
#define LOCAL_HOST_NAMEDPIPE "." #define LOCAL_HOST_NAMEDPIPE "."
#if defined(__WIN__) && !defined( _CUSTOMCONFIG_) #if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
#define MYSQL_NAMEDPIPE "MySQL" #define MYSQL_NAMEDPIPE "MySQL"
#define MYSQL_SERVICENAME "MySql" #define MYSQL_SERVICENAME "MySql"
...@@ -44,6 +45,11 @@ enum enum_server_command ...@@ -44,6 +45,11 @@ enum enum_server_command
COM_PREPARE, COM_EXECUTE, COM_LONG_DATA, COM_CLOSE_STMT COM_PREPARE, COM_EXECUTE, COM_LONG_DATA, COM_CLOSE_STMT
}; };
#define SCRAMBLE_LENGTH 8
#define SCRAMBLE41_LENGTH 20
#define NOT_NULL_FLAG 1 /* Field can't be NULL */ #define NOT_NULL_FLAG 1 /* Field can't be NULL */
#define PRI_KEY_FLAG 2 /* Field is part of a primary key */ #define PRI_KEY_FLAG 2 /* Field is part of a primary key */
#define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */ #define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */
......
This diff is collapsed.
...@@ -170,12 +170,20 @@ fi ...@@ -170,12 +170,20 @@ fi
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA @bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
alter table user alter table user
change password password char(45) not null,
add max_questions int(11) NOT NULL AFTER x509_subject, add max_questions int(11) NOT NULL AFTER x509_subject,
add max_updates int(11) unsigned NOT NULL AFTER max_questions, add max_updates int(11) unsigned NOT NULL AFTER max_questions,
add max_connections int(11) unsigned NOT NULL AFTER max_updates; add max_connections int(11) unsigned NOT NULL AFTER max_updates;
END_OF_DATA END_OF_DATA
# Increase password length to handle new passwords
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
alter table user
change password password char(45) not null;
END_OF_DATA
# #
# Add Create_tmp_table_priv and Lock_tables_priv to db and host # Add Create_tmp_table_priv and Lock_tables_priv to db and host
# #
......
...@@ -490,7 +490,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -490,7 +490,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
uint net_read_timeout) uint net_read_timeout)
{ {
char buff[NAME_LEN+USERNAME_LENGTH+100],*end,*host_info; char buff[NAME_LEN+USERNAME_LENGTH+100],*end,*host_info;
char password_hash[20]; char password_hash[SCRAMBLE41_LENGTH];
my_socket sock; my_socket sock;
ulong ip_addr; ulong ip_addr;
struct sockaddr_in sock_addr; struct sockaddr_in sock_addr;
...@@ -856,28 +856,29 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -856,28 +856,29 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
/* Build full password hash as it is required to decode scramble */ /* Build full password hash as it is required to decode scramble */
password_hash_stage1(buff, passwd); password_hash_stage1(buff, passwd);
/* Store copy as we'll need it later */ /* Store copy as we'll need it later */
memcpy(password_hash,buff,20); memcpy(password_hash,buff,SCRAMBLE41_LENGTH);
/* Finally hash complete password using hash we got from server */ /* Finally hash complete password using hash we got from server */
password_hash_stage2(password_hash,(char*)net->read_pos); password_hash_stage2(password_hash,(char*)net->read_pos);
/* Decypt and store scramble 4 = hash for stage2 */ /* Decypt and store scramble 4 = hash for stage2 */
password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,20); password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,
mysql->scramble_buff[20]=0; SCRAMBLE41_LENGTH);
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
/* Encode scramble with password. Recycle buffer */ /* Encode scramble with password. Recycle buffer */
password_crypt(mysql->scramble_buff,buff,buff,20); password_crypt(mysql->scramble_buff,buff,buff,SCRAMBLE41_LENGTH);
} }
else else
{ {
/* Create password to decode scramble */ /* Create password to decode scramble */
create_key_from_old_password(passwd,password_hash); create_key_from_old_password(passwd,password_hash);
/* Decypt and store scramble 4 = hash for stage2 */ /* Decypt and store scramble 4 = hash for stage2 */
password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,20); password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,
mysql->scramble_buff[20]=0; SCRAMBLE41_LENGTH);
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
/* Finally scramble decoded scramble with password */ /* Finally scramble decoded scramble with password */
scramble(buff, mysql->scramble_buff, passwd, scramble(buff, mysql->scramble_buff, passwd,0);
(my_bool) (mysql->protocol_version == 9));
} }
/* Write second package of authentication */ /* Write second package of authentication */
if (my_net_write(net,buff,20) || net_flush(net)) if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net))
{ {
net->last_errno= CR_SERVER_LOST; net->last_errno= CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno)); strmov(net->last_error,ER(net->last_errno));
......
...@@ -2496,6 +2496,9 @@ static void create_new_thread(THD *thd) ...@@ -2496,6 +2496,9 @@ static void create_new_thread(THD *thd)
for (uint i=0; i < 8 ; i++) // Generate password teststring for (uint i=0; i < 8 ; i++) // Generate password teststring
thd->scramble[i]= (char) (rnd(&sql_rand)*94+33); thd->scramble[i]= (char) (rnd(&sql_rand)*94+33);
thd->scramble[8]=0; thd->scramble[8]=0;
// Back it up as old clients may need it
memcpy(thd->old_scramble,thd->scramble,9);
thd->real_id=pthread_self(); // Keep purify happy thd->real_id=pthread_self(); // Keep purify happy
......
...@@ -66,7 +66,6 @@ ...@@ -66,7 +66,6 @@
#define PVERSION41_CHAR '*' #define PVERSION41_CHAR '*'
/* Scramble length for new password version */ /* Scramble length for new password version */
#define SCRAMBLE41_LENGTH 20
/* /*
...@@ -175,17 +174,12 @@ void create_random_string(int length,struct rand_struct *rand_st,char* target) ...@@ -175,17 +174,12 @@ void create_random_string(int length,struct rand_struct *rand_st,char* target)
none none
*/ */
inline void password_crypt(const char* from,char* to, const char* password,int length) void password_crypt(const char* from,char* to, const char* password,int length)
{ {
const char *from_end=from+length; const char *from_end=from+length;
while(from<from_end) while (from < from_end)
{ *to++= *(from++) ^* (password++);
*to=*from^*password;
from++;
to++;
password++;
}
} }
...@@ -286,7 +280,9 @@ void password_hash_stage2(char *to,const char *salt) ...@@ -286,7 +280,9 @@ void password_hash_stage2(char *to,const char *salt)
none none
*/ */
void make_scrambled_password(char *to,const char *password,my_bool force_old_scramble,struct rand_struct *rand_st) void make_scrambled_password(char *to,const char *password,
my_bool force_old_scramble,
struct rand_struct *rand_st)
{ {
ulong hash_res[2]; /* Used for pre 4.1 password hashing */ ulong hash_res[2]; /* Used for pre 4.1 password hashing */
unsigned short salt; /* Salt for 4.1 version password */ unsigned short salt; /* Salt for 4.1 version password */
...@@ -336,7 +332,6 @@ void get_salt_from_bin_password(ulong *res,unsigned char *password,ulong salt) ...@@ -336,7 +332,6 @@ void get_salt_from_bin_password(ulong *res,unsigned char *password,ulong salt)
unsigned char* password_end=password+SCRAMBLE41_LENGTH; unsigned char* password_end=password+SCRAMBLE41_LENGTH;
*res=salt; *res=salt;
res++; res++;
bzero(res,5*sizeof(res[0]));
/* Process password of known length*/ /* Process password of known length*/
while (password<password_end) while (password<password_end)
...@@ -364,12 +359,14 @@ void get_salt_from_bin_password(ulong *res,unsigned char *password,ulong salt) ...@@ -364,12 +359,14 @@ void get_salt_from_bin_password(ulong *res,unsigned char *password,ulong salt)
!0 for invalid password !0 for invalid password
*/ */
my_bool validate_password(const char* password, const char* message, ulong* salt) my_bool validate_password(const char* password, const char* message,
ulong* salt)
{ {
char buffer[SCRAMBLE41_LENGTH]; /* Used for password validation */ char buffer[SCRAMBLE41_LENGTH]; /* Used for password validation */
char tmpsalt[8]; /* Temporary value to convert salt to string form */ char tmpsalt[8]; /* Temporary value to convert salt to string form */
int i;
ulong salt_candidate[6]; /* Computed candidate salt */ ulong salt_candidate[6]; /* Computed candidate salt */
ulong* sc=salt_candidate; /* we need to be able to increment */
ulong* salt_end;
/* Now we shall get stage1 encrypted password in buffer*/ /* Now we shall get stage1 encrypted password in buffer*/
password_crypt(password,buffer,message,SCRAMBLE41_LENGTH); password_crypt(password,buffer,message,SCRAMBLE41_LENGTH);
...@@ -381,9 +378,11 @@ my_bool validate_password(const char* password, const char* message, ulong* salt ...@@ -381,9 +378,11 @@ my_bool validate_password(const char* password, const char* message, ulong* salt
/* Convert password to salt to compare */ /* Convert password to salt to compare */
get_salt_from_bin_password(salt_candidate,buffer,salt[0]); get_salt_from_bin_password(salt_candidate,buffer,salt[0]);
/* Now we shall get exactly the same password as we have stored for user */ /* Now we shall get exactly the same password as we have stored for user */
for(i=1;i<6;i++) for (salt_end=salt+5 ; salt < salt_end; )
if (salt[i]!=salt_candidate[i]) return 1; if (*++salt != *++sc)
return 1;
/* Or password correct*/ /* Or password correct*/
return 0; return 0;
} }
...@@ -400,11 +399,9 @@ my_bool validate_password(const char* password, const char* message, ulong* salt ...@@ -400,11 +399,9 @@ my_bool validate_password(const char* password, const char* message, ulong* salt
password length >0 password length >0
*/ */
inline int get_password_length(my_bool force_old_scramble) int get_password_length(my_bool force_old_scramble)
{ {
if (force_old_scramble) return (force_old_scramble) ? 16 : SHA1_HASH_SIZE*2+4+1;
return 16;
else return SHA1_HASH_SIZE*2+4+1;
} }
...@@ -420,9 +417,9 @@ inline int get_password_length(my_bool force_old_scramble) ...@@ -420,9 +417,9 @@ inline int get_password_length(my_bool force_old_scramble)
!0 password version char for newer passwords !0 password version char for newer passwords
*/ */
inline char get_password_version(const char* password) char get_password_version(const char* password)
{ {
if (password==NULL) return 0; if (password==NULL) return 0;
if (password[0]==PVERSION41_CHAR) return PVERSION41_CHAR; if (password[0]==PVERSION41_CHAR) return PVERSION41_CHAR;
return 0; return 0;
} }
...@@ -467,7 +464,6 @@ inline uint char_val(char X) ...@@ -467,7 +464,6 @@ inline uint char_val(char X)
void get_salt_from_password(ulong *res,const char *password) void get_salt_from_password(ulong *res,const char *password)
{ {
bzero(res,6*sizeof(res[0]));
if (password) /* zero salt corresponds to empty password */ if (password) /* zero salt corresponds to empty password */
{ {
if (password[0]==PVERSION41_CHAR) /* if new password */ if (password[0]==PVERSION41_CHAR) /* if new password */
...@@ -553,19 +549,17 @@ void get_hash_and_password(ulong* salt, uint8 pversion, char* hash, unsigned cha ...@@ -553,19 +549,17 @@ void get_hash_and_password(ulong* salt, uint8 pversion, char* hash, unsigned cha
if (pversion) /* New password version assumed */ if (pversion) /* New password version assumed */
{ {
salt_end=salt+6; salt_end=salt+5;
sprintf(hash,"%04x",(unsigned short)salt[0]); sprintf(hash,"%04x",(unsigned short)salt[0]);
salt++; /* position to the second element */
while (salt<salt_end) /* Iterate over these elements*/ while (salt<salt_end) /* Iterate over these elements*/
{ {
val=*salt; val=*(++salt);
for(t=3;t>=0;t--) for (t=3; t>=0; t--)
{ {
bin_password[t]=val%256; bin_password[t]=val%256;
val>>=8; /* Scroll 8 bits to get next part*/ val>>=8; /* Scroll 8 bits to get next part*/
} }
bin_password+=4; /* Get to next 4 chars*/ bin_password+=4; /* Get to next 4 chars*/
salt++;
} }
} }
else else
...@@ -611,7 +605,7 @@ void get_hash_and_password(ulong* salt, uint8 pversion, char* hash, unsigned cha ...@@ -611,7 +605,7 @@ void get_hash_and_password(ulong* salt, uint8 pversion, char* hash, unsigned cha
void create_key_from_old_password(const char* passwd, char* key) void create_key_from_old_password(const char* passwd, char* key)
{ {
char buffer[20]; /* Buffer for various needs */ char buffer[SCRAMBLE41_LENGTH]; /* Buffer for various needs */
ulong salt[6]; /* Salt (large for safety) */ ulong salt[6]; /* Salt (large for safety) */
/* At first hash password to the string stored in password */ /* At first hash password to the string stored in password */
make_scrambled_password(buffer,passwd,1,(struct rand_struct *)NULL); make_scrambled_password(buffer,passwd,1,(struct rand_struct *)NULL);
......
This diff is collapsed.
...@@ -499,7 +499,10 @@ public: ...@@ -499,7 +499,10 @@ public:
uint check_loops_counter; //last id used to check loops uint check_loops_counter; //last id used to check loops
/* variables.transaction_isolation is reset to this after each commit */ /* variables.transaction_isolation is reset to this after each commit */
enum_tx_isolation session_tx_isolation; enum_tx_isolation session_tx_isolation;
char scramble[21]; // extend scramble to handle new auth // extend scramble to handle new auth
char scramble[SCRAMBLE41_LENGTH+1];
// old scramble is needed to handle old clients
char old_scramble[SCRAMBLE_LENGTH+1];
uint8 query_cache_type; // type of query cache processing uint8 query_cache_type; // type of query cache processing
bool slave_thread; bool slave_thread;
bool set_query_id,locked,count_cuted_fields,some_tables_deleted; bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment