1
by brian
clean slate |
1 |
/* Copyright (C) 2000-2006 MySQL AB
|
2 |
||
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.
|
|
6 |
||
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.
|
|
11 |
||
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 */
|
|
15 |
||
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.
|
|
20 |
||
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
|
|
26 |
random string.
|
|
27 |
||
28 |
The password is saved (in user.password) by using the PASSWORD() function in
|
|
29 |
mysql.
|
|
30 |
||
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).
|
|
33 |
Example:
|
|
34 |
update user set password=PASSWORD("hello") where user="test"
|
|
35 |
This saves a hashed number as a string in the password field.
|
|
36 |
||
37 |
The new authentication is performed in following manner:
|
|
38 |
||
39 |
SERVER: public_seed=create_random_string()
|
|
40 |
send(public_seed)
|
|
41 |
||
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)
|
|
46 |
||
47 |
// this three steps are done in scramble()
|
|
48 |
||
49 |
send(reply)
|
|
50 |
||
51 |
|
|
52 |
SERVER: recv(reply)
|
|
53 |
hash_stage1=xor(reply, sha1(public_seed,hash_stage2))
|
|
54 |
candidate_hash2=sha1(hash_stage1)
|
|
55 |
check(candidate_hash2==hash_stage2)
|
|
56 |
||
57 |
// this three steps are done in check_scramble()
|
|
58 |
||
59 |
*****************************************************************************/
|
|
60 |
||
212.5.39
by Monty Taylor
Phew. Moved my_base and my_global. |
61 |
#include <drizzled/global.h> |
212.5.45
by Monty Taylor
Removed excess AM_CPPFLAGS from the tree. Now the only thing that should be in the include path should be -I${top_srcdir} and -I${top_builddir}w |
62 |
#include <mysys/my_sys.h> |
212.5.18
by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype. |
63 |
#include <mystrings/m_string.h> |
212.5.45
by Monty Taylor
Removed excess AM_CPPFLAGS from the tree. Now the only thing that should be in the include path should be -I${top_srcdir} and -I${top_builddir}w |
64 |
#include <mysys/sha1.h> |
77.1.39
by Monty Taylor
More mysql->drizzle renaming. |
65 |
#include "drizzle.h" |
1
by brian
clean slate |
66 |
|
67 |
/************ MySQL 3.23-4.0 authentication routines: untouched ***********/
|
|
68 |
||
69 |
/*
|
|
70 |
New (MySQL 3.21+) random generation structure initialization
|
|
71 |
SYNOPSIS
|
|
72 |
randominit()
|
|
73 |
rand_st OUT Structure to initialize
|
|
74 |
seed1 IN First initialization parameter
|
|
75 |
seed2 IN Second initialization parameter
|
|
76 |
*/
|
|
77 |
||
164
by Brian Aker
Commit cleanup of export types. |
78 |
void randominit(struct rand_struct *rand_st, uint32_t seed1, uint32_t seed2) |
1
by brian
clean slate |
79 |
{ /* For mysql 3.21.# */ |
212.6.16
by Mats Kindahl
Removing redundant use of casts in libdrizzle/ for memcmp(), memcpy(), memset(), and memmove(). |
80 |
memset(rand_st, 0, sizeof(*rand_st)); /* Avoid UMC varnings */ |
1
by brian
clean slate |
81 |
rand_st->max_value= 0x3FFFFFFFL; |
82 |
rand_st->max_value_dbl=(double) rand_st->max_value; |
|
83 |
rand_st->seed1=seed1%rand_st->max_value ; |
|
84 |
rand_st->seed2=seed2%rand_st->max_value; |
|
85 |
}
|
|
86 |
||
87 |
||
88 |
/*
|
|
89 |
Generate random number.
|
|
90 |
SYNOPSIS
|
|
91 |
my_rnd()
|
|
92 |
rand_st INOUT Structure used for number generation
|
|
93 |
RETURN VALUE
|
|
94 |
generated pseudo random number
|
|
95 |
*/
|
|
96 |
||
97 |
double my_rnd(struct rand_struct *rand_st) |
|
98 |
{
|
|
99 |
rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value; |
|
100 |
rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value; |
|
101 |
return (((double) rand_st->seed1)/rand_st->max_value_dbl); |
|
102 |
}
|
|
103 |
||
104 |
||
105 |
/*
|
|
106 |
Generate binary hash from raw text string
|
|
107 |
Used for Pre-4.1 password handling
|
|
108 |
SYNOPSIS
|
|
109 |
hash_password()
|
|
110 |
result OUT store hash in this location
|
|
111 |
password IN plain text password to build hash
|
|
112 |
password_len IN password length (password may be not null-terminated)
|
|
113 |
*/
|
|
114 |
||
164
by Brian Aker
Commit cleanup of export types. |
115 |
void hash_password(uint32_t *result, const char *password, uint32_t password_len) |
1
by brian
clean slate |
116 |
{
|
294
by Brian Aker
libdrizzle has ulong removed. |
117 |
register uint32_t nr=1345345333L, add=7, nr2=0x12345671L; |
164
by Brian Aker
Commit cleanup of export types. |
118 |
uint32_t tmp; |
1
by brian
clean slate |
119 |
const char *password_end= password + password_len; |
120 |
for (; password < password_end; password++) |
|
121 |
{
|
|
122 |
if (*password == ' ' || *password == '\t') |
|
123 |
continue; /* skip space in password */ |
|
164
by Brian Aker
Commit cleanup of export types. |
124 |
tmp= (uint32_t) (uchar) *password; |
1
by brian
clean slate |
125 |
nr^= (((nr & 63)+add)*tmp)+ (nr << 8); |
126 |
nr2+=(nr2 << 8) ^ nr; |
|
127 |
add+=tmp; |
|
128 |
}
|
|
164
by Brian Aker
Commit cleanup of export types. |
129 |
result[0]=nr & (((uint32_t) 1L << 31) -1L); /* Don't use sign bit (str2int) */; |
130 |
result[1]=nr2 & (((uint32_t) 1L << 31) -1L); |
|
1
by brian
clean slate |
131 |
}
|
132 |
||
206
by Brian Aker
Removed final uint dead types. |
133 |
static inline uint8_t char_val(uint8_t X) |
1
by brian
clean slate |
134 |
{
|
135 |
return (uint) (X >= '0' && X <= '9' ? X-'0' : |
|
136 |
X >= 'A' && X <= 'Z' ? X-'A'+10 : X-'a'+10); |
|
137 |
}
|
|
138 |
||
139 |
||
140 |
/*
|
|
141 |
**************** MySQL 4.1.1 authentication routines *************
|
|
142 |
*/
|
|
143 |
||
144 |
/*
|
|
145 |
Generate string of printable random characters of requested length
|
|
146 |
SYNOPSIS
|
|
147 |
create_random_string()
|
|
148 |
to OUT buffer for generation; must be at least length+1 bytes
|
|
149 |
long; result string is always null-terminated
|
|
150 |
length IN how many random characters to put in buffer
|
|
151 |
rand_st INOUT structure used for number generation
|
|
152 |
*/
|
|
153 |
||
154 |
void create_random_string(char *to, uint length, struct rand_struct *rand_st) |
|
155 |
{
|
|
156 |
char *end= to + length; |
|
157 |
/* Use pointer arithmetics as it is faster way to do so. */
|
|
158 |
for (; to < end; to++) |
|
159 |
*to= (char) (my_rnd(rand_st)*94+33); |
|
160 |
*to= '\0'; |
|
161 |
}
|
|
162 |
||
163 |
||
164 |
/* Character to use as version identifier for version 4.1 */
|
|
165 |
||
166 |
#define PVERSION41_CHAR '*'
|
|
167 |
||
168 |
||
169 |
/*
|
|
170 |
Convert given octet sequence to asciiz string of hex characters;
|
|
171 |
str..str+len and 'to' may not overlap.
|
|
172 |
SYNOPSIS
|
|
173 |
octet2hex()
|
|
174 |
buf OUT output buffer. Must be at least 2*len+1 bytes
|
|
175 |
str, len IN the beginning and the length of the input string
|
|
176 |
||
177 |
RETURN
|
|
178 |
buf+len*2
|
|
179 |
*/
|
|
180 |
||
181 |
char *octet2hex(char *to, const char *str, uint len) |
|
182 |
{
|
|
183 |
const char *str_end= str + len; |
|
184 |
for (; str != str_end; ++str) |
|
185 |
{
|
|
186 |
*to++= _dig_vec_upper[((uchar) *str) >> 4]; |
|
187 |
*to++= _dig_vec_upper[((uchar) *str) & 0x0F]; |
|
188 |
}
|
|
189 |
*to= '\0'; |
|
190 |
return to; |
|
191 |
}
|