ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/tools/mkpasswd.c
Revision: 5009
Committed: Tue Dec 9 14:37:06 2014 UTC (9 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 11140 byte(s)
Log Message:
- mkpasswd.c: removed extraneous parentheses

File Contents

# Content
1 /* simple password generator by Nelson Minar (minar@reed.edu)
2 ** copyright 1991, all rights reserved.
3 ** You can use this code as long as my name stays with it.
4 **
5 ** md5 patch by W. Campbell <wcampbel@botbay.net>
6 ** Modernization, getopt, etc for the Hybrid IRCD team
7 ** by W. Campbell
8 **
9 ** /dev/random for salt generation added by
10 ** Aaron Sethman <androsyn@ratbox.org>
11 **
12 ** $Id$
13 */
14
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <time.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21
22 #define FLAG_MD5 0x00000001
23 #define FLAG_DES 0x00000002
24 #define FLAG_SALT 0x00000004
25 #define FLAG_PASS 0x00000008
26 #define FLAG_LENGTH 0x00000010
27 #define FLAG_BLOWFISH 0x00000020
28 #define FLAG_ROUNDS 0x00000040
29 #define FLAG_EXT 0x00000080
30 #define FLAG_RAW 0x00000100
31 #define FLAG_SHA256 0x00000200
32 #define FLAG_SHA512 0x00000400
33
34
35 extern char *crypt();
36
37
38 static char *make_sha256_salt(int);
39 static char *make_sha256_salt_para(const char *);
40 static char *make_sha512_salt(int);
41 static char *make_sha512_salt_para(const char *);
42 static char *make_des_salt(void);
43 static char *make_ext_salt(int);
44 static char *make_ext_salt_para(int, const char *);
45 static char *make_md5_salt(int);
46 static char *make_md5_salt_para(const char *);
47 static char *make_bf_salt(int, int);
48 static char *make_bf_salt_para(int, const char *);
49 static char *int_to_base64(int);
50 static char *generate_random_salt(char *, int);
51 static char *generate_poor_salt(char *, int);
52 static void full_usage(void);
53 static void brief_usage(void);
54
55 static const char saltChars[] =
56 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
57 /* 0 .. 63, ascii - 64 */
58
59 int
60 main(int argc, char *argv[])
61 {
62 const char *plaintext = NULL;
63 const char *saltpara = NULL;
64 const char *salt = NULL;
65 int c;
66 int flag = 0;
67 int length = 0; /* Not Set */
68 int rounds = 0; /* Not set, since extended DES needs 25 and blowfish needs
69 ** 4 by default, a side effect of this being the encryption
70 ** type parameter must be specified before the rounds
71 ** parameter.
72 */
73
74 while ((c = getopt(argc, argv, "56mdber:h?l:s:p:R:")) != -1)
75 {
76 switch (c)
77 {
78 case '5':
79 flag |= FLAG_SHA256;
80 break;
81 case '6':
82 flag |= FLAG_SHA512;
83 break;
84 case 'm':
85 flag |= FLAG_MD5;
86 break;
87 case 'd':
88 flag |= FLAG_DES;
89 break;
90 case 'b':
91 flag |= FLAG_BLOWFISH;
92 rounds = 4;
93 break;
94 case 'e':
95 flag |= FLAG_EXT;
96 rounds = 25;
97 break;
98 case 'l':
99 flag |= FLAG_LENGTH;
100 length = atoi(optarg);
101 break;
102 case 'r':
103 flag |= FLAG_ROUNDS;
104 rounds = atoi(optarg);
105 break;
106 case 's':
107 flag |= FLAG_SALT;
108 saltpara = optarg;
109 break;
110 case 'p':
111 flag |= FLAG_PASS;
112 plaintext = optarg;
113 break;
114 case 'R':
115 flag |= FLAG_RAW;
116 saltpara = optarg;
117 break;
118 case 'h':
119 full_usage();
120 /* NOT REACHED */
121 break;
122 case '?':
123 brief_usage();
124 /* NOT REACHED */
125 break;
126 default:
127 printf("Invalid Option: -%c\n", c);
128 break;
129 }
130 }
131
132 if (flag & FLAG_DES)
133 {
134 if (flag & FLAG_SALT)
135 {
136 if (strlen(saltpara) == 2)
137 salt = saltpara;
138 else
139 {
140 printf("Invalid salt, please enter 2 alphanumeric characters\n");
141 exit(1);
142 }
143 }
144 else
145 salt = make_des_salt();
146 }
147 else if (flag & FLAG_SHA256)
148 {
149 if (length == 0)
150 length = 16;
151 if (flag & FLAG_SALT)
152 salt = make_sha256_salt_para(saltpara);
153 else
154 salt = make_sha256_salt(length);
155 }
156 else if (flag & FLAG_SHA512)
157 {
158 if (length == 0)
159 length = 16;
160 if (flag & FLAG_SALT)
161 salt = make_sha512_salt_para(saltpara);
162 else
163 salt = make_sha512_salt(length);
164 }
165 else if (flag & FLAG_BLOWFISH)
166 {
167 if (length == 0)
168 length = 22;
169 if (flag & FLAG_SALT)
170 salt = make_bf_salt_para(rounds, saltpara);
171 else
172 salt = make_bf_salt(rounds, length);
173 }
174 else if (flag & FLAG_EXT)
175 {
176 /* XXX - rounds needs to be done */
177 if (flag & FLAG_SALT)
178 {
179 if (strlen(saltpara) == 4)
180 {
181 salt = make_ext_salt_para(rounds, saltpara);
182 }
183 else
184 {
185 printf("Invalid salt, please enter 4 alphanumeric characters\n");
186 exit(1);
187 }
188 }
189 else
190 {
191 salt = make_ext_salt(rounds);
192 }
193 }
194 else if (flag & FLAG_RAW)
195 {
196 salt = saltpara;
197 }
198 else /* Default to MD5 */
199 {
200 if (length == 0)
201 length = 8;
202 if (flag & FLAG_SALT)
203 salt = make_md5_salt_para(saltpara);
204 else
205 salt = make_md5_salt(length);
206 }
207
208 if (flag & FLAG_PASS)
209 {
210 if (!plaintext)
211 printf("Please enter a valid password\n");
212 }
213 else
214 plaintext = getpass("plaintext: ");
215
216 printf("%s\n", crypt(plaintext, salt));
217 return 0;
218 }
219
220 static char *
221 make_des_salt(void)
222 {
223 static char salt[3];
224
225 generate_random_salt(salt, 2);
226 salt[2] = '\0';
227 return salt;
228 }
229
230 static char *
231 int_to_base64(int value)
232 {
233 static char buf[5];
234 int i;
235
236 for (i = 0; i < 4; i++)
237 {
238 buf[i] = saltChars[value & 63];
239 value >>= 6; /* Right shifting 6 places is the same as dividing by 64 */
240 }
241
242 buf[i] = '\0'; /* not REALLY needed as it's static, and thus initialized
243 ** to \0.
244 */
245 return buf;
246 }
247
248 static char *
249 make_ext_salt(int rounds)
250 {
251 static char salt[10];
252
253 snprintf(salt, sizeof(salt), "_%s", int_to_base64(rounds));
254
255 generate_random_salt(&salt[5], 4);
256 salt[9] = '\0';
257
258 return salt;
259 }
260
261 static char *
262 make_ext_salt_para(int rounds, const char *saltpara)
263 {
264 static char salt[10];
265
266 snprintf(salt, sizeof(salt), "_%s%s", int_to_base64(rounds), saltpara);
267 return salt;
268 }
269
270 static char *
271 make_sha256_salt_para(const char *saltpara)
272 {
273 static char salt[21];
274
275 if (saltpara && (strlen(saltpara) <= 16))
276 {
277 snprintf(salt, sizeof(salt), "$5$%s$", saltpara);
278 return salt;
279 }
280
281 printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
282 exit(1);
283
284 /* NOT REACHED */
285 return NULL;
286 }
287
288 static char *
289 make_sha256_salt(int length)
290 {
291 static char salt[21];
292
293 if (length > 16)
294 {
295 printf("SHA-256 salt length too long\n");
296 exit(0);
297 }
298
299 salt[0] = '$';
300 salt[1] = '5';
301 salt[2] = '$';
302
303 generate_random_salt(&salt[3], length);
304
305 salt[length + 3] = '$';
306 salt[length + 4] = '\0';
307
308 return salt;
309 }
310
311 static char *
312 make_sha512_salt_para(const char *saltpara)
313 {
314 static char salt[21];
315
316 if (saltpara && (strlen(saltpara) <= 16))
317 {
318 snprintf(salt, sizeof(salt), "$6$%s$", saltpara);
319 return salt;
320 }
321
322 printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
323 exit(1);
324
325 /* NOT REACHED */
326 return NULL;
327 }
328
329 static char *
330 make_sha512_salt(int length)
331 {
332 static char salt[21];
333
334 if (length > 16)
335 {
336 printf("SHA-512 salt length too long\n");
337 exit(0);
338 }
339
340 salt[0] = '$';
341 salt[1] = '6';
342 salt[2] = '$';
343
344 generate_random_salt(&salt[3], length);
345
346 salt[length + 3] = '$';
347 salt[length + 4] = '\0';
348
349 return salt;
350 }
351
352 static char *
353 make_md5_salt_para(const char *saltpara)
354 {
355 static char salt[21];
356
357 if (saltpara && (strlen(saltpara) <= 16))
358 {
359 snprintf(salt, sizeof(salt), "$1$%s$", saltpara);
360 return salt;
361 }
362
363 printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
364 exit(1);
365
366 /* NOT REACHED */
367 return NULL;
368 }
369
370 static char *
371 make_md5_salt(int length)
372 {
373 static char salt[21];
374
375 if (length > 16)
376 {
377 printf("MD5 salt length too long\n");
378 exit(0);
379 }
380
381 salt[0] = '$';
382 salt[1] = '1';
383 salt[2] = '$';
384
385 generate_random_salt(&salt[3], length);
386
387 salt[length + 3] = '$';
388 salt[length + 4] = '\0';
389
390 return salt;
391 }
392
393 static char *
394 make_bf_salt_para(int rounds, const char *saltpara)
395 {
396 static char salt[31];
397 char tbuf[3];
398
399 if (saltpara && (strlen(saltpara) <= 22))
400 {
401 snprintf(tbuf, sizeof(tbuf), "%02d", rounds);
402 snprintf(salt, sizeof(salt), "$2a$%s$%s$", tbuf, saltpara);
403 return salt;
404 }
405
406 printf("Invalid Salt, please use up to 22 random alphanumeric characters\n");
407 exit(1);
408
409 /* NOT REACHED */
410 return NULL;
411 }
412
413 static char *
414 make_bf_salt(int rounds, int length)
415 {
416 static char salt[31];
417 char tbuf[3];
418
419 if (length > 22)
420 {
421 printf("BlowFish salt length too long\n");
422 exit(0);
423 }
424
425 snprintf(tbuf, sizeof(tbuf), "%02d", rounds);
426 snprintf(salt, sizeof(salt), "$2a$%s$", tbuf);
427
428 generate_random_salt(&salt[7], length);
429
430 salt[length + 7] = '$';
431 salt[length + 8] = '\0';
432
433 return salt;
434 }
435
436 static char *
437 generate_poor_salt(char *salt, int length)
438 {
439 int i;
440
441 srandom(time(NULL));
442
443 for (i = 0; i < length; i++)
444 salt[i] = saltChars[random() % 64];
445
446 return salt;
447 }
448
449 static char *
450 generate_random_salt(char *salt, int length)
451 {
452 char *buf;
453 int fd, i;
454
455 if ((fd = open("/dev/random", O_RDONLY)) < 0)
456 return generate_poor_salt(salt, length);
457
458 buf = calloc(1, length);
459
460 if (read(fd, buf, length) != length)
461 {
462 close(fd);
463 free(buf);
464
465 return generate_poor_salt(salt, length);
466 }
467
468 for (i = 0; i < length; i++)
469 salt[i] = saltChars[abs(buf[i]) % 64];
470
471 close(fd);
472 free(buf);
473
474 return salt;
475 }
476
477 static void
478 full_usage(void)
479 {
480 printf("mkpasswd [-5|-6|-m|-d|-b|-e] [-l saltlength] [-r rounds] [-s salt] [-p plaintext]\n");
481 printf(" [-R rawsalt]\n");
482 printf("-5 Generate a SHA-256 password\n");
483 printf("-6 Generate a SHA-512 password\n");
484 printf("-m Generate an MD5 password\n");
485 printf("-d Generate a DES password\n");
486 printf("-b Generate a BlowFish password\n");
487 printf("-e Generate an Extended DES password\n");
488 printf("-l Specify a length for a random MD5 or BlowFish salt\n");
489 printf("-r Specify a number of rounds for a BlowFish or Extended DES password\n");
490 printf(" BlowFish: default 4, no more than 6 recommended\n");
491 printf(" Extended DES: default 25\n");
492 printf("-s Specify a salt, 2 alphanumeric characters for DES, up to 16 for SHA/MD5,\n");
493 printf(" up to 22 for BlowFish, and 4 for Extended DES\n");
494 printf("-R Specify a raw salt passed directly to crypt()\n");
495 printf("-p Specify a plaintext password to use\n");
496 printf("Example: mkpasswd -m -s 3dr -p test\n");
497 exit(0);
498 }
499
500 static void
501 brief_usage(void)
502 {
503 printf("mkpasswd - password hash generator\n");
504 printf("Standard DES: mkpasswd [-d] [-s salt] [-p plaintext]\n");
505 printf("Extended DES: mkpasswd -e [-r rounds] [-s salt] [-p plaintext]\n");
506 printf(" SHA-256: mkpasswd -5 [-l saltlength] [-s salt] [-p plaintext]\n");
507 printf(" SHA-512: mkpasswd -6 [-l saltlength] [-s salt] [-p plaintext]\n");
508 printf(" MD5: mkpasswd -m [-l saltlength] [-s salt] [-p plaintext]\n");
509 printf(" BlowFish: mkpasswd -b [-r rounds] [-l saltlength] [-s salt]\n");
510 printf(" [-p plaintext]\n");
511 printf(" Raw: mkpasswd -R <rawsalt> [-p plaintext]\n");
512 printf("Use -h for full usage\n");
513 exit(0);
514 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision