~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
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
51
           // this three steps are done in scramble()
1 by brian
clean slate
52
53
           send(reply)
54
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
55
1 by brian
clean slate
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"
542 by Monty Taylor
Cleaned up the last commit.
67
#include <libdrizzle/password.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...
68
#include <stdlib.h>
69
#include <string.h>
1 by brian
clean slate
70
71
/************ MySQL 3.23-4.0 authentication routines: untouched ***********/
72
73
/*
74
  New (MySQL 3.21+) random generation structure initialization
75
  SYNOPSIS
76
    randominit()
77
    rand_st    OUT  Structure to initialize
78
    seed1      IN   First initialization parameter
79
    seed2      IN   Second initialization parameter
80
*/
81
164 by Brian Aker
Commit cleanup of export types.
82
void randominit(struct rand_struct *rand_st, uint32_t seed1, uint32_t seed2)
1 by brian
clean slate
83
{                                               /* For mysql 3.21.# */
212.6.16 by Mats Kindahl
Removing redundant use of casts in libdrizzle/ for memcmp(), memcpy(), memset(), and memmove().
84
  memset(rand_st, 0, sizeof(*rand_st));      /* Avoid UMC varnings */
1 by brian
clean slate
85
  rand_st->max_value= 0x3FFFFFFFL;
86
  rand_st->max_value_dbl=(double) rand_st->max_value;
87
  rand_st->seed1=seed1%rand_st->max_value ;
88
  rand_st->seed2=seed2%rand_st->max_value;
89
}
90
91
92
/*
93
    Generate random number.
94
  SYNOPSIS
95
    my_rnd()
96
    rand_st    INOUT  Structure used for number generation
97
  RETURN VALUE
98
    generated pseudo random number
99
*/
100
101
double my_rnd(struct rand_struct *rand_st)
102
{
103
  rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
104
  rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
105
  return (((double) rand_st->seed1)/rand_st->max_value_dbl);
106
}
107
108
109
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
110
    Generate binary hash from raw text string
1 by brian
clean slate
111
    Used for Pre-4.1 password handling
112
  SYNOPSIS
113
    hash_password()
114
    result       OUT store hash in this location
115
    password     IN  plain text password to build hash
116
    password_len IN  password length (password may be not null-terminated)
117
*/
118
164 by Brian Aker
Commit cleanup of export types.
119
void hash_password(uint32_t *result, const char *password, uint32_t password_len)
1 by brian
clean slate
120
{
294 by Brian Aker
libdrizzle has ulong removed.
121
  register uint32_t nr=1345345333L, add=7, nr2=0x12345671L;
164 by Brian Aker
Commit cleanup of export types.
122
  uint32_t tmp;
1 by brian
clean slate
123
  const char *password_end= password + password_len;
124
  for (; password < password_end; password++)
125
  {
126
    if (*password == ' ' || *password == '\t')
127
      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...
128
    tmp= (uint32_t) (unsigned char) *password;
1 by brian
clean slate
129
    nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
130
    nr2+=(nr2 << 8) ^ nr;
131
    add+=tmp;
132
  }
164 by Brian Aker
Commit cleanup of export types.
133
  result[0]=nr & (((uint32_t) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
134
  result[1]=nr2 & (((uint32_t) 1L << 31) -1L);
1 by brian
clean slate
135
}
136
206 by Brian Aker
Removed final uint dead types.
137
static inline uint8_t char_val(uint8_t X)
1 by brian
clean slate
138
{
395 by Brian Aker
Fixed uint/ushort issue in libdrizzle
139
  return (uint32_t) (X >= '0' && X <= '9' ? X-'0' :
1 by brian
clean slate
140
      X >= 'A' && X <= 'Z' ? X-'A'+10 : X-'a'+10);
141
}
142
143
144
/*
145
     **************** MySQL 4.1.1 authentication routines *************
146
*/
147
148
/*
149
    Generate string of printable random characters of requested length
150
  SYNOPSIS
151
    create_random_string()
152
    to       OUT   buffer for generation; must be at least length+1 bytes
153
                   long; result string is always null-terminated
154
    length   IN    how many random characters to put in buffer
155
    rand_st  INOUT structure used for number generation
156
*/
157
395 by Brian Aker
Fixed uint/ushort issue in libdrizzle
158
void create_random_string(char *to, uint32_t length, struct rand_struct *rand_st)
1 by brian
clean slate
159
{
160
  char *end= to + length;
161
  /* Use pointer arithmetics as it is faster way to do so. */
162
  for (; to < end; to++)
163
    *to= (char) (my_rnd(rand_st)*94+33);
164
  *to= '\0';
165
}
166
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
395 by Brian Aker
Fixed uint/ushort issue in libdrizzle
181
char *octet2hex(char *to, const char *str, uint32_t len)
1 by brian
clean slate
182
{
584.3.3 by Moriyoshi Koizumi
Incorporating changes proposed by mtaylor.
183
  static const char _dig_vec_upper[]= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
184
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
185
  const char *str_end= str + len;
1 by brian
clean slate
186
  for (; str != str_end; ++str)
187
  {
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...
188
    *to++= _dig_vec_upper[((unsigned char) *str) >> 4];
189
    *to++= _dig_vec_upper[((unsigned char) *str) & 0x0F];
1 by brian
clean slate
190
  }
191
  *to= '\0';
192
  return to;
193
}