~ubuntu-branches/ubuntu/lucid/apr-util/lucid

« back to all changes in this revision

Viewing changes to debian/patches/099_alternate_md4_md5_impl.dpatch

  • Committer: Bazaar Package Importer
  • Author(s): Tollef Fog Heen
  • Date: 2006-08-18 19:50:31 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060818195031-vddj2q74qlfp4gtx
Tags: 1.2.7+dfsg-2
Fix stupid code duplication in apr_md[45].c resulting from C&P.
Thanks to Peter Samuelson for notifying me.  This makes md[45] work
correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /bin/sh /usr/share/dpatch/dpatch-run
 
2
## 099_alternate_md4_md5_impl.dpatch by  <tfheen@debian.org>
 
3
##
 
4
## All lines beginning with `## DP:' are a description of the patch.
 
5
## DP: No description.
 
6
 
 
7
@DPATCH@
 
8
diff -urNad apr-util-1.2.7~/crypto/apr_md4.c apr-util-1.2.7/crypto/apr_md4.c
 
9
--- apr-util-1.2.7~/crypto/apr_md4.c    1970-01-01 01:00:00.000000000 +0100
 
10
+++ apr-util-1.2.7/crypto/apr_md4.c     2006-08-18 14:21:41.000000000 +0200
 
11
@@ -0,0 +1,389 @@
 
12
+/* Adopted for apr-util by Tollef Fog Heen <tfheen@err.no> */
 
13
+
 
14
+/*
 
15
+ * MD4 (RFC-1320) message digest.
 
16
+ * Modified from MD5 code by Andrey Panin <pazke@donpac.ru>
 
17
+ *
 
18
+ * Written by Solar Designer <solar@openwall.com> in 2001, and placed in
 
19
+ * the public domain.  There's absolutely no warranty.
 
20
+ *
 
21
+ * This differs from Colin Plumb's older public domain implementation in
 
22
+ * that no 32-bit integer data type is required, there's no compile-time
 
23
+ * endianness configuration, and the function prototypes match OpenSSL's.
 
24
+ * The primary goals are portability and ease of use.
 
25
+ *
 
26
+ * This implementation is meant to be fast, but not as fast as possible.
 
27
+ * Some known optimizations are not included to reduce source code size
 
28
+ * and avoid compile-time configuration.
 
29
+ */
 
30
+
 
31
+/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
 
32
+ * applicable.
 
33
+ *
 
34
+ * Licensed under the Apache License, Version 2.0 (the "License");
 
35
+ * you may not use this file except in compliance with the License.
 
36
+ * You may obtain a copy of the License at
 
37
+ *
 
38
+ *     http://www.apache.org/licenses/LICENSE-2.0
 
39
+ *
 
40
+ * Unless required by applicable law or agreed to in writing, software
 
41
+ * distributed under the License is distributed on an "AS IS" BASIS,
 
42
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
43
+ * See the License for the specific language governing permissions and
 
44
+ * limitations under the License.
 
45
+ */
 
46
+
 
47
+#include "apr_strings.h"
 
48
+#include "apr_md4.h"
 
49
+#include "apr_lib.h"
 
50
+
 
51
+#if APR_HAVE_STRING_H
 
52
+#include <string.h>
 
53
+#endif
 
54
+#if APR_HAVE_UNISTD_H
 
55
+#include <unistd.h>
 
56
+#endif
 
57
+
 
58
+#if APR_CHARSET_EBCDIC
 
59
+static apr_xlate_t *xlate_ebcdic_to_ascii; /* used in apr_md4_encode() */
 
60
+#endif
 
61
+
 
62
+static const void *body(apr_md4_ctx_t *context, const void *data, size_t size);
 
63
+
 
64
+/*
 
65
+ * The basic MD4 functions.
 
66
+ */
 
67
+#define F(x, y, z)      ((z) ^ ((x) & ((y) ^ (z))))
 
68
+#define G(x, y, z)      (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
 
69
+#define H(x, y, z)      ((x) ^ (y) ^ (z))
 
70
+
 
71
+/*
 
72
+ * The MD4 transformation for all four rounds.
 
73
+ */
 
74
+#define STEP(f, a, b, c, d, x, s) \
 
75
+        (a) += f((b), (c), (d)) + (x);   \
 
76
+        (a) = ((a) << (s)) | ((a) >> (32 - (s)))
 
77
+
 
78
+
 
79
+/*
 
80
+ * SET reads 4 input bytes in little-endian byte order and stores them
 
81
+ * in a properly aligned word in host byte order.
 
82
+ *
 
83
+ * The check for little-endian architectures which tolerate unaligned
 
84
+ * memory accesses is just an optimization.  Nothing will break if it
 
85
+ * doesn't work.
 
86
+ */
 
87
+/*#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
 
88
+#define SET(n) \
 
89
+        (*(const apr_uint32_t *)&ptr[(n) * 4])
 
90
+#define GET(n) \
 
91
+        SET(n)
 
92
+        #else*/
 
93
+#define SET(n) \
 
94
+        (block[(n)] = \
 
95
+        (apr_uint32_t)ptr[(n) * 4] | \
 
96
+        ((apr_uint32_t)ptr[(n) * 4 + 1] << 8) | \
 
97
+        ((apr_uint32_t)ptr[(n) * 4 + 2] << 16) | \
 
98
+        ((apr_uint32_t)ptr[(n) * 4 + 3] << 24))
 
99
+#define GET(n) \
 
100
+        (block[(n)])
 
101
+/*#endif*/
 
102
+
 
103
+
 
104
+
 
105
+/* MD4 initialization. Begins an MD4 operation, writing a new context.
 
106
+ */
 
107
+APU_DECLARE(apr_status_t) apr_md4_init(apr_md4_ctx_t *context)
 
108
+{
 
109
+    context->count[0] = context->count[1] = 0;
 
110
+
 
111
+    /* Load magic initialization constants. */
 
112
+    context->state[0] = 0x67452301;
 
113
+    context->state[1] = 0xefcdab89;
 
114
+    context->state[2] = 0x98badcfe;
 
115
+    context->state[3] = 0x10325476;
 
116
+    
 
117
+#if APR_HAS_XLATE
 
118
+    context->xlate = NULL;
 
119
+#endif
 
120
+
 
121
+    return APR_SUCCESS;
 
122
+}
 
123
+
 
124
+#if APR_HAS_XLATE
 
125
+/* MD4 translation setup.  Provides the APR translation handle
 
126
+ * to be used for translating the content before calculating the
 
127
+ * digest.
 
128
+ */
 
129
+APU_DECLARE(apr_status_t) apr_md4_set_xlate(apr_md4_ctx_t *context, 
 
130
+                                            apr_xlate_t *xlate)
 
131
+{
 
132
+    apr_status_t rv;
 
133
+    int is_sb;
 
134
+
 
135
+    /* TODO: remove the single-byte-only restriction from this code
 
136
+     */
 
137
+    rv = apr_xlate_sb_get(xlate, &is_sb);
 
138
+    if (rv != APR_SUCCESS) {
 
139
+        return rv;
 
140
+    }
 
141
+    if (!is_sb) {
 
142
+        return APR_EINVAL;
 
143
+    }
 
144
+    context->xlate = xlate;
 
145
+    return APR_SUCCESS;
 
146
+}
 
147
+#endif /* APR_HAS_XLATE */
 
148
+
 
149
+/* MD4 block update operation. Continues an MD4 message-digest
 
150
+ * operation, processing another message block, and updating the
 
151
+ * context.
 
152
+ */
 
153
+APU_DECLARE(apr_status_t) apr_md4_update(apr_md4_ctx_t *context,
 
154
+                                         const unsigned char *input,
 
155
+                                         apr_size_t inputLen)
 
