ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/tools/mkpasswd.c
Revision: 6589
Committed: Wed Oct 21 18:44:03 2015 UTC (8 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 8266 byte(s)
Log Message:
- mkpasswd.c: remove MD5 support as well; reformatting
- Update README.mkpasswd

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

Properties

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