~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/password.c

  • Committer: Mats Kindahl
  • Date: 2008-08-26 07:32:59 UTC
  • mto: (489.1.2 codestyle)
  • mto: This revision was merged to the branch mainline in revision 491.
  • Revision ID: mats@mysql.com-20080826073259-9k4evtajgldgolli
Replaced use of thd_proc_info() macro with calls to
set_proc_info() and get_proc_info() internally.  Introduced
functions set_thd_proc_info() and get_thd_proc_info() for
external users, i.e., plug-ins.

The set_thd_proc_info() accepted callers info that can be used to
print debug output, but the information was not used. The return
value was changed to void and the old value is not fetched any
more. To be able to get the value of proc_info for external
users, the function get_thd_proc_info() was introduced.

The thd_proc_info() macro called set_thd_proc_info() but almost
never used the return value of set_thd_proc_info() so the macro
was replaced with a call of THD::set_proc_info().

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
}