156
+{
 
157
+    apr_uint32_t saved_lo;
 
158
+    unsigned long used, free;
 
159
+#if APR_HAS_XLATE
 
160
+/*    apr_size_t inbytes_left, outbytes_left;*/
 
161
+#endif
 
162
+
 
163
+    /* Update number of bits */
 
164
+    saved_lo = context->count[0];
 
165
+    if ((context->count[0] = (saved_lo + inputLen) & 0x1fffffff) < saved_lo)
 
166
+        context->count[1]++;
 
167
+    context->count[1] += (apr_uint32_t)inputLen >> 29;
 
168
+
 
169
+    /* Compute number of bytes mod 64 */
 
170
+    used = saved_lo & 0x3f;
 
171
+
 
172
+    /* Transform as many times as possible. */
 
173
+    if (used) {
 
174
+        free = 64 - used;
 
175
+        
 
176
+        if (inputLen < free) {
 
177
+            memcpy(&context->buffer[used], input, inputLen);
 
178
+            return APR_SUCCESS;
 
179
+        }
 
180
+
 
181
+        memcpy(&context->buffer[used], input, free);
 
182
+        input = (const unsigned char *) input + free;
 
183
+        inputLen -= free;
 
184
+        body(context, context->buffer, 64);
 
185
+    }
 
186
+
 
187
+    if (inputLen >= 64) {
 
188
+        input = body(context, input, inputLen & ~(unsigned long)0x3f);
 
189
+        inputLen &= 0x3f;
 
190
+    }
 
191
+
 
192
+    /* Buffer remaining input */
 
193
+    memcpy(context->buffer, input, inputLen);
 
194
+    return APR_SUCCESS;
 
195
+}
 
196
+
 
197
+/* MD4 finalization. Ends an MD4 message-digest operation, writing the
 
198
+ * the message digest and zeroizing the context.
 
199
+ */
 
200
+APU_DECLARE(apr_status_t) apr_md4_final(
 
201
+                                    unsigned char digest[APR_MD4_DIGESTSIZE],
 
202
+                                    apr_md4_ctx_t *context)
 
203
+{
 
204
+    unsigned long used, free;
 
205
+
 
206
+    used = context->count[0] & 0x3f;
 
207
+
 
208
+    context->buffer[used++] = 0x80;
 
209
+
 
210
+    free = 64 - used;
 
211
+
 
212
+#if APR_HAS_XLATE
 
213
+    /* apr_md4_update() should not translate for this final round. */
 
214
+    context->xlate = NULL;
 
215
+#endif /*APR_HAS_XLATE*/
 
216
+
 
217
+    if (free < 8) {
 
218
+        memset(&context->buffer[used], 0, free);
 
219
+        body(context, context->buffer, 64);
 
220
+        used = 0;
 
221
+        free = 64;
 
222
+    }
 
223
+
 
224
+    memset(&context->buffer[used], 0, free - 8);
 
225
+
 
226
+    context->count[0] <<= 3;
 
227
+    context->buffer[56] = context->count[0];
 
228
+    context->buffer[57] = context->count[0] >> 8;
 
229
+    context->buffer[58] = context->count[0] >> 16;
 
230
+    context->buffer[59] = context->count[0] >> 24;
 
231
+    context->buffer[60] = context->count[1];
 
232
+    context->buffer[61] = context->count[1] >> 8;
 
233
+    context->buffer[62] = context->count[1] >> 16;
 
234
+    context->buffer[63] = context->count[1] >> 24;
 
235
+
 
236
+    body(context, context->buffer, 64);
 
237
+
 
238
+    digest[0] = context->state[0];
 
239
+    digest[1] = context->state[0] >> 8;
 
240
+    digest[2] = context->state[0] >> 16;
 
241
+    digest[3] = context->state[0] >> 24;
 
242
+    digest[4] = context->state[1];
 
243
+    digest[5] = context->state[1] >> 8;
 
244
+    digest[6] = context->state[1] >> 16;
 
245
+    digest[7] = context->state[1] >> 24;
 
246
+    digest[8] = context->state[2];
 
247
+    digest[9] = context->state[2] >> 8;
 
248
+    digest[10] = context->state[2] >> 16;
 
249
+    digest[11] = context->state[2] >> 24;
 
250
+    digest[12] = context->state[3];
 
251
+    digest[13] = context->state[3] >> 8;
 
252
+    digest[14] = context->state[3] >> 16;
 
253
+    digest[15] = context->state[3] >> 24;
 
254
+
 
255
+    /* Zeroize sensitive information. */
 
256
+    memset(context, 0, sizeof(*context));
 
257
+    
 
258
+    return APR_SUCCESS;
 
259
+}
 
260
+
 
261
+/* MD4 computation in one step (init, update, final)
 
262
+ */
 
263
+APU_DECLARE(apr_status_t) apr_md4(unsigned char digest[APR_MD4_DIGESTSIZE],
 
264
+                                  const unsigned char *input,
 
265
+                                  apr_size_t inputLen)
 
266
+{
 
267
+    apr_md4_ctx_t ctx;
 
268
+    apr_status_t rv;
 
269
+
 
270
+    apr_md4_init(&ctx);
 
271
+
 
272
+    if ((rv = apr_md4_update(&ctx, input, inputLen)) != APR_SUCCESS)
 
273
+        return rv;
 
274
+
 
275
+    return apr_md4_final(digest, &ctx);
 
276
+}
 
277
+
 
278
+/*
 
279
+ * This processes one or more 64-byte data blocks, but does NOT update
 
280
+ * the bit counters.  There're no alignment requirements.
 
281
+ */
 
282
+static const void *body(apr_md4_ctx_t *context, const void *data, size_t size)
 
