Deleted Added
full compact
passwd.c (59191) passwd.c (68651)
1/* apps/passwd.c */
2
3#if defined NO_MD5 || defined CHARSET_EBCDIC
1/* apps/passwd.c */
2
3#if defined NO_MD5 || defined CHARSET_EBCDIC
4# define NO_APR1
4# define NO_MD5CRYPT_1
5#endif
6
5#endif
6
7#if !defined(NO_DES) || !defined(NO_APR1)
7#if !defined(NO_DES) || !defined(NO_MD5CRYPT_1)
8
9#include <assert.h>
10#include <string.h>
11
12#include "apps.h"
13
14#include <openssl/bio.h>
15#include <openssl/err.h>
16#include <openssl/evp.h>
17#include <openssl/rand.h>
18
19#ifndef NO_DES
20# include <openssl/des.h>
21#endif
8
9#include <assert.h>
10#include <string.h>
11
12#include "apps.h"
13
14#include <openssl/bio.h>
15#include <openssl/err.h>
16#include <openssl/evp.h>
17#include <openssl/rand.h>
18
19#ifndef NO_DES
20# include <openssl/des.h>
21#endif
22#ifndef NO_APR1
22#ifndef NO_MD5CRYPT_1
23# include <openssl/md5.h>
24#endif
25
26
27#undef PROG
28#define PROG passwd_main
29
30

--- 6 unchanged lines hidden (view full) ---

37 0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
38 0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
39 0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
40 0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
41};
42
43static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
44 char *passwd, BIO *out, int quiet, int table, int reverse,
23# include <openssl/md5.h>
24#endif
25
26
27#undef PROG
28#define PROG passwd_main
29
30

--- 6 unchanged lines hidden (view full) ---

