Commit 121217e1 121217e112fb11e03575b772cd7368256c119777 by Sergey Poznyakoff

Do not use any libmysql functions to

scramble passwords: mysql people are evidently
unable to keep this API stable.
1 parent 1e70da46
...@@ -194,6 +194,61 @@ errstr (mu_sql_connection_t conn) ...@@ -194,6 +194,61 @@ errstr (mu_sql_connection_t conn)
194 return mysql_error (mp->mysql); 194 return mysql_error (mp->mysql);
195 } 195 }
196 196
197
198 /* MySQL scrambled password support */
199
200 /* Convert a single hex digit to corresponding number */
201 static unsigned
202 digit_to_number (char c)
203 {
204 return (unsigned) (c >= '0' && c <= '9' ? c-'0' :
205 c >= 'A' && c <= 'Z' ? c-'A'+10 :
206 c-'a'+10);
207 }
208
209 /* Extract salt value from MySQL scrambled password.
210
211 WARNING: The code assumes that
212 1. strlen (password) % 8 == 0
213 2. number_of_entries (RES) = strlen (password) / 8
214
215 For MySQL >= 3.21, strlen(password) == 16 */
216 static void
217 get_salt_from_scrambled (unsigned long *res, const char *password)
218 {
219 res[0] = res[1] = 0;
220 while (*password)
221 {
222 unsigned long val = 0;
223 unsigned i;
224
225 for (i = 0; i < 8 ; i++)
226 val = (val << 4) + digit_to_number (*password++);
227 *res++ = val;
228 }
229 }
230
231 /* Scramble a plaintext password */
232 static void
233 scramble_password (unsigned long *result, const char *password)
234 {
235 unsigned long nr = 1345345333L, add = 7, nr2 = 0x12345671L;
236 unsigned long tmp;
237
238 for (; *password ; password++)
239 {
240 if (*password == ' ' || *password == '\t')
241 continue;
242 tmp = (unsigned long) (unsigned char) *password;
243 nr ^= (((nr & 63) + add) * tmp)+ (nr << 8);
244 nr2 += (nr2 << 8) ^ nr;
245 add += tmp;
246 }
247
248 result[0] = nr & (((unsigned long) 1L << 31) -1L);
249 result[1] = nr2 & (((unsigned long) 1L << 31) -1L);
250 }
251
197 /* Check whether a plaintext password MESSAGE matches MySQL scrambled password 252 /* Check whether a plaintext password MESSAGE matches MySQL scrambled password
198 PASSWORD */ 253 PASSWORD */
199 int 254 int
...@@ -219,11 +274,13 @@ mu_check_mysql_scrambled_password (const char *scrambled, const char *message) ...@@ -219,11 +274,13 @@ mu_check_mysql_scrambled_password (const char *scrambled, const char *message)
219 } 274 }
220 275
221 get_salt_from_password (hash_pass, scrambled); 276 get_salt_from_password (hash_pass, scrambled);
222 hash_password (hash_message, message); 277 scramble_password (hash_message, message);
223 return !(hash_message[0] == hash_pass[0] 278 return !(hash_message[0] == hash_pass[0]
224 && hash_message[1] == hash_pass[1]); 279 && hash_message[1] == hash_pass[1]);
225 } 280 }
226 281
282
283 /* Register module */
227 MU_DECL_SQL_DISPATCH_T(mysql) = { 284 MU_DECL_SQL_DISPATCH_T(mysql) = {
228 "mysql", 285 "mysql",
229 3306, 286 3306,
......