283
+{
 
284
+    const unsigned char *ptr, *convptr;
 
285
+    uint32_t a, b, c, d;
 
286
+    uint32_t saved_a, saved_b, saved_c, saved_d;
 
287
+    apr_uint32_t block[16];
 
288
+    
 
289
+#ifdef APR_HAS_XLATE
 
290
+    apr_size_t inbytes_left, outbytes_left;
 
291
+#endif
 
292
+
 
293
+    ptr = data;
 
294
+    
 
295
+    a = context->state[0];
 
296
+    b = context->state[1];
 
297
+    c = context->state[2];
 
298
+    d = context->state[3];
 
299
+    
 
300
+    do {
 
301
+        saved_a = a;
 
302
+        saved_b = b;
 
303
+        saved_c = c;
 
304
+        saved_d = d;
 
305
+        
 
306
+        convptr = ptr;
 
307
+#ifdef APR_HAS_XLATE
 
308
+        if (context->xlate) {
 
309
+            inbytes_left = outbytes_left = 64;
 
310
+            unsigned char inp_tmp[64];
 
311
+            apr_xlate_conv_buffer(context->xlate, ptr, &inbytes_left,
 
312
+                                  inp_tmp, &outbytes_left);
 
313
+            convptr = inp_tmp;
 
314
+        }
 
315
+#endif
 
316
+        /* Round 1 */
 
317
+        STEP(F, a, b, c, d, SET( 0),  3);
 
318
+        STEP(F, d, a, b, c, SET( 1),  7);
 
319
+        STEP(F, c, d, a, b, SET( 2), 11);
 
320
+        STEP(F, b, c, d, a, SET( 3), 19);
 
321
+        
 
322
+        STEP(F, a, b, c, d, SET( 4),  3);
 
323
+        STEP(F, d, a, b, c, SET( 5),  7);
 
324
+        STEP(F, c, d, a, b, SET( 6), 11);
 
325
+        STEP(F, b, c, d, a, SET( 7), 19);
 
326
+        
 
327
+        STEP(F, a, b, c, d, SET( 8),  3);
 
328
+        STEP(F, d, a, b, c, SET( 9),  7);
 
329
+        STEP(F, c, d, a, b, SET(10), 11);
 
330
+        STEP(F, b, c, d, a, SET(11), 19);
 
331
+        
 
332
+        STEP(F, a, b, c, d, SET(12),  3);
 
333
+        STEP(F, d, a, b, c, SET(13),  7);
 
334
+        STEP(F, c, d, a, b, SET(14), 11);
 
335
+        STEP(F, b, c, d, a, SET(15), 19);
 
336
+        /* Round 2 */
 
337
+        STEP(G, a, b, c, d, GET( 0) + 0x5A827999,  3);
 
338
+        STEP(G, d, a, b, c, GET( 4) + 0x5A827999,  5);
 
339
+        STEP(G, c, d, a, b, GET( 8) + 0x5A827999,  9);
 
340
+        STEP(G, b, c, d, a, GET(12) + 0x5A827999, 13);
 
341
+        
 
342
+        STEP(G, a, b, c, d, GET( 1) + 0x5A827999,  3);
 
343
+        STEP(G, d, a, b, c, GET( 5) + 0x5A827999,  5);
 
344
+        STEP(G, c, d, a, b, GET( 9) + 0x5A827999,  9);
 
345
+        STEP(G, b, c, d, a, GET(13) + 0x5A827999, 13);
 
346
+        
 
347
+        STEP(G, a, b, c, d, GET( 2) + 0x5A827999,  3);
 
348
+        STEP(G, d, a, b, c, GET( 6) + 0x5A827999,  5);
 
349
+        STEP(G, c, d, a, b, GET(10) + 0x5A827999,  9);
 
350
+        STEP(G, b, c, d, a, GET(14) + 0x5A827999, 13);
 
351
+        
 
352
+        STEP(G, a, b, c, d, GET( 3) + 0x5A827999,  3);
 
353
+        STEP(G, d, a, b, c, GET( 7) + 0x5A827999,  5);
 
354
+        STEP(G, c, d, a, b, GET(11) + 0x5A827999,  9);
 
355
+        STEP(G, b, c, d, a, GET(15) + 0x5A827999, 13);
 
356
+        /* Round 3 */
 
357
+        STEP(H, a, b, c, d, GET( 0) + 0x6ED9EBA1,  3);
 
358
+        STEP(H, d, a, b, c, GET( 8) + 0x6ED9EBA1,  9);
 
359
+        STEP(H, c, d, a, b, GET( 4) + 0x6ED9EBA1, 11);
 
360
+        STEP(H, b, c, d, a, GET(12) + 0x6ED9EBA1, 15);
 
361
+        
 
362
+        STEP(H, a, b, c, d, GET( 2) + 0x6ED9EBA1,  3);
 
363
+        STEP(H, d, a, b, c, GET(10) + 0x6ED9EBA1,  9);
 
364
+        STEP(H, c, d, a, b, GET( 6) + 0x6ED9EBA1, 11);
 
365
+        STEP(H, b, c, d, a, GET(14) + 0x6ED9EBA1, 15);
 
366
+        
 
367
+        STEP(H, a, b, c, d, GET( 1) + 0x6ED9EBA1,  3);
 
368
+        STEP(H, d, a, b, c, GET( 9) + 0x6ED9EBA1,  9);
 
369
+        STEP(H, c, d, a, b, GET( 5) + 0x6ED9EBA1, 11);
 
370
+        STEP(H, b, c, d, a, GET(13) + 0x6ED9EBA1, 15);
 
371
+        
 
372
+        STEP(H, a, b, c, d, GET( 3) + 0x6ED9EBA1,  3);
 
373
+        STEP(H, d, a, b, c, GET(11) + 0x6ED9EBA1,  9);
 
374
+        STEP(H, c, d, a, b, GET( 7) + 0x6ED9EBA1, 11);
 
375
+        STEP(H, b, c, d, a, GET(15) + 0x6ED9EBA1, 15);
 
376
+        
 
377
+        a += saved_a;
 
378
+        b += saved_b;
 
379
+        c += saved_c;
 
380
+        d += saved_d;
 
381
+        
 
382
+        ptr += 64;
 
383
+    } while (size -= 64);
 
384
+    
 
385
+    context->state[0] = a;
 
386
+    context->state[1] = b;
 
387
+    context->state[2] = c;
 
388
+    context->state[3] = d;
 
389
+    
 
390
+    return ptr;
 
391
+}
 
392
+
 
393
+
 
394
+#if APR_CHARSET_EBCDIC
 
395
+APU_DECLARE(apr_status_t) apr_MD4InitEBCDIC(apr_xlate_t *xlate)
 
396
+{
 
397
+    xlate_ebcdic_to_ascii = xlate;
 
398
+    return APR_SUCCESS;
 
399
+}
 
400
+#endif
 
401
diff -urNad apr-util-1.2.7~/crypto/apr_md5.c apr-util-1.2.7/crypto/apr_md5.c
 
402
--- apr-util-1.2.7~/crypto/apr_md5.c    1970-01-01 01:00:00.000000000 +0100
 
403
+++ apr-util-1.2.7/crypto/apr_md5.c     2006-08-18 14:21:41.000000000 +0200
 
404
@@ -0,0 +1,686 @@
 
405
+/* FIXME: body must handle xlate */
 
406
+
 
407
+/*
 
408
+ * Adopted for apr-util by Tollef Fog Heen <tfheen@err.no>
 
409
+ */
 
410
+
 
411
+/*
 
412
+ * This is an OpenSSL-compatible implementation of the RSA Data Security,
 
413
+ * Inc. MD5 Message-Digest Algorithm.
 
414
+ *
 
415
+ * Written by Solar Designer <solar@openwall.com> in 2001, and placed in
 
416
+ * the public domain.  See md5.c for more information.
 
417
+ */
 
418
+
 
419
+/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
420
+ * applicable.
 
421
+ *
 
422
+ * Licensed under the Apache License, Version 2.0 (the "License");
 
423
+ * you may not use this file except in compliance with the License.
 
424
+ * You may obtain a copy of the License at
 
425
+ *
 
426
+ *     http://www.apache.org/licenses/LICENSE-2.0
 
427
+ *
 
428
+ * Unless required by applicable law or agreed to in writing, software
 
429
+ * distributed under the License is distributed on an "AS IS" BASIS,
 
430
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
431
+ * See the License for the specific language governing permissions and
 
432
+ * limitations under the License.
 
433
+ */
 
434
+
 
435
+/*
 
436
+ * The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
 
437
+ * MD5 crypt() function, which is licenced as follows:
 
438
+ * ----------------------------------------------------------------------------
 
439
+ * "THE BEER-WARE LICENSE" (Revision 42):
 
440
+ * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
 
441
+ * can do whatever you want with this stuff. If we meet some day, and you think
 
442
+ * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
 
443
+ * ----------------------------------------------------------------------------
 
444
+ */
 
445
+#include "apr_strings.h"
 
446
+#include "apr_md5.h"
 
447
+#include "apr_lib.h"
 
448
+#include "apu_config.h"
 
449
+#include "apr_sha1.h"
 
450
+
 
451
+#if APR_HAVE_STRING_H
 
452
+#include <string.h>
 
453
+#endif
 
454
+#if APR_HAVE_CRYPT_H
 
455
+#include <crypt.h>
 
456
+#endif
 
457
+#if APR_HAVE_UNISTD_H
 
458
+#include <unistd.h>
 
459
+#endif
 
460
+#if APR_HAVE_PTHREAD_H
 
461
+#include <pthread.h>
 
462
+#endif
 
463
+
 
464
+static const void *body(apr_md5_ctx_t *context, const void *data, apr_size_t size);
 
465
+
 
466
+#if APR_CHARSET_EBCDIC
 
467
+static apr_xlate_t *xlate_ebcdic_to_ascii; /* used in apr_md5_encode() */
 
468
+#endif
 
469
+
 
470
+/*
 
471
+ * The basic MD5 functions.
 
472
+ *
 
473
+ * F is optimized compared to its RFC 1321 definition just like in Colin
 
474
+ * Plumb's implementation.
 
475
+ */
 
476
+#define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
 
477
+#define G(x, y, z)                      ((y) ^ ((z) & ((x) ^ (y))))
 
478
+#define H(x, y, z)                      ((x) ^ (y) ^ (z))
 
479
+#define I(x, y, z)                      ((y) ^ ((x) | ~(z)))
 
480
+
 
481
+/*
 
482
+ * The MD5 transformation for all four rounds.
 
483
+ */
 
484
+#define STEP(f, a, b, c, d, x, t, s) \
 
485
+        (a) += f((b), (c), (d)) + (x) + (t); \
 
486
+        (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
 
487
+        (a) += (b);
 
488
+
 
489
+/*
 
490
+ * SET reads 4 input bytes in little-endian byte order and stores them
 
491
+ * in a properly aligned word in host byte order.
 
492
+ *
 
493
+ * The check for little-endian architectures which tolerate unaligned
 
494
+ * memory accesses is just an optimization.  Nothing will break if it
 
495
+ * doesn't work.
 
496
+ */
 
497
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
 
498
+#define SET(n) \
 
499
+        (*(const apr_uint32_t *)&convptr[(n) * 4])
 
500
+#define GET(n) \
 
501
+        SET(n)
 
502
+#else
 
503
+#define SET(n) \
 
504
+        (block[(n)] = \
 
505
+        (apr_uint32_t)convptr[(n) * 4] | \
 
506
+        ((apr_uint32_t)convptr[(n) * 4 + 1] << 8) | \
 
507
+        ((apr_uint32_t)convptr[(n) * 4 + 2] << 16) | \
 
508
+        ((apr_uint32_t)convptr[(n) * 4 + 3] << 24))
 
509
+#define GET(n) \
 
510
+        (block[(n)])
 
511
+#endif
 
512
+
 
513
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
 
514
+ */
 
515
+APU_DECLARE(apr_status_t) apr_md5_init(apr_md5_ctx_t *context)
 
516
+{
 
517
+    context->count[0] = context->count[1] = 0;
 
518
+    
 
519
+    /* Load magic initialization constants. */
 
520
+    context->state[0] = 0x67452301;
 
521
+    context->state[1] = 0xefcdab89;
 
522
+    context->state[2] = 0x98badcfe;
 
523
+    context->state[3] = 0x10325476;
 
524
+    context->xlate = NULL;
 
525
+    
 
526
+    return APR_SUCCESS;
 
527
+}
 
528
+
 
529
+/* MD5 translation setup.  Provides the APR translation handle
 
530
+ * to be used for translating the content before calculating the
 
531
+ * digest.
 
532
+ */
 
533
+APU_DECLARE(apr_status_t) apr_md5_set_xlate(apr_md5_ctx_t *context, 
 
534
+                                            apr_xlate_t *xlate)
 
535
+{
 
536
+#if APR_HAS_XLATE
 
537
+    apr_status_t rv;
 
538
+    int is_sb;
 
539
+
 
540
+    /* TODO: remove the single-byte-only restriction from this code
 
541
+     */
 
542
+    rv = apr_xlate_sb_get(xlate, &is_sb);
 
543
+    if (rv != APR_SUCCESS) {
 
544
+        return rv;
 
545
+    }
 
546
+    if (!is_sb) {
 
547
+        return APR_EINVAL;
 
548
+    }
 
549
+    context->xlate = xlate;
 
550
+    return APR_SUCCESS;
 
551
+#else
 
552
+    return APR_ENOTIMPL;
 
553
+#endif /* APR_HAS_XLATE */
 
554
+}
 
555
+
 
556
+/* MD5 block update operation. Continues an MD5 message-digest
 
557
+ * operation, processing another message block, and updating the
 
558
+ * context.
 
559
+ */
 
560
+APU_DECLARE(apr_status_t) apr_md5_update(apr_md5_ctx_t *context,
 
561
+                                         const void *_input,
 
562
+                                         apr_size_t inputLen)
 
563
+{
 
564
+    apr_uint32_t saved_lo;
 
565
+    unsigned long used, free;
 
566
+#if APR_HAS_XLATE
 
567
+/*    apr_size_t inbytes_left, outbytes_left;*/
 
568
+#endif
 
569
+
 
570
+    /* Update number of bits */
 
571
+    saved_lo = context->count[0];
 
572
+    if ((context->count[0] = (saved_lo + inputLen) & 0x1fffffff) < saved_lo)
 
573
+        context->count[1]++;
 
574
+    context->count[1] += (apr_uint32_t)inputLen >> 29;
 
575
+
 
576
+    /* Compute number of bytes mod 64 */
 
577
+    used = saved_lo & 0x3f;
 
578
+
 
579
+    /* Transform as many times as possible. */
 
580
+    if (used) {
 
581
+        free = 64 - used;
 
582
+        
 
583
+        if (inputLen < free) {
 
584
+            memcpy(&context->buffer[used], _input, inputLen);
 
585
+            return APR_SUCCESS;
 
586
+        }
 
587
+
 
588
+        memcpy(&context->buffer[used], _input, free);
 
589
+        _input = (const unsigned char *) _input + free;
 
590
+        inputLen -= free;
 
591
+        body(context, context->buffer, 64);
 
592
+    }
 
593
+
 
594
+    if (inputLen >= 64) {
 
595
+        _input = body(context, _input, inputLen & ~(unsigned long)0x3f);
 
596
+        inputLen &= 0x3f;
 
597
+    }
 
598
+
 
599
+    /* Buffer remaining input */
 
600
+    memcpy(context->buffer, _input, inputLen);
 
601
+    return APR_SUCCESS;
 
602
+}
 
603
+
 
604
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
 
605
+ * the message digest and zeroizing the context.
 
606
+ */
 
607
+APU_DECLARE(apr_status_t) apr_md5_final(unsigned char digest[APR_MD5_DIGESTSIZE],
 
608
+                                        apr_md5_ctx_t *context)
 
609
+{
 
610
+    unsigned long used, free;
 
611
+
 
612
+    used = context->count[0] & 0x3f;
 
613
+
 
614
+    context->buffer[used++] = 0x80;
 
615
+
 
616
+    free = 64 - used;
 
617
+
 
618
+#if APR_HAS_XLATE
 
619
+    /* apr_md5_update() should not translate for this final round. */
 
620
+    context->xlate = NULL;
 
621
+#endif /*APR_HAS_XLATE*/
 
622
+
 
623
+    if (free < 8) {
 
624
+        memset(&context->buffer[used], 0, free);
 
625
+        body(context, context->buffer, 64);
 
626
+        used = 0;
 
627
+        free = 64;
 
628
+    }
 
629
+
 
630
+    memset(&context->buffer[used], 0, free - 8);
 
631
+
 
632
+    context->count[0] <<= 3;
 
633
+    context->buffer[56] = context->count[0];
 
634
+    context->buffer[57] = context->count[0] >> 8;
 
635
+    context->buffer[58] = context->count[0] >> 16;
 
636
+    context->buffer[59] = context->count[0] >> 24;
 
637
+    context->buffer[60] = context->count[1];
 
638
+    context->buffer[61] = context->count[1] >> 8;
 
639
+    context->buffer[62] = context->count[1] >> 16;
 
640
+    context->buffer[63] = context->count[1] >> 24;
 
641
+
 
642
+    body(context, context->buffer, 64);
 
643
+
 
644
+    digest[0] = context->state[0];
 
645
+    digest[1] = context->state[0] >> 8;
 
646
+    digest[2] = context->state[0] >> 16;
 
647
+    digest[3] = context->state[0] >> 24;
 
648
+    digest[4] = context->state[1];
 
649
+    digest[5] = context->state[1] >> 8;
 
650
+    digest[6] = context->state[1] >> 16;
 
651
+    digest[7] = context->state[1] >> 24;
 
652
+    digest[8] = context->state[2];
 
653
+    digest[9] = context->state[2] >> 8;
 
654
+    digest[10] = context->state[2] >> 16;
 
655
+    digest[11] = context->state[2] >> 24;
 
656
+    digest[12] = context->state[3];
 
657
+    digest[13] = context->state[3] >> 8;
 
658
+    digest[14] = context->state[3] >> 16;
 
659
+    digest[15] = context->state[3] >> 24;
 
660
+
 
661
+    /* Zeroize sensitive information. */
 
662
+    memset(context, 0, sizeof(*context));
 
663
+    
 
664
+    return APR_SUCCESS;
 
665
+}
 
666
+
 
667
+/* MD5 in one step (init, update, final)
 
668
+ */
 
669
+APU_DECLARE(apr_status_t) apr_md5(unsigned char digest[APR_MD5_DIGESTSIZE],
 
670
+                                  const void *_input,
 
671
+                                  apr_size_t inputLen)
 
672
+{
 
673
+    const unsigned char *input = _input;
 
674
+    apr_md5_ctx_t ctx;
 
675
+    apr_status_t rv;
 
676
+
 
677
+    apr_md5_init(&ctx);
 
678
+
 
679
+    if ((rv = apr_md5_update(&ctx, input, inputLen)) != APR_SUCCESS)
 
680
+        return rv;
 
681
+
 
682
+    return apr_md5_final(digest, &ctx);
 
683
+}
 
684
+
 
685
+/*
 
686
+ * This processes one or more 64-byte data blocks, but does NOT update
 
687
+ * the bit counters.  There're no alignment requirements.
 
688
+ */
 
689
+static const void *body(apr_md5_ctx_t *context, const void *data, apr_size_t size)
 
690
+{
 
691
+    const unsigned char *ptr, *convptr;
 
692
+    uint_fast32_t a, b, c, d;
 
693
+    uint_fast32_t saved_a, saved_b, saved_c, saved_d;
 
694
+    apr_uint32_t block[16];
 
695
+    
 
696
+#ifdef APR_HAS_XLATE
 
697
+    apr_size_t inbytes_left, outbytes_left;
 
698
+#endif
 
699
+
 
700
+    ptr = data;
 
701
+
 
702
+    a = context->state[0];
 
703
+    b = context->state[1];
 
704
+    c = context->state[2];
 
705
+    d = context->state[3];
 
706
+    
 
707
+    do {
 
708
+        saved_a = a;
 
709
+        saved_b = b;
 
710
+        saved_c = c;
 
711
+        saved_d = d;
 
712
+
 
713
+        convptr = ptr;
 
714
+#ifdef APR_HAS_XLATE
 
715
+        if (context->xlate) {
 
716
+            inbytes_left = outbytes_left = 64;
 
717
+            unsigned char inp_tmp[64];
 
718
+            apr_xlate_conv_buffer(context->xlate, ptr, &inbytes_left,
 
719
+                                  inp_tmp, &outbytes_left);
 
720
+            convptr = inp_tmp;
 
721
+        }
 
722
+#endif
 
723
+
 
724
+
 
725
+/* Round 1 */
 
726
+               STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
 
727
+               STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
 
728
+               STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
 
729
+               STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
 
730
+               STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
 
731
+               STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
 
732
+               STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
 
733
+               STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
 
734
+               STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
 
735
+               STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
 
736
+               STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
 
737
+               STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
 
738
+               STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
 
739
+               STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
 
740
+               STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
 
741
+               STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
 
742
+
 
743
+/* Round 2 */
 
744
+               STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
 
745
+               STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
 
746
+               STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
 
747
+               STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
 
748
+               STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
 
749
+               STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
 
750
+               STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
 
751
+               STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
 
752
+               STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
 
753
+               STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
 
754
+               STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
 
755
+               STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
 
756
+               STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
 
757
+               STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
 
758
+               STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
 
759
+               STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
 
760
+
 
761
+/* Round 3 */
 
762
+               STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
 
763
+               STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
 
764
+               STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
 
765
+               STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
 
766
+               STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
 
767
+               STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
 
768
+               STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
 
769
+               STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
 
770
+               STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
 
771
+               STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
 
772
+               STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
 
773
+               STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
 
774
+               STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
 
775
+               STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
 
776
+               STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
 
777
+               STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
 
778
+
 
779
+/* Round 4 */
 
780
+               STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
 
781
+               STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
 
782
+               STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
 
783
+               STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
 
784
+               STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
 
785
+               STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
 
786
+               STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
 
787
+               STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
 
788
+               STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
 
789
+               STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
 
790
+               STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
 
791
+               STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
 
792
+               STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
 
793
+               STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
 
794
+               STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
 
795
+               STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
 
796
+
 
797
+               a += saved_a;
 
798
+               b += saved_b;
 
799
+               c += saved_c;
 
800
+               d += saved_d;
 
801
+
 
802
+               ptr += 64;
 
803
+       } while (size -= 64);
 
804
+
 
805
+       context->state[0] = a;
 
806
+       context->state[1] = b;
 
807
+       context->state[2] = c;
 
808
+       context->state[3] = d;
 
809
+
 
810
+       return ptr;
 
811
+}
 
812
+
 
813
+#if APR_CHARSET_EBCDIC
 
814
+APU_DECLARE(apr_status_t) apr_MD5InitEBCDIC(apr_xlate_t *xlate)
 
815
+{
 
816
+    xlate_ebcdic_to_ascii = xlate;
 
817
+    return APR_SUCCESS;
 
818
+}
 
819
+#endif
 
820
+
 
821
+/*
 
822
+ * Define the Magic String prefix that identifies a password as being
 
823
+ * hashed using our algorithm.
 
824
+ */
 
825
+static const char *apr1_id = "$apr1$";
 
826
+
 
827
+/*
 
828
+ * The following MD5 password encryption code was largely borrowed from
 
829
+ * the FreeBSD 3.0 /usr/src/lib/libcrypt/crypt.c file, which is
 
830
+ * licenced as stated at the top of this file.
 
831
+ */
 
832
+
 
833
+static void to64(char *s, unsigned long v, int n)
 
834
+{
 
835
+    static unsigned char itoa64[] =         /* 0 ... 63 => ASCII - 64 */
 
836
+        "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
837
+
 
838
+    while (--n >= 0) {
 
839
+        *s++ = itoa64[v&0x3f];
 
840
+        v >>= 6;
 
841
+    }
 
842
+}
 
843
+
 
844
+APU_DECLARE(apr_status_t) apr_md5_encode(const char *pw, const char *salt,
 
845
+                             char *result, apr_size_t nbytes)
 
846
+{
 
847
+    /*
 
848
+     * Minimum size is 8 bytes for salt, plus 1 for the trailing NUL,
 
849
+     * plus 4 for the '$' separators, plus the password hash itself.
 
850
+     * Let's leave a goodly amount of leeway.
 
851
+     */
 
852
+
 
853
+    char passwd[120], *p;
 
854
+    const char *sp, *ep;
 
855
+    unsigned char final[APR_MD5_DIGESTSIZE];
 
856
+    apr_ssize_t sl, pl, i;
 
857
+    apr_md5_ctx_t ctx, ctx1;
 
858
+    unsigned long l;
 
859
+
 
860
+    /* 
 
861
+     * Refine the salt first.  It's possible we were given an already-hashed
 
862
+     * string as the salt argument, so extract the actual salt value from it
 
863
+     * if so.  Otherwise just use the string up to the first '$' as the salt.
 
864
+     */
 
865
+    sp = salt;
 
866
+
 
867
+    /*
 
868
+     * If it starts with the magic string, then skip that.
 
869
+     */
 
870
+    if (!strncmp(sp, apr1_id, strlen(apr1_id))) {
 
871
+        sp += strlen(apr1_id);
 
872
+    }
 
873
+
 
874
+    /*
 
875
+     * It stops at the first '$' or 8 chars, whichever comes first
 
876
+     */
 
877
+    for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++) {
 
878
+        continue;
 
879
+    }
 
880
+
 
881
+    /*
 
882
+     * Get the length of the true salt
 
883
+     */
 
884
+    sl = ep - sp;
 
885
+
 
886
+    /*
 
887
+     * 'Time to make the doughnuts..'
 
888
+     */
 
889
+    apr_md5_init(&ctx);
 
890
+#if APR_CHARSET_EBCDIC
 
891
+    apr_md5_set_xlate(&ctx, xlate_ebcdic_to_ascii);
 
892
+#endif
 
893
+    
 
894
+    /*
 
895
+     * The password first, since that is what is most unknown
 
896
+     */
 
897
+    apr_md5_update(&ctx, pw, strlen(pw));
 
898
+
 
899
+    /*
 
900
+     * Then our magic string
 
901
+     */
 
902
+    apr_md5_update(&ctx, apr1_id, strlen(apr1_id));
 
903
+
 
904
+    /*
 
905
+     * Then the raw salt
 
906
+     */
 
907
+    apr_md5_update(&ctx, sp, sl);
 
908
+
 
909
+    /*
 
910
+     * Then just as many characters of the MD5(pw, salt, pw)
 
911
+     */
 
912
+    apr_md5_init(&ctx1);
 
913
+    apr_md5_update(&ctx1, pw, strlen(pw));
 
914
+    apr_md5_update(&ctx1, sp, sl);
 
915
+    apr_md5_update(&ctx1, pw, strlen(pw));
 
916
+    apr_md5_final(final, &ctx1);
 
917
+    for (pl = strlen(pw); pl > 0; pl -= APR_MD5_DIGESTSIZE) {
 
918
+        apr_md5_update(&ctx, final, 
 
919
+                      (pl > APR_MD5_DIGESTSIZE) ? APR_MD5_DIGESTSIZE : pl);
 
920
+    }
 
921
+
 
922
+    /*
 
923
+     * Don't leave anything around in vm they could use.
 
924
+     */
 
925
+    memset(final, 0, sizeof(final));
 
926
+
 
927
+    /*
 
928
+     * Then something really weird...
 
929
+     */
 
930
+    for (i = strlen(pw); i != 0; i >>= 1) {
 
931
+        if (i & 1) {
 
932
+            apr_md5_update(&ctx, final, 1);
 
933
+        }
 
934
+        else {
 
935
+            apr_md5_update(&ctx, pw, 1);
 
936
+        }
 
937
+    }
 
938
+
 
939
+    /*
 
940
+     * Now make the output string.  We know our limitations, so we
 
941
+     * can use the string routines without bounds checking.
 
942
+     */
 
943
+    strcpy(passwd, apr1_id);
 
944
+    strncat(passwd, sp, sl);
 
945
+    strcat(passwd, "$");
 
946
+
 
947
+    apr_md5_final(final, &ctx);
 
948
+
 
949
+    /*
 
950
+     * And now, just to make sure things don't run too fast..
 
951
+     * On a 60 Mhz Pentium this takes 34 msec, so you would
 
952
+     * need 30 seconds to build a 1000 entry dictionary...
 
953
+     */
 
954
+    for (i = 0; i < 1000; i++) {
 
955
+        apr_md5_init(&ctx1);
 
956
+        if (i & 1) {
 
957
+            apr_md5_update(&ctx1, pw, strlen(pw));
 
958
+        }
 
959
+        else {
 
960
+            apr_md5_update(&ctx1, final, APR_MD5_DIGESTSIZE);
 
961
+        }
 
962
+        if (i % 3) {
 
963
+            apr_md5_update(&ctx1, sp, sl);
 
964
+        }
 
965
+
 
966
+        if (i % 7) {
 
967
+            apr_md5_update(&ctx1, pw, strlen(pw));
 
968
+        }
 
969
+
 
970
+        if (i & 1) {
 
971
+            apr_md5_update(&ctx1, final, APR_MD5_DIGESTSIZE);
 
972
+        }
 
973
+        else {
 
974
+            apr_md5_update(&ctx1, pw, strlen(pw));
 
975
+        }
 
976
+        apr_md5_final(final,&ctx1);
 
977
+    }
 
978
+
 
979
+    p = passwd + strlen(passwd);
 
980
+
 
981
+    l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p, l, 4); p += 4;
 
982
+    l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p, l, 4); p += 4;
 
983
+    l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p, l, 4); p += 4;
 
984
+    l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p, l, 4); p += 4;
 
985
+    l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p, l, 4); p += 4;
 
986
+    l =                    final[11]                ; to64(p, l, 2); p += 2;
 
987
+    *p = '\0';
 
988
+
 
989
+    /*
 
990
+     * Don't leave anything around in vm they could use.
 
991
+     */
 
992
+    memset(final, 0, sizeof(final));
 
993
+
 
994
+    apr_cpystrn(result, passwd, nbytes - 1);
 
995
+    return APR_SUCCESS;
 
996
+}
 
997
+
 
998
+#if !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
 
999
+#if defined(APU_CRYPT_THREADSAFE) || !APR_HAS_THREADS || \
 
1000
+    defined(CRYPT_R_CRYPTD) || defined(CRYPT_R_STRUCT_CRYPT_DATA)
 
1001
+
 
1002
+#define crypt_mutex_lock()
 
1003
+#define crypt_mutex_unlock()
 
1004
+
 
1005
+#elif APR_HAVE_PTHREAD_H && defined(PTHREAD_MUTEX_INITIALIZER)
 
1006
+
 
1007
+static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER;
 
1008
+static void crypt_mutex_lock(void)
 
1009
+{
 
1010
+    pthread_mutex_lock(&crypt_mutex);
 
1011
+}
 
1012
+
 
1013
+static void crypt_mutex_unlock(void)
 
1014
+{
 
1015
+    pthread_mutex_unlock(&crypt_mutex);
 
1016
+}
 
1017
+
 
1018
+#else
 
1019
+
 
1020
+#error apr_password_validate() is not threadsafe.  rebuild APR without thread support.
 
1021
+
 
1022
+#endif
 
1023
+#endif
 
1024
+
 
1025
+/*
 
1026
+ * Validate a plaintext password against a smashed one.  Uses either
 
1027
+ * crypt() (if available) or apr_md5_encode() or apr_sha1_base64(), depending
 
1028
+ * upon the format of the smashed input password.  Returns APR_SUCCESS if
 
1029
+ * they match, or APR_EMISMATCH if they don't.  If the platform doesn't
 
1030
+ * support crypt, then the default check is against a clear text string.
 
1031
+ */
 
1032
+APU_DECLARE(apr_status_t) apr_password_validate(const char *passwd, 
 
1033
+                                                const char *hash)
 
1034
+{
 
1035
+    char sample[120];
 
1036
+#if !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
 
1037
+    char *crypt_pw;
 
1038
+#endif
 
1039
+    if (!strncmp(hash, apr1_id, strlen(apr1_id))) {
 
1040
+        /*
 
1041
+         * The hash was created using our custom algorithm.
 
1042
+         */
 
1043
+        apr_md5_encode(passwd, hash, sample, sizeof(sample));
 
1044
+    }
 
1045
+    else if (!strncmp(hash, APR_SHA1PW_ID, APR_SHA1PW_IDLEN)) {
 
1046
+         apr_sha1_base64(passwd, strlen(passwd), sample);
 
1047
+    }
 
1048
+    else {
 
1049
+        /*
 
1050
+         * It's not our algorithm, so feed it to crypt() if possible.
 
1051
+         */
 
1052
+#if defined(WIN32) || defined(BEOS) || defined(NETWARE)
 
1053
+        apr_cpystrn(sample, passwd, sizeof(sample) - 1);
 
1054
+#elif defined(CRYPT_R_CRYPTD)
 
1055
+        CRYPTD buffer;
 
1056
+
 
1057
+        crypt_pw = crypt_r(passwd, hash, &buffer);
 
1058
+        apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1);
 
1059
+#elif defined(CRYPT_R_STRUCT_CRYPT_DATA)
 
1060
+        struct crypt_data buffer;
 
1061
+
 
1062
+        /* having to clear this seems bogus... GNU doc is
 
1063
+         * confusing...  user report found from google says
 
1064
+         * the crypt_data struct had to be cleared to get
 
1065
+         * the same result as plain crypt()
 
1066
+         */
 
1067
+        memset(&buffer, 0, sizeof(buffer));
 
1068
+        crypt_pw = crypt_r(passwd, hash, &buffer);
 
1069
+        apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1);
 
1070
+#else
 
1071
+        /* Do a bit of sanity checking since we know that crypt_r()
 
1072
+         * should always be used for threaded builds on AIX, and
 
1073
+         * problems in configure logic can result in the wrong
 
1074
+         * choice being made.
 
1075
+         */
 
1076
+#if defined(_AIX) && APR_HAS_THREADS
 
1077
+#error Configuration error!  crypt_r() should have been selected!
 
1078
+#endif
 
1079
+
 
1080
+        /* Handle thread safety issues by holding a mutex around the
 
1081
+         * call to crypt().
 
1082
+         */
 
1083
+        crypt_mutex_lock();
 
1084
+        crypt_pw = crypt(passwd, hash);
 
1085
+        apr_cpystrn(sample, crypt_pw, sizeof(sample) - 1);
 
1086
+        crypt_mutex_unlock();
 
1087
+#endif
 
1088
+    }
 
1089
+    return (strcmp(sample, hash) == 0) ? APR_SUCCESS : APR_EMISMATCH;
 
1090
+}
 
1091
diff -urNad apr-util-1.2.7~/include/apr_md4.h apr-util-1.2.7/include/apr_md4.h
 
1092
--- apr-util-1.2.7~/include/apr_md4.h   1970-01-01 01:00:00.000000000 +0100
 
1093
+++ apr-util-1.2.7/include/apr_md4.h    2006-08-18 14:22:04.000000000 +0200
 
1094
@@ -0,0 +1,135 @@
 
1095
+/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
 
1096
+ * applicable.
 
1097
+ *
 
1098
+ * Licensed under the Apache License, Version 2.0 (the "License");
 
1099
+ * you may not use this file except in compliance with the License.
 
1100
+ * You may obtain a copy of the License at
 
1101
+ *
 
1102
+ *     http://www.apache.org/licenses/LICENSE-2.0
 
1103
+ *
 
1104
+ * Unless required by applicable law or agreed to in writing, software
 
1105
+ * distributed under the License is distributed on an "AS IS" BASIS,
 
1106
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
1107
+ * See the License for the specific language governing permissions and
 
1108
+ * limitations under the License.
 
1109
+ */
 
1110
+/* This is derived from material copyright RSA Data Security, Inc.
 
1111
+ * Their notice is reproduced below in its entirety.
 
1112
+ *
 
1113
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
 
1114
+ * rights reserved.
 
1115
+ *
 
1116
+ * License to copy and use this software is granted provided that it
 
1117
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
 
1118
+ * Algorithm" in all material mentioning or referencing this software
 
1119
+ * or this function.
 
1120
+ *
 
1121
+ * License is also granted to make and use derivative works provided
 
1122
+ * that such works are identified as "derived from the RSA Data
 
1123
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
 
1124
+ * mentioning or referencing the derived work.
 
1125
+ *
 
1126
+ * RSA Data Security, Inc. makes no representations concerning either
 
1127
+ * the merchantability of this software or the suitability of this
 
1128
+ * software for any particular purpose. It is provided "as is"
 
1129
+ * without express or implied warranty of any kind.
 
1130
+ *
 
1131
+ * These notices must be retained in any copies of any part of this
 
1132
+ * documentation and/or software.
 
1133
+ */
 
1134
+
 
1135
+#ifndef APR_MD4_H
 
1136
+#define APR_MD4_H
 
1137
+
 
1138
+#include "apu.h"
 
1139
+#include "apr_xlate.h"
 
1140
+/**
 
1141
+ * @file apr_md4.h
 
1142
+ * @brief APR-UTIL MD4 Library
 
1143
+ */
 
1144
+#ifdef __cplusplus
 
1145
+extern "C" {
 
1146
+#endif
 
1147
+
 
1148
+/**
 
1149
+ * @defgroup APR_Util_MD4 MD4 Library
 
1150
+ * @ingroup APR_Util
 
1151
+ * @{
 
1152
+ */
 
1153
+
 
1154
+/** The digestsize for MD4 */
 
1155
+#define APR_MD4_DIGESTSIZE 16
 
1156
+
 
1157
+/** @see apr_md4_ctx_t */
 
1158
+typedef struct apr_md4_ctx_t apr_md4_ctx_t;
 
1159
+
 
1160
+/** MD4 context. */
 
1161
+struct apr_md4_ctx_t {
 
1162
+    /** state (ABCD) */
 
1163
+    apr_uint32_t state[4];
 
1164
+    /** number of bits, modulo 2^64 (lsb first) */
 
1165
+    apr_uint32_t count[2];
 
1166
+    /** input buffer */
 
1167
+    unsigned char buffer[64];
 
1168
+#if APR_HAS_XLATE
 
1169
+    /** translation handle */
 
1170
+    apr_xlate_t *xlate;
 
1171
+#endif
 
1172
+};
 
1173
+
 
1174
+/**
 
1175
+ * MD4 Initialize.  Begins an MD4 operation, writing a new context.
 
1176
+ * @param context The MD4 context to initialize.
 
1177
+ */
 
1178
+APU_DECLARE(apr_status_t) apr_md4_init(apr_md4_ctx_t *context);
 
1179
+
 
1180
+#if APR_HAS_XLATE
 
1181
+/**
 
1182
+ * MDr4 translation setup.  Provides the APR translation handle to be used 
 
1183
+ * for translating the content before calculating the digest.
 
1184
+ * @param context The MD4 content to set the translation for.
 
1185
+ * @param xlate The translation handle to use for this MD4 context 
 
1186
+ */
 
1187
+APU_DECLARE(apr_status_t) apr_md4_set_xlate(apr_md4_ctx_t *context,
 
1188
+                                            apr_xlate_t *xlate);
 
1189
+#else
 
1190
+#define apr_md4_set_xlate(context, xlate) APR_ENOTIMPL
 
1191
+#endif
 
1192
+
 
1193
+/**
 
1194
+ * MD4 block update operation.  Continue an MD4 message-digest operation, 
 
1195
+ * processing another message block, and updating the context.
 
1196
+ * @param context The MD4 content to update.
 
1197
+ * @param input next message block to update
 
1198
+ * @param inputLen The length of the next message block
 
1199
+ */
 
1200
+APU_DECLARE(apr_status_t) apr_md4_update(apr_md4_ctx_t *context,
 
1201
+                                         const unsigned char *input,
 
1202
+                                         apr_size_t inputLen);
 
1203
+
 
1204
+/**
 
1205
+ * MD4 finalization.  Ends an MD4 message-digest operation, writing the 
 
1206
+ * message digest and zeroing the context
 
1207
+ * @param digest The final MD4 digest
 
1208
+ * @param context The MD4 content we are finalizing.
 
1209
+ */
 
1210
+APU_DECLARE(apr_status_t) apr_md4_final(
 
1211
+                                    unsigned char digest[APR_MD4_DIGESTSIZE],
 
1212
+                                    apr_md4_ctx_t *context);
 
1213
+
 
1214
+/**
 
1215
+ * MD4 digest computation
 
1216
+ * @param digest The MD4 digest
 
1217
+ * @param input message block to use
 
1218
+ * @param inputLen The length of the message block
 
1219
+ */
 
1220
+APU_DECLARE(apr_status_t) apr_md4(unsigned char digest[APR_MD4_DIGESTSIZE],
 
1221
+                                  const unsigned char *input,
 
1222
+                                  apr_size_t inputLen);
 
1223
+
 
1224
+/** @} */
 
1225
+#ifdef __cplusplus
 
1226
+}
 
