ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/tools/mkpasswd.c
Revision: 34
Committed: Sun Oct 2 21:05:51 2005 UTC (18 years, 5 months ago) by lusky
Content type: text/x-csrc
File size: 8894 byte(s)
Log Message:
create 7.2 branch, we can move/rename it as needed.


File Contents

# User Rev Content
1 adx 30 /* 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 knight 31 ** $Id$
13 adx 30 */
14     #include <stdio.h>
15     #include <string.h>
16     #include <stdlib.h>
17     #include <time.h>
18     #include <unistd.h>
19     #include <fcntl.h>
20    
21     #define FLAG_MD5 0x00000001
22     #define FLAG_DES 0x00000002
23     #define FLAG_SALT 0x00000004
24     #define FLAG_PASS 0x00000008
25     #define FLAG_LENGTH 0x00000010
26     #define FLAG_BLOWFISH 0x00000020
27     #define FLAG_ROUNDS 0x00000040
28     #define FLAG_EXT 0x00000080
29     #define FLAG_RAW 0x00000100
30    
31     extern char *crypt();
32    
33     static char *make_des_salt(void);
34     static char *make_ext_salt(int);
35     static char *make_ext_salt_para(int, char *);
36     static char *make_md5_salt(int);
37     static char *make_md5_salt_para(char *);
38     static char *make_bf_salt(int, int);
39     static char *make_bf_salt_para(int, char *);
40     static char *int_to_base64(int);
41     static char *generate_random_salt(char *, int);
42     static char *generate_poor_salt(char *, int);
43     static void full_usage(void);
44     static void brief_usage(void);
45    
46     static const char saltChars[] =
47     "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
48     /* 0 .. 63, ascii - 64 */
49    
50     int main(int argc, char *argv[])
51     {
52     const char *plaintext = NULL;
53     int c;
54     char *saltpara = NULL;
55     char *salt;
56     int flag = 0;
57     int length = 0; /* Not Set */
58     int rounds = 0; /* Not set, since extended DES needs 25 and blowfish needs
59     ** 4 by default, a side effect of this being the encryption
60     ** type parameter must be specified before the rounds
61     ** parameter.
62     */
63    
64     while ((c = getopt(argc, argv, "mdber:h?l:s:p:R:")) != -1)
65     {
66     switch(c)
67     {
68     case 'm':
69     flag |= FLAG_MD5;
70     break;
71     case 'd':
72     flag |= FLAG_DES;
73     break;
74     case 'b':
75     flag |= FLAG_BLOWFISH;
76     rounds = 4;
77     break;
78     case 'e':
79     flag |= FLAG_EXT;
80     rounds = 25;
81     break;
82     case 'l':
83     flag |= FLAG_LENGTH;
84     length = atoi(optarg);
85     break;
86     case 'r':
87     flag |= FLAG_ROUNDS;
88     rounds = atoi(optarg);
89     break;
90     case 's':
91     flag |= FLAG_SALT;
92     saltpara = optarg;
93     break;
94     case 'p':
95     flag |= FLAG_PASS;
96     plaintext = optarg;
97     break;
98     case 'R':
99     flag |= FLAG_RAW;
100     saltpara = optarg;
101     break;
102     case 'h':
103     full_usage();
104     /* NOT REACHED */
105     break;
106     case '?':
107     brief_usage();
108     /* NOT REACHED */
109     break;
110     default:
111     printf("Invalid Option: -%c\n", c);
112     break;
113     }
114     }
115    
116     if (flag & FLAG_MD5)
117     {
118     if (length == 0)
119     length = 8;
120     if (flag & FLAG_SALT)
121     salt = make_md5_salt_para(saltpara);
122     else
123     salt = make_md5_salt(length);
124     }
125     else if (flag & FLAG_BLOWFISH)
126     {
127     if (length == 0)
128     length = 22;
129     if (flag & FLAG_SALT)
130     salt = make_bf_salt_para(rounds, saltpara);
131     else
132     salt = make_bf_salt(rounds, length);
133     }
134     else if (flag & FLAG_EXT)
135     {
136     /* XXX - rounds needs to be done */
137     if (flag & FLAG_SALT)
138     {
139     if ((strlen(saltpara) == 4))
140     {
141     salt = make_ext_salt_para(rounds, saltpara);
142     }
143     else
144     {
145     printf("Invalid salt, please enter 4 alphanumeric characters\n");
146     exit(1);
147     }
148     }
149     else
150     {
151     salt = make_ext_salt(rounds);
152     }
153     }
154     else if (flag & FLAG_RAW)
155     {
156     salt = saltpara;
157     }
158     else /* Default to DES */
159     {
160     if (flag & FLAG_SALT)
161     {
162     if ((strlen(saltpara) == 2))
163     {
164     salt = saltpara;
165     }
166     else
167     {
168     printf("Invalid salt, please enter 2 alphanumeric characters\n");
169     exit(1);
170     }
171     }
172     else
173     {
174     salt = make_des_salt();
175     }
176     }
177    
178     if (flag & FLAG_PASS)
179     {
180     if (!plaintext)
181     printf("Please enter a valid password\n");
182     }
183     else
184     {
185     plaintext = getpass("plaintext: ");
186     }
187    
188     printf("%s\n", crypt(plaintext, salt));
189     return 0;
190     }
191    
192     static char *make_des_salt(void)
193     {
194     static char salt[3];
195     generate_random_salt(salt, 2);
196     salt[2] = '\0';
197     return salt;
198     }
199    
200     static char *int_to_base64(int value)
201     {
202     static char buf[5];
203     int i;
204    
205     for (i = 0; i < 4; i++)
206     {
207     buf[i] = saltChars[value & 63];
208     value >>= 6; /* Right shifting 6 places is the same as dividing by 64 */
209     }
210    
211     buf[i] = '\0'; /* not REALLY needed as it's static, and thus initialized
212     ** to \0.
213     */
214     return buf;
215     }
216    
217     static char *make_ext_salt(int rounds)
218     {
219     static char salt[10];
220    
221     sprintf(salt, "_%s", int_to_base64(rounds));
222     generate_random_salt(&salt[5], 4);
223     salt[9] = '\0';
224     return salt;
225     }
226    
227     static char *make_ext_salt_para(int rounds, char *saltpara)
228     {
229     static char salt[10];
230    
231     sprintf(salt, "_%s%s", int_to_base64(rounds), saltpara);
232     return salt;
233     }
234    
235     static char *make_md5_salt_para(char *saltpara)
236     {
237     static char salt[21];
238     if (saltpara && (strlen(saltpara) <= 16))
239     {
240     /* sprintf used because of portability requirements, the length
241     ** is checked above, so it should not be too much of a concern
242     */
243     sprintf(salt, "$1$%s$", saltpara);
244     return salt;
245     }
246     printf("Invalid Salt, please use up to 16 random alphanumeric characters\n");
247     exit(1);
248    
249     /* NOT REACHED */
250     return NULL;
251     }
252    
253     static char *make_md5_salt(int length)
254     {
255     static char salt[21];
256     if (length > 16)
257     {
258     printf("MD5 salt length too long\n");
259     exit(0);
260     }
261     salt[0] = '$';
262     salt[1] = '1';
263     salt[2] = '$';
264     generate_random_salt(&salt[3], length);
265     salt[length+3] = '$';
266     salt[length+4] = '\0';
267     return salt;
268     }
269    
270     static char *make_bf_salt_para(int rounds, char *saltpara)
271     {
272     static char salt[31];
273     char tbuf[3];
274     if (saltpara && (strlen(saltpara) <= 22))
275     {
276     /* sprintf used because of portability requirements, the length
277     ** is checked above, so it should not be too much of a concern
278     */
279     sprintf(tbuf, "%02d", rounds);
280     sprintf(salt, "$2a$%s$%s$", tbuf, saltpara);
281     return salt;
282     }
283     printf("Invalid Salt, please use up to 22 random alphanumeric characters\n");
284     exit(1);
285    
286     /* NOT REACHED */
287     return NULL;
288     }
289    
290     static char *make_bf_salt(int rounds, int length)
291     {
292     static char salt[31];
293     char tbuf[3];
294     if (length > 22)
295     {
296     printf("BlowFish salt length too long\n");
297     exit(0);
298     }
299     sprintf(tbuf, "%02d", rounds);
300     sprintf(salt, "$2a$%s$", tbuf);
301     generate_random_salt(&salt[7], length);
302     salt[length+7] = '$';
303     salt[length+8] = '\0';
304     return salt;
305     }
306    
307     static char *generate_poor_salt(char *salt, int length)
308     {
309     int i;
310     srandom(time(NULL));
311     for(i = 0; i < length; i++)
312     {
313     salt[i] = saltChars[random() % 64];
314     }
315     return(salt);
316     }
317    
318     static char *generate_random_salt(char *salt, int length)
319     {
320     char *buf;
321     int fd, i;
322     if((fd = open("/dev/random", O_RDONLY)) < 0)
323     {
324     return(generate_poor_salt(salt, length));
325     }
326     buf = calloc(1, length);
327     if(read(fd, buf, length) != length)
328     {
329     free(buf);
330     return(generate_poor_salt(salt, length));
331     }
332    
333     for(i = 0; i < length; i++)
334     {
335     salt[i] = saltChars[abs(buf[i]) % 64];
336     }
337     free(buf);
338     return(salt);
339     }
340    
341     static void full_usage(void)
342     {
343     printf("mkpasswd [-m|-d|-b|-e] [-l saltlength] [-r rounds] [-s salt] [-p plaintext]\n");
344     printf(" [-R rawsalt]\n");
345     printf("-m Generate an MD5 password\n");
346     printf("-d Generate a DES password\n");
347     printf("-b Generate a BlowFish password\n");
348     printf("-e Generate an Extended DES password\n");
349     printf("-l Specify a length for a random MD5 or BlowFish salt\n");
350     printf("-r Specify a number of rounds for a BlowFish or Extended DES password\n");
351     printf(" BlowFish: default 4, no more than 6 recommended\n");
352     printf(" Extended DES: default 25\n");
353     printf("-s Specify a salt, 2 alphanumeric characters for DES, up to 16 for MD5,\n");
354     printf(" up to 22 for BlowFish, and 4 for Extended DES\n");
355     printf("-R Specify a raw salt passed directly to crypt()\n");
356     printf("-p Specify a plaintext password to use\n");
357     printf("Example: mkpasswd -m -s 3dr -p test\n");
358     exit(0);
359     }
360    
361     static void brief_usage(void)
362     {
363     printf("mkpasswd - password hash generator\n");
364     printf("Standard DES: mkpasswd [-d] [-s salt] [-p plaintext]\n");
365     printf("Extended DES: mkpasswd -e [-r rounds] [-s salt] [-p plaintext]\n");
366     printf(" MD5: mkpasswd -m [-l saltlength] [-s salt] [-p plaintext]\n");
367     printf(" BlowFish: mkpasswd -b [-r rounds] [-l saltlength] [-s salt]\n");
368     printf(" [-p plaintext]\n");
369     printf(" Raw: mkpasswd -R <rawsalt> [-p plaintext]\n");
370     printf("Use -h for full usage\n");
371     exit(0);
372     }

Properties

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