~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/password.c

Merged in Jay's tree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
75
75
    seed2      IN   Second initialization parameter
76
76
*/
77
77
 
78
 
void randominit(struct rand_struct *rand_st, ulong seed1, ulong seed2)
 
78
void randominit(struct rand_struct *rand_st, uint32_t seed1, uint32_t seed2)
79
79
{                                               /* For mysql 3.21.# */
80
80
#ifdef HAVE_purify
81
81
  bzero((char*) rand_st,sizeof(*rand_st));      /* Avoid UMC varnings */
114
114
    password_len IN  password length (password may be not null-terminated)
115
115
*/
116
116
 
117
 
void hash_password(ulong *result, const char *password, uint password_len)
 
117
void hash_password(uint32_t *result, const char *password, uint32_t password_len)
118
118
{
119
119
  register ulong nr=1345345333L, add=7, nr2=0x12345671L;
120
 
  ulong tmp;
 
120
  uint32_t tmp;
121
121
  const char *password_end= password + password_len;
122
122
  for (; password < password_end; password++)
123
123
  {
124
124
    if (*password == ' ' || *password == '\t')
125
125
      continue;                                 /* skip space in password */
126
 
    tmp= (ulong) (uchar) *password;
 
126
    tmp= (uint32_t) (uchar) *password;
127
127
    nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
128
128
    nr2+=(nr2 << 8) ^ nr;
129
129
    add+=tmp;
130
130
  }
131
 
  result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
132
 
  result[1]=nr2 & (((ulong) 1L << 31) -1L);
133
 
}
134
 
 
135
 
 
136
 
/*
137
 
    Create password to be stored in user database from raw string
138
 
    Used for pre-4.1 password handling
139
 
  SYNOPSIS
140
 
    make_scrambled_password_323()
141
 
    to        OUT store scrambled password here
142
 
    password  IN  user-supplied password
143
 
*/
144
 
 
145
 
void make_scrambled_password_323(char *to, const char *password)
146
 
{
147
 
  ulong hash_res[2];
148
 
  hash_password(hash_res, password, (uint) strlen(password));
149
 
  sprintf(to, "%08lx%08lx", hash_res[0], hash_res[1]);
150
 
}
151
 
 
152
 
 
153
 
/*
154
 
    Scramble string with password.
155
 
    Used in pre 4.1 authentication phase.
156
 
  SYNOPSIS
157
 
    scramble_323()
158
 
    to       OUT Store scrambled message here. Buffer must be at least
159
 
                 SCRAMBLE_LENGTH_323+1 bytes long
160
 
    message  IN  Message to scramble. Message must be at least
161
 
                 SRAMBLE_LENGTH_323 bytes long.
162
 
    password IN  Password to use while scrambling
163
 
*/
164
 
 
165
 
void scramble_323(char *to, const char *message, const char *password)
166
 
{
167
 
  struct rand_struct rand_st;
168
 
  ulong hash_pass[2], hash_message[2];
169
 
 
170
 
  if (password && password[0])
171
 
  {
172
 
    char extra, *to_start=to;
173
 
    const char *message_end= message + SCRAMBLE_LENGTH_323;
174
 
    hash_password(hash_pass,password, (uint) strlen(password));
175
 
    hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
176
 
    randominit(&rand_st,hash_pass[0] ^ hash_message[0],
177
 
               hash_pass[1] ^ hash_message[1]);
178
 
    for (; message < message_end; message++)
179
 
      *to++= (char) (floor(my_rnd(&rand_st)*31)+64);
180
 
    extra=(char) (floor(my_rnd(&rand_st)*31));
181
 
    while (to_start != to)
182
 
      *(to_start++)^=extra;
183
 
  }
184
 
  *to= 0;
185
 
}
186
 
 
187
 
 
188
 
/*
189
 
    Check scrambled message
190
 
    Used in pre 4.1 password handling
191
 
  SYNOPSIS
192
 
    check_scramble_323()
193
 
    scrambled  scrambled message to check.
194
 
    message    original random message which was used for scrambling; must
195
 
               be exactly SCRAMBLED_LENGTH_323 bytes long and
196
 
               NULL-terminated.
197
 
    hash_pass  password which should be used for scrambling
198
 
    All params are IN.
199
 
 
200
 
  RETURN VALUE
201
 
    0 - password correct
202
 
   !0 - password invalid
203
 
*/
204
 
 
205
 
my_bool
206
 
check_scramble_323(const char *scrambled, const char *message,
207
 
                   ulong *hash_pass)
208
 
{
209
 
  struct rand_struct rand_st;
210
 
  ulong hash_message[2];
211
 
  char buff[16],*to,extra;                      /* Big enough for check */
212
 
  const char *pos;
213
 
 
214
 
  hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
215
 
  randominit(&rand_st,hash_pass[0] ^ hash_message[0],
216
 
             hash_pass[1] ^ hash_message[1]);
217
 
  to=buff;
218
 
  DBUG_ASSERT(sizeof(buff) > SCRAMBLE_LENGTH_323);
219
 
  for (pos=scrambled ; *pos && to < buff+sizeof(buff) ; pos++)
220
 
    *to++=(char) (floor(my_rnd(&rand_st)*31)+64);
221
 
  if (pos-scrambled != SCRAMBLE_LENGTH_323)
222
 
    return 1;
223
 
  extra=(char) (floor(my_rnd(&rand_st)*31));
224
 
  to=buff;
225
 
  while (*scrambled)
226
 
  {
227
 
    if (*scrambled++ != (char) (*to++ ^ extra))
228
 
      return 1;                                 /* Wrong password */
229
 
  }
230
 
  return 0;
 
131
  result[0]=nr & (((uint32_t) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
 
132
  result[1]=nr2 & (((uint32_t) 1L << 31) -1L);
231
133
}
232
134
 
233
135
static inline uint8 char_val(uint8 X)
238
140
 
239
141
 
240
142
/*
241
 
    Convert password from hex string (as stored in mysql.user) to binary form.
242
 
  SYNOPSIS
243
 
    get_salt_from_password_323()
244
 
    res       OUT store salt here 
245
 
    password  IN  password string as stored in mysql.user
246
 
  NOTE
247
 
    This function does not have length check for passwords. It will just crash
248
 
    Password hashes in old format must have length divisible by 8
249
 
*/
250
 
 
251
 
void get_salt_from_password_323(ulong *res, const char *password)
252
 
{
253
 
  res[0]= res[1]= 0;
254
 
  if (password)
255
 
  {
256
 
    while (*password)
257
 
    {
258
 
      ulong val=0;
259
 
      uint i;
260
 
      for (i=0 ; i < 8 ; i++)
261
 
        val=(val << 4)+char_val(*password++);
262
 
      *res++=val;
263
 
    }
264
 
  }
265
 
}
266
 
 
267
 
 
268
 
/*
269
 
    Convert scrambled password from binary form to asciiz hex string.
270
 
  SYNOPSIS
271
 
    make_password_from_salt_323()
272
 
    to    OUT store resulting string password here, at least 17 bytes 
273
 
    salt  IN  password in salt format, 2 ulongs 
274
 
*/
275
 
 
276
 
void make_password_from_salt_323(char *to, const ulong *salt)
277
 
{
278
 
  sprintf(to,"%08lx%08lx", salt[0], salt[1]);
279
 
}
280
 
 
281
 
 
282
 
/*
283
143
     **************** MySQL 4.1.1 authentication routines *************
284
144
*/
285
145