Commit 42c7698c authored by unknown's avatar unknown

Bug fixes for authentication

OLD_PASSWORD made a keyword to allow set password=old_password('abc') constructions.


BitKeeper/etc/ignore:
  Added BitKeeper/post-commit BitKeeper/post-commit-manual build_tags.sh tests/connect_test BUILD/compile-pentium-maintainer to the ignore list
include/mysql_com.h:
  scramble return type changed to void as now it's not used
libmysql/libmysql.c:
  fixed bug with with failed authentification when scramble contained zero byte
sql-common/client.c:
  applied patch from Lycos team
  fixed bug with scramble containing zero byte
sql/item_create.cc:
  removed create_func_old_password, create_func_password as they are not used any more
sql/item_create.h:
  removed create_func_old_password, create_func_password as they are not used any more
sql/item_strfunc.cc:
  Added alloc() function to Item_func_password, Item_func_old_password, which is used in sql_yacc.yy
sql/item_strfunc.h:
  Added alloc() function to Item_func_password, Item_func_old_password, which is used in sql_yacc.yy
sql/lex.h:
  OLD_PASSWORD now is keyword, to allow statements like
  set password=old_password('abc')
sql/password.c:
  fixed scramble return value
  trailing zero now is not written
sql/sql_acl.cc:
  incorporated patch from Lycos team
  41 replaced with constant
  acl_getroot rewritten to support ER_AUTH_... error
sql/sql_parse.cc:
  authenticate merged with check_user
  check_user return values reversed, support for ER_AUTH in check_user.added
sql/sql_yacc.yy:
  OLD_PASSWORD now is keyword, to allow statements like
  set password=old_password('abc')
