159191Skris/* apps/passwd.c */ 259191Skris 3109998Smarkm#if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC 468651Skris# define NO_MD5CRYPT_1 559191Skris#endif 659191Skris 7109998Smarkm#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1) 859191Skris 9280297Sjkim# include <assert.h> 10280297Sjkim# include <string.h> 1159191Skris 12280297Sjkim# include "apps.h" 1359191Skris 14280297Sjkim# include <openssl/bio.h> 15280297Sjkim# include <openssl/err.h> 16280297Sjkim# include <openssl/evp.h> 17280297Sjkim# include <openssl/rand.h> 18280297Sjkim# ifndef OPENSSL_NO_DES 19280297Sjkim# include <openssl/des.h> 20280297Sjkim# endif 21280297Sjkim# ifndef NO_MD5CRYPT_1 22280297Sjkim# include <openssl/md5.h> 23280297Sjkim# endif 2459191Skris 25280297Sjkim# undef PROG 26280297Sjkim# define PROG passwd_main 2759191Skris 28280297Sjkimstatic unsigned const char cov_2char[64] = { 29280297Sjkim /* from crypto/des/fcrypt.c */ 30280297Sjkim 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 31280297Sjkim 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 32280297Sjkim 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 33280297Sjkim 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 34280297Sjkim 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 35280297Sjkim 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 36280297Sjkim 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 37280297Sjkim 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A 3859191Skris}; 3959191Skris 4059191Skrisstatic int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, 41280297Sjkim char *passwd, BIO *out, int quiet, int table, 42280297Sjkim int reverse, size_t pw_maxlen, int usecrypt, int use1, 43280297Sjkim int useapr1); 4459191Skris 45280297Sjkim/*- 46280297Sjkim * -crypt - standard Unix password algorithm (default) 4768651Skris * -1 - MD5-based password algorithm 4868651Skris * -apr1 - MD5-based password algorithm, Apache variant 4959191Skris * -salt string - salt 5059191Skris * -in file - read passwords from file 5159191Skris * -stdin - read passwords from stdin 52109998Smarkm * -noverify - never verify when reading password from terminal 5359191Skris * -quiet - no warnings 5459191Skris * -table - format output as table 5559191Skris * -reverse - switch table columns 5659191Skris */ 5759191Skris 5859191Skrisint MAIN(int, char **); 5959191Skris 6059191Skrisint MAIN(int argc, char **argv) 61280297Sjkim{ 62280297Sjkim int ret = 1; 63280297Sjkim char *infile = NULL; 64280297Sjkim int in_stdin = 0; 65280297Sjkim int in_noverify = 0; 66280297Sjkim char *salt = NULL, *passwd = NULL, **passwds = NULL; 67280297Sjkim char *salt_malloc = NULL, *passwd_malloc = NULL; 68280297Sjkim size_t passwd_malloc_size = 0; 69280297Sjkim int pw_source_defined = 0; 70280297Sjkim BIO *in = NULL, *out = NULL; 71280297Sjkim int i, badopt, opt_done; 72280297Sjkim int passed_salt = 0, quiet = 0, table = 0, reverse = 0; 73280297Sjkim int usecrypt = 0, use1 = 0, useapr1 = 0; 74280297Sjkim size_t pw_maxlen = 0; 7559191Skris 76280297Sjkim apps_startup(); 7759191Skris 78280297Sjkim if (bio_err == NULL) 79280297Sjkim if ((bio_err = BIO_new(BIO_s_file())) != NULL) 80280297Sjkim BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 81109998Smarkm 82280297Sjkim if (!load_config(bio_err, NULL)) 83280297Sjkim goto err; 84280297Sjkim out = BIO_new(BIO_s_file()); 85280297Sjkim if (out == NULL) 86280297Sjkim goto err; 87280297Sjkim BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); 88280297Sjkim# ifdef OPENSSL_SYS_VMS 89280297Sjkim { 90280297Sjkim BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 91280297Sjkim out = BIO_push(tmpbio, out); 92280297Sjkim } 93280297Sjkim# endif 9459191Skris 95280297Sjkim badopt = 0, opt_done = 0; 96280297Sjkim i = 0; 97280297Sjkim while (!badopt && !opt_done && argv[++i] != NULL) { 98280297Sjkim if (strcmp(argv[i], "-crypt") == 0) 99280297Sjkim usecrypt = 1; 100280297Sjkim else if (strcmp(argv[i], "-1") == 0) 101280297Sjkim use1 = 1; 102280297Sjkim else if (strcmp(argv[i], "-apr1") == 0) 103280297Sjkim useapr1 = 1; 104280297Sjkim else if (strcmp(argv[i], "-salt") == 0) { 105280297Sjkim if ((argv[i + 1] != NULL) && (salt == NULL)) { 106280297Sjkim passed_salt = 1; 107280297Sjkim salt = argv[++i]; 108280297Sjkim } else 109280297Sjkim badopt = 1; 110280297Sjkim } else if (strcmp(argv[i], "-in") == 0) { 111280297Sjkim if ((argv[i + 1] != NULL) && !pw_source_defined) { 112280297Sjkim pw_source_defined = 1; 113280297Sjkim infile = argv[++i]; 114280297Sjkim } else 115280297Sjkim badopt = 1; 116280297Sjkim } else if (strcmp(argv[i], "-stdin") == 0) { 117280297Sjkim if (!pw_source_defined) { 118280297Sjkim pw_source_defined = 1; 119280297Sjkim in_stdin = 1; 120280297Sjkim } else 121280297Sjkim badopt = 1; 122280297Sjkim } else if (strcmp(argv[i], "-noverify") == 0) 123280297Sjkim in_noverify = 1; 124280297Sjkim else if (strcmp(argv[i], "-quiet") == 0) 125280297Sjkim quiet = 1; 126280297Sjkim else if (strcmp(argv[i], "-table") == 0) 127280297Sjkim table = 1; 128280297Sjkim else if (strcmp(argv[i], "-reverse") == 0) 129280297Sjkim reverse = 1; 130280297Sjkim else if (argv[i][0] == '-') 131280297Sjkim badopt = 1; 132280297Sjkim else if (!pw_source_defined) 133280297Sjkim /* non-option arguments, use as passwords */ 134280297Sjkim { 135280297Sjkim pw_source_defined = 1; 136280297Sjkim passwds = &argv[i]; 137280297Sjkim opt_done = 1; 138280297Sjkim } else 139280297Sjkim badopt = 1; 140280297Sjkim } 14159191Skris 142280297Sjkim if (!usecrypt && !use1 && !useapr1) /* use default */ 143280297Sjkim usecrypt = 1; 144280297Sjkim if (usecrypt + use1 + useapr1 > 1) /* conflict */ 145280297Sjkim badopt = 1; 14659191Skris 147280297Sjkim /* reject unsupported algorithms */ 148280297Sjkim# ifdef OPENSSL_NO_DES 149280297Sjkim if (usecrypt) 150280297Sjkim badopt = 1; 151280297Sjkim# endif 152280297Sjkim# ifdef NO_MD5CRYPT_1 153280297Sjkim if (use1 || useapr1) 154280297Sjkim badopt = 1; 155280297Sjkim# endif 15659191Skris 157280297Sjkim if (badopt) { 158280297Sjkim BIO_printf(bio_err, "Usage: passwd [options] [passwords]\n"); 159280297Sjkim BIO_printf(bio_err, "where options are\n"); 160280297Sjkim# ifndef OPENSSL_NO_DES 161280297Sjkim BIO_printf(bio_err, 162280297Sjkim "-crypt standard Unix password algorithm (default)\n"); 163280297Sjkim# endif 164280297Sjkim# ifndef NO_MD5CRYPT_1 165280297Sjkim BIO_printf(bio_err, 166280297Sjkim "-1 MD5-based password algorithm\n"); 167280297Sjkim BIO_printf(bio_err, 168280297Sjkim "-apr1 MD5-based password algorithm, Apache variant\n"); 169280297Sjkim# endif 170280297Sjkim BIO_printf(bio_err, "-salt string use provided salt\n"); 171280297Sjkim BIO_printf(bio_err, "-in file read passwords from file\n"); 172280297Sjkim BIO_printf(bio_err, "-stdin read passwords from stdin\n"); 173280297Sjkim BIO_printf(bio_err, 174280297Sjkim "-noverify never verify when reading password from terminal\n"); 175280297Sjkim BIO_printf(bio_err, "-quiet no warnings\n"); 176280297Sjkim BIO_printf(bio_err, "-table format output as table\n"); 177280297Sjkim BIO_printf(bio_err, "-reverse switch table columns\n"); 17859191Skris 179280297Sjkim goto err; 180280297Sjkim } 18159191Skris 182280297Sjkim if ((infile != NULL) || in_stdin) { 183280297Sjkim in = BIO_new(BIO_s_file()); 184280297Sjkim if (in == NULL) 185280297Sjkim goto err; 186280297Sjkim if (infile != NULL) { 187280297Sjkim assert(in_stdin == 0); 188280297Sjkim if (BIO_read_filename(in, infile) <= 0) 189280297Sjkim goto err; 190280297Sjkim } else { 191280297Sjkim assert(in_stdin); 192280297Sjkim BIO_set_fp(in, stdin, BIO_NOCLOSE); 193280297Sjkim } 194280297Sjkim } 19568651Skris 196280297Sjkim if (usecrypt) 197280297Sjkim pw_maxlen = 8; 198280297Sjkim else if (use1 || useapr1) 199280297Sjkim pw_maxlen = 256; /* arbitrary limit, should be enough for most 200280297Sjkim * passwords */ 20159191Skris 202280297Sjkim if (passwds == NULL) { 203280297Sjkim /* no passwords on the command line */ 20459191Skris 205280297Sjkim passwd_malloc_size = pw_maxlen + 2; 206280297Sjkim /* 207280297Sjkim * longer than necessary so that we can warn about truncation 208280297Sjkim */ 209280297Sjkim passwd = passwd_malloc = OPENSSL_malloc(passwd_malloc_size); 210280297Sjkim if (passwd_malloc == NULL) 211280297Sjkim goto err; 212280297Sjkim } 21359191Skris 214280297Sjkim if ((in == NULL) && (passwds == NULL)) { 215280297Sjkim /* build a null-terminated list */ 216280297Sjkim static char *passwds_static[2] = { NULL, NULL }; 21759191Skris 218280297Sjkim passwds = passwds_static; 219280297Sjkim if (in == NULL) 220280297Sjkim if (EVP_read_pw_string 221280297Sjkim (passwd_malloc, passwd_malloc_size, "Password: ", 222280297Sjkim !(passed_salt || in_noverify)) != 0) 223280297Sjkim goto err; 224280297Sjkim passwds[0] = passwd_malloc; 225280297Sjkim } 22659191Skris 227280297Sjkim if (in == NULL) { 228280297Sjkim assert(passwds != NULL); 229280297Sjkim assert(*passwds != NULL); 23059191Skris 231280297Sjkim do { /* loop over list of passwords */ 232280297Sjkim passwd = *passwds++; 233280297Sjkim if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out, 234280297Sjkim quiet, table, reverse, pw_maxlen, usecrypt, use1, 235280297Sjkim useapr1)) 236280297Sjkim goto err; 237280297Sjkim } 238280297Sjkim while (*passwds != NULL); 239280297Sjkim } else 240280297Sjkim /* in != NULL */ 241280297Sjkim { 242280297Sjkim int done; 243280297Sjkim 244280297Sjkim assert(passwd != NULL); 245280297Sjkim do { 246280297Sjkim int r = BIO_gets(in, passwd, pw_maxlen + 1); 247280297Sjkim if (r > 0) { 248280297Sjkim char *c = (strchr(passwd, '\n')); 249280297Sjkim if (c != NULL) 250280297Sjkim *c = 0; /* truncate at newline */ 251280297Sjkim else { 252280297Sjkim /* ignore rest of line */ 253280297Sjkim char trash[BUFSIZ]; 254280297Sjkim do 255331638Sjkim r = BIO_gets(in, trash, sizeof(trash)); 256280297Sjkim while ((r > 0) && (!strchr(trash, '\n'))); 257280297Sjkim } 258280297Sjkim 259280297Sjkim if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out, 260280297Sjkim quiet, table, reverse, pw_maxlen, usecrypt, 261280297Sjkim use1, useapr1)) 262280297Sjkim goto err; 263280297Sjkim } 264280297Sjkim done = (r <= 0); 265280297Sjkim } 266280297Sjkim while (!done); 267280297Sjkim } 268280297Sjkim ret = 0; 269280297Sjkim 270280297Sjkim err: 271280297Sjkim ERR_print_errors(bio_err); 272280297Sjkim if (salt_malloc) 273280297Sjkim OPENSSL_free(salt_malloc); 274280297Sjkim if (passwd_malloc) 275280297Sjkim OPENSSL_free(passwd_malloc); 276280297Sjkim if (in) 277280297Sjkim BIO_free(in); 278280297Sjkim if (out) 279280297Sjkim BIO_free_all(out); 280280297Sjkim apps_shutdown(); 281280297Sjkim OPENSSL_EXIT(ret); 282280297Sjkim} 283280297Sjkim 284280297Sjkim# ifndef NO_MD5CRYPT_1 285280297Sjkim/* 286280297Sjkim * MD5-based password algorithm (should probably be available as a library 287280297Sjkim * function; then the static buffer would not be acceptable). For magic 288280297Sjkim * string "1", this should be compatible to the MD5-based BSD password 289280297Sjkim * algorithm. For 'magic' string "apr1", this is compatible to the MD5-based 290280297Sjkim * Apache password algorithm. (Apparently, the Apache password algorithm is 291280297Sjkim * identical except that the 'magic' string was changed -- the laziest 292280297Sjkim * application of the NIH principle I've ever encountered.) 29368651Skris */ 29468651Skrisstatic char *md5crypt(const char *passwd, const char *magic, const char *salt) 295280297Sjkim{ 296280297Sjkim /* "$apr1$..salt..$.......md5hash..........\0" */ 297280297Sjkim static char out_buf[6 + 9 + 24 + 2]; 298280297Sjkim unsigned char buf[MD5_DIGEST_LENGTH]; 299280297Sjkim char *salt_out; 300280297Sjkim int n; 301280297Sjkim unsigned int i; 302280297Sjkim EVP_MD_CTX md, md2; 303280297Sjkim size_t passwd_len, salt_len; 30459191Skris 305280297Sjkim passwd_len = strlen(passwd); 306280297Sjkim out_buf[0] = '$'; 307280297Sjkim out_buf[1] = 0; 308280297Sjkim assert(strlen(magic) <= 4); /* "1" or "apr1" */ 309337982Sjkim BUF_strlcat(out_buf, magic, sizeof(out_buf)); 310337982Sjkim BUF_strlcat(out_buf, "$", sizeof(out_buf)); 311337982Sjkim BUF_strlcat(out_buf, salt, sizeof(out_buf)); 312280297Sjkim assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */ 313280297Sjkim salt_out = out_buf + 2 + strlen(magic); 314280297Sjkim salt_len = strlen(salt_out); 315280297Sjkim assert(salt_len <= 8); 31659191Skris 317280297Sjkim EVP_MD_CTX_init(&md); 318280297Sjkim EVP_DigestInit_ex(&md, EVP_md5(), NULL); 319280297Sjkim EVP_DigestUpdate(&md, passwd, passwd_len); 320280297Sjkim EVP_DigestUpdate(&md, "$", 1); 321280297Sjkim EVP_DigestUpdate(&md, magic, strlen(magic)); 322280297Sjkim EVP_DigestUpdate(&md, "$", 1); 323280297Sjkim EVP_DigestUpdate(&md, salt_out, salt_len); 32459191Skris 325280297Sjkim EVP_MD_CTX_init(&md2); 326280297Sjkim EVP_DigestInit_ex(&md2, EVP_md5(), NULL); 327280297Sjkim EVP_DigestUpdate(&md2, passwd, passwd_len); 328280297Sjkim EVP_DigestUpdate(&md2, salt_out, salt_len); 329280297Sjkim EVP_DigestUpdate(&md2, passwd, passwd_len); 330280297Sjkim EVP_DigestFinal_ex(&md2, buf, NULL); 33159191Skris 332331638Sjkim for (i = passwd_len; i > sizeof(buf); i -= sizeof(buf)) 333331638Sjkim EVP_DigestUpdate(&md, buf, sizeof(buf)); 334280297Sjkim EVP_DigestUpdate(&md, buf, i); 33559191Skris 336280297Sjkim n = passwd_len; 337280297Sjkim while (n) { 338280297Sjkim EVP_DigestUpdate(&md, (n & 1) ? "\0" : passwd, 1); 339280297Sjkim n >>= 1; 340280297Sjkim } 341280297Sjkim EVP_DigestFinal_ex(&md, buf, NULL); 34259191Skris 343280297Sjkim for (i = 0; i < 1000; i++) { 344280297Sjkim EVP_DigestInit_ex(&md2, EVP_md5(), NULL); 345280297Sjkim EVP_DigestUpdate(&md2, (i & 1) ? (unsigned const char *)passwd : buf, 346331638Sjkim (i & 1) ? passwd_len : sizeof(buf)); 347280297Sjkim if (i % 3) 348280297Sjkim EVP_DigestUpdate(&md2, salt_out, salt_len); 349280297Sjkim if (i % 7) 350280297Sjkim EVP_DigestUpdate(&md2, passwd, passwd_len); 351280297Sjkim EVP_DigestUpdate(&md2, (i & 1) ? buf : (unsigned const char *)passwd, 352331638Sjkim (i & 1) ? sizeof(buf) : passwd_len); 353280297Sjkim EVP_DigestFinal_ex(&md2, buf, NULL); 354280297Sjkim } 355280297Sjkim EVP_MD_CTX_cleanup(&md2); 35659191Skris 357280297Sjkim { 358280297Sjkim /* transform buf into output string */ 35959191Skris 360331638Sjkim unsigned char buf_perm[sizeof(buf)]; 361280297Sjkim int dest, source; 362280297Sjkim char *output; 363280297Sjkim 364280297Sjkim /* silly output permutation */ 365280297Sjkim for (dest = 0, source = 0; dest < 14; 366280297Sjkim dest++, source = (source + 6) % 17) 367280297Sjkim buf_perm[dest] = buf[source]; 368280297Sjkim buf_perm[14] = buf[5]; 369280297Sjkim buf_perm[15] = buf[11]; 370280297Sjkim# ifndef PEDANTIC /* Unfortunately, this generates a "no 371280297Sjkim * effect" warning */ 372331638Sjkim assert(16 == sizeof(buf_perm)); 373280297Sjkim# endif 374280297Sjkim 375280297Sjkim output = salt_out + salt_len; 376280297Sjkim assert(output == out_buf + strlen(out_buf)); 377280297Sjkim 378280297Sjkim *output++ = '$'; 379280297Sjkim 380280297Sjkim for (i = 0; i < 15; i += 3) { 381280297Sjkim *output++ = cov_2char[buf_perm[i + 2] & 0x3f]; 382280297Sjkim *output++ = cov_2char[((buf_perm[i + 1] & 0xf) << 2) | 383280297Sjkim (buf_perm[i + 2] >> 6)]; 384280297Sjkim *output++ = cov_2char[((buf_perm[i] & 3) << 4) | 385280297Sjkim (buf_perm[i + 1] >> 4)]; 386280297Sjkim *output++ = cov_2char[buf_perm[i] >> 2]; 387280297Sjkim } 388280297Sjkim assert(i == 15); 389280297Sjkim *output++ = cov_2char[buf_perm[i] & 0x3f]; 390280297Sjkim *output++ = cov_2char[buf_perm[i] >> 6]; 391280297Sjkim *output = 0; 392280297Sjkim assert(strlen(out_buf) < sizeof(out_buf)); 393280297Sjkim } 394280297Sjkim EVP_MD_CTX_cleanup(&md); 395280297Sjkim 396280297Sjkim return out_buf; 397280297Sjkim} 398280297Sjkim# endif 399280297Sjkim 40059191Skrisstatic int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, 401280297Sjkim char *passwd, BIO *out, int quiet, int table, 402280297Sjkim int reverse, size_t pw_maxlen, int usecrypt, int use1, 403280297Sjkim int useapr1) 404280297Sjkim{ 405280297Sjkim char *hash = NULL; 40659191Skris 407280297Sjkim assert(salt_p != NULL); 408280297Sjkim assert(salt_malloc_p != NULL); 40959191Skris 410280297Sjkim /* first make sure we have a salt */ 411280297Sjkim if (!passed_salt) { 412280297Sjkim# ifndef OPENSSL_NO_DES 413280297Sjkim if (usecrypt) { 414280297Sjkim if (*salt_malloc_p == NULL) { 415280297Sjkim *salt_p = *salt_malloc_p = OPENSSL_malloc(3); 416280297Sjkim if (*salt_malloc_p == NULL) 417280297Sjkim goto err; 418280297Sjkim } 419306195Sjkim if (RAND_bytes((unsigned char *)*salt_p, 2) <= 0) 420280297Sjkim goto err; 421280297Sjkim (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */ 422280297Sjkim (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */ 423280297Sjkim (*salt_p)[2] = 0; 424280297Sjkim# ifdef CHARSET_EBCDIC 425280297Sjkim ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert back 426280297Sjkim * to ASCII */ 427280297Sjkim# endif 428280297Sjkim } 429280297Sjkim# endif /* !OPENSSL_NO_DES */ 43059191Skris 431280297Sjkim# ifndef NO_MD5CRYPT_1 432280297Sjkim if (use1 || useapr1) { 433280297Sjkim int i; 43459191Skris 435280297Sjkim if (*salt_malloc_p == NULL) { 436280297Sjkim *salt_p = *salt_malloc_p = OPENSSL_malloc(9); 437280297Sjkim if (*salt_malloc_p == NULL) 438280297Sjkim goto err; 439280297Sjkim } 440306195Sjkim if (RAND_bytes((unsigned char *)*salt_p, 8) <= 0) 441280297Sjkim goto err; 442280297Sjkim 443280297Sjkim for (i = 0; i < 8; i++) 444280297Sjkim (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */ 445280297Sjkim (*salt_p)[8] = 0; 446280297Sjkim } 447280297Sjkim# endif /* !NO_MD5CRYPT_1 */ 448280297Sjkim } 449280297Sjkim 450280297Sjkim assert(*salt_p != NULL); 451280297Sjkim 452280297Sjkim /* truncate password if necessary */ 453280297Sjkim if ((strlen(passwd) > pw_maxlen)) { 454280297Sjkim if (!quiet) 455280297Sjkim /* 456280297Sjkim * XXX: really we should know how to print a size_t, not cast it 457280297Sjkim */ 458280297Sjkim BIO_printf(bio_err, 459280297Sjkim "Warning: truncating password to %u characters\n", 460280297Sjkim (unsigned)pw_maxlen); 461280297Sjkim passwd[pw_maxlen] = 0; 462280297Sjkim } 463280297Sjkim assert(strlen(passwd) <= pw_maxlen); 464280297Sjkim 465280297Sjkim /* now compute password hash */ 466280297Sjkim# ifndef OPENSSL_NO_DES 467280297Sjkim if (usecrypt) 468280297Sjkim hash = DES_crypt(passwd, *salt_p); 469280297Sjkim# endif 470280297Sjkim# ifndef NO_MD5CRYPT_1 471280297Sjkim if (use1 || useapr1) 472280297Sjkim hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p); 473280297Sjkim# endif 474280297Sjkim assert(hash != NULL); 475280297Sjkim 476280297Sjkim if (table && !reverse) 477280297Sjkim BIO_printf(out, "%s\t%s\n", passwd, hash); 478280297Sjkim else if (table && reverse) 479280297Sjkim BIO_printf(out, "%s\t%s\n", hash, passwd); 480280297Sjkim else 481280297Sjkim BIO_printf(out, "%s\n", hash); 482280297Sjkim return 1; 483280297Sjkim 484280297Sjkim err: 485280297Sjkim return 0; 486280297Sjkim} 48759191Skris#else 48859191Skris 48959191Skrisint MAIN(int argc, char **argv) 490280297Sjkim{ 491280297Sjkim fputs("Program not available.\n", stderr) 492280297Sjkim OPENSSL_EXIT(1); 493280297Sjkim} 49459191Skris#endif 495