~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
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
43
  SERVER:  public_seed=drizzleclient_create_random_string()
1 by brian
clean slate
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
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...
65
#include "libdrizzle_priv.h"
779.3.37 by Monty Taylor
Renmaed libdrizzle in the tree to libdrizzleclient to avoid namespace clashes
66
#include "password.h"
67
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
892.2.3 by Monty Taylor
Fixed fixes.
76
    drizzleclient_randominit()
1 by brian
clean slate
77
    rand_st    OUT  Structure to initialize
78
    seed1      IN   First initialization parameter
79
    seed2      IN   Second initialization parameter
80
*/
81
892.2.3 by Monty Taylor
Fixed fixes.
82
void drizzleclient_randominit(struct rand_struct *rand_st,
83
                              uint64_t seed1,
84
                              uint64_t seed2)
1 by brian
clean slate
85
{                                               /* For mysql 3.21.# */
212.6.16 by Mats Kindahl
Removing redundant use of casts in libdrizzle/ for memcmp(), memcpy(), memset(), and memmove().
86
  memset(rand_st, 0, sizeof(*rand_st));      /* Avoid UMC varnings */
1 by brian
clean slate
87
  rand_st->max_value= 0x3FFFFFFFL;
88
  rand_st->max_value_dbl=(double) rand_st->max_value;
89
  rand_st->seed1=seed1%rand_st->max_value ;
90
  rand_st->seed2=seed2%rand_st->max_value;
91
}
92
93
94
/*
95
    Generate random number.
96
  SYNOPSIS
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
97
    drizzleclient_my_rnd()
1 by brian
clean slate
98
    rand_st    INOUT  Structure used for number generation
99
  RETURN VALUE
100
    generated pseudo random number
101
*/
102
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
103
double drizzleclient_my_rnd(struct rand_struct *rand_st)
1 by brian
clean slate
104
{
105
  rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
106
  rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
107
  return (((double) rand_st->seed1)/rand_st->max_value_dbl);
108
}
109
110
111
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
112
    Generate binary hash from raw text string
1 by brian
clean slate
113
    Used for Pre-4.1 password handling
114
  SYNOPSIS
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
115
    drizzleclient_hash_password()
1 by brian
clean slate
116
    result       OUT store hash in this location
117
    password     IN  plain text password to build hash
118
    password_len IN  password length (password may be not null-terminated)
119
*/
120
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
121
void drizzleclient_hash_password(uint32_t *result, const char *password, uint32_t password_len)
1 by brian
clean slate
122
{
294 by Brian Aker
libdrizzle has ulong removed.
123
  register uint32_t nr=1345345333L, add=7, nr2=0x12345671L;
164 by Brian Aker
Commit cleanup of export types.
124
  uint32_t tmp;
1 by brian
clean slate
125
  const char *password_end= password + password_len;
126
  for (; password < password_end; password++)
127
  {
128
    if (*password == ' ' || *password == '\t')
129
      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...
130
    tmp= (uint32_t) (unsigned char) *password;
1 by brian
clean slate
131
    nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
132
    nr2+=(nr2 << 8) ^ nr;
133
    add+=tmp;
134
  }
164 by Brian Aker
Commit cleanup of export types.
135
  result[0]=nr & (((uint32_t) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
136
  result[1]=nr2 & (((uint32_t) 1L << 31) -1L);
1 by brian
clean slate
137
}
138
206 by Brian Aker
Removed final uint dead types.
139
static inline uint8_t char_val(uint8_t X)
1 by brian
clean slate
140
{
395 by Brian Aker
Fixed uint/ushort issue in libdrizzle
141
  return (uint32_t) (X >= '0' && X <= '9' ? X-'0' :
1 by brian
clean slate
142
      X >= 'A' && X <= 'Z' ? X-'A'+10 : X-'a'+10);
143
}
144
145
146
/*
147
     **************** MySQL 4.1.1 authentication routines *************
148
*/
149
150
/*
151
    Generate string of printable random characters of requested length
152
  SYNOPSIS
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
153
    drizzleclient_create_random_string()
1 by brian
clean slate
154
    to       OUT   buffer for generation; must be at least length+1 bytes
155
                   long; result string is always null-terminated
156
    length   IN    how many random characters to put in buffer
157
    rand_st  INOUT structure used for number generation
158
*/
159
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
160
void drizzleclient_create_random_string(char *to, uint32_t length, struct rand_struct *rand_st)
1 by brian
clean slate
161
{
162
  char *end= to + length;
163
  /* Use pointer arithmetics as it is faster way to do so. */
164
  for (; to < end; to++)
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
165
    *to= (char) (drizzleclient_my_rnd(rand_st)*94+33);
1 by brian
clean slate
166
  *to= '\0';
167
}
168
169
170
171
/*
172
    Convert given octet sequence to asciiz string of hex characters;
173
    str..str+len and 'to' may not overlap.
174
  SYNOPSIS
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
175
    drizzleclient_drizzleclient_octet2hex()
1 by brian
clean slate
176
    buf       OUT output buffer. Must be at least 2*len+1 bytes
177
    str, len  IN  the beginning and the length of the input string
178
179
  RETURN
180
    buf+len*2
181
*/
182
840.1.20 by Monty Taylor
Renamed non-prefixed things from libdrizzleclient to drizzleclient.
183
char *drizzleclient_drizzleclient_octet2hex(char *to, const char *str, uint32_t len)
1 by brian
clean slate
184
{
584.3.3 by Moriyoshi Koizumi
Incorporating changes proposed by mtaylor.
185
  static const char _dig_vec_upper[]= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
186
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
187
  const char *str_end= str + len;
1 by brian
clean slate
188
  for (; str != str_end; ++str)
189
  {
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...
190
    *to++= _dig_vec_upper[((unsigned char) *str) >> 4];
191
    *to++= _dig_vec_upper[((unsigned char) *str) & 0x0F];
1 by brian
clean slate
192
  }
193
  *to= '\0';
194
  return to;
195
}