parent 2b0a481c
...@@ -624,3 +624,8 @@ vio/test-sslserver ...@@ -624,3 +624,8 @@ vio/test-sslserver
vio/viotest-ssl vio/viotest-ssl
start_mysqld.sh start_mysqld.sh
mysys/main.cc mysys/main.cc
BitKeeper/post-commit
BitKeeper/post-commit-manual
build_tags.sh
tests/connect_test
BUILD/compile-pentium-maintainer
...@@ -327,7 +327,7 @@ void get_salt_from_password_323(unsigned long *res, const char *password); ...@@ -327,7 +327,7 @@ void get_salt_from_password_323(unsigned long *res, const char *password);
void make_password_from_salt_323(char *to, const unsigned long *salt); void make_password_from_salt_323(char *to, const unsigned long *salt);
void make_scrambled_password(char *to, const char *password); void make_scrambled_password(char *to, const char *password);
char *scramble(char *to, const char *message, const char *password); void scramble(char *to, const char *message, const char *password);
my_bool check_scramble(const char *reply, const char *message, my_bool check_scramble(const char *reply, const char *message,
const unsigned char *hash_stage2); const unsigned char *hash_stage2);
void get_salt_from_password(unsigned char *res, const char *password); void get_salt_from_password(unsigned char *res, const char *password);
......
...@@ -619,16 +619,20 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, ...@@ -619,16 +619,20 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
/* write scrambled password according to server capabilities */ /* write scrambled password according to server capabilities */
if (passwd[0]) if (passwd[0])
{ {
/* Write NULL-terminated scrambled password: */ if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
end= mysql->server_capabilities & CLIENT_SECURE_CONNECTION ? {
scramble(end, mysql->scramble, passwd) : *end++= SCRAMBLE_LENGTH;
scramble_323(end, mysql->scramble_323, passwd, scramble(end, mysql->scramble, passwd);
(my_bool) (mysql->protocol_version == 9)); end+= SCRAMBLE_LENGTH;
}
else
end= scramble_323(end, mysql->scramble_323, passwd,
(my_bool) (mysql->protocol_version == 9)) + 1;
} }
else else
*end= '\0'; // empty password *end++= '\0'; // empty password
/* Add database if needed */ /* Add database if needed */
end=strmov(end+1,db ? db : ""); end= strmov(end, db ? db : "") + 1;
/* Write authentication package */ /* Write authentication package */
simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1); simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1);
......
...@@ -1823,7 +1823,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -1823,7 +1823,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
mysql->server_status, client_flag)); mysql->server_status, client_flag));
/* This needs to be changed as it's not useful with big packets */ /* This needs to be changed as it's not useful with big packets */
if (user && user[0]) if (user && user[0])
strmake(end,user,32); /* Max user name */ strmake(end,user,USERNAME_LENGTH); /* Max user name */
else else
read_user_name((char*) end); read_user_name((char*) end);
...@@ -1835,21 +1835,25 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -1835,21 +1835,25 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
end= strend(end) + 1; end= strend(end) + 1;
if (passwd[0]) if (passwd[0])
{ {
/* Write NULL-terminated scrambled password: */ if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
end= mysql->server_capabilities & CLIENT_SECURE_CONNECTION ? {
scramble(end, mysql->scramble, passwd) : *end++= SCRAMBLE_LENGTH;
scramble_323(end, mysql->scramble_323, passwd, scramble(end, mysql->scramble, passwd);
(my_bool) (mysql->protocol_version == 9)); end+= SCRAMBLE_LENGTH;
}
else
end= scramble_323(end, mysql->scramble_323, passwd,
(my_bool) (mysql->protocol_version == 9)) + 1;
} }
else else
*end= '\0'; /* empty password */ *end++= '\0'; /* empty password */
/* Add database if needed */ /* Add database if needed */
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{ {
end=strmake(end+1,db,NAME_LEN); end= strmake(end, db, NAME_LEN) + 1;
mysql->db=my_strdup(db,MYF(MY_WME)); mysql->db= my_strdup(db,MYF(MY_WME));
db=0; db= 0;
} }
/* Write authentication package */ /* Write authentication package */
if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net)) if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
......
...@@ -52,13 +52,6 @@ Item *create_func_ord(Item* a) ...@@ -52,13 +52,6 @@ Item *create_func_ord(Item* a)
return new Item_func_ord(a); return new Item_func_ord(a);
} }
Item *create_func_old_password(Item* a)
{
return new Item_func_old_password(a);
}
Item *create_func_asin(Item* a) Item *create_func_asin(Item* a)
{ {
return new Item_func_asin(a); return new Item_func_asin(a);
...@@ -332,11 +325,6 @@ Item *create_func_quarter(Item* a) ...@@ -332,11 +325,6 @@ Item *create_func_quarter(Item* a)
return new Item_func_quarter(a); return new Item_func_quarter(a);
} }
Item *create_func_password(Item* a)
{
return new Item_func_password(a);
}
Item *create_func_radians(Item *a) Item *create_func_radians(Item *a)
{ {
return new Item_func_units((char*) "radians",a,M_PI/180,0.0); return new Item_func_units((char*) "radians",a,M_PI/180,0.0);
......
...@@ -69,14 +69,12 @@ Item *create_func_monthname(Item* a); ...@@ -69,14 +69,12 @@ Item *create_func_monthname(Item* a);
Item *create_func_nullif(Item* a, Item *b); Item *create_func_nullif(Item* a, Item *b);
Item *create_func_oct(Item *); Item *create_func_oct(Item *);
Item *create_func_ord(Item* a); Item *create_func_ord(Item* a);
Item *create_func_old_password(Item* a);
Item *create_func_period_add(Item* a, Item *b); Item *create_func_period_add(Item* a, Item *b);
Item *create_func_period_diff(Item* a, Item *b); Item *create_func_period_diff(Item* a, Item *b);
Item *create_func_pi(void); Item *create_func_pi(void);
Item *create_func_pow(Item* a, Item *b); Item *create_func_pow(Item* a, Item *b);
Item *create_func_current_user(void); Item *create_func_current_user(void);
Item *create_func_quarter(Item* a); Item *create_func_quarter(Item* a);
Item *create_func_password(Item* a);
Item *create_func_radians(Item *a); Item *create_func_radians(Item *a);
Item *create_func_release_lock(Item* a); Item *create_func_release_lock(Item* a);
Item *create_func_repeat(Item* a, Item *b); Item *create_func_repeat(Item* a, Item *b);
......
...@@ -1360,6 +1360,14 @@ String *Item_func_password::val_str(String *str) ...@@ -1360,6 +1360,14 @@ String *Item_func_password::val_str(String *str)
return str; return str;
} }
char *Item_func_password::alloc(THD *thd, const char *password)
{
char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
if (buff)
make_scrambled_password(buff, password);
return buff;
}
/* Item_func_old_password */ /* Item_func_old_password */
String *Item_func_old_password::val_str(String *str) String *Item_func_old_password::val_str(String *str)
...@@ -1374,6 +1382,14 @@ String *Item_func_old_password::val_str(String *str) ...@@ -1374,6 +1382,14 @@ String *Item_func_old_password::val_str(String *str)
return str; return str;
} }
char *Item_func_old_password::alloc(THD *thd, const char *password)
{
char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
if (buff)
make_scrambled_password_323(buff, password);
return buff;
}
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
......
...@@ -270,6 +270,7 @@ class Item_func_password :public Item_str_func ...@@ -270,6 +270,7 @@ class Item_func_password :public Item_str_func
String *val_str(String *str); String *val_str(String *str);
void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH; } void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH; }
const char *func_name() const { return "password"; } const char *func_name() const { return "password"; }
static char *alloc(THD *thd, const char *password);
}; };
...@@ -288,7 +289,7 @@ class Item_func_old_password :public Item_str_func ...@@ -288,7 +289,7 @@ class Item_func_old_password :public Item_str_func
String *val_str(String *str); String *val_str(String *str);
void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; } void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; }
const char *func_name() const { return "old_password"; } const char *func_name() const { return "old_password"; }
unsigned int size_of() { return sizeof(*this);} static char *alloc(THD *thd, const char *password);
}; };
......
...@@ -284,6 +284,7 @@ static SYMBOL symbols[] = { ...@@ -284,6 +284,7 @@ static SYMBOL symbols[] = {
{ "NULL", SYM(NULL_SYM),0,0}, { "NULL", SYM(NULL_SYM),0,0},
{ "NUMERIC", SYM(NUMERIC_SYM),0,0}, { "NUMERIC", SYM(NUMERIC_SYM),0,0},
{ "OFFSET", SYM(OFFSET_SYM),0,0}, { "OFFSET", SYM(OFFSET_SYM),0,0},
{ "OLD_PASSWORD", SYM(OLD_PASSWORD),0,0},
{ "ON", SYM(ON),0,0}, { "ON", SYM(ON),0,0},
{ "OPEN", SYM(OPEN_SYM),0,0}, { "OPEN", SYM(OPEN_SYM),0,0},
{ "OPTIMIZE", SYM(OPTIMIZE),0,0}, { "OPTIMIZE", SYM(OPTIMIZE),0,0},
...@@ -577,7 +578,6 @@ static SYMBOL sql_functions[] = { ...@@ -577,7 +578,6 @@ static SYMBOL sql_functions[] = {
{ "NUMPOINTS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numpoints)}, { "NUMPOINTS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_numpoints)},
{ "OCTET_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)}, { "OCTET_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
{ "OCT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_oct)}, { "OCT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_oct)},
{ "OLD_PASSWORD", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_old_password)},
{ "ORD", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ord)}, { "ORD", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ord)},
{ "OVERLAPS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_overlaps)}, { "OVERLAPS", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_overlaps)},
{ "PERIOD_ADD", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_add)}, { "PERIOD_ADD", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_add)},
......
...@@ -446,22 +446,20 @@ make_scrambled_password(char *to, const char *password) ...@@ -446,22 +446,20 @@ make_scrambled_password(char *to, const char *password)
Produce an obscure octet sequence from password and random Produce an obscure octet sequence from password and random
string, recieved from the server. This sequence corresponds to the string, recieved from the server. This sequence corresponds to the
password, but password can not be easily restored from it. The sequence password, but password can not be easily restored from it. The sequence
is then sent to the server for validation. Trailing zero is stored in is then sent to the server for validation. Trailing zero is not stored
the buf. in the buf as it is not needed.
This function is used by client to create authenticated reply to the This function is used by client to create authenticated reply to the
server's greeting. server's greeting.
SYNOPSIS SYNOPSIS
scramble() scramble()
buf OUT store scrambled string here. The buf must be at least buf OUT store scrambled string here. The buf must be at least
SHA1_HASH_SIZE+1 bytes long. SHA1_HASH_SIZE bytes long.
message IN random message, must be exactly SCRAMBLE_LENGTH long and message IN random message, must be exactly SCRAMBLE_LENGTH long and
NULL-terminated. NULL-terminated.
password IN users' password password IN users' password
RETURN VALUE
end of scrambled string
*/ */
char * void
scramble(char *to, const char *message, const char *password) scramble(char *to, const char *message, const char *password)
{ {
SHA1_CONTEXT sha1_context; SHA1_CONTEXT sha1_context;
...@@ -483,8 +481,6 @@ scramble(char *to, const char *message, const char *password) ...@@ -483,8 +481,6 @@ scramble(char *to, const char *message, const char *password)
/* xor allows 'from' and 'to' overlap: lets take advantage of it */ /* xor allows 'from' and 'to' overlap: lets take advantage of it */
sha1_result(&sha1_context, (uint8 *) to); sha1_result(&sha1_context, (uint8 *) to);
my_crypt(to, (const uint8 *) to, hash_stage1, SCRAMBLE_LENGTH); my_crypt(to, (const uint8 *) to, hash_stage1, SCRAMBLE_LENGTH);
to[SHA1_HASH_SIZE]= '\0';
return to + SHA1_HASH_SIZE;
} }
......
...@@ -51,7 +51,7 @@ static byte* acl_entry_get_key(acl_entry *entry,uint *length, ...@@ -51,7 +51,7 @@ static byte* acl_entry_get_key(acl_entry *entry,uint *length,
return (byte*) entry->key; return (byte*) entry->key;
} }
#define ACL_KEY_LENGTH (sizeof(long)+NAME_LEN+17) #define ACL_KEY_LENGTH (sizeof(long)+NAME_LEN+USERNAME_LENGTH+1)
static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs; static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs;
static MEM_ROOT mem, memex; static MEM_ROOT mem, memex;
...@@ -208,7 +208,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ...@@ -208,7 +208,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
DBUG_PRINT("info",("user table fields: %d, password length: %d", DBUG_PRINT("info",("user table fields: %d, password length: %d",
table->fields, table->field[2]->field_length)); table->fields, table->field[2]->field_length));
if (table->field[2]->field_length < 41 && !use_old_passwords) if (table->field[2]->field_length < SCRAMBLED_PASSWORD_CHAR_LENGTH &&
!use_old_passwords)
{ {
sql_print_error("mysql.user table is not updated to new password format; " sql_print_error("mysql.user table is not updated to new password format; "
"Disabling new password usage until " "Disabling new password usage until "
...@@ -516,6 +517,7 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) ...@@ -516,6 +517,7 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
RETURN VALUE RETURN VALUE
0 success: thread data and mqh are updated 0 success: thread data and mqh are updated
1 user not found or authentification failure 1 user not found or authentification failure
2 user found, has long (4.1.1) salt, but passwd is in old (3.23) format.
-1 user found, has short (3.23) salt, but passwd is in new (4.1.1) format. -1 user found, has short (3.23) salt, but passwd is in new (4.1.1) format.
*/ */
...@@ -564,6 +566,9 @@ acl_getroot(THD *thd, USER_RESOURCES *mqh, ...@@ -564,6 +566,9 @@ acl_getroot(THD *thd, USER_RESOURCES *mqh,
else if (passwd_len == SCRAMBLE_LENGTH && else if (passwd_len == SCRAMBLE_LENGTH &&
user_i->salt_len == SCRAMBLE_LENGTH_323) user_i->salt_len == SCRAMBLE_LENGTH_323)
res= -1; res= -1;
else if (passwd_len == SCRAMBLE_LENGTH_323 &&
user_i->salt_len == SCRAMBLE_LENGTH)
res= 2;
/* linear search complete: */ /* linear search complete: */
break; break;
} }
......
This diff is collapsed.
...@@ -493,6 +493,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -493,6 +493,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MULTIPOINT %token MULTIPOINT
%token MULTIPOLYGON %token MULTIPOLYGON
%token NOW_SYM %token NOW_SYM
%token OLD_PASSWORD
%token PASSWORD %token PASSWORD
%token POINTFROMTEXT %token POINTFROMTEXT
%token POINT_SYM %token POINT_SYM
...@@ -2516,9 +2517,11 @@ simple_expr: ...@@ -2516,9 +2517,11 @@ simple_expr:
{ $$= new Item_func_now($3); Lex->safe_to_cache_query=0;} { $$= new Item_func_now($3); Lex->safe_to_cache_query=0;}
| PASSWORD '(' expr ')' | PASSWORD '(' expr ')'
{ {
$$= use_old_passwords ? (Item *) new Item_func_old_password($3) : $$= use_old_passwords ? (Item *) new Item_func_old_password($3) :
(Item *) new Item_func_password($3); (Item *) new Item_func_password($3);
} }
| OLD_PASSWORD '(' expr ')'
{ $$= new Item_func_old_password($3); }
| POINT_SYM '(' expr ',' expr ')' | POINT_SYM '(' expr ',' expr ')'
{ $$= new Item_func_point($3,$5); } { $$= new Item_func_point($3,$5); }
| POINTFROMTEXT '(' expr ')' | POINTFROMTEXT '(' expr ')'
...@@ -4412,6 +4415,7 @@ keyword: ...@@ -4412,6 +4415,7 @@ keyword:
| NO_SYM {} | NO_SYM {}
| NONE_SYM {} | NONE_SYM {}
| OFFSET_SYM {} | OFFSET_SYM {}
| OLD_PASSWORD {}
| OPEN_SYM {} | OPEN_SYM {}
| PACK_KEYS_SYM {} | PACK_KEYS_SYM {}
| PARTIAL {} | PARTIAL {}
...@@ -4603,24 +4607,15 @@ text_or_password: ...@@ -4603,24 +4607,15 @@ text_or_password:
TEXT_STRING { $$=$1.str;} TEXT_STRING { $$=$1.str;}
| PASSWORD '(' TEXT_STRING ')' | PASSWORD '(' TEXT_STRING ')'
{ {
if (!$3.length) $$= $3.length ? use_old_passwords ?
$$=$3.str; Item_func_old_password::alloc(YYTHD, $3.str) :
else if (use_old_passwords) Item_func_password::alloc(YYTHD, $3.str) :
{ $3.str;
char *buff= (char *) }
YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1); | OLD_PASSWORD '(' TEXT_STRING ')'
if (buff) {
make_scrambled_password_323(buff, $3.str); $$= $3.length ? Item_func_old_password::alloc(YYTHD, $3.str) :
$$=buff; $3.str;
}
else
{
char *buff= (char *)
YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
if (buff)
make_scrambled_password(buff, $3.str);
$$=buff;
}
} }
; ;
......
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