]>
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>
23 #define FLAG_MD5 0x00000001
24 #define FLAG_SALT 0x00000002
25 #define FLAG_PASS 0x00000004
26 #define FLAG_LENGTH 0x00000008
27 #define FLAG_BLOWFISH 0x00000010
28 #define FLAG_ROUNDS 0x00000020
29 #define FLAG_SHA256 0x00000040
30 #define FLAG_SHA512 0x00000080
33 static char *make_md5_salt(int);
34 static char *make_md5_salt_para(char *);
35 static char *make_sha256_salt(int);
36 static char *make_sha256_salt_para(char *);
37 static char *make_sha512_salt(int);
38 static char *make_sha512_salt_para(char *);
39 static char *make_bf_salt(int, int);
40 static char *make_bf_salt_para(int, char *);
41 static char *int_to_base64(int);
42 static char *generate_random_salt(char *, int);
43 static char *generate_poor_salt(char *, int);
45 static void full_usage(void);
46 static void brief_usage(void);
48 static char saltChars
[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
49 /* 0 .. 63, ascii - 64 */
57 static char getpassbuf
[PASS_MAX
+ 1];
60 getpass(const char *prompt
)
65 memset(getpassbuf
, 0, sizeof(getpassbuf
));
66 fputs(prompt
, stderr
);
80 fputs("\r\n", stderr
);
88 main(int argc
, char *argv
[])
90 char *plaintext
= NULL
;
92 char *saltpara
= NULL
;
96 int length
= 0; /* Not Set */
97 int rounds
= 0; /* Not set, since blowfish needs 4 by default, a side effect
98 * of this being the encryption type parameter must be
99 * specified before the rounds parameter.
102 while((c
= getopt(argc
, argv
, "xymbr:h?l:s:p:")) != -1)
110 flag
|= FLAG_BLOWFISH
;
115 length
= atoi(optarg
);
119 rounds
= atoi(optarg
);
144 printf("Invalid Option: -%c\n", c
);
154 salt
= make_md5_salt_para(saltpara
);
156 salt
= make_md5_salt(length
);
158 else if(flag
& FLAG_BLOWFISH
)
163 salt
= make_bf_salt_para(rounds
, saltpara
);
165 salt
= make_bf_salt(rounds
, length
);
167 else if(flag
& FLAG_SHA256
)
172 salt
= make_sha256_salt_para(saltpara
);
174 salt
= make_sha256_salt(length
);
181 salt
= make_sha512_salt_para(saltpara
);
183 salt
= make_sha512_salt(length
);
190 fprintf(stderr
, "Please enter a valid password\n");
194 hashed
= rb_crypt(plaintext
, salt
);
198 hashed
= strdup(rb_crypt(getpass("plaintext: "), salt
));
199 plaintext
= getpass("again: ");
201 if (strcmp(rb_crypt(plaintext
, salt
), hashed
) != 0)
203 fprintf(stderr
, "Passwords do not match\n");
208 printf("%s\n", hashed
);
213 int_to_base64(int value
)
218 for(i
= 0; i
< 4; i
++)
220 buf
[i
] = saltChars
[value
& 63];
221 value
>>= 6; /* Right shifting 6 places is the same as dividing by 64 */
224 buf
[i
] = '\0'; /* not REALLY needed as it's static, and thus initialized
231 make_md5_salt_para(char *saltpara
)
233 static char salt
[21];
234 if(saltpara
&& (strlen(saltpara
) <= 16))
236 /* sprintf used because of portability requirements, the length
237 ** is checked above, so it should not be too much of a concern
239 sprintf(salt
, "$1$%s$", saltpara
);
242 printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
250 make_md5_salt(int length
)
252 static char salt
[21];
255 printf("MD5 salt length too long\n");
261 generate_random_salt(&salt
[3], length
);
262 salt
[length
+ 3] = '$';
263 salt
[length
+ 4] = '\0';
268 make_sha256_salt_para(char *saltpara
)
270 static char salt
[21];
271 if(saltpara
&& (strlen(saltpara
) <= 16))
273 /* sprintf used because of portability requirements, the length
274 ** is checked above, so it should not be too much of a concern
276 sprintf(salt
, "$5$%s$", saltpara
);
279 printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
287 make_sha512_salt_para(char *saltpara
)
289 static char salt
[21];
290 if(saltpara
&& (strlen(saltpara
) <= 16))
292 /* sprintf used because of portability requirements, the length
293 ** is checked above, so it should not be too much of a concern
295 sprintf(salt
, "$6$%s$", saltpara
);
298 printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
307 make_sha256_salt(int length
)
309 static char salt
[21];
312 printf("SHA256 salt length too long\n");
318 generate_random_salt(&salt
[3], length
);
319 salt
[length
+ 3] = '$';
320 salt
[length
+ 4] = '\0';
325 make_sha512_salt(int length
)
327 static char salt
[21];
330 printf("SHA512 salt length too long\n");
336 generate_random_salt(&salt
[3], length
);
337 salt
[length
+ 3] = '$';
338 salt
[length
+ 4] = '\0';
343 make_bf_salt_para(int rounds
, char *saltpara
)
345 static char salt
[31];
347 if(saltpara
&& (strlen(saltpara
) <= 22))
349 /* sprintf used because of portability requirements, the length
350 ** is checked above, so it should not be too much of a concern
352 sprintf(tbuf
, "%02d", rounds
);
353 sprintf(salt
, "$2a$%s$%s$", tbuf
, saltpara
);
356 printf("Invalid Salt, please use up to 22 random alphanumeric characters\n");
364 make_bf_salt(int rounds
, int length
)
366 static char salt
[31];
370 printf("Blowfish salt length too long\n");
373 sprintf(tbuf
, "%02d", rounds
);
374 sprintf(salt
, "$2a$%s$", tbuf
);
375 generate_random_salt(&salt
[7], length
);
376 salt
[length
+ 7] = '$';
377 salt
[length
+ 8] = '\0';
382 generate_poor_salt(char *salt
, int length
)
386 for(i
= 0; i
< length
; i
++)
388 salt
[i
] = saltChars
[rand() % 64];
394 generate_random_salt(char *salt
, int length
)
398 if((fd
= open("/dev/random", O_RDONLY
)) < 0)
400 return (generate_poor_salt(salt
, length
));
402 buf
= calloc(1, length
);
403 if(read(fd
, buf
, length
) != length
)
406 return (generate_poor_salt(salt
, length
));
409 for(i
= 0; i
< length
; i
++)
411 salt
[i
] = saltChars
[abs(buf
[i
]) % 64];
420 printf("mkpasswd [-m|-b|-x|-y] [-l saltlength] [-r rounds] [-s salt] [-p plaintext]\n");
421 printf("-x Generate a SHA256 password\n");
422 printf("-y Generate a SHA512 password\n");
423 printf("-m Generate an MD5 password\n");
424 printf("-b Generate a Blowfish password\n");
425 printf("-l Specify a length for a random MD5 or Blowfish salt\n");
426 printf("-r Specify a number of rounds for a Blowfish password\n");
427 printf(" Default 4, no more than 6 recommended\n");
428 printf("-s Specify a salt, up to 16 for MD5, SHA256, and SHA512\n");
429 printf(" up to 22 for Blowfish\n");
430 printf("-p Specify a plaintext password to use\n");
431 printf("Example: mkpasswd -m -s 3dr -p test\n");
438 printf("mkpasswd - password hash generator\n");
439 printf(" SHA512: mkpasswd [-y] [-l saltlength] [-s salt] [-p plaintext]\n");
440 printf(" SHA256: mkpasswd -x [-l saltlength] [-s salt] [-p plaintext]\n");
441 printf(" MD5: mkpasswd -m [-l saltlength] [-s salt] [-p plaintext]\n");
442 printf("Blowfish: mkpasswd -b [-r rounds] [-l saltlength] [-s salt]\n");
443 printf(" [-p plaintext]\n");
444 printf("Use -h for full usage\n");