37 0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
38 0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
39 0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
40 0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
41};
42
43static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
44 char *passwd, BIO *out, int quiet, int table, int reverse,
45 size_t pw_maxlen, int usecrypt, int useapr1);
45 size_t pw_maxlen, int usecrypt, int use1, int useapr1);
46
46
47/* -crypt - standard Unix password algorithm (default, only choice)
48 * -apr1 - MD5-based password algorithm
47/* -crypt - standard Unix password algorithm (default)
48 * -1 - MD5-based password algorithm
49 * -apr1 - MD5-based password algorithm, Apache variant
49 * -salt string - salt
50 * -in file - read passwords from file
51 * -stdin - read passwords from stdin
52 * -quiet - no warnings
53 * -table - format output as table
54 * -reverse - switch table columns
55 */
56
57int MAIN(int, char **);
58
59int MAIN(int argc, char **argv)
60 {
61 int ret = 1;
62 char *infile = NULL;
63 int in_stdin = 0;
64 char *salt = NULL, *passwd = NULL, **passwds = NULL;
65 char *salt_malloc = NULL, *passwd_malloc = NULL;
50 * -salt string - salt
51 * -in file - read passwords from file
52 * -stdin - read passwords from stdin
53 * -quiet - no warnings
54 * -table - format output as table
55 * -reverse - switch table columns
56 */
57
58int MAIN(int, char **);
59
60int MAIN(int argc, char **argv)
61 {
62 int ret = 1;
63 char *infile = NULL;
64 int in_stdin = 0;
65 char *salt = NULL, *passwd = NULL, **passwds = NULL;
66 char *salt_malloc = NULL, *passwd_malloc = NULL;
67 size_t passwd_malloc_size = 0;
66 int pw_source_defined = 0;
67 BIO *in = NULL, *out = NULL;
68 int i, badopt, opt_done;
69 int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
68 int pw_source_defined = 0;
69 BIO *in = NULL, *out = NULL;
70 int i, badopt, opt_done;
71 int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
70 int usecrypt = 0, useapr1 = 0;
72 int usecrypt = 0, use1 = 0, useapr1 = 0;
71 size_t pw_maxlen = 0;
72
73 apps_startup();
74
75 if (bio_err == NULL)
76 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
77 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
78 out = BIO_new(BIO_s_file());
79 if (out == NULL)
80 goto err;
81 BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
73 size_t pw_maxlen = 0;
74
75 apps_startup();
76
77 if (bio_err == NULL)
78 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
79 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
80 out = BIO_new(BIO_s_file());
81 if (out == NULL)
82 goto err;
83 BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
84#ifdef VMS
85 {
86 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
87 out = BIO_push(tmpbio, out);
88 }
89#endif
82
83 badopt = 0, opt_done = 0;
84 i = 0;
85 while (!badopt && !opt_done && argv[++i] != NULL)
86 {
87 if (strcmp(argv[i], "-crypt") == 0)
88 usecrypt = 1;
90
91 badopt = 0, opt_done = 0;
92 i = 0;
93 while (!badopt && !opt_done && argv[++i] != NULL)
94 {
95 if (strcmp(argv[i], "-crypt") == 0)
96 usecrypt = 1;
97 else if (strcmp(argv[i], "-1") == 0)
98 use1 = 1;
89 else if (strcmp(argv[i], "-apr1") == 0)
90 useapr1 = 1;
91 else if (strcmp(argv[i], "-salt") == 0)
92 {
93 if ((argv[i+1] != NULL) && (salt == NULL))
94 {
95 passed_salt = 1;
96 salt = argv[++i];

--- 35 unchanged lines hidden (view full) ---

132 pw_source_defined = 1;
133 passwds = &argv[i];
134 opt_done = 1;
135 }
136 else
137 badopt = 1;
138 }
139
99 else if (strcmp(argv[i], "-apr1") == 0)
100 useapr1 = 1;
101 else if (strcmp(argv[i], "-salt") == 0)
102 {
103 if ((argv[i+1] != NULL) && (salt == NULL))
104 {
105 passed_salt = 1;
106 salt = argv[++i];

--- 35 unchanged lines hidden (view full) ---

142 pw_source_defined = 1;
143 passwds = &argv[i];
144 opt_done = 1;
145 }
146 else
147 badopt = 1;
148 }
149
140 if (!usecrypt && !useapr1) /* use default */
150 if (!usecrypt && !use1 && !useapr1) /* use default */
141 usecrypt = 1;
151 usecrypt = 1;
142 if (usecrypt + useapr1 > 1) /* conflict */
152 if (usecrypt + use1 + useapr1 > 1) /* conflict */
143 badopt = 1;
144
145 /* reject unsupported algorithms */
146#ifdef NO_DES
147 if (usecrypt) badopt = 1;
148#endif
153 badopt = 1;
154
155 /* reject unsupported algorithms */
156#ifdef NO_DES
157 if (usecrypt) badopt = 1;
158#endif
149#ifdef NO_APR1
150 if (useapr1) badopt = 1;
159#ifdef NO_MD5CRYPT_1
160 if (use1 || useapr1) badopt = 1;
151#endif
152
153 if (badopt)
154 {
155 BIO_printf(bio_err, "Usage: passwd [options] [passwords]\n");
156 BIO_printf(bio_err, "where options are\n");
157#ifndef NO_DES
158 BIO_printf(bio_err, "-crypt standard Unix password algorithm (default)\n");
159#endif
161#endif
162
163 if (badopt)
164 {
165 BIO_printf(bio_err, "Usage: passwd [options] [passwords]\n");
166 BIO_printf(bio_err, "where options are\n");
167#ifndef NO_DES
168 BIO_printf(bio_err, "-crypt standard Unix password algorithm (default)\n");
169#endif
160#ifndef NO_APR1
161 BIO_printf(bio_err, "-apr1 MD5-based password algorithm\n");
170#ifndef NO_MD5CRYPT_1
171 BIO_printf(bio_err, "-1 MD5-based password algorithm\n");
172 BIO_printf(bio_err, "-apr1 MD5-based password algorithm, Apache variant\n");
162#endif
163 BIO_printf(bio_err, "-salt string use provided salt\n");
164 BIO_printf(bio_err, "-in file read passwords from file\n");
165 BIO_printf(bio_err, "-stdin read passwords from stdin\n");
166 BIO_printf(bio_err, "-quiet no warnings\n");
167 BIO_printf(bio_err, "-table format output as table\n");
168 BIO_printf(bio_err, "-reverse switch table columns\n");
169

--- 15 unchanged lines hidden (view full) ---

185 {
186 assert(in_stdin);
187 BIO_set_fp(in, stdin, BIO_NOCLOSE);
188 }
189 }
190
191 if (usecrypt)
192 pw_maxlen = 8;
173#endif
174 BIO_printf(bio_err, "-salt string use provided salt\n");
175 BIO_printf(bio_err, "-in file read passwords from file\n");
176 BIO_printf(bio_err, "-stdin read passwords from stdin\n");
177 BIO_printf(bio_err, "-quiet no warnings\n");
178 BIO_printf(bio_err, "-table format output as table\n");
179 BIO_printf(bio_err, "-reverse switch table columns\n");
180

--- 15 unchanged lines hidden (view full) ---

196 {
197 assert(in_stdin);
198 BIO_set_fp(in, stdin, BIO_NOCLOSE);
199 }
200 }
201
202 if (usecrypt)
203 pw_maxlen = 8;
193 else if (useapr1)
204 else if (use1 || useapr1)
194 pw_maxlen = 256; /* arbitrary limit, should be enough for most passwords */
195
196 if (passwds == NULL)
197 {
198 /* no passwords on the command line */
205 pw_maxlen = 256; /* arbitrary limit, should be enough for most passwords */
206
207 if (passwds == NULL)
208 {
209 /* no passwords on the command line */
199 passwd = passwd_malloc = Malloc(pw_maxlen + 1);
210
211 passwd_malloc_size = pw_maxlen + 2;
212 /* longer than necessary so that we can warn about truncation */
213 passwd = passwd_malloc = OPENSSL_malloc(passwd_malloc_size);
200 if (passwd_malloc == NULL)
201 goto err;
202 }
203
204 if ((in == NULL) && (passwds == NULL))
205 {
206 /* build a null-terminated list */
207 static char *passwds_static[2] = {NULL, NULL};
208
209 passwds = passwds_static;
210 if (in == NULL)
214 if (passwd_malloc == NULL)
215 goto err;
216 }
217
218 if ((in == NULL) && (passwds == NULL))
219 {
220 /* build a null-terminated list */
221 static char *passwds_static[2] = {NULL, NULL};
222
223 passwds = passwds_static;
224 if (in == NULL)
211 if (EVP_read_pw_string(passwd_malloc, pw_maxlen + 1, "Password: ", 0) != 0)
225 if (EVP_read_pw_string(passwd_malloc, passwd_malloc_size, "Password: ", 0) != 0)
212 goto err;
213 passwds[0] = passwd_malloc;
214 }
215
216 if (in == NULL)
217 {
218 assert(passwds != NULL);
219 assert(*passwds != NULL);
220
221 do /* loop over list of passwords */
222 {
223 passwd = *passwds++;
224 if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
226 goto err;
227 passwds[0] = passwd_malloc;
228 }
229
230 if (in == NULL)
231 {
232 assert(passwds != NULL);
233 assert(*passwds != NULL);
234
235 do /* loop over list of passwords */
236 {
237 passwd = *passwds++;
238 if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
225 quiet, table, reverse, pw_maxlen, usecrypt, useapr1))
239 quiet, table, reverse, pw_maxlen, usecrypt, use1, useapr1))
226 goto err;
227 }
228 while (*passwds != NULL);
229 }
230 else
231 /* in != NULL */
232 {
233 int done;

--- 12 unchanged lines hidden (view full) ---

246 /* ignore rest of line */
247 char trash[BUFSIZ];
248 do
249 r = BIO_gets(in, trash, sizeof trash);
250 while ((r > 0) && (!strchr(trash, '\n')));
251 }
252
253 if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
240 goto err;
241 }
242 while (*passwds != NULL);
243 }
244 else
245 /* in != NULL */
246 {
247 int done;

--- 12 unchanged lines hidden (view full) ---

260 /* ignore rest of line */
261 char trash[BUFSIZ];
262 do
263 r = BIO_gets(in, trash, sizeof trash);
264 while ((r > 0) && (!strchr(trash, '\n')));
265 }
266
267 if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
254 quiet, table, reverse, pw_maxlen, usecrypt, useapr1))
268 quiet, table, reverse, pw_maxlen, usecrypt, use1, useapr1))
255 goto err;
256 }
257 done = (r <= 0);
258 }
259 while (!done);
260 }
261
262err:
263 ERR_print_errors(bio_err);
264 if (salt_malloc)
269 goto err;
270 }
271 done = (r <= 0);
272 }
273 while (!done);
274 }
275
276err:
277 ERR_print_errors(bio_err);
278 if (salt_malloc)
265 Free(salt_malloc);
279 OPENSSL_free(salt_malloc);
266 if (passwd_malloc)
280 if (passwd_malloc)
267 Free(passwd_malloc);
281 OPENSSL_free(passwd_malloc);
268 if (in)
269 BIO_free(in);
270 if (out)
282 if (in)
283 BIO_free(in);
284 if (out)
271 BIO_free(out);
285 BIO_free_all(out);
272 EXIT(ret);
273 }
274
275
286 EXIT(ret);
287 }
288
289
276#ifndef NO_APR1
277/* MD5-based password algorithm compatible to the one found in Apache
278 * (should probably be available as a library function;
279 * then the static buffer would not be acceptable) */
280static char *apr1_crypt(const char *passwd, const char *salt)
290#ifndef NO_MD5CRYPT_1
291/* MD5-based password algorithm (should probably be available as a library
292 * function; then the static buffer would not be acceptable).
293 * For magic string "1", this should be compatible to the MD5-based BSD
294 * password algorithm.
295 * For 'magic' string "apr1", this is compatible to the MD5-based Apache
296 * password algorithm.
297 * (Apparently, the Apache password algorithm is identical except that the
298 * 'magic' string was changed -- the laziest application of the NIH principle
299 * I've ever encountered.)
300 */
301static char *md5crypt(const char *passwd, const char *magic, const char *salt)
281 {
282 static char out_buf[6 + 9 + 24 + 2]; /* "$apr1$..salt..$.......md5hash..........\0" */
283 unsigned char buf[MD5_DIGEST_LENGTH];
284 char *salt_out;
285 int n, i;
286 MD5_CTX md;
287 size_t passwd_len, salt_len;
288
289 passwd_len = strlen(passwd);
302 {
303 static char out_buf[6 + 9 + 24 + 2]; /* "$apr1$..salt..$.......md5hash..........\0" */
304 unsigned char buf[MD5_DIGEST_LENGTH];
305 char *salt_out;
306 int n, i;
307 MD5_CTX md;
308 size_t passwd_len, salt_len;
309
310 passwd_len = strlen(passwd);
290 strcpy(out_buf, "$apr1$");
311 out_buf[0] = '$';
312 out_buf[1] = 0;
313 assert(strlen(magic) <= 4); /* "1" or "apr1" */
314 strncat(out_buf, magic, 4);
315 strncat(out_buf, "$", 1);
291 strncat(out_buf, salt, 8);
292 assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
293 salt_out = out_buf + 6;
294 salt_len = strlen(salt_out);
295 assert(salt_len <= 8);
296
297 MD5_Init(&md);
298 MD5_Update(&md, passwd, passwd_len);
316 strncat(out_buf, salt, 8);
317 assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
318 salt_out = out_buf + 6;
319 salt_len = strlen(salt_out);
320 assert(salt_len <= 8);
321
322 MD5_Init(&md);
323 MD5_Update(&md, passwd, passwd_len);
299 MD5_Update(&md, "$apr1$", 6);
324 MD5_Update(&md, "$", 1);
325 MD5_Update(&md, magic, strlen(magic));
326 MD5_Update(&md, "$", 1);
300 MD5_Update(&md, salt_out, salt_len);
301
302 {
303 MD5_CTX md2;
304
305 MD5_Init(&md2);
306 MD5_Update(&md2, passwd, passwd_len);
307 MD5_Update(&md2, salt_out, salt_len);

--- 67 unchanged lines hidden (view full) ---

375
376 return out_buf;
377 }
378#endif
379
380
381static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
382 char *passwd, BIO *out, int quiet, int table, int reverse,
327 MD5_Update(&md, salt_out, salt_len);
328
329 {
330 MD5_CTX md2;
331
332 MD5_Init(&md2);
333 MD5_Update(&md2, passwd, passwd_len);
334 MD5_Update(&md2, salt_out, salt_len);

--- 67 unchanged lines hidden (view full) ---

402
403 return out_buf;
404 }
405#endif
406
407
408static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
409 char *passwd, BIO *out, int quiet, int table, int reverse,
383 size_t pw_maxlen, int usecrypt, int useapr1)
410 size_t pw_maxlen, int usecrypt, int use1, int useapr1)
384 {
385 char *hash = NULL;
386
387 assert(salt_p != NULL);
388 assert(salt_malloc_p != NULL);
389
390 /* first make sure we have a salt */
391 if (!passed_salt)
392 {
393#ifndef NO_DES
394 if (usecrypt)
395 {
396 if (*salt_malloc_p == NULL)
397 {
411 {
412 char *hash = NULL;
413
414 assert(salt_p != NULL);
415 assert(salt_malloc_p != NULL);
416
417 /* first make sure we have a salt */
418 if (!passed_salt)
419 {
420#ifndef NO_DES
421 if (usecrypt)
422 {
423 if (*salt_malloc_p == NULL)
424 {
398 *salt_p = *salt_malloc_p = Malloc(3);
425 *salt_p = *salt_malloc_p = OPENSSL_malloc(3);
399 if (*salt_malloc_p == NULL)
400 goto err;
401 }
402 if (RAND_pseudo_bytes((unsigned char *)*salt_p, 2) < 0)
403 goto err;
404 (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
405 (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
406 (*salt_p)[2] = 0;
407#ifdef CHARSET_EBCDIC
408 ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert
409 * back to ASCII */
410#endif
411 }
412#endif /* !NO_DES */
413
426 if (*salt_malloc_p == NULL)
427 goto err;
428 }
429 if (RAND_pseudo_bytes((unsigned char *)*salt_p, 2) < 0)
430 goto err;
431 (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
432 (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
433 (*salt_p)[2] = 0;
434#ifdef CHARSET_EBCDIC
435 ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert
436 * back to ASCII */
437#endif
438 }
439#endif /* !NO_DES */
440
414#ifndef NO_APR1
415 if (useapr1)
441#ifndef NO_MD5CRYPT_1
442 if (use1 || useapr1)
416 {
417 int i;
418
419 if (*salt_malloc_p == NULL)
420 {
443 {
444 int i;
445
446 if (*salt_malloc_p == NULL)
447 {
421 *salt_p = *salt_malloc_p = Malloc(9);
448 *salt_p = *salt_malloc_p = OPENSSL_malloc(9);
422 if (*salt_malloc_p == NULL)
423 goto err;
424 }
425 if (RAND_pseudo_bytes((unsigned char *)*salt_p, 8) < 0)
426 goto err;
427
428 for (i = 0; i < 8; i++)
429 (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
430 (*salt_p)[8] = 0;
431 }
449 if (*salt_malloc_p == NULL)
450 goto err;
451 }
452 if (RAND_pseudo_bytes((unsigned char *)*salt_p, 8) < 0)
453 goto err;
454
455 for (i = 0; i < 8; i++)
456 (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
457 (*salt_p)[8] = 0;
458 }
432#endif /* !NO_APR1 */
459#endif /* !NO_MD5CRYPT_1 */
433 }
434
435 assert(*salt_p != NULL);
436
437 /* truncate password if necessary */
438 if ((strlen(passwd) > pw_maxlen))
439 {
440 if (!quiet)
441 BIO_printf(bio_err, "Warning: truncating password to %u characters\n", pw_maxlen);
442 passwd[pw_maxlen] = 0;
443 }
444 assert(strlen(passwd) <= pw_maxlen);
445
446 /* now compute password hash */
447#ifndef NO_DES
448 if (usecrypt)
449 hash = des_crypt(passwd, *salt_p);
450#endif
460 }
461
462 assert(*salt_p != NULL);
463
464 /* truncate password if necessary */
465 if ((strlen(passwd) > pw_maxlen))
466 {
467 if (!quiet)
468 BIO_printf(bio_err, "Warning: truncating password to %u characters\n", pw_maxlen);
469 passwd[pw_maxlen] = 0;
470 }
471 assert(strlen(passwd) <= pw_maxlen);
472
473 /* now compute password hash */
474#ifndef NO_DES
475 if (usecrypt)
476 hash = des_crypt(passwd, *salt_p);
477#endif
451#ifndef NO_APR1
452 if (useapr1)
453 hash = apr1_crypt(passwd, *salt_p);
478#ifndef NO_MD5CRYPT_1
479 if (use1 || useapr1)
480 hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p);
454#endif
455 assert(hash != NULL);
456
457 if (table && !reverse)
458 BIO_printf(out, "%s\t%s\n", passwd, hash);
459 else if (table && reverse)
460 BIO_printf(out, "%s\t%s\n", hash, passwd);
461 else

--- 14 unchanged lines hidden ---
481#endif
482 assert(hash != NULL);
483
484 if (table && !reverse)
485 BIO_printf(out, "%s\t%s\n", passwd, hash);
486 else if (table && reverse)
487 BIO_printf(out, "%s\t%s\n", hash, passwd);
488 else

--- 14 unchanged lines hidden ---