]>
jfr.im git - solanum.git/blob - tools/mkpasswd.c
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.
5 ** md5 patch by W. Campbell <wcampbel@botbay.net>
6 ** Modernization, getopt, etc for the Hybrid IRCD team
9 ** /dev/random for salt generation added by
10 ** Aaron Sethman <androsyn@ratbox.org>
12 ** $Id: mkpasswd.c 26439 2009-02-01 15:27:24Z jilles $
20 #include "ratbox_lib.h"
25 #define FLAG_MD5 0x00000001
26 #define FLAG_DES 0x00000002
27 #define FLAG_SALT 0x00000004
28 #define FLAG_PASS 0x00000008
29 #define FLAG_LENGTH 0x00000010
30 #define FLAG_BLOWFISH 0x00000020
31 #define FLAG_ROUNDS 0x00000040
32 #define FLAG_EXT 0x00000080
33 #define FLAG_SHA256 0x00000100
34 #define FLAG_SHA512 0x00000200
37 static char *make_des_salt(void);
38 static char *make_ext_salt(int);
39 static char *make_ext_salt_para(int, char *);
40 static char *make_md5_salt(int);
41 static char *make_md5_salt_para(char *);
42 static char *make_sha256_salt(int);
43 static char *make_sha256_salt_para(char *);
44 static char *make_sha512_salt(int);
45 static char *make_sha512_salt_para(char *);
46 static char *make_bf_salt(int, int);
47 static char *make_bf_salt_para(int, char *);
48 static char *int_to_base64(int);
49 static char *generate_random_salt(char *, int);
50 static char *generate_poor_salt(char *, int);
52 static void full_usage(void);
53 static void brief_usage(void);
55 static char saltChars
[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
56 /* 0 .. 63, ascii - 64 */
64 static char getpassbuf
[PASS_MAX
+ 1];
67 getpass(const char *prompt
)
72 memset(getpassbuf
, 0, sizeof(getpassbuf
));
73 fputs(prompt
, stderr
);
87 fputs("\r\n", stderr
);
95 main(int argc
, char *argv
[])
97 char *plaintext
= NULL
;
99 char *saltpara
= NULL
;
103 int length
= 0; /* Not Set */
104 int rounds
= 0; /* Not set, since extended DES needs 25 and blowfish needs
105 ** 4 by default, a side effect of this being the encryption
106 ** type parameter must be specified before the rounds
110 while((c
= getopt(argc
, argv
, "xymdber:h?l:s:p:")) != -1)
121 flag
|= FLAG_BLOWFISH
;
130 length
= atoi(optarg
);
134 rounds
= atoi(optarg
);
159 printf("Invalid Option: -%c\n", c
);
169 salt
= make_md5_salt_para(saltpara
);
171 salt
= make_md5_salt(length
);
173 else if(flag
& FLAG_BLOWFISH
)
178 salt
= make_bf_salt_para(rounds
, saltpara
);
180 salt
= make_bf_salt(rounds
, length
);
182 else if(flag
& FLAG_SHA256
)
187 salt
= make_sha256_salt_para(saltpara
);
189 salt
= make_sha256_salt(length
);
191 else if(flag
& FLAG_EXT
)
193 /* XXX - rounds needs to be done */
196 if((strlen(saltpara
) == 4))
198 salt
= make_ext_salt_para(rounds
, saltpara
);
202 printf("Invalid salt, please enter 4 alphanumeric characters\n");
208 salt
= make_ext_salt(rounds
);
211 else if (flag
& FLAG_DES
)
215 if((strlen(saltpara
) == 2))
221 printf("Invalid salt, please enter 2 alphanumeric characters\n");
227 salt
= make_des_salt();
235 salt
= make_sha512_salt_para(saltpara
);
237 salt
= make_sha512_salt(length
);
244 fprintf(stderr
, "Please enter a valid password\n");
248 hashed
= rb_crypt(plaintext
, salt
);
252 hashed
= strdup(rb_crypt(getpass("plaintext: "), salt
));
253 plaintext
= getpass("again: ");
255 if (strcmp(rb_crypt(plaintext
, salt
), hashed
) != 0)
257 fprintf(stderr
, "Passwords do not match\n");
262 printf("%s\n", hashed
);
270 generate_random_salt(salt
, 2);
276 int_to_base64(int value
)
281 for(i
= 0; i
< 4; i
++)
283 buf
[i
] = saltChars
[value
& 63];
284 value
>>= 6; /* Right shifting 6 places is the same as dividing by 64 */
287 buf
[i
] = '\0'; /* not REALLY needed as it's static, and thus initialized
294 make_ext_salt(int rounds
)
296 static char salt
[10];
298 sprintf(salt
, "_%s", int_to_base64(rounds
));
299 generate_random_salt(&salt
[5], 4);
305 make_ext_salt_para(int rounds
, char *saltpara
)
307 static char salt
[10];
309 sprintf(salt
, "_%s%s", int_to_base64(rounds
), saltpara
);
314 make_md5_salt_para(char *saltpara
)
316 static char salt
[21];
317 if(saltpara
&& (strlen(saltpara
) <= 16))
319 /* sprintf used because of portability requirements, the length
320 ** is checked above, so it should not be too much of a concern
322 sprintf(salt
, "$1$%s$", saltpara
);
325 printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
333 make_md5_salt(int length
)
335 static char salt
[21];
338 printf("MD5 salt length too long\n");
344 generate_random_salt(&salt
[3], length
);
345 salt
[length
+ 3] = '$';
346 salt
[length
+ 4] = '\0';
351 make_sha256_salt_para(char *saltpara
)
353 static char salt
[21];
354 if(saltpara
&& (strlen(saltpara
) <= 16))
356 /* sprintf used because of portability requirements, the length
357 ** is checked above, so it should not be too much of a concern
359 sprintf(salt
, "$5$%s$", saltpara
);
362 printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
370 make_sha512_salt_para(char *saltpara
)
372 static char salt
[21];
373 if(saltpara
&& (strlen(saltpara
) <= 16))
375 /* sprintf used because of portability requirements, the length
376 ** is checked above, so it should not be too much of a concern
378 sprintf(salt
, "$6$%s$", saltpara
);
381 printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
390 make_sha256_salt(int length
)
392 static char salt
[21];
395 printf("SHA256 salt length too long\n");
401 generate_random_salt(&salt
[3], length
);
402 salt
[length
+ 3] = '$';
403 salt
[length
+ 4] = '\0';
408 make_sha512_salt(int length
)
410 static char salt
[21];
413 printf("SHA512 salt length too long\n");
419 generate_random_salt(&salt
[3], length
);
420 salt
[length
+ 3] = '$';
421 salt
[length
+ 4] = '\0';
426 make_bf_salt_para(int rounds
, char *saltpara
)
428 static char salt
[31];
430 if(saltpara
&& (strlen(saltpara
) <= 22))
432 /* sprintf used because of portability requirements, the length
433 ** is checked above, so it should not be too much of a concern
435 sprintf(tbuf
, "%02d", rounds
);
436 sprintf(salt
, "$2a$%s$%s$", tbuf
, saltpara
);
439 printf("Invalid Salt, please use up to 22 random alphanumeric characters\n");
447 make_bf_salt(int rounds
, int length
)
449 static char salt
[31];
453 printf("Blowfish salt length too long\n");
456 sprintf(tbuf
, "%02d", rounds
);
457 sprintf(salt
, "$2a$%s$", tbuf
);
458 generate_random_salt(&salt
[7], length
);
459 salt
[length
+ 7] = '$';
460 salt
[length
+ 8] = '\0';
465 generate_poor_salt(char *salt
, int length
)
469 for(i
= 0; i
< length
; i
++)
471 salt
[i
] = saltChars
[rand() % 64];
477 generate_random_salt(char *salt
, int length
)
481 if((fd
= open("/dev/random", O_RDONLY
)) < 0)
483 return (generate_poor_salt(salt
, length
));
485 buf
= calloc(1, length
);
486 if(read(fd
, buf
, length
) != length
)
489 return (generate_poor_salt(salt
, length
));
492 for(i
= 0; i
< length
; i
++)
494 salt
[i
] = saltChars
[abs(buf
[i
]) % 64];
503 printf("mkpasswd [-m|-d|-b|-e] [-l saltlength] [-r rounds] [-s salt] [-p plaintext]\n");
504 printf("-x Generate a SHA256 password\n");
505 printf("-y Generate a SHA512 password\n");
506 printf("-m Generate an MD5 password\n");
507 printf("-d Generate a DES password\n");
508 printf("-b Generate a Blowfish password\n");
509 printf("-e Generate an Extended DES password\n");
510 printf("-l Specify a length for a random MD5 or Blowfish salt\n");
511 printf("-r Specify a number of rounds for a Blowfish or Extended DES password\n");
512 printf(" Blowfish: default 4, no more than 6 recommended\n");
513 printf(" Extended DES: default 25\n");
514 printf("-s Specify a salt, 2 alphanumeric characters for DES, up to 16 for MD5,\n");
515 printf(" up to 22 for Blowfish, and 4 for Extended DES\n");
516 printf("-p Specify a plaintext password to use\n");
517 printf("Example: mkpasswd -m -s 3dr -p test\n");
524 printf("mkpasswd - password hash generator\n");
525 printf("Standard DES: mkpasswd [-d] [-s salt] [-p plaintext]\n");
526 printf("Extended DES: mkpasswd -e [-r rounds] [-s salt] [-p plaintext]\n");
527 printf(" MD5: mkpasswd -m [-l saltlength] [-s salt] [-p plaintext]\n");
528 printf(" Blowfish: mkpasswd -b [-r rounds] [-l saltlength] [-s salt]\n");
529 printf(" [-p plaintext]\n");
530 printf("Use -h for full usage\n");