~drizzle-trunk/drizzle/development

390.1.4 by Monty Taylor
More copyright header file fixes.
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
1 by brian
clean slate
19
20
/* password checking routines */
21
/*****************************************************************************
22
  The main idea is that no password are sent between client & server on
23
  connection and that no password are saved in mysql in a decodable form.
24
25
  On connection a random string is generated and sent to the client.
26
  The client generates a new string with a random generator inited with
27
  the hash values from the password and the sent string.
28
  This 'check' string is sent to the server where it is compared with
29
  a string generated from the stored hash_value of the password and the
30
  random string.
31
32
  The password is saved (in user.password) by using the PASSWORD() function in
33
  mysql.
34
35
  This is .c file because it's used in libmysqlclient, which is entirely in C.
36
  (we need it to be portable to a variety of systems).
37
  Example:
38
    update user set password=PASSWORD("hello") where user="test"
39
  This saves a hashed number as a string in the password field.
40
41
  The new authentication is performed in following manner:
42
43
  SERVER:  public_seed=create_random_string()
44
           send(public_seed)
45
46
  CLIENT:  recv(public_seed)
47
           hash_stage1=sha1("password")
48
           hash_stage2=sha1(hash_stage1)
49
           reply=xor(hash_stage1, sha1(public_seed,hash_stage2)
50
51
           // this three steps are done in scramble() 
52
53
           send(reply)
54
55
     
56
  SERVER:  recv(reply)
57
           hash_stage1=xor(reply, sha1(public_seed,hash_stage2))
58
           candidate_hash2=sha1(hash_stage1)
59
           check(candidate_hash2==hash_stage2)
60
61
           // this three steps are done in check_scramble()
62
63
*****************************************************************************/
64
383.1.44 by Monty Taylor
Renamed drizzle.h to libdrizzle.h.
65
#include "libdrizzle.h"
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
66
#include "libdrizzle_priv.h"
67
#include <stdlib.h>
68
#include <string.h>
1 by brian
clean slate
69
70
/************ MySQL 3.23-4.0 authentication routines: untouched ***********/
71
72
/*
73
  New (MySQL 3.21+) random generation structure initialization
74
  SYNOPSIS
75
    randominit()
76
    rand_st    OUT  Structure to initialize
77
    seed1      IN   First initialization parameter
78
    seed2      IN   Second initialization parameter
79
*/
80
164 by Brian Aker
Commit cleanup of export types.
81
void randominit(struct rand_struct *rand_st, uint32_t seed1, uint32_t seed2)
1 by brian
clean slate
82
{                                               /* For mysql 3.21.# */
212.6.16 by Mats Kindahl
Removing redundant use of casts in libdrizzle/ for memcmp(), memcpy(), memset(), and memmove().
83
  memset(rand_st, 0, sizeof(*rand_st));      /* Avoid UMC varnings */
1 by brian
clean slate
84
  rand_st->max_value= 0x3FFFFFFFL;
85
  rand_st->max_value_dbl=(double) rand_st->max_value;
86
  rand_st->seed1=seed1%rand_st->max_value ;
87
  rand_st->seed2=seed2%rand_st->max_value;
88
}
89
90
91
/*
92
    Generate random number.
93
  SYNOPSIS
94
    my_rnd()
95
    rand_st    INOUT  Structure used for number generation
96
  RETURN VALUE
97
    generated pseudo random number
98
*/
99
100
double my_rnd(struct rand_struct *rand_st)
101
{
102
  rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
103
  rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
104
  return (((double) rand_st->seed1)/rand_st->max_value_dbl);
105
}
106
107
108
/*
109
    Generate binary hash from raw text string 
110
    Used for Pre-4.1 password handling
111
  SYNOPSIS
112
    hash_password()
113
    result       OUT store hash in this location
114
    password     IN  plain text password to build hash
115
    password_len IN  password length (password may be not null-terminated)
116
*/
117
164 by Brian Aker
Commit cleanup of export types.
118
void hash_password(uint32_t *result, const char *password, uint32_t password_len)
1 by brian
clean slate
119
{
294 by Brian Aker
libdrizzle has ulong removed.
120
  register uint32_t nr=1345345333L, add=7, nr2=0x12345671L;
164 by Brian Aker
Commit cleanup of export types.
121
  uint32_t tmp;
1 by brian
clean slate
122
  const char *password_end= password + password_len;
123
  for (; password < password_end; password++)
124
  {
125
    if (*password == ' ' || *password == '\t')
126
      continue;                                 /* skip space in password */
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
127
    tmp= (uint32_t) (unsigned char) *password;
1 by brian
clean slate
128
    nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
129
    nr2+=(nr2 << 8) ^ nr;
130
    add+=tmp;
131
  }
164 by Brian Aker
Commit cleanup of export types.
132
  result[0]=nr & (((uint32_t) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
133
  result[1]=nr2 & (((uint32_t) 1L << 31) -1L);
1 by brian
clean slate
134
}
135
206 by Brian Aker
Removed final uint dead types.
136
static inline uint8_t char_val(uint8_t X)
1 by brian
clean slate
137
{
138
  return (uint) (X >= '0' && X <= '9' ? X-'0' :
139
      X >= 'A' && X <= 'Z' ? X-'A'+10 : X-'a'+10);
140
}
141
142
143
/*
144
     **************** MySQL 4.1.1 authentication routines *************
145
*/
146
147
/*
148
    Generate string of printable random characters of requested length
149
  SYNOPSIS
150
    create_random_string()
151
    to       OUT   buffer for generation; must be at least length+1 bytes
152
                   long; result string is always null-terminated
153
    length   IN    how many random characters to put in buffer
154
    rand_st  INOUT structure used for number generation
155
*/
156
157
void create_random_string(char *to, uint length, struct rand_struct *rand_st)
158
{
159
  char *end= to + length;
160
  /* Use pointer arithmetics as it is faster way to do so. */
161
  for (; to < end; to++)
162
    *to= (char) (my_rnd(rand_st)*94+33);
163
  *to= '\0';
164
}
165
166
167
/* Character to use as version identifier for version 4.1 */
168
169
#define PVERSION41_CHAR '*'
170
171
172
/*
173
    Convert given octet sequence to asciiz string of hex characters;
174
    str..str+len and 'to' may not overlap.
175
  SYNOPSIS
176
    octet2hex()
177
    buf       OUT output buffer. Must be at least 2*len+1 bytes
178
    str, len  IN  the beginning and the length of the input string
179
180
  RETURN
181
    buf+len*2
182
*/
183
184
char *octet2hex(char *to, const char *str, uint len)
185
{
186
  const char *str_end= str + len; 
187
  for (; str != str_end; ++str)
188
  {
390.1.6 by Monty Taylor
Oh dear god the changes. The changes. I'd tell you what they are, but I'd just be making stuff up. Suffice it to day it's mostly all around splitting files in libdrizzle into different files and removing interdepends. And whatever else I happened to see...
189
    *to++= _dig_vec_upper[((unsigned char) *str) >> 4];
190
    *to++= _dig_vec_upper[((unsigned char) *str) & 0x0F];
1 by brian
clean slate
191
  }
192
  *to= '\0';
193
  return to;
194
}