1 /*
2    Copyright (c) 2000, 2011, Oracle and/or its affiliates.
3    Copyright (c) 2012, Monty Program Ab
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; version 2 of the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
17 
18 /* password checking routines */
19 /*****************************************************************************
20   The main idea is that no password are sent between client & server on
21   connection and that no password are saved in mysql in a decodable form.
22 
23   On connection a random string is generated and sent to the client.
24   The client generates a new string with a random generator inited with
25   the hash values from the password and the sent string.
26   This 'check' string is sent to the server where it is compared with
27   a string generated from the stored hash_value of the password and the
28   random string.
29 
30   The password is saved (in user.password) by using the PASSWORD() function in
31   mysql.
32 
33   This is .c file because it's used in libmysqlclient, which is entirely in C.
34   (we need it to be portable to a variety of systems).
35   Example:
36     update user set password=PASSWORD("hello") where user="test"
37   This saves a hashed number as a string in the password field.
38 
39   The new authentication is performed in following manner:
40 
41   SERVER:  public_seed=thd_create_random_password()
42            send(public_seed)
43 
44   CLIENT:  recv(public_seed)
45            hash_stage1=sha1("password")
46            hash_stage2=sha1(hash_stage1)
47            reply=xor(hash_stage1, sha1(public_seed,hash_stage2)
48 
49            // this three steps are done in scramble()
50 
51            send(reply)
52 
53 
54   SERVER:  recv(reply)
55            hash_stage1=xor(reply, sha1(public_seed,hash_stage2))
56            candidate_hash2=sha1(hash_stage1)
57            check(candidate_hash2==hash_stage2)
58 
59            // this three steps are done in check_scramble()
60 
61 *****************************************************************************/
62 
63 #include "mariadb.h"
64 #include <my_sys.h>
65 #include <m_string.h>
66 #include <password.h>
67 #include <mysql.h>
68 #include <my_rnd.h>
69 
70 /************ MySQL 3.23-4.0 authentication routines: untouched ***********/
71 
72 /*
73   New (MySQL 3.21+) random generation structure initialization
74   SYNOPSIS
75     my_rnd_init()
76     rand_st    OUT  Structure to initialize
77     seed1      IN   First initialization parameter
78     seed2      IN   Second initialization parameter
79 */
80 
81 /*
82     Generate binary hash from raw text string
83     Used for Pre-4.1 password handling
84   SYNOPSIS
85     hash_password()
86     result       OUT store hash in this location
87     password     IN  plain text password to build hash
88     password_len IN  password length (password may be not null-terminated)
89 */
90 
hash_password(ulong * result,const char * password,uint password_len)91 void hash_password(ulong *result, const char *password, uint password_len)
92 {
93   ulong nr=1345345333L, add=7, nr2=0x12345671L;
94   ulong tmp;
95   const char *password_end= password + password_len;
96   for (; password < password_end; password++)
97   {
98     if (*password == ' ' || *password == '\t')
99       continue;                                 /* skip space in password */
100     tmp= (ulong) (uchar) *password;
101     nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
102     nr2+=(nr2 << 8) ^ nr;
103     add+=tmp;
104   }
105   result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
106   result[1]=nr2 & (((ulong) 1L << 31) -1L);
107 }
108 
109 
110 /*
111     Create password to be stored in user database from raw string
112     Used for pre-4.1 password handling
113   SYNOPSIS
114     my_make_scrambled_password_323()
115     to        OUT store scrambled password here
116     password  IN  user-supplied password
117     pass_len  IN  length of password string
118 */
119 
my_make_scrambled_password_323(char * to,const char * password,size_t pass_len)120 void my_make_scrambled_password_323(char *to, const char *password,
121                                     size_t pass_len)
122 {
123   ulong hash_res[2];
124   hash_password(hash_res, password, (uint) pass_len);
125   sprintf(to, "%08lx%08lx", hash_res[0], hash_res[1]);
126 }
127 
128 
129 /*
130   Wrapper around my_make_scrambled_password_323() to maintain client lib ABI
131   compatibility.
132   In server code usage of my_make_scrambled_password_323() is preferred to
133   avoid strlen().
134   SYNOPSIS
135     make_scrambled_password_323()
136     to        OUT store scrambled password here
137     password  IN  NULL-terminated string with user-supplied password
138 */
139 
make_scrambled_password_323(char * to,const char * password)140 void make_scrambled_password_323(char *to, const char *password)
141 {
142   my_make_scrambled_password_323(to, password, strlen(password));
143 }
144 
145 
146 /*
147     Scramble string with password.
148     Used in pre 4.1 authentication phase.
149   SYNOPSIS
150     scramble_323()
151     to       OUT Store scrambled message here. Buffer must be at least
152                  SCRAMBLE_LENGTH_323+1 bytes long
153     message  IN  Message to scramble. Message must be at least
154                  SRAMBLE_LENGTH_323 bytes long.
155     password IN  Password to use while scrambling
156 */
157 
scramble_323(char * to,const char * message,const char * password)158 void scramble_323(char *to, const char *message, const char *password)
159 {
160   struct my_rnd_struct rand_st;
161   ulong hash_pass[2], hash_message[2];
162 
163   if (password && password[0])
164   {
165     char extra, *to_start=to;
166     const char *message_end= message + SCRAMBLE_LENGTH_323;
167     hash_password(hash_pass,password, (uint) strlen(password));
168     hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
169     my_rnd_init(&rand_st,hash_pass[0] ^ hash_message[0],
170                hash_pass[1] ^ hash_message[1]);
171     for (; message < message_end; message++)
172       *to++= (char) (floor(my_rnd(&rand_st)*31)+64);
173     extra=(char) (floor(my_rnd(&rand_st)*31));
174     while (to_start != to)
175       *(to_start++)^=extra;
176   }
177   *to= 0;
178 }
179 
180 
181 /**
182   Check scrambled message. Used in pre 4.1 password handling.
183 
184   @param scrambled  Scrambled message to check.
185   @param message    Original random message which was used for scrambling.
186   @param hash_pass  Password which should be used for scrambling.
187 
188   @remark scrambled and message must be SCRAMBLED_LENGTH_323 bytes long.
189 
190   @return FALSE if password is correct, TRUE otherwise.
191 */
192 
193 my_bool
check_scramble_323(const unsigned char * scrambled,const char * message,ulong * hash_pass)194 check_scramble_323(const unsigned char *scrambled, const char *message,
195                    ulong *hash_pass)
196 {
197   struct my_rnd_struct rand_st;
198   ulong hash_message[2];
199   /* Big enough for checks. */
200   uchar buff[16], scrambled_buff[SCRAMBLE_LENGTH_323 + 1];
201   uchar *to, extra;
202   const uchar *pos;
203 
204   /* Ensure that the scrambled message is null-terminated. */
205   memcpy(scrambled_buff, scrambled, SCRAMBLE_LENGTH_323);
206   scrambled_buff[SCRAMBLE_LENGTH_323]= '\0';
207   scrambled= scrambled_buff;
208 
209   hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
210   my_rnd_init(&rand_st,hash_pass[0] ^ hash_message[0],
211              hash_pass[1] ^ hash_message[1]);
212   to=buff;
213   DBUG_ASSERT(sizeof(buff) > SCRAMBLE_LENGTH_323);
214   for (pos=scrambled ; *pos && to < buff+sizeof(buff) ; pos++)
215     *to++=(char) (floor(my_rnd(&rand_st)*31)+64);
216   if (pos-scrambled != SCRAMBLE_LENGTH_323)
217     return 1;
218   extra=(char) (floor(my_rnd(&rand_st)*31));
219   to=buff;
220   while (*scrambled)
221   {
222     if (*scrambled++ != (uchar) (*to++ ^ extra))
223       return 1;                                 /* Wrong password */
224   }
225   return 0;
226 }
227 
char_val(uint8 X)228 static inline uint8 char_val(uint8 X)
229 {
230   return (uint) (X >= '0' && X <= '9' ? X-'0' :
231       X >= 'A' && X <= 'Z' ? X-'A'+10 : X-'a'+10);
232 }
233 
234 
235 /*
236     Convert password from hex string (as stored in mysql.user) to binary form.
237   SYNOPSIS
238     get_salt_from_password_323()
239     res       OUT store salt here
240     password  IN  password string as stored in mysql.user
241   NOTE
242     This function does not have length check for passwords. It will just crash
243     Password hashes in old format must have length divisible by 8
244 */
245 
get_salt_from_password_323(ulong * res,const char * password)246 void get_salt_from_password_323(ulong *res, const char *password)
247 {
248   res[0]= res[1]= 0;
249   if (password)
250   {
251     while (*password)
252     {
253       ulong val=0;
254       uint i;
255       for (i=0 ; i < 8 ; i++)
256         val=(val << 4)+char_val(*password++);
257       *res++=val;
258     }
259   }
260 }
261 
262 
263 /*
264     Convert scrambled password from binary form to asciiz hex string.
265   SYNOPSIS
266     make_password_from_salt_323()
267     to    OUT store resulting string password here, at least 17 bytes
268     salt  IN  password in salt format, 2 ulongs
269 */
270 
make_password_from_salt_323(char * to,const ulong * salt)271 void make_password_from_salt_323(char *to, const ulong *salt)
272 {
273   sprintf(to,"%08lx%08lx", salt[0], salt[1]);
274 }
275 
276 
277 /*
278      **************** MySQL 4.1.1 authentication routines *************
279 */
280 
281 
282 /* Character to use as version identifier for version 4.1 */
283 
284 #define PVERSION41_CHAR '*'
285 
286 
287 /*
288     Convert given octet sequence to asciiz string of hex characters;
289     str..str+len and 'to' may not overlap.
290   SYNOPSIS
291     octet2hex()
292     buf       OUT output buffer. Must be at least 2*len+1 bytes
293     str, len  IN  the beginning and the length of the input string
294 
295   RETURN
296     buf+len*2
297 */
298 
octet2hex(char * to,const char * str,size_t len)299 char *octet2hex(char *to, const char *str, size_t len)
300 {
301   const char *str_end= str + len;
302   for (; str != str_end; ++str)
303   {
304     *to++= _dig_vec_upper[((uchar) *str) >> 4];
305     *to++= _dig_vec_upper[((uchar) *str) & 0x0F];
306   }
307   *to= '\0';
308   return to;
309 }
310 
311 
312 /*
313     Convert given asciiz string of hex (0..9 a..f) characters to octet
314     sequence.
315   SYNOPSIS
316     hex2octet()
317     to        OUT buffer to place result; must be at least len/2 bytes
318     str, len  IN  begin, length for character string; str and to may not
319                   overlap; len % 2 == 0
320 */
321 
322 static void
hex2octet(uint8 * to,const char * str,uint len)323 hex2octet(uint8 *to, const char *str, uint len)
324 {
325   const char *str_end= str + len;
326   while (str < str_end)
327   {
328     char tmp= char_val(*str++);
329     *to++= (tmp << 4) | char_val(*str++);
330   }
331 }
332 
333 
334 /*
335     Encrypt/Decrypt function used for password encryption in authentication.
336     Simple XOR is used here but it is OK as we crypt random strings. Note,
337     that XOR(s1, XOR(s1, s2)) == s2, XOR(s1, s2) == XOR(s2, s1)
338   SYNOPSIS
339     my_crypt()
340     to      OUT buffer to hold crypted string; must be at least len bytes
341                 long; to and s1 (or s2) may be the same.
342     s1, s2  IN  input strings (of equal length)
343     len     IN  length of s1 and s2
344 */
345 
346 static void
my_crypt(char * to,const uchar * s1,const uchar * s2,uint len)347 my_crypt(char *to, const uchar *s1, const uchar *s2, uint len)
348 {
349   const uint8 *s1_end= s1 + len;
350   while (s1 < s1_end)
351     *to++= *s1++ ^ *s2++;
352 }
353 
354 
355 /**
356   Compute two stage SHA1 hash of the password :
357 
358     hash_stage1=sha1("password")
359     hash_stage2=sha1(hash_stage1)
360 
361   @param password    [IN]   Password string.
362   @param pass_len    [IN]   Length of the password.
363   @param hash_stage1 [OUT]  sha1(password)
364   @param hash_stage2 [OUT]  sha1(hash_stage1)
365 */
366 
367 inline static
compute_two_stage_sha1_hash(const char * password,size_t pass_len,uint8 * hash_stage1,uint8 * hash_stage2)368 void compute_two_stage_sha1_hash(const char *password, size_t pass_len,
369                                  uint8 *hash_stage1, uint8 *hash_stage2)
370 {
371   /* Stage 1: hash password */
372   my_sha1(hash_stage1, password, pass_len);
373 
374   /* Stage 2 : hash first stage's output. */
375   my_sha1(hash_stage2, (const char *) hash_stage1, MY_SHA1_HASH_SIZE);
376 }
377 
378 
379 /*
380     MySQL 4.1.1 password hashing: SHA conversion (see RFC 2289, 3174) twice
381     applied to the password string, and then produced octet sequence is
382     converted to hex string.
383     The result of this function is used as return value from PASSWORD() and
384     is stored in the database.
385   SYNOPSIS
386     my_make_scrambled_password()
387     buf       OUT buffer of size 2*MY_SHA1_HASH_SIZE + 2 to store hex string
388     password  IN  password string
389     pass_len  IN  length of password string
390 */
391 
my_make_scrambled_password(char * to,const char * password,size_t pass_len)392 void my_make_scrambled_password(char *to, const char *password,
393                                 size_t pass_len)
394 {
395   uint8 hash_stage2[MY_SHA1_HASH_SIZE];
396 
397   /* Two stage SHA1 hash of the password. */
398   compute_two_stage_sha1_hash(password, pass_len, (uint8 *) to, hash_stage2);
399 
400   /* convert hash_stage2 to hex string */
401   *to++= PVERSION41_CHAR;
402   octet2hex(to, (const char*) hash_stage2, MY_SHA1_HASH_SIZE);
403 }
404 
405 
406 /*
407   Wrapper around my_make_scrambled_password() to maintain client lib ABI
408   compatibility.
409   In server code usage of my_make_scrambled_password() is preferred to
410   avoid strlen().
411   SYNOPSIS
412     make_scrambled_password()
413     buf       OUT buffer of size 2*MY_SHA1_HASH_SIZE + 2 to store hex string
414     password  IN  NULL-terminated password string
415 */
416 
make_scrambled_password(char * to,const char * password)417 void make_scrambled_password(char *to, const char *password)
418 {
419   my_make_scrambled_password(to, password, strlen(password));
420 }
421 
422 
423 /*
424     Produce an obscure octet sequence from password and random
425     string, received from the server. This sequence corresponds to the
426     password, but password can not be easily restored from it. The sequence
427     is then sent to the server for validation. Trailing zero is not stored
428     in the buf as it is not needed.
429     This function is used by client to create authenticated reply to the
430     server's greeting.
431   SYNOPSIS
432     scramble()
433     buf       OUT store scrambled string here. The buf must be at least
434                   MY_SHA1_HASH_SIZE bytes long.
435     message   IN  random message, must be exactly SCRAMBLE_LENGTH long and
436                   NULL-terminated.
437     password  IN  users' password
438 */
439 
440 void
scramble(char * to,const char * message,const char * password)441 scramble(char *to, const char *message, const char *password)
442 {
443   uint8 hash_stage1[MY_SHA1_HASH_SIZE];
444   uint8 hash_stage2[MY_SHA1_HASH_SIZE];
445 
446   /* Two stage SHA1 hash of the password. */
447   compute_two_stage_sha1_hash(password, strlen(password), hash_stage1,
448                               hash_stage2);
449 
450   /* create crypt string as sha1(message, hash_stage2) */;
451   my_sha1_multi((uint8 *) to, message, SCRAMBLE_LENGTH,
452                 (const char *) hash_stage2, MY_SHA1_HASH_SIZE, NULL);
453   my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH);
454 }
455 
456 
457 /*
458     Check that scrambled message corresponds to the password; the function
459     is used by server to check that received reply is authentic.
460     This function does not check lengths of given strings: message must be
461     null-terminated, reply and hash_stage2 must be at least MY_SHA1_HASH_SIZE
462     long (if not, something fishy is going on).
463   SYNOPSIS
464     check_scramble()
465     scramble     clients' reply, presumably produced by scramble()
466     message      original random string, previously sent to client
467                  (presumably second argument of scramble()), must be
468                  exactly SCRAMBLE_LENGTH long and NULL-terminated.
469     hash_stage2  hex2octet-decoded database entry
470     All params are IN.
471 
472   RETURN VALUE
473     0  password is correct
474     !0  password is invalid
475 */
476 
477 my_bool
check_scramble(const uchar * scramble_arg,const char * message,const uint8 * hash_stage2)478 check_scramble(const uchar *scramble_arg, const char *message,
479                const uint8 *hash_stage2)
480 {
481   uint8 buf[MY_SHA1_HASH_SIZE];
482   uint8 hash_stage2_reassured[MY_SHA1_HASH_SIZE];
483 
484   /* create key to encrypt scramble */
485   my_sha1_multi(buf, message, SCRAMBLE_LENGTH,
486                 (const char *) hash_stage2, MY_SHA1_HASH_SIZE, NULL);
487   /* encrypt scramble */
488   my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH);
489 
490   /* now buf supposedly contains hash_stage1: so we can get hash_stage2 */
491   my_sha1(hash_stage2_reassured, (const char *) buf, MY_SHA1_HASH_SIZE);
492 
493   return MY_TEST(memcmp(hash_stage2, hash_stage2_reassured, MY_SHA1_HASH_SIZE));
494 }
495 
496 /*
497   Convert scrambled password from asciiz hex string to binary form.
498 
499   SYNOPSIS
500     get_salt_from_password()
501     res       OUT buf to hold password. Must be at least MY_SHA1_HASH_SIZE
502                   bytes long.
503     password  IN  4.1.1 version value of user.password
504 */
505 
get_salt_from_password(uint8 * hash_stage2,const char * password)506 void get_salt_from_password(uint8 *hash_stage2, const char *password)
507 {
508   hex2octet(hash_stage2, password+1 /* skip '*' */, MY_SHA1_HASH_SIZE * 2);
509 }
510 
511 /*
512     Convert scrambled password from binary form to asciiz hex string.
513   SYNOPSIS
514     make_password_from_salt()
515     to    OUT store resulting string here, 2*MY_SHA1_HASH_SIZE+2 bytes
516     salt  IN  password in salt format
517 */
518 
make_password_from_salt(char * to,const uint8 * hash_stage2)519 void make_password_from_salt(char *to, const uint8 *hash_stage2)
520 {
521   *to++= PVERSION41_CHAR;
522   octet2hex(to, (const char*) hash_stage2, MY_SHA1_HASH_SIZE);
523 }
524 
525