Fix parsing of rusage in stats data.
[apr-util.git] / crypto / apr_md5.c
blob691cc8787c624db6103b3f7d4941f1bd072c5520
1 /*
2 * This is work is derived from material Copyright RSA Data Security, Inc.
4 * The RSA copyright statement and Licence for that original material is
5 * included below. This is followed by the Apache copyright statement and
6 * licence for the modifications made to that material.
7 */
9 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
12 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
13 rights reserved.
15 License to copy and use this software is granted provided that it
16 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
17 Algorithm" in all material mentioning or referencing this software
18 or this function.
20 License is also granted to make and use derivative works provided
21 that such works are identified as "derived from the RSA Data
22 Security, Inc. MD5 Message-Digest Algorithm" in all material
23 mentioning or referencing the derived work.
25 RSA Data Security, Inc. makes no representations concerning either
26 the merchantability of this software or the suitability of this
27 software for any particular purpose. It is provided "as is"
28 without express or implied warranty of any kind.
30 These notices must be retained in any copies of any part of this
31 documentation and/or software.
34 /* Licensed to the Apache Software Foundation (ASF) under one or more
35 * contributor license agreements. See the NOTICE file distributed with
36 * this work for additional information regarding copyright ownership.
37 * The ASF licenses this file to You under the Apache License, Version 2.0
38 * (the "License"); you may not use this file except in compliance with
39 * the License. You may obtain a copy of the License at
41 * http://www.apache.org/licenses/LICENSE-2.0
43 * Unless required by applicable law or agreed to in writing, software
44 * distributed under the License is distributed on an "AS IS" BASIS,
45 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46 * See the License for the specific language governing permissions and
47 * limitations under the License.
51 * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
52 * MD5 crypt() function, which is licenced as follows:
53 * ----------------------------------------------------------------------------
54 * "THE BEER-WARE LICENSE" (Revision 42):
55 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
56 * can do whatever you want with this stuff. If we meet some day, and you think
57 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
58 * ----------------------------------------------------------------------------
60 #include "apr_strings.h"
61 #include "apr_md5.h"
62 #include "apr_lib.h"
63 #include "apu_config.h"
64 #include "apr_sha1.h"
66 #if APR_HAVE_STRING_H
67 #include <string.h>
68 #endif
69 #if APR_HAVE_CRYPT_H
70 #include <crypt.h>
71 #endif
72 #if APR_HAVE_UNISTD_H
73 #include <unistd.h>
74 #endif
75 #if APR_HAVE_PTHREAD_H
76 #include <pthread.h>
77 #endif
79 /* Constants for MD5Transform routine.
82 #define S11 7
83 #define S12 12
84 #define S13 17
85 #define S14 22
86 #define S21 5
87 #define S22 9
88 #define S23 14
89 #define S24 20
90 #define S31 4
91 #define S32 11
92 #define S33 16
93 #define S34 23
94 #define S41 6
95 #define S42 10
96 #define S43 15
97 #define S44 21
99 static void MD5Transform(apr_uint32_t state[4], const unsigned char block[64]);
100 static void Encode(unsigned char *output, const apr_uint32_t *input,
101 unsigned int len);
102 static void Decode(apr_uint32_t *output, const unsigned char *input,
103 unsigned int len);
105 static const unsigned char PADDING[64] =
107 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
112 #if APR_CHARSET_EBCDIC
113 static apr_xlate_t *xlate_ebcdic_to_ascii; /* used in apr_md5_encode() */
114 #endif
115 #define DO_XLATE 0
116 #define SKIP_XLATE 1
118 /* F, G, H and I are basic MD5 functions.
120 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
121 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
122 #define H(x, y, z) ((x) ^ (y) ^ (z))
123 #define I(x, y, z) ((y) ^ ((x) | (~z)))
125 /* ROTATE_LEFT rotates x left n bits.
127 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
129 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
130 * Rotation is separate from addition to prevent recomputation.
132 #define FF(a, b, c, d, x, s, ac) { \
133 (a) += F ((b), (c), (d)) + (x) + (apr_uint32_t)(ac); \
134 (a) = ROTATE_LEFT ((a), (s)); \
135 (a) += (b); \
137 #define GG(a, b, c, d, x, s, ac) { \
138 (a) += G ((b), (c), (d)) + (x) + (apr_uint32_t)(ac); \
139 (a) = ROTATE_LEFT ((a), (s)); \
140 (a) += (b); \
142 #define HH(a, b, c, d, x, s, ac) { \
143 (a) += H ((b), (c), (d)) + (x) + (apr_uint32_t)(ac); \
144 (a) = ROTATE_LEFT ((a), (s)); \
145 (a) += (b); \
147 #define II(a, b, c, d, x, s, ac) { \
148 (a) += I ((b), (c), (d)) + (x) + (apr_uint32_t)(ac); \
149 (a) = ROTATE_LEFT ((a), (s)); \
150 (a) += (b); \
153 /* MD5 initialization. Begins an MD5 operation, writing a new context.
155 APU_DECLARE(apr_status_t) apr_md5_init(apr_md5_ctx_t *context)
157 context->count[0] = context->count[1] = 0;
159 /* Load magic initialization constants. */
160 context->state[0] = 0x67452301;
161 context->state[1] = 0xefcdab89;
162 context->state[2] = 0x98badcfe;
163 context->state[3] = 0x10325476;
164 context->xlate = NULL;
166 return APR_SUCCESS;
169 /* MD5 translation setup. Provides the APR translation handle
170 * to be used for translating the content before calculating the
171 * digest.
173 APU_DECLARE(apr_status_t) apr_md5_set_xlate(apr_md5_ctx_t *context,
174 apr_xlate_t *xlate)
176 #if APR_HAS_XLATE
177 apr_status_t rv;
178 int is_sb;
180 /* TODO: remove the single-byte-only restriction from this code
182 rv = apr_xlate_sb_get(xlate, &is_sb);
183 if (rv != APR_SUCCESS) {
184 return rv;
186 if (!is_sb) {
187 return APR_EINVAL;
189 context->xlate = xlate;
190 return APR_SUCCESS;
191 #else
192 return APR_ENOTIMPL;
193 #endif /* APR_HAS_XLATE */
196 /* MD5 block update operation. Continues an MD5 message-digest
197 * operation, processing another message block, and updating the
198 * context.
200 static apr_status_t md5_update_buffer(apr_md5_ctx_t *context,
201 const void *vinput,
202 apr_size_t inputLen,
203 int xlate_buffer)
205 const unsigned char *input = vinput;
206 unsigned int i, idx, partLen;
207 #if APR_HAS_XLATE
208 apr_size_t inbytes_left, outbytes_left;
209 #endif
211 /* Compute number of bytes mod 64 */
212 idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
214 /* Update number of bits */
215 if ((context->count[0] += ((apr_uint32_t)inputLen << 3))
216 < ((apr_uint32_t)inputLen << 3))
217 context->count[1]++;
218 context->count[1] += (apr_uint32_t)inputLen >> 29;
220 partLen = 64 - idx;
222 /* Transform as many times as possible. */
223 #if !APR_HAS_XLATE
224 if (inputLen >= partLen) {
225 memcpy(&context->buffer[idx], input, partLen);
226 MD5Transform(context->state, context->buffer);
228 for (i = partLen; i + 63 < inputLen; i += 64)
229 MD5Transform(context->state, &input[i]);
231 idx = 0;
233 else
234 i = 0;
236 /* Buffer remaining input */
237 memcpy(&context->buffer[idx], &input[i], inputLen - i);
238 #else /*APR_HAS_XLATE*/
239 if (inputLen >= partLen) {
240 if (context->xlate && (xlate_buffer == DO_XLATE)) {
241 inbytes_left = outbytes_left = partLen;
242 apr_xlate_conv_buffer(context->xlate, (const char *)input,
243 &inbytes_left,
244 (char *)&context->buffer[idx],
245 &outbytes_left);
247 else {
248 memcpy(&context->buffer[idx], input, partLen);
250 MD5Transform(context->state, context->buffer);
252 for (i = partLen; i + 63 < inputLen; i += 64) {
253 if (context->xlate && (xlate_buffer == DO_XLATE)) {
254 unsigned char inp_tmp[64];
255 inbytes_left = outbytes_left = 64;
256 apr_xlate_conv_buffer(context->xlate, (const char *)&input[i],
257 &inbytes_left, (char *)inp_tmp,
258 &outbytes_left);
259 MD5Transform(context->state, inp_tmp);
261 else {
262 MD5Transform(context->state, &input[i]);
266 idx = 0;
268 else
269 i = 0;
271 /* Buffer remaining input */
272 if (context->xlate && (xlate_buffer == DO_XLATE)) {
273 inbytes_left = outbytes_left = inputLen - i;
274 apr_xlate_conv_buffer(context->xlate, (const char *)&input[i],
275 &inbytes_left, (char *)&context->buffer[idx],
276 &outbytes_left);
278 else {
279 memcpy(&context->buffer[idx], &input[i], inputLen - i);
281 #endif /*APR_HAS_XLATE*/
282 return APR_SUCCESS;
285 /* MD5 block update operation. API with the default setting
286 * for EBCDIC translations
288 APU_DECLARE(apr_status_t) apr_md5_update(apr_md5_ctx_t *context,
289 const void *input,
290 apr_size_t inputLen)
292 return md5_update_buffer(context, input, inputLen, DO_XLATE);
295 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
296 * the message digest and zeroizing the context.
298 APU_DECLARE(apr_status_t) apr_md5_final(unsigned char digest[APR_MD5_DIGESTSIZE],
299 apr_md5_ctx_t *context)
301 unsigned char bits[8];
302 unsigned int idx, padLen;
304 /* Save number of bits */
305 Encode(bits, context->count, 8);
307 #if APR_HAS_XLATE
308 /* apr_md5_update() should not translate for this final round. */
309 context->xlate = NULL;
310 #endif /*APR_HAS_XLATE*/
312 /* Pad out to 56 mod 64. */
313 idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
314 padLen = (idx < 56) ? (56 - idx) : (120 - idx);
315 apr_md5_update(context, PADDING, padLen);
317 /* Append length (before padding) */
318 apr_md5_update(context, bits, 8);
320 /* Store state in digest */
321 Encode(digest, context->state, APR_MD5_DIGESTSIZE);
323 /* Zeroize sensitive information. */
324 memset(context, 0, sizeof(*context));
326 return APR_SUCCESS;
329 /* MD5 in one step (init, update, final)
331 APU_DECLARE(apr_status_t) apr_md5(unsigned char digest[APR_MD5_DIGESTSIZE],
332 const void *_input,
333 apr_size_t inputLen)
335 const unsigned char *input = _input;
336 apr_md5_ctx_t ctx;
337 apr_status_t rv;
339 apr_md5_init(&ctx);
341 if ((rv = apr_md5_update(&ctx, input, inputLen)) != APR_SUCCESS)
342 return rv;
344 return apr_md5_final(digest, &ctx);
347 /* MD5 basic transformation. Transforms state based on block. */
348 static void MD5Transform(apr_uint32_t state[4], const unsigned char block[64])
350 apr_uint32_t a = state[0], b = state[1], c = state[2], d = state[3],
351 x[APR_MD5_DIGESTSIZE];
353 Decode(x, block, 64);
355 /* Round 1 */
356 FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
357 FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
358 FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
359 FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
360 FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
361 FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
362 FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
363 FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
364 FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
365 FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
366 FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
367 FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
368 FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
369 FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
370 FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
371 FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
373 /* Round 2 */
374 GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
375 GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
376 GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
377 GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
378 GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
379 GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
380 GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
381 GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
382 GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
383 GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
384 GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
385 GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
386 GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
387 GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
388 GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
389 GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
391 /* Round 3 */
392 HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
393 HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
394 HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
395 HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
396 HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
397 HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
398 HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
399 HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
400 HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
401 HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
402 HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
403 HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
404 HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
405 HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
406 HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
407 HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
409 /* Round 4 */
410 II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
411 II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
412 II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
413 II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
414 II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
415 II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
416 II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
417 II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
418 II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
419 II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
420 II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
421 II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
422 II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
423 II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
424 II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
425 II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
427 state[0] += a;
428 state[1] += b;
429 state[2] += c;
430 state[3] += d;
432 /* Zeroize sensitive information. */
433 memset(x, 0, sizeof(x));
436 /* Encodes input (apr_uint32_t) into output (unsigned char). Assumes len is
437 * a multiple of 4.
439 static void Encode(unsigned char *output, const apr_uint32_t *input,
440 unsigned int len)
442 unsigned int i, j;
443 apr_uint32_t k;
445 for (i = 0, j = 0; j < len; i++, j += 4) {
446 k = input[i];
447 output[j] = (unsigned char)(k & 0xff);
448 output[j + 1] = (unsigned char)((k >> 8) & 0xff);
449 output[j + 2] = (unsigned char)((k >> 16) & 0xff);
450 output[j + 3] = (unsigned char)((k >> 24) & 0xff);
454 /* Decodes input (unsigned char) into output (apr_uint32_t). Assumes len is
455 * a multiple of 4.
457 static void Decode(apr_uint32_t *output, const unsigned char *input,
458 unsigned int len)
460 unsigned int i, j;
462 for (i = 0, j = 0; j < len; i++, j += 4)
463 output[i] = ((apr_uint32_t)input[j]) |
464 (((apr_uint32_t)input[j + 1]) << 8) |
465 (((apr_uint32_t)input[j + 2]) << 16) |
466 (((apr_uint32_t)input[j + 3]) << 24);
469 #if APR_CHARSET_EBCDIC
470 APU_DECLARE(apr_status_t) apr_MD5InitEBCDIC(apr_xlate_t *xlate)
472 xlate_ebcdic_to_ascii = xlate;
473 return APR_SUCCESS;
475 #endif
478 * Define the Magic String prefix that identifies a password as being
479 * hashed using our algorithm.
481 static const char *apr1_id = "$apr1$";
484 * The following MD5 password encryption code was largely borrowed from
485 * the FreeBSD 3.0 /usr/src/lib/libcrypt/crypt.c file, which is
486 * licenced as stated at the top of this file.
489 static void to64(char *s, unsigned long v, int n)
491 static unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */
492 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
494 while (--n >= 0) {
495 *s++ = itoa64[v&0x3f];
496 v >>= 6;
500 APU_DECLARE(apr_status_t) apr_md5_encode(const char *pw, const char *salt,
501 char *result, apr_size_t nbytes)
504 * Minimum size is 8 bytes for salt, plus 1 for the trailing NUL,
505 * plus 4 for the '$' separators, plus the password hash itself.
506 * Let's leave a goodly amount of leeway.
509 char passwd[120], *p;
510 const char *sp, *ep;
511 unsigned char final[APR_MD5_DIGESTSIZE];
512 apr_ssize_t sl, pl, i;
513 apr_md5_ctx_t ctx, ctx1;
514 unsigned long l;
517 * Refine the salt first. It's possible we were given an already-hashed
518 * string as the salt argument, so extract the actual salt value from it
519 * if so. Otherwise just use the string up to the first '$' as the salt.
521 sp = salt;
524 * If it starts with the magic string, then skip that.
526 if (!strncmp(sp, apr1_id, strlen(apr1_id))) {
527 sp += strlen(apr1_id);
531 * It stops at the first '$' or 8 chars, whichever comes first
533 for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++) {
534 continue;
538 * Get the length of the true salt
540 sl = ep - sp;
543 * 'Time to make the doughnuts..'
545 apr_md5_init(&ctx);
546 #if APR_CHARSET_EBCDIC
547 apr_md5_set_xlate(&ctx, xlate_ebcdic_to_ascii);
548 #endif
551 * The password first, since that is what is most unknown
553 apr_md5_update(&ctx, pw, strlen(pw));
556 * Then our magic string
558 apr_md5_update(&ctx, apr1_id, strlen(apr1_id));
561 * Then the raw salt
563 apr_md5_update(&ctx, sp, sl);
566 * Then just as many characters of the MD5(pw, salt, pw)
568 apr_md5_init(&ctx1);
569 #if APR_CHARSET_EBCDIC
570 apr_md5_set_xlate(&ctx1, xlate_ebcdic_to_ascii);
571 #endif
572 apr_md5_update(&ctx1, pw, strlen(pw));
573 apr_md5_update(&ctx1, sp, sl);
574 apr_md5_update(&ctx1, pw, strlen(pw));
575 apr_md5_final(final, &ctx1);
576 for (pl = strlen(pw); pl > 0; pl -= APR_MD5_DIGESTSIZE) {
577 md5_update_buffer(&ctx, final,
578 (pl > APR_MD5_DIGESTSIZE) ? APR_MD5_DIGESTSIZE : pl, SKIP_XLATE);
582 * Don't leave anything around in vm they could use.
584 memset(final, 0, sizeof(final));
587 * Then something really weird...
589 for (i = strlen(pw); i != 0; i >>= 1) {
590 if (i & 1) {
591 md5_update_buffer(&ctx, final, 1, SKIP_XLATE);
593 else {
594 apr_md5_update(&ctx, pw, 1);
599 * Now make the output string. We know our limitations, so we
600 * can use the string routines without bounds checking.
602 strcpy(passwd, apr1_id);
603 strncat(passwd, sp, sl);
604 strcat(passwd, "$");
606 apr_md5_final(final, &ctx);
609 * And now, just to make sure things don't run too fast..
610 * On a 60 Mhz Pentium this takes 34 msec, so you would
611 * need 30 seconds to build a 1000 entry dictionary...
613 for (i = 0; i < 1000; i++) {
614 apr_md5_init(&ctx1);
616 * apr_md5_final clears out ctx1.xlate at the end of each loop,
617 * so need to to set it each time through
619 #if APR_CHARSET_EBCDIC
620 apr_md5_set_xlate(&ctx1, xlate_ebcdic_to_ascii);
621 #endif
622 if (i & 1) {
623 apr_md5_update(&ctx1, pw, strlen(pw));
625 else {
626 md5_update_buffer(&ctx1, final, APR_MD5_DIGESTSIZE, SKIP_XLATE);
628 if (i % 3) {
629 apr_md5_update(&ctx1, sp, sl);
632 if (i % 7) {
633 apr_md5_update(&ctx1, pw, strlen(pw));
636 if (i & 1) {
637 md5_update_buffer(&ctx1, final, APR_MD5_DIGESTSIZE, SKIP_XLATE);
639 else {
640 apr_md5_update(&ctx1, pw, strlen(pw));
642 apr_md5_final(final,&ctx1);
645 p = passwd + strlen(passwd);
647 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p, l, 4); p += 4;
648 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p, l, 4); p += 4;
649 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p, l, 4); p += 4;
650 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p, l, 4); p += 4;
651 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p, l, 4); p += 4;
652 l = final[11] ; to64(p, l, 2); p += 2;
653 *p = '\0';
656 * Don't leave anything around in vm they could use.
658 memset(final, 0, sizeof(final));
660 apr_cpystrn(result, passwd, nbytes - 1);
661 return APR_SUCCESS;
664 #if !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
665 #if defined(APU_CRYPT_THREADSAFE) || !APR_HAS_THREADS || \
666 defined(CRYPT_R_CRYPTD) || defined(CRYPT_R_STRUCT_CRYPT_DATA)
668 #define crypt_mutex_lock()
669 #define crypt_mutex_unlock()
671 #elif APR_HAVE_PTHREAD_H && defined(PTHREAD_MUTEX_INITIALIZER)
673 static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER;
674 static void crypt_mutex_lock(void)
676 pthread_mutex_lock(&crypt_mutex);
679 static void crypt_mutex_unlock(void)
681 pthread_mutex_unlock(&crypt_mutex);
684 #else
686 #error apr_password_validate() is not threadsafe. rebuild APR without thread support.
688 #endif
689 #endif
692 * Validate a plaintext password against a smashed one. Uses either
693 * crypt() (if available) or apr_md5_encode() or apr_sha1_base64(), depending
694 * upon the format of the smashed input password. Returns APR_SUCCESS if
695 * they match, or APR_EMISMATCH if they don't. If the platform doesn't
696 * support crypt, then the default check is against a clear text string.
698 APU_DECLARE(apr_status_t) apr_password_validate(const char *passwd,
699 const char *hash)
701 char sample[120];
702 #if !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
703 char *crypt_pw;
704 #endif
705 if (!strncmp(hash, apr1_id, strlen(apr1_id))) {
707 * The hash was created using our custom algorithm.
709 apr_md5_encode(passwd, hash, sample, sizeof(sample));
711 else if (!strncmp(hash, APR_SHA1PW_ID, APR_SHA1PW_IDLEN)) {
712 apr_sha1_base64(passwd, (int)strlen(passwd), sample);
714 else {
716 * It's not our algorithm, so feed it to crypt() if possible.
718 #if defined(WIN32) || defined(BEOS) || defined(NETWARE)
719 apr_cpystrn(sample, passwd, sizeof(sample) - 1);
720 #elif defined(CRYPT_R_CRYPTD)
721 CRYPTD buffer;
723 crypt_pw = crypt_r(passwd, hash, &buffer);
724 apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1);
725 #elif defined(CRYPT_R_STRUCT_CRYPT_DATA)
726 struct crypt_data buffer;
728 /* having to clear this seems bogus... GNU doc is
729 * confusing... user report found from google says
730 * the crypt_data struct had to be cleared to get
731 * the same result as plain crypt()
733 memset(&buffer, 0, sizeof(buffer));
734 crypt_pw = crypt_r(passwd, hash, &buffer);
735 apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1);
736 #else
737 /* Do a bit of sanity checking since we know that crypt_r()
738 * should always be used for threaded builds on AIX, and
739 * problems in configure logic can result in the wrong
740 * choice being made.
742 #if defined(_AIX) && APR_HAS_THREADS
743 #error Configuration error! crypt_r() should have been selected!
744 #endif
746 /* Handle thread safety issues by holding a mutex around the
747 * call to crypt().
749 crypt_mutex_lock();
750 crypt_pw = crypt(passwd, hash);
751 apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1);
752 crypt_mutex_unlock();
753 #endif
755 return (strcmp(sample, hash) == 0) ? APR_SUCCESS : APR_EMISMATCH;