1
/* Copyright (C) 2000-2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
/* password checking routines */
17
/*****************************************************************************
18
The main idea is that no password are sent between client & server on
19
connection and that no password are saved in mysql in a decodable form.
21
On connection a random string is generated and sent to the client.
22
The client generates a new string with a random generator inited with
23
the hash values from the password and the sent string.
24
This 'check' string is sent to the server where it is compared with
25
a string generated from the stored hash_value of the password and the
28
The password is saved (in user.password) by using the PASSWORD() function in
31
This is .c file because it's used in libmysqlclient, which is entirely in C.
32
(we need it to be portable to a variety of systems).
34
update user set password=PASSWORD("hello") where user="test"
35
This saves a hashed number as a string in the password field.
37
The new authentication is performed in following manner:
39
SERVER: public_seed=create_random_string()
42
CLIENT: recv(public_seed)
43
hash_stage1=sha1("password")
44
hash_stage2=sha1(hash_stage1)
45
reply=xor(hash_stage1, sha1(public_seed,hash_stage2)
47
// this three steps are done in scramble()
53
hash_stage1=xor(reply, sha1(public_seed,hash_stage2))
54
candidate_hash2=sha1(hash_stage1)
55
check(candidate_hash2==hash_stage2)
57
// this three steps are done in check_scramble()
59
*****************************************************************************/
61
#include <my_global.h>
67
/************ MySQL 3.23-4.0 authentication routines: untouched ***********/
70
New (MySQL 3.21+) random generation structure initialization
73
rand_st OUT Structure to initialize
74
seed1 IN First initialization parameter
75
seed2 IN Second initialization parameter
78
void randominit(struct rand_struct *rand_st, ulong seed1, ulong seed2)
79
{ /* For mysql 3.21.# */
81
bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
83
rand_st->max_value= 0x3FFFFFFFL;
84
rand_st->max_value_dbl=(double) rand_st->max_value;
85
rand_st->seed1=seed1%rand_st->max_value ;
86
rand_st->seed2=seed2%rand_st->max_value;
91
Generate random number.
94
rand_st INOUT Structure used for number generation
96
generated pseudo random number
99
double my_rnd(struct rand_struct *rand_st)
101
rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
102
rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
103
return (((double) rand_st->seed1)/rand_st->max_value_dbl);
108
Generate binary hash from raw text string
109
Used for Pre-4.1 password handling
112
result OUT store hash in this location
113
password IN plain text password to build hash
114
password_len IN password length (password may be not null-terminated)
117
void hash_password(ulong *result, const char *password, uint password_len)
119
register ulong nr=1345345333L, add=7, nr2=0x12345671L;
121
const char *password_end= password + password_len;
122
for (; password < password_end; password++)
124
if (*password == ' ' || *password == '\t')
125
continue; /* skip space in password */
126
tmp= (ulong) (uchar) *password;
127
nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
128
nr2+=(nr2 << 8) ^ nr;
131
result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
132
result[1]=nr2 & (((ulong) 1L << 31) -1L);
137
Create password to be stored in user database from raw string
138
Used for pre-4.1 password handling
140
my_make_scrambled_password_323()
141
to OUT store scrambled password here
142
password IN user-supplied password
143
pass_len IN length of password string
146
void my_make_scrambled_password_323(char *to, const char *password,
150
hash_password(hash_res, password, (uint) pass_len);
151
sprintf(to, "%08lx%08lx", hash_res[0], hash_res[1]);
156
Wrapper around my_make_scrambled_password_323() to maintain client lib ABI
158
In server code usage of my_make_scrambled_password_323() is preferred to
161
make_scrambled_password_323()
162
to OUT store scrambled password here
163
password IN NULL-terminated string with user-supplied password
166
void make_scrambled_password_323(char *to, const char *password)
168
my_make_scrambled_password_323(to, password, strlen(password));
173
Scramble string with password.
174
Used in pre 4.1 authentication phase.
177
to OUT Store scrambled message here. Buffer must be at least
178
SCRAMBLE_LENGTH_323+1 bytes long
179
message IN Message to scramble. Message must be at least
180
SRAMBLE_LENGTH_323 bytes long.
181
password IN Password to use while scrambling
184
void scramble_323(char *to, const char *message, const char *password)
186
struct rand_struct rand_st;
187
ulong hash_pass[2], hash_message[2];
189
if (password && password[0])
191
char extra, *to_start=to;
192
const char *message_end= message + SCRAMBLE_LENGTH_323;
193
hash_password(hash_pass,password, (uint) strlen(password));
194
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
195
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
196
hash_pass[1] ^ hash_message[1]);
197
for (; message < message_end; message++)
198
*to++= (char) (floor(my_rnd(&rand_st)*31)+64);
199
extra=(char) (floor(my_rnd(&rand_st)*31));
200
while (to_start != to)
201
*(to_start++)^=extra;
208
Check scrambled message
209
Used in pre 4.1 password handling
212
scrambled scrambled message to check.
213
message original random message which was used for scrambling; must
214
be exactly SCRAMBLED_LENGTH_323 bytes long and
216
hash_pass password which should be used for scrambling
221
!0 - password invalid
225
check_scramble_323(const char *scrambled, const char *message,
228
struct rand_struct rand_st;
229
ulong hash_message[2];
230
char buff[16],*to,extra; /* Big enough for check */
233
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
234
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
235
hash_pass[1] ^ hash_message[1]);
237
DBUG_ASSERT(sizeof(buff) > SCRAMBLE_LENGTH_323);
238
for (pos=scrambled ; *pos && to < buff+sizeof(buff) ; pos++)
239
*to++=(char) (floor(my_rnd(&rand_st)*31)+64);
240
if (pos-scrambled != SCRAMBLE_LENGTH_323)
242
extra=(char) (floor(my_rnd(&rand_st)*31));
246
if (*scrambled++ != (char) (*to++ ^ extra))
247
return 1; /* Wrong password */
252
static inline uint8 char_val(uint8 X)
254
return (uint) (X >= '0' && X <= '9' ? X-'0' :
255
X >= 'A' && X <= 'Z' ? X-'A'+10 : X-'a'+10);
260
Convert password from hex string (as stored in mysql.user) to binary form.
262
get_salt_from_password_323()
263
res OUT store salt here
264
password IN password string as stored in mysql.user
266
This function does not have length check for passwords. It will just crash
267
Password hashes in old format must have length divisible by 8
270
void get_salt_from_password_323(ulong *res, const char *password)
279
for (i=0 ; i < 8 ; i++)
280
val=(val << 4)+char_val(*password++);
288
Convert scrambled password from binary form to asciiz hex string.
290
make_password_from_salt_323()
291
to OUT store resulting string password here, at least 17 bytes
292
salt IN password in salt format, 2 ulongs
295
void make_password_from_salt_323(char *to, const ulong *salt)
297
sprintf(to,"%08lx%08lx", salt[0], salt[1]);
302
**************** MySQL 4.1.1 authentication routines *************
306
Generate string of printable random characters of requested length
308
create_random_string()
309
to OUT buffer for generation; must be at least length+1 bytes
310
long; result string is always null-terminated
311
length IN how many random characters to put in buffer
312
rand_st INOUT structure used for number generation
315
void create_random_string(char *to, uint length, struct rand_struct *rand_st)
317
char *end= to + length;
318
/* Use pointer arithmetics as it is faster way to do so. */
319
for (; to < end; to++)
320
*to= (char) (my_rnd(rand_st)*94+33);
325
/* Character to use as version identifier for version 4.1 */
327
#define PVERSION41_CHAR '*'
331
Convert given octet sequence to asciiz string of hex characters;
332
str..str+len and 'to' may not overlap.
335
buf OUT output buffer. Must be at least 2*len+1 bytes
336
str, len IN the beginning and the length of the input string
342
char *octet2hex(char *to, const char *str, uint len)
344
const char *str_end= str + len;
345
for (; str != str_end; ++str)
347
*to++= _dig_vec_upper[((uchar) *str) >> 4];
348
*to++= _dig_vec_upper[((uchar) *str) & 0x0F];
356
Convert given asciiz string of hex (0..9 a..f) characters to octet
360
to OUT buffer to place result; must be at least len/2 bytes
361
str, len IN begin, length for character string; str and to may not
362
overlap; len % 2 == 0
366
hex2octet(uint8 *to, const char *str, uint len)
368
const char *str_end= str + len;
369
while (str < str_end)
371
register char tmp= char_val(*str++);
372
*to++= (tmp << 4) | char_val(*str++);
378
Encrypt/Decrypt function used for password encryption in authentication.
379
Simple XOR is used here but it is OK as we crypt random strings. Note,
380
that XOR(s1, XOR(s1, s2)) == s2, XOR(s1, s2) == XOR(s2, s1)
383
to OUT buffer to hold crypted string; must be at least len bytes
384
long; to and s1 (or s2) may be the same.
385
s1, s2 IN input strings (of equal length)
386
len IN length of s1 and s2
390
my_crypt(char *to, const uchar *s1, const uchar *s2, uint len)
392
const uint8 *s1_end= s1 + len;
394
*to++= *s1++ ^ *s2++;
399
MySQL 4.1.1 password hashing: SHA conversion (see RFC 2289, 3174) twice
400
applied to the password string, and then produced octet sequence is
401
converted to hex string.
402
The result of this function is used as return value from PASSWORD() and
403
is stored in the database.
405
my_make_scrambled_password()
406
buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string
407
password IN password string
408
pass_len IN length of password string
411
void my_make_scrambled_password(char *to, const char *password,
414
SHA1_CONTEXT sha1_context;
415
uint8 hash_stage2[SHA1_HASH_SIZE];
417
mysql_sha1_reset(&sha1_context);
418
/* stage 1: hash password */
419
mysql_sha1_input(&sha1_context, (uint8 *) password, (uint) pass_len);
420
mysql_sha1_result(&sha1_context, (uint8 *) to);
421
/* stage 2: hash stage1 output */
422
mysql_sha1_reset(&sha1_context);
423
mysql_sha1_input(&sha1_context, (uint8 *) to, SHA1_HASH_SIZE);
424
/* separate buffer is used to pass 'to' in octet2hex */
425
mysql_sha1_result(&sha1_context, hash_stage2);
426
/* convert hash_stage2 to hex string */
427
*to++= PVERSION41_CHAR;
428
octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE);
433
Wrapper around my_make_scrambled_password() to maintain client lib ABI
435
In server code usage of my_make_scrambled_password() is preferred to
438
make_scrambled_password()
439
buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string
440
password IN NULL-terminated password string
443
void make_scrambled_password(char *to, const char *password)
445
my_make_scrambled_password(to, password, strlen(password));
450
Produce an obscure octet sequence from password and random
451
string, recieved from the server. This sequence corresponds to the
452
password, but password can not be easily restored from it. The sequence
453
is then sent to the server for validation. Trailing zero is not stored
454
in the buf as it is not needed.
455
This function is used by client to create authenticated reply to the
459
buf OUT store scrambled string here. The buf must be at least
460
SHA1_HASH_SIZE bytes long.
461
message IN random message, must be exactly SCRAMBLE_LENGTH long and
463
password IN users' password
467
scramble(char *to, const char *message, const char *password)
469
SHA1_CONTEXT sha1_context;
470
uint8 hash_stage1[SHA1_HASH_SIZE];
471
uint8 hash_stage2[SHA1_HASH_SIZE];
473
mysql_sha1_reset(&sha1_context);
474
/* stage 1: hash password */
475
mysql_sha1_input(&sha1_context, (uint8 *) password, (uint) strlen(password));
476
mysql_sha1_result(&sha1_context, hash_stage1);
477
/* stage 2: hash stage 1; note that hash_stage2 is stored in the database */
478
mysql_sha1_reset(&sha1_context);
479
mysql_sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE);
480
mysql_sha1_result(&sha1_context, hash_stage2);
481
/* create crypt string as sha1(message, hash_stage2) */;
482
mysql_sha1_reset(&sha1_context);
483
mysql_sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH);
484
mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
485
/* xor allows 'from' and 'to' overlap: lets take advantage of it */
486
mysql_sha1_result(&sha1_context, (uint8 *) to);
487
my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH);
492
Check that scrambled message corresponds to the password; the function
493
is used by server to check that recieved reply is authentic.
494
This function does not check lengths of given strings: message must be
495
null-terminated, reply and hash_stage2 must be at least SHA1_HASH_SIZE
496
long (if not, something fishy is going on).
499
scramble clients' reply, presumably produced by scramble()
500
message original random string, previously sent to client
501
(presumably second argument of scramble()), must be
502
exactly SCRAMBLE_LENGTH long and NULL-terminated.
503
hash_stage2 hex2octet-decoded database entry
507
0 password is correct
508
!0 password is invalid
512
check_scramble(const char *scramble_arg, const char *message,
513
const uint8 *hash_stage2)
515
SHA1_CONTEXT sha1_context;
516
uint8 buf[SHA1_HASH_SIZE];
517
uint8 hash_stage2_reassured[SHA1_HASH_SIZE];
519
mysql_sha1_reset(&sha1_context);
520
/* create key to encrypt scramble */
521
mysql_sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH);
522
mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);
523
mysql_sha1_result(&sha1_context, buf);
524
/* encrypt scramble */
525
my_crypt((char *) buf, buf, (const uchar *) scramble_arg, SCRAMBLE_LENGTH);
526
/* now buf supposedly contains hash_stage1: so we can get hash_stage2 */
527
mysql_sha1_reset(&sha1_context);
528
mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
529
mysql_sha1_result(&sha1_context, hash_stage2_reassured);
530
return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
535
Convert scrambled password from asciiz hex string to binary form.
538
get_salt_from_password()
539
res OUT buf to hold password. Must be at least SHA1_HASH_SIZE
541
password IN 4.1.1 version value of user.password
544
void get_salt_from_password(uint8 *hash_stage2, const char *password)
546
hex2octet(hash_stage2, password+1 /* skip '*' */, SHA1_HASH_SIZE * 2);
550
Convert scrambled password from binary form to asciiz hex string.
552
make_password_from_salt()
553
to OUT store resulting string here, 2*SHA1_HASH_SIZE+2 bytes
554
salt IN password in salt format
557
void make_password_from_salt(char *to, const uint8 *hash_stage2)
559
*to++= PVERSION41_CHAR;
560
octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE);