ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/ircservices-5.1.24/modules/encryption/md5.c
Revision: 3389
Committed: Fri Apr 25 14:12:15 2014 UTC (11 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 19262 byte(s)
Log Message:
- Imported ircservices-5.1.24

File Contents

# User Rev Content
1 michael 3389 /* Module for encryption using MD5.
2     *
3     * IRC Services is copyright (c) 1996-2009 Andrew Church.
4     * E-mail: <achurch@achurch.org>
5     * Parts written by Andrew Kempe and others.
6     * This program is free but copyrighted software; see the file GPL.txt for
7     * details.
8     */
9    
10     #include "services.h"
11     #include "modules.h"
12     #include "conffile.h"
13     #include "encrypt.h"
14    
15     /*************************************************************************/
16     /*************************************************************************/
17    
18     /* Enable a workaround for Anope/Epona broken MD5 passwords? */
19     static int EnableAnopeWorkaround = 0;
20    
21     /* For the Anope hack: */
22     #define XTOI(c) ((c)>9 ? (c)-'A'+10 : (c)-'0')
23    
24     /*************************************************************************/
25     /*======== Beginning of L. Peter Deutsch's md5.h ========*/
26     /*
27     Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
28    
29     This software is provided 'as-is', without any express or implied
30     warranty. In no event will the authors be held liable for any damages
31     arising from the use of this software.
32    
33     Permission is granted to anyone to use this software for any purpose,
34     including commercial applications, and to alter it and redistribute it
35     freely, subject to the following restrictions:
36    
37     1. The origin of this software must not be misrepresented; you must not
38     claim that you wrote the original software. If you use this software
39     in a product, an acknowledgment in the product documentation would be
40     appreciated but is not required.
41     2. Altered source versions must be plainly marked as such, and must not be
42     misrepresented as being the original software.
43     3. This notice may not be removed or altered from any source distribution.
44    
45     L. Peter Deutsch
46     ghost@aladdin.com
47    
48     */
49     /* $Id: md5.c,v 2.28 2009/06/17 09:18:39 achurch Exp $ */
50     /*
51     Independent implementation of MD5 (RFC 1321).
52    
53     This code implements the MD5 Algorithm defined in RFC 1321, whose
54     text is available at
55     http://www.ietf.org/rfc/rfc1321.txt
56     The code is derived from the text of the RFC, including the test suite
57     (section A.5) but excluding the rest of Appendix A. It does not include
58     any code or documentation that is identified in the RFC as being
59     copyrighted.
60    
61     The original and principal author of md5.h is L. Peter Deutsch
62     <ghost@aladdin.com>. Other authors are noted in the change history
63     that follows (in reverse chronological order):
64    
65     2002-04-13 lpd Removed support for non-ANSI compilers; removed
66     references to Ghostscript; clarified derivation from RFC 1321;
67     now handles byte order either statically or dynamically.
68     1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
69     1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
70     added conditionalization for C++ compilation from Martin
71     Purschke <purschke@bnl.gov>.
72     1999-05-03 lpd Original version.
73     */
74    
75     #ifndef md5_INCLUDED
76     # define md5_INCLUDED
77    
78     /*
79     * This package supports both compile-time and run-time determination of CPU
80     * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
81     * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
82     * defined as non-zero, the code will be compiled to run only on big-endian
83     * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
84     * run on either big- or little-endian CPUs, but will run slightly less
85     * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
86     */
87    
88     typedef unsigned char md5_byte_t; /* 8-bit byte */
89     typedef unsigned int md5_word_t; /* 32-bit word */
90    
91     /* Define the state of the MD5 Algorithm. */
92     typedef struct md5_state_s {
93     md5_word_t count[2]; /* message length in bits, lsw first */
94     md5_word_t abcd[4]; /* digest buffer */
95     md5_byte_t buf[64]; /* accumulate block */
96     } md5_state_t;
97    
98     #ifdef __cplusplus
99     extern "C"
100     {
101     #endif
102    
103     /* Initialize the algorithm. */
104     void md5_init(md5_state_t *pms);
105    
106     /* Append a string to the message. */
107     void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
108    
109     /* Finish the message and return the digest. */
110     void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
111    
112     #ifdef __cplusplus
113     } /* end extern "C" */
114     #endif
115    
116     #endif /* md5_INCLUDED */
117     /*======== End of L. Peter Deutsch's md5.h ========*/
118    
119     /*======== Beginning of L. Peter Deutsch's md5.c (with the line ========
120     ======== [#include "md5.h"] removed) ========*/
121     /*
122     Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
123    
124     This software is provided 'as-is', without any express or implied
125     warranty. In no event will the authors be held liable for any damages
126     arising from the use of this software.
127    
128     Permission is granted to anyone to use this software for any purpose,
129     including commercial applications, and to alter it and redistribute it
130     freely, subject to the following restrictions:
131    
132     1. The origin of this software must not be misrepresented; you must not
133     claim that you wrote the original software. If you use this software
134     in a product, an acknowledgment in the product documentation would be
135     appreciated but is not required.
136     2. Altered source versions must be plainly marked as such, and must not be
137     misrepresented as being the original software.
138     3. This notice may not be removed or altered from any source distribution.
139    
140     L. Peter Deutsch
141     ghost@aladdin.com
142    
143     */
144     /* $Id: md5.c,v 2.28 2009/06/17 09:18:39 achurch Exp $ */
145     /*
146     Independent implementation of MD5 (RFC 1321).
147    
148     This code implements the MD5 Algorithm defined in RFC 1321, whose
149     text is available at
150     http://www.ietf.org/rfc/rfc1321.txt
151     The code is derived from the text of the RFC, including the test suite
152     (section A.5) but excluding the rest of Appendix A. It does not include
153     any code or documentation that is identified in the RFC as being
154     copyrighted.
155    
156     The original and principal author of md5.c is L. Peter Deutsch
157     <ghost@aladdin.com>. Other authors are noted in the change history
158     that follows (in reverse chronological order):
159    
160     2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
161     either statically or dynamically; added missing #include <string.h>
162     in library.
163     2002-03-11 lpd Corrected argument list for main(), and added int return
164     type, in test program and T value program.
165     2002-02-21 lpd Added missing #include <stdio.h> in test program.
166     2000-07-03 lpd Patched to eliminate warnings about "constant is
167     unsigned in ANSI C, signed in traditional"; made test program
168     self-checking.
169     1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
170     1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
171     1999-05-03 lpd Original version.
172     */
173    
174     #include <string.h>
175    
176     #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
177     #ifdef ARCH_IS_BIG_ENDIAN
178     # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
179     #else
180     # define BYTE_ORDER 0
181     #endif
182    
183     #define T_MASK ((md5_word_t)~0)
184     #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
185     #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
186     #define T3 0x242070db
187     #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
188     #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
189     #define T6 0x4787c62a
190     #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
191     #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
192     #define T9 0x698098d8
193     #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
194     #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
195     #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
196     #define T13 0x6b901122
197     #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
198     #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
199     #define T16 0x49b40821
200     #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
201     #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
202     #define T19 0x265e5a51
203     #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
204     #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
205     #define T22 0x02441453
206     #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
207     #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
208     #define T25 0x21e1cde6
209     #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
210     #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
211     #define T28 0x455a14ed
212     #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
213     #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
214     #define T31 0x676f02d9
215     #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
216     #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
217     #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
218     #define T35 0x6d9d6122
219     #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
220     #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
221     #define T38 0x4bdecfa9
222     #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
223     #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
224     #define T41 0x289b7ec6
225     #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
226     #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
227     #define T44 0x04881d05
228     #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
229     #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
230     #define T47 0x1fa27cf8
231     #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
232     #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
233     #define T50 0x432aff97
234     #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
235     #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
236     #define T53 0x655b59c3
237     #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
238     #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
239     #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
240     #define T57 0x6fa87e4f
241     #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
242     #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
243     #define T60 0x4e0811a1
244     #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
245     #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
246     #define T63 0x2ad7d2bb
247     #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
248    
249    
250     static void
251     md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
252     {
253     md5_word_t
254     a = pms->abcd[0], b = pms->abcd[1],
255     c = pms->abcd[2], d = pms->abcd[3];
256     md5_word_t t;
257     #if BYTE_ORDER > 0
258     /* Define storage only for big-endian CPUs. */
259     md5_word_t X[16];
260     #else
261     /* Define storage for little-endian or both types of CPUs. */
262     md5_word_t xbuf[16];
263     const md5_word_t *X;
264     #endif
265    
266     {
267     #if BYTE_ORDER == 0
268     /*
269     * Determine dynamically whether this is a big-endian or
270     * little-endian machine, since we can use a more efficient
271     * algorithm on the latter.
272     */
273     static const int w = 1;
274    
275     if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
276     #endif
277     #if BYTE_ORDER <= 0 /* little-endian */
278     {
279     /*
280     * On little-endian machines, we can process properly aligned
281     * data without copying it.
282     */
283     if (!((data - (const md5_byte_t *)0) & 3)) {
284     /* data are properly aligned */
285     X = (const md5_word_t *)data;
286     } else {
287     /* not aligned */
288     memcpy(xbuf, data, 64);
289     X = xbuf;
290     }
291     }
292     #endif
293     #if BYTE_ORDER == 0
294     else /* dynamic big-endian */
295     #endif
296     #if BYTE_ORDER >= 0 /* big-endian */
297     {
298     /*
299     * On big-endian machines, we must arrange the bytes in the
300     * right order.
301     */
302     const md5_byte_t *xp = data;
303     int i;
304    
305     # if BYTE_ORDER == 0
306     X = xbuf; /* (dynamic only) */
307     # else
308     # define xbuf X /* (static only) */
309     # endif
310     for (i = 0; i < 16; ++i, xp += 4)
311     xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
312     }
313     #endif
314     }
315    
316     #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
317    
318     /* Round 1. */
319     /* Let [abcd k s i] denote the operation
320     a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
321     #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
322     #define SET(a, b, c, d, k, s, Ti)\
323     t = a + F(b,c,d) + X[k] + Ti;\
324     a = ROTATE_LEFT(t, s) + b
325     /* Do the following 16 operations. */
326     SET(a, b, c, d, 0, 7, T1);
327     SET(d, a, b, c, 1, 12, T2);
328     SET(c, d, a, b, 2, 17, T3);
329     SET(b, c, d, a, 3, 22, T4);
330     SET(a, b, c, d, 4, 7, T5);
331     SET(d, a, b, c, 5, 12, T6);
332     SET(c, d, a, b, 6, 17, T7);
333     SET(b, c, d, a, 7, 22, T8);
334     SET(a, b, c, d, 8, 7, T9);
335     SET(d, a, b, c, 9, 12, T10);
336     SET(c, d, a, b, 10, 17, T11);
337     SET(b, c, d, a, 11, 22, T12);
338     SET(a, b, c, d, 12, 7, T13);
339     SET(d, a, b, c, 13, 12, T14);
340     SET(c, d, a, b, 14, 17, T15);
341     SET(b, c, d, a, 15, 22, T16);
342     #undef SET
343    
344     /* Round 2. */
345     /* Let [abcd k s i] denote the operation
346     a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
347     #define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
348     #define SET(a, b, c, d, k, s, Ti)\
349     t = a + G(b,c,d) + X[k] + Ti;\
350     a = ROTATE_LEFT(t, s) + b
351     /* Do the following 16 operations. */
352     SET(a, b, c, d, 1, 5, T17);
353     SET(d, a, b, c, 6, 9, T18);
354     SET(c, d, a, b, 11, 14, T19);
355     SET(b, c, d, a, 0, 20, T20);
356     SET(a, b, c, d, 5, 5, T21);
357     SET(d, a, b, c, 10, 9, T22);
358     SET(c, d, a, b, 15, 14, T23);
359     SET(b, c, d, a, 4, 20, T24);
360     SET(a, b, c, d, 9, 5, T25);
361     SET(d, a, b, c, 14, 9, T26);
362     SET(c, d, a, b, 3, 14, T27);
363     SET(b, c, d, a, 8, 20, T28);
364     SET(a, b, c, d, 13, 5, T29);
365     SET(d, a, b, c, 2, 9, T30);
366     SET(c, d, a, b, 7, 14, T31);
367     SET(b, c, d, a, 12, 20, T32);
368     #undef SET
369    
370     /* Round 3. */
371     /* Let [abcd k s t] denote the operation
372     a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
373     #define H(x, y, z) ((x) ^ (y) ^ (z))
374     #define SET(a, b, c, d, k, s, Ti)\
375     t = a + H(b,c,d) + X[k] + Ti;\
376     a = ROTATE_LEFT(t, s) + b
377     /* Do the following 16 operations. */
378     SET(a, b, c, d, 5, 4, T33);
379     SET(d, a, b, c, 8, 11, T34);
380     SET(c, d, a, b, 11, 16, T35);
381     SET(b, c, d, a, 14, 23, T36);
382     SET(a, b, c, d, 1, 4, T37);
383     SET(d, a, b, c, 4, 11, T38);
384     SET(c, d, a, b, 7, 16, T39);
385     SET(b, c, d, a, 10, 23, T40);
386     SET(a, b, c, d, 13, 4, T41);
387     SET(d, a, b, c, 0, 11, T42);
388     SET(c, d, a, b, 3, 16, T43);
389     SET(b, c, d, a, 6, 23, T44);
390     SET(a, b, c, d, 9, 4, T45);
391     SET(d, a, b, c, 12, 11, T46);
392     SET(c, d, a, b, 15, 16, T47);
393     SET(b, c, d, a, 2, 23, T48);
394     #undef SET
395    
396     /* Round 4. */
397     /* Let [abcd k s t] denote the operation
398     a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
399     #define I(x, y, z) ((y) ^ ((x) | ~(z)))
400     #define SET(a, b, c, d, k, s, Ti)\
401     t = a + I(b,c,d) + X[k] + Ti;\
402     a = ROTATE_LEFT(t, s) + b
403     /* Do the following 16 operations. */
404     SET(a, b, c, d, 0, 6, T49);
405     SET(d, a, b, c, 7, 10, T50);
406     SET(c, d, a, b, 14, 15, T51);
407     SET(b, c, d, a, 5, 21, T52);
408     SET(a, b, c, d, 12, 6, T53);
409     SET(d, a, b, c, 3, 10, T54);
410     SET(c, d, a, b, 10, 15, T55);
411     SET(b, c, d, a, 1, 21, T56);
412     SET(a, b, c, d, 8, 6, T57);
413     SET(d, a, b, c, 15, 10, T58);
414     SET(c, d, a, b, 6, 15, T59);
415     SET(b, c, d, a, 13, 21, T60);
416     SET(a, b, c, d, 4, 6, T61);
417     SET(d, a, b, c, 11, 10, T62);
418     SET(c, d, a, b, 2, 15, T63);
419     SET(b, c, d, a, 9, 21, T64);
420     #undef SET
421    
422     /* Then perform the following additions. (That is increment each
423     of the four registers by the value it had before this block
424     was started.) */
425     pms->abcd[0] += a;
426     pms->abcd[1] += b;
427     pms->abcd[2] += c;
428     pms->abcd[3] += d;
429     }
430    
431     void
432     md5_init(md5_state_t *pms)
433     {
434     pms->count[0] = pms->count[1] = 0;
435     pms->abcd[0] = 0x67452301;
436     pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
437     pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
438     pms->abcd[3] = 0x10325476;
439     }
440    
441     void
442     md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
443     {
444     const md5_byte_t *p = data;
445     int left = nbytes;
446     int offset = (pms->count[0] >> 3) & 63;
447     md5_word_t nbits = (md5_word_t)(nbytes << 3);
448    
449     if (nbytes <= 0)
450     return;
451    
452     /* Update the message length. */
453     pms->count[1] += nbytes >> 29;
454     pms->count[0] += nbits;
455     if (pms->count[0] < nbits)
456     pms->count[1]++;
457    
458     /* Process an initial partial block. */
459     if (offset) {
460     int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
461    
462     memcpy(pms->buf + offset, p, copy);
463     if (offset + copy < 64)
464     return;
465     p += copy;
466     left -= copy;
467     md5_process(pms, pms->buf);
468     }
469    
470     /* Process full blocks. */
471     for (; left >= 64; p += 64, left -= 64)
472     md5_process(pms, p);
473    
474     /* Process a final partial block. */
475     if (left)
476     memcpy(pms->buf, p, left);
477     }
478    
479     void
480     md5_finish(md5_state_t *pms, md5_byte_t digest[16])
481     {
482     static const md5_byte_t pad[64] = {
483     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
484     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
485     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
486     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
487     };
488     md5_byte_t data[8];
489     int i;
490    
491     /* Save the length before padding. */
492     for (i = 0; i < 8; ++i)
493     data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
494     /* Pad to 56 bytes mod 64. */
495     md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
496     /* Append the length. */
497     md5_append(pms, data, 8);
498     for (i = 0; i < 16; ++i)
499     digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
500     }
501     /*======== End of L. Peter Deutsch's md5.c ========*/
502     /*************************************************************************/
503     /*************************************************************************/
504    
505     /* Services routines. See encrypt.h for documentation. */
506    
507     /*************************************************************************/
508    
509     static int md5_encrypt(const char *src, int len, char *dest, int size)
510     {
511     md5_state_t context;
512    
513     if (size < 16)
514     return 16;
515     md5_init(&context);
516     md5_append(&context, (unsigned char *)src, len);
517     md5_finish(&context, (unsigned char *)dest);
518     return 0;
519     }
520    
521     /*************************************************************************/
522    
523     static int md5_decrypt(const char *src, char *dest, int size)
524     {
525     return -2; /* decryption impossible (for all practical purposes) */
526     }
527    
528     /*************************************************************************/
529    
530     static int md5_check_password(const char *plaintext, const char *password)
531     {
532     char buf[16];
533     char tmpbuf[8];
534     int i;
535    
536     if (md5_encrypt(plaintext, strlen(plaintext), buf, sizeof(buf)) != 0)
537     return -1;
538     if (memcmp(buf, password, 16) == 0)
539     return 1;
540     if (EnableAnopeWorkaround) {
541     for (i = 0; i < 16; i += 2)
542     tmpbuf[i/2] = XTOI(buf[i])<<4 | XTOI(buf[i+1]);
543     if (memcmp(tmpbuf, password, 8) == 0)
544     return 1;
545     }
546     return 0;
547     }
548    
549     /*************************************************************************/
550     /*************************************************************************/
551    
552     /* Module stuff. */
553    
554     ConfigDirective module_config[] = {
555     { "EnableAnopeWorkaround", { {CD_SET, 0, &EnableAnopeWorkaround} } },
556     { NULL }
557     };
558    
559     static CipherInfo md5_info = {
560     .name = "md5",
561     .encrypt = md5_encrypt,
562     .decrypt = md5_decrypt,
563     .check_password = md5_check_password,
564     };
565    
566     int init_module(void)
567     {
568     if (PASSMAX < 16) {
569     module_log("PASSMAX too small (must be at least 16)");
570     return 0;
571     }
572     register_cipher(&md5_info);
573     return 1;
574     }
575    
576     int exit_module(int shutdown_unused)
577     {
578     unregister_cipher(&md5_info);
579     return 1;
580     }
581    
582     /*************************************************************************/
583    
584     /*
585     * Local variables:
586     * c-file-style: "stroustrup"
587     * c-file-offsets: ((case-label . *) (statement-case-intro . *))
588     * indent-tabs-mode: nil
589     * End:
590     *
591     * vim: expandtab shiftwidth=4:
592     */