~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/password.c

pandora-build v0.71. Added check for avahi.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
61
 
#include <drizzled/global.h>
62
 
#include "drizzle.h"
63
 
 
64
 
/************ MySQL 3.23-4.0 authentication routines: untouched ***********/
65
 
 
66
 
/*
67
 
  New (MySQL 3.21+) random generation structure initialization
68
 
  SYNOPSIS
69
 
    randominit()
70
 
    rand_st    OUT  Structure to initialize
71
 
    seed1      IN   First initialization parameter
72
 
    seed2      IN   Second initialization parameter
73
 
*/
74
 
 
75
 
void randominit(struct rand_struct *rand_st, uint32_t seed1, uint32_t seed2)
76
 
{                                               /* For mysql 3.21.# */
77
 
  memset(rand_st, 0, sizeof(*rand_st));      /* Avoid UMC varnings */
78
 
  rand_st->max_value= 0x3FFFFFFFL;
79
 
  rand_st->max_value_dbl=(double) rand_st->max_value;
80
 
  rand_st->seed1=seed1%rand_st->max_value ;
81
 
  rand_st->seed2=seed2%rand_st->max_value;
82
 
}
83
 
 
84
 
 
85
 
/*
86
 
    Generate random number.
87
 
  SYNOPSIS
88
 
    my_rnd()
89
 
    rand_st    INOUT  Structure used for number generation
90
 
  RETURN VALUE
91
 
    generated pseudo random number
92
 
*/
93
 
 
94
 
double my_rnd(struct rand_struct *rand_st)
95
 
{
96
 
  rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
97
 
  rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
98
 
  return (((double) rand_st->seed1)/rand_st->max_value_dbl);
99
 
}
100
 
 
101
 
 
102
 
/*
103
 
    Generate binary hash from raw text string 
104
 
    Used for Pre-4.1 password handling
105
 
  SYNOPSIS
106
 
    hash_password()
107
 
    result       OUT store hash in this location
108
 
    password     IN  plain text password to build hash
109
 
    password_len IN  password length (password may be not null-terminated)
110
 
*/
111
 
 
112
 
void hash_password(uint32_t *result, const char *password, uint32_t password_len)
113
 
{
114
 
  register uint32_t nr=1345345333L, add=7, nr2=0x12345671L;
115
 
  uint32_t tmp;
116
 
  const char *password_end= password + password_len;
117
 
  for (; password < password_end; password++)
118
 
  {
119
 
    if (*password == ' ' || *password == '\t')
120
 
      continue;                                 /* skip space in password */
121
 
    tmp= (uint32_t) (uchar) *password;
122
 
    nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
123
 
    nr2+=(nr2 << 8) ^ nr;
124
 
    add+=tmp;
125
 
  }
126
 
  result[0]=nr & (((uint32_t) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
127
 
  result[1]=nr2 & (((uint32_t) 1L << 31) -1L);
128
 
}
129
 
 
130
 
static inline uint8_t char_val(uint8_t X)
131
 
{
132
 
  return (uint) (X >= '0' && X <= '9' ? X-'0' :
133
 
      X >= 'A' && X <= 'Z' ? X-'A'+10 : X-'a'+10);
134
 
}
135
 
 
136
 
 
137
 
/*
138
 
     **************** MySQL 4.1.1 authentication routines *************
139
 
*/
140
 
 
141
 
/*
142
 
    Generate string of printable random characters of requested length
143
 
  SYNOPSIS
144
 
    create_random_string()
145
 
    to       OUT   buffer for generation; must be at least length+1 bytes
146
 
                   long; result string is always null-terminated
147
 
    length   IN    how many random characters to put in buffer
148
 
    rand_st  INOUT structure used for number generation
149
 
*/
150
 
 
151
 
void create_random_string(char *to, uint length, struct rand_struct *rand_st)
152
 
{
153
 
  char *end= to + length;
154
 
  /* Use pointer arithmetics as it is faster way to do so. */
155
 
  for (; to < end; to++)
156
 
    *to= (char) (my_rnd(rand_st)*94+33);
157
 
  *to= '\0';
158
 
}
159
 
 
160
 
 
161
 
/* Character to use as version identifier for version 4.1 */
162
 
 
163
 
#define PVERSION41_CHAR '*'
164
 
 
165
 
 
166
 
/*
167
 
    Convert given octet sequence to asciiz string of hex characters;
168
 
    str..str+len and 'to' may not overlap.
169
 
  SYNOPSIS
170
 
    octet2hex()
171
 
    buf       OUT output buffer. Must be at least 2*len+1 bytes
172
 
    str, len  IN  the beginning and the length of the input string
173
 
 
174
 
  RETURN
175
 
    buf+len*2
176
 
*/
177
 
 
178
 
char *octet2hex(char *to, const char *str, uint len)
179
 
{
180
 
  const char *str_end= str + len; 
181
 
  for (; str != str_end; ++str)
182
 
  {
183
 
    *to++= _dig_vec_upper[((uchar) *str) >> 4];
184
 
    *to++= _dig_vec_upper[((uchar) *str) & 0x0F];
185
 
  }
186
 
  *to= '\0';
187
 
  return to;
188
 
}