1227
+#endif
 
1228
+
 
1229
+#endif /* !APR_MD4_H */
 
1230
diff -urNad apr-util-1.2.7~/include/apr_md5.h apr-util-1.2.7/include/apr_md5.h
 
1231
--- apr-util-1.2.7~/include/apr_md5.h   1970-01-01 01:00:00.000000000 +0100
 
1232
+++ apr-util-1.2.7/include/apr_md5.h    2006-08-18 14:22:04.000000000 +0200
 
1233
@@ -0,0 +1,144 @@
 
1234
+/*
 
1235
+ * Adopted for apr-util by Tollef Fog Heen <tfheen@err.no>
 
1236
+ */
 
1237
+
 
1238
+/*
 
1239
+ * This is an OpenSSL-compatible implementation of the RSA Data Security,
 
1240
+ * Inc. MD5 Message-Digest Algorithm.
 
1241
+ *
 
1242
+ * Written by Solar Designer <solar@openwall.com> in 2001, and placed in
 
1243
+ * the public domain.  See md5.c for more information.
 
1244
+ */
 
1245
+
 
1246
+/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
1247
+ * applicable.
 
1248
+ *
 
1249
+ * Licensed under the Apache License, Version 2.0 (the "License");
 
1250
+ * you may not use this file except in compliance with the License.
 
1251
+ * You may obtain a copy of the License at
 
1252
+ *
 
1253
+ *     http://www.apache.org/licenses/LICENSE-2.0
 
1254
+ *
 
1255
+ * Unless required by applicable law or agreed to in writing, software
 
1256
+ * distributed under the License is distributed on an "AS IS" BASIS,
 
1257
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
1258
+ * See the License for the specific language governing permissions and
 
1259
+ * limitations under the License.
 
1260
+ */
 
1261
+
 
1262
+#ifndef APR_MD5_H
 
1263
+#define APR_MD5_H
 
1264
+
 
1265
+#include "apu.h"
 
1266
+#include "apr_xlate.h"
 
1267
+
 
1268
+#ifdef __cplusplus
 
1269
+extern "C" {
 
1270
+#endif
 
1271
+/**
 
1272
+ * @file apr_md5.h
 
1273
+ * @brief APR MD5 Routines
 
1274
+ */
 
1275
+
 
1276
+/**
 
1277
+ * @defgroup APR_MD5 MD5 Routines
 
1278
+ * @ingroup APR
 
1279
+ * @{
 
1280
+ */
 
1281
+
 
1282
+/** The MD5 digest size */
 
1283
+#define APR_MD5_DIGESTSIZE 16
 
1284
+
 
1285
+/** @see apr_md5_ctx_t */
 
1286
+typedef struct apr_md5_ctx_t apr_md5_ctx_t;
 
1287
+
 
1288
+/** MD5 context. */
 
1289
+struct apr_md5_ctx_t {
 
1290
+    /** state (ABCD) */
 
1291
+    apr_uint32_t state[4];
 
1292
+    /** number of bits, modulo 2^64 (lsb first) */
 
1293
+    apr_uint32_t count[2];
 
1294
+    /** input buffer */
 
1295
+    unsigned char buffer[64];
 
1296
+    /** translation handle 
 
1297
+     *  ignored if xlate is unsupported
 
1298
+     */
 
1299
+    apr_xlate_t *xlate;
 
1300
+};
 
1301
+
 
1302
+/**
 
1303
+ * MD5 Initialize.  Begins an MD5 operation, writing a new context.
 
1304
+ * @param context The MD5 context to initialize.
 
1305
+ */
 
1306
+APU_DECLARE(apr_status_t) apr_md5_init(apr_md5_ctx_t *context);
 
1307
+
 
1308
+/**
 
1309
+ * MD5 translation setup.  Provides the APR translation handle to be used 
 
1310
+ * for translating the content before calculating the digest.
 
1311
+ * @param context The MD5 content to set the translation for.
 
1312
+ * @param xlate The translation handle to use for this MD5 context 
 
1313
+ */
 
1314
+APU_DECLARE(apr_status_t) apr_md5_set_xlate(apr_md5_ctx_t *context,
 
1315
+                                            apr_xlate_t *xlate);
 
1316
+
 
1317
+/**
 
1318
+ * MD5 block update operation.  Continue an MD5 message-digest operation, 
 
1319
+ * processing another message block, and updating the context.
 
1320
+ * @param context The MD5 content to update.
 
1321
+ * @param input next message block to update
 
1322
+ * @param inputLen The length of the next message block
 
1323
+ */
 
1324
+APU_DECLARE(apr_status_t) apr_md5_update(apr_md5_ctx_t *context,
 
1325
+                                         const void *input,
 
1326
+                                         apr_size_t inputLen);
 
1327
+
 
1328
+/**
 
1329
+ * MD5 finalization.  Ends an MD5 message-digest operation, writing the 
 
1330
+ * message digest and zeroing the context
 
1331
+ * @param digest The final MD5 digest
 
1332
+ * @param context The MD5 content we are finalizing.
 
1333
+ */
 
1334
+APU_DECLARE(apr_status_t) apr_md5_final(unsigned char digest[APR_MD5_DIGESTSIZE],
 
1335
+                                        apr_md5_ctx_t *context);
 
1336
+
 
1337
+/**
 
1338
+ * MD5 in one step
 
1339
+ * @param digest The final MD5 digest
 
1340
+ * @param input The message block to use
 
1341
+ * @param inputLen The length of the message block
 
1342
+ */
 
1343
+APU_DECLARE(apr_status_t) apr_md5(unsigned char digest[APR_MD5_DIGESTSIZE],
 
1344
+                                  const void *input,
 
1345
+                                  apr_size_t inputLen);
 
1346
+
 
1347
+/**
 
1348
+ * Encode a password using an MD5 algorithm
 
1349
+ * @param password The password to encode
 
1350
+ * @param salt The salt to use for the encoding
 
1351
+ * @param result The string to store the encoded password in
 
1352
+ * @param nbytes The size of the result buffer
 
1353
+ */
 
1354
+APU_DECLARE(apr_status_t) apr_md5_encode(const char *password, const char *salt,
 
1355
+                                         char *result, apr_size_t nbytes);
 
1356
+
 
1357
+
 
1358
+/**
 
1359
+ * Validate hashes created by APR-supported algorithms: md5 and sha1.
 
1360
+ * hashes created by crypt are supported only on platforms that provide
 
1361
+ * crypt(3), so don't rely on that function unless you know that your
 
1362
+ * application will be run only on platforms that support it.  On platforms
 
1363
+ * that don't support crypt(3), this falls back to a clear text string
 
1364
+ * comparison.
 
1365
+ * @param passwd The password to validate
 
1366
+ * @param hash The password to validate against
 
1367
+ */
 
1368
+APU_DECLARE(apr_status_t) apr_password_validate(const char *passwd, 
 
1369
+                                                const char *hash);
 
1370
+
 
1371
+
 
1372
+/** @} */
 
1373
+#ifdef __cplusplus
 
1374
+}
 
1375
+#endif
 
1376
+
 
1377
+#endif /* !APR_MD5_H */