/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- POINTER
- UINT2
- UINT4
- MD5_CTX
- MD5Init
- MD5Update
- MD5Final
- MD5Transform
- Encode
- Decode
- MD5_memcpy
- MD5_memset
- _crypt_to64
- crypt_md5
- salt_invalid
- main
1 /***************************************
2 $Revision: 1.1 $
3
4 Stand alone utilitie for creating crypt md5 passwords
5
6 Status: NOT REVIEWED, TESTED
7
8 Author(s): Denis Walker
9
10 ******************/ /******************
11 Modification History:
12 denis (29/04/2002) Created.
13 ******************/ /******************
14 Copyright (c) 2002 RIPE NCC
15
16 All Rights Reserved
17
18 Permission to use, copy, modify, and distribute this software and its
19 documentation for any purpose and without fee is hereby granted,
20 provided that the above copyright notice appear in all copies and that
21 both that copyright notice and this permission notice appear in
22 supporting documentation, and that the name of the author not be
23 used in advertising or publicity pertaining to distribution of the
24 software without specific, written prior permission.
25
26 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
28 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
29 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
30 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32 ***************************************/
33
34 #include <unistd.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 /*#include <md5.h>*/
39 /* #include "crypt.h" */
40 #include <sys/types.h>
41
42 /* magic sizes */
43 #define MD5_SIZE 16
44
45 /* PROTOTYPES should be set to one if and only if the compiler supports
46 function argument prototyping.
47 The following makes PROTOTYPES default to 0 if it has not already
48 been defined with C compiler flags.
49 */
50 #ifndef PROTOTYPES
51 #define PROTOTYPES 0
52 #endif
53
54 /* POINTER defines a generic pointer type */
55 typedef unsigned char *POINTER;
/* [<][>][^][v][top][bottom][index][help] */
56
57 /* UINT2 defines a two byte word */
58 typedef unsigned short int UINT2;
/* [<][>][^][v][top][bottom][index][help] */
59
60 /* UINT4 defines a four byte word */
61 typedef unsigned long int UINT4;
/* [<][>][^][v][top][bottom][index][help] */
62
63 /* MD5 context. */
64 typedef struct {
65 UINT4 state[4]; /* state (ABCD) */
66 UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
67 unsigned char buffer[64]; /* input buffer */
68 } MD5_CTX;
/* [<][>][^][v][top][bottom][index][help] */
69
70 /* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
71 If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
72 returns an empty list.
73 */
74 #if PROTOTYPES
75 #define PROTO_LIST(list) list
76 #else
77 #define PROTO_LIST(list) ()
78 #endif
79
80
81 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
82 */
83
84 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
85 rights reserved.
86
87 License to copy and use this software is granted provided that it
88 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
89 Algorithm" in all material mentioning or referencing this software
90 or this function.
91
92 License is also granted to make and use derivative works provided
93 that such works are identified as "derived from the RSA Data
94 Security, Inc. MD5 Message-Digest Algorithm" in all material
95 mentioning or referencing the derived work.
96
97 RSA Data Security, Inc. makes no representations concerning either
98 the merchantability of this software or the suitability of this
99 software for any particular purpose. It is provided "as is"
100 without express or implied warranty of any kind.
101
102 These notices must be retained in any copies of any part of this
103 documentation and/or software.
104 */
105
106 /* Constants for MD5Transform routine.
107 */
108
109 #define S11 7
110 #define S12 12
111 #define S13 17
112 #define S14 22
113 #define S21 5
114 #define S22 9
115 #define S23 14
116 #define S24 20
117 #define S31 4
118 #define S32 11
119 #define S33 16
120 #define S34 23
121 #define S41 6
122 #define S42 10
123 #define S43 15
124 #define S44 21
125
126 static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
127 static void Encode PROTO_LIST
128 ((unsigned char *, UINT4 *, unsigned int));
129 static void Decode PROTO_LIST
130 ((UINT4 *, unsigned char *, unsigned int));
131 static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
132 static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
133
134 static unsigned char PADDING[64] = {
135 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
137 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
138 };
139
140 /* F, G, H and I are basic MD5 functions.
141 */
142 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
143 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
144 #define H(x, y, z) ((x) ^ (y) ^ (z))
145 #define I(x, y, z) ((y) ^ ((x) | (~z)))
146
147 /* ROTATE_LEFT rotates x left n bits.
148 */
149 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
150
151 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
152 Rotation is separate from addition to prevent recomputation.
153 */
154 #define FF(a, b, c, d, x, s, ac) { \
155 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
156 (a) = ROTATE_LEFT ((a), (s)); \
157 (a) += (b); \
158 }
159 #define GG(a, b, c, d, x, s, ac) { \
160 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
161 (a) = ROTATE_LEFT ((a), (s)); \
162 (a) += (b); \
163 }
164 #define HH(a, b, c, d, x, s, ac) { \
165 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
166 (a) = ROTATE_LEFT ((a), (s)); \
167 (a) += (b); \
168 }
169 #define II(a, b, c, d, x, s, ac) { \
170 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
171 (a) = ROTATE_LEFT ((a), (s)); \
172 (a) += (b); \
173 }
174
175 /* MD5 initialization. Begins an MD5 operation, writing a new context.
176 */
177 void MD5Init (context)
/* [<][>][^][v][top][bottom][index][help] */
178 MD5_CTX *context; /* context */
179 {
180 context->count[0] = context->count[1] = 0;
181 /* Load magic initialization constants.
182 */
183 context->state[0] = 0x67452301;
184 context->state[1] = 0xefcdab89;
185 context->state[2] = 0x98badcfe;
186 context->state[3] = 0x10325476;
187 }
188
189 /* MD5 block update operation. Continues an MD5 message-digest
190 operation, processing another message block, and updating the
191 context.
192 */
193 void MD5Update (context, input, inputLen)
/* [<][>][^][v][top][bottom][index][help] */
194 MD5_CTX *context; /* context */
195 unsigned char *input; /* input block */
196 unsigned int inputLen; /* length of input block */
197 {
198 unsigned int i, index, partLen;
199
200 /* Compute number of bytes mod 64 */
201 index = (unsigned int)((context->count[0] >> 3) & 0x3F);
202
203 /* Update number of bits */
204 if ((context->count[0] += ((UINT4)inputLen << 3))
205 < ((UINT4)inputLen << 3))
206 context->count[1]++;
207 context->count[1] += ((UINT4)inputLen >> 29);
208
209 partLen = 64 - index;
210
211 /* Transform as many times as possible.
212 */
213 if (inputLen >= partLen) {
214 MD5_memcpy
215 ((POINTER)&context->buffer[index], (POINTER)input, partLen);
216 MD5Transform (context->state, context->buffer);
217
218 for (i = partLen; i + 63 < inputLen; i += 64)
219 MD5Transform (context->state, &input[i]);
220
221 index = 0;
222 }
223 else
224 i = 0;
225
226 /* Buffer remaining input */
227 MD5_memcpy
228 ((POINTER)&context->buffer[index], (POINTER)&input[i],
229 inputLen-i);
230 }
231
232 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
233 the message digest and zeroizing the context.
234 */
235 void MD5Final (digest, context)
/* [<][>][^][v][top][bottom][index][help] */
236 unsigned char digest[16]; /* message digest */
237 MD5_CTX *context; /* context */
238 {
239 unsigned char bits[8];
240 unsigned int index, padLen;
241
242 /* Save number of bits */
243 Encode (bits, context->count, 8);
244
245 /* Pad out to 56 mod 64.
246 */
247 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
248 padLen = (index < 56) ? (56 - index) : (120 - index);
249 MD5Update (context, PADDING, padLen);
250
251 /* Append length (before padding) */
252 MD5Update (context, bits, 8);
253
254 /* Store state in digest */
255 Encode (digest, context->state, 16);
256
257 /* Zeroize sensitive information.
258 */
259 MD5_memset ((POINTER)context, 0, sizeof (*context));
260 }
261
262 /* MD5 basic transformation. Transforms state based on block.
263 */
264 static void MD5Transform (state, block)
/* [<][>][^][v][top][bottom][index][help] */
265 UINT4 state[4];
266 unsigned char block[64];
267 {
268 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
269
270 Decode (x, block, 64);
271
272 /* Round 1 */
273 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
274 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
275 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
276 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
277 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
278 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
279 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
280 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
281 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
282 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
283 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
284 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
285 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
286 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
287 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
288 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
289
290 /* Round 2 */
291 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
292 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
293 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
294 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
295 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
296 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
297 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
298 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
299 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
300 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
301 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
302 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
303 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
304 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
305 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
306 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
307
308 /* Round 3 */
309 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
310 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
311 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
312 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
313 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
314 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
315 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
316 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
317 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
318 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
319 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
320 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
321 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
322 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
323 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
324 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
325
326 /* Round 4 */
327 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
328 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
329 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
330 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
331 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
332 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
333 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
334 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
335 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
336 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
337 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
338 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
339 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
340 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
341 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
342 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
343
344 state[0] += a;
345 state[1] += b;
346 state[2] += c;
347 state[3] += d;
348
349 /* Zeroize sensitive information.
350 */
351 MD5_memset ((POINTER)x, 0, sizeof (x));
352 }
353
354 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
355 a multiple of 4.
356 */
357 static void Encode (output, input, len)
/* [<][>][^][v][top][bottom][index][help] */
358 unsigned char *output;
359 UINT4 *input;
360 unsigned int len;
361 {
362 unsigned int i, j;
363
364 for (i = 0, j = 0; j < len; i++, j += 4) {
365 output[j] = (unsigned char)(input[i] & 0xff);
366 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
367 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
368 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
369 }
370 }
371
372 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
373 a multiple of 4.
374 */
375 static void Decode (output, input, len)
/* [<][>][^][v][top][bottom][index][help] */
376 UINT4 *output;
377 unsigned char *input;
378 unsigned int len;
379 {
380 unsigned int i, j;
381
382 for (i = 0, j = 0; j < len; i++, j += 4)
383 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
384 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
385 }
386
387 /* Note: Replace "for loop" with standard memcpy if possible.
388 */
389
390 static void MD5_memcpy (output, input, len)
/* [<][>][^][v][top][bottom][index][help] */
391 POINTER output;
392 POINTER input;
393 unsigned int len;
394 {
395 unsigned int i;
396
397 for (i = 0; i < len; i++)
398
399 output[i] = input[i];
400 }
401
402 /* Note: Replace "for loop" with standard memset if possible.
403 */
404 static void MD5_memset (output, value, len)
/* [<][>][^][v][top][bottom][index][help] */
405 POINTER output;
406 int value;
407 unsigned int len;
408 {
409 unsigned int i;
410
411 for (i = 0; i < len; i++)
412 ((char *)output)[i] = (char)value;
413 }
414
415 /*
416 * Copyright (c) 1999
417 * University of California. All rights reserved.
418 *
419 * Redistribution and use in source and binary forms, with or without
420 * modification, are permitted provided that the following conditions
421 * are met:
422 * 1. Redistributions of source code must retain the above copyright
423 * notice, this list of conditions and the following disclaimer.
424 * 2. Redistributions in binary form must reproduce the above copyright
425 * notice, this list of conditions and the following disclaimer in the
426 * documentation and/or other materials provided with the distribution.
427 * 3. Neither the name of the author nor the names of any co-contributors
428 * may be used to endorse or promote products derived from this software
429 * without specific prior written permission.
430 *
431 * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
432 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
433 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
434 * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
435 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
436 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
437 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
438 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
439 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
440 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
441 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
442 */
443
444 static char itoa64[] = /* 0 ... 63 => ascii - 64 */
445 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
446
447 void
448 _crypt_to64(char *s, u_long v, int n)
/* [<][>][^][v][top][bottom][index][help] */
449 {
450 while (--n >= 0) {
451 *s++ = itoa64[v&0x3f];
452 v >>= 6;
453 }
454 }
455
456 /*
457 * ----------------------------------------------------------------------------
458 * "THE BEER-WARE LICENSE" (Revision 42):
459 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
460 * can do whatever you want with this stuff. If we meet some day, and you think
461 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
462 * ----------------------------------------------------------------------------
463 */
464
465 char *
466 crypt_md5(const char *pw, const char *salt)
/* [<][>][^][v][top][bottom][index][help] */
467 {
468 MD5_CTX ctx,ctx1;
469 unsigned long l;
470 int sl, pl;
471 u_int i;
472 u_char final[MD5_SIZE];
473 static const char *sp, *ep;
474 static char passwd[120], *p;
475 static const char *magic = "$1$"; /*
476 * This string is magic for
477 * this algorithm. Having
478 * it this way, we can get
479 * better later on.
480 */
481
482 /* Refine the Salt first */
483 sp = salt;
484
485 /* If it starts with the magic string, then skip that */
486 if(!strncmp(sp, magic, strlen(magic)))
487 sp += strlen(magic);
488
489 /* It stops at the first '$', max 8 chars */
490 for(ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
491 continue;
492
493 /* get the length of the true salt */
494 sl = ep - sp;
495
496 MD5Init(&ctx);
497
498 /* The password first, since that is what is most unknown */
499 MD5Update(&ctx, (u_char *)pw, strlen(pw));
500
501 /* Then our magic string */
502 MD5Update(&ctx, (u_char *)magic, strlen(magic));
503
504 /* Then the raw salt */
505 MD5Update(&ctx, (u_char *)sp, (u_int)sl);
506
507 /* Then just as many characters of the MD5(pw,salt,pw) */
508 MD5Init(&ctx1);
509 MD5Update(&ctx1, (u_char *)pw, strlen(pw));
510 MD5Update(&ctx1, (u_char *)sp, (u_int)sl);
511 MD5Update(&ctx1, (u_char *)pw, strlen(pw));
512 MD5Final(final, &ctx1);
513 for(pl = (int)strlen(pw); pl > 0; pl -= MD5_SIZE)
514 MD5Update(&ctx, (u_char *)final,
515 (u_int)(pl > MD5_SIZE ? MD5_SIZE : pl));
516
517 /* Don't leave anything around in vm they could use. */
518 memset(final, 0, sizeof(final));
519
520 /* Then something really weird... */
521 for (i = strlen(pw); i; i >>= 1)
522 if(i & 1)
523 MD5Update(&ctx, (u_char *)final, 1);
524 else
525 MD5Update(&ctx, (u_char *)pw, 1);
526
527 /* Now make the output string */
528 strcpy(passwd, magic);
529 strncat(passwd, sp, (u_int)sl);
530 strcat(passwd, "$");
531
532 MD5Final(final, &ctx);
533
534 /*
535 * and now, just to make sure things don't run too fast
536 * On a 60 Mhz Pentium this takes 34 msec, so you would
537 * need 30 seconds to build a 1000 entry dictionary...
538 */
539 for(i = 0; i < 1000; i++) {
540 MD5Init(&ctx1);
541 if(i & 1)
542 MD5Update(&ctx1, (u_char *)pw, strlen(pw));
543 else
544 MD5Update(&ctx1, (u_char *)final, MD5_SIZE);
545
546 if(i % 3)
547 MD5Update(&ctx1, (u_char *)sp, (u_int)sl);
548
549 if(i % 7)
550 MD5Update(&ctx1, (u_char *)pw, strlen(pw));
551
552 if(i & 1)
553 MD5Update(&ctx1, (u_char *)final, MD5_SIZE);
554 else
555 MD5Update(&ctx1, (u_char *)pw, strlen(pw));
556 MD5Final(final, &ctx1);
557 }
558
559 p = passwd + strlen(passwd);
560
561 l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
562 _crypt_to64(p, l, 4); p += 4;
563 l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
564 _crypt_to64(p, l, 4); p += 4;
565 l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
566 _crypt_to64(p, l, 4); p += 4;
567 l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
568 _crypt_to64(p, l, 4); p += 4;
569 l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
570 _crypt_to64(p, l, 4); p += 4;
571 l = final[11] ;
572 _crypt_to64(p, l, 2); p += 2;
573 *p = '\0';
574
575 /* Don't leave anything around in vm they could use. */
576 memset(final, 0, sizeof(final));
577
578 return passwd;
579 }
580
581
582 /* check for valid characters only in the salt value supplied */
583
584 int salt_invalid(char *salt)
/* [<][>][^][v][top][bottom][index][help] */
585 {
586 int i;
587
588 for ( i=0; i<strlen(salt); i++ )
589 {
590 if ( (salt[i] >= 'A' && salt[i] <= 'Z')
591 || (salt[i] >= 'a' && salt[i] <= 'z')
592 || (salt[i] >= '0' && salt[i] <= '9')
593 || salt[i] == '.' || salt[i] == '/' )
594 continue; /* valid character */
595 else
596 return 1; /* invalid character found */
597 }
598 return 0;
599 }
600
601
602 int main(int argc, char **argv)
/* [<][>][^][v][top][bottom][index][help] */
603 {
604 char *cryptpw;
605 char *passwd;
606 char *salt;
607
608
609 if ( argc < 3 )
610 {
611 printf("\nUsage: md5_pw password salt\n\n");
612 return(0);
613 }
614
615 passwd = argv[1];
616 salt = argv[2];
617 if ( salt_invalid(salt) )
618 {
619 printf("\nsalt [%s] contains characters that are not allowed - only [A-Za-z0-9./] are allowed\n", salt);
620 exit(0);
621 }
622 if (strlen(salt) > 8)
623 printf("\nOnly first 8 characters of the salt were used\n");
624
625 /* printf("salt [%s]\n", salt);
626 printf("password [%s]\n", passwd); */
627
628 cryptpw = crypt_md5((const char *)passwd, (const char *)salt );
629 printf("\nmd5 crypt password: %s\n\n", cryptpw);
630
631 return(0);
632 }