passwd.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /* ====================================================================
  2. * Copyright (c) 2000-2015 The OpenSSL Project. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. *
  16. * 3. All advertising materials mentioning features or use of this
  17. * software must display the following acknowledgment:
  18. * "This product includes software developed by the OpenSSL Project
  19. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  20. *
  21. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  22. * endorse or promote products derived from this software without
  23. * prior written permission. For written permission, please contact
  24. * licensing@OpenSSL.org.
  25. *
  26. * 5. Products derived from this software may not be called "OpenSSL"
  27. * nor may "OpenSSL" appear in their names without prior written
  28. * permission of the OpenSSL Project.
  29. *
  30. * 6. Redistributions of any form whatsoever must retain the following
  31. * acknowledgment:
  32. * "This product includes software developed by the OpenSSL Project
  33. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  34. *
  35. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  36. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46. * OF THE POSSIBILITY OF SUCH DAMAGE.
  47. * ====================================================================
  48. */
  49. #if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC
  50. # define NO_MD5CRYPT_1
  51. #endif
  52. #if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
  53. # include <string.h>
  54. # include "apps.h"
  55. # include <openssl/bio.h>
  56. # include <openssl/err.h>
  57. # include <openssl/evp.h>
  58. # include <openssl/rand.h>
  59. # ifndef OPENSSL_NO_DES
  60. # include <openssl/des.h>
  61. # endif
  62. # ifndef NO_MD5CRYPT_1
  63. # include <openssl/md5.h>
  64. # endif
  65. static unsigned const char cov_2char[64] = {
  66. /* from crypto/des/fcrypt.c */
  67. 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
  68. 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
  69. 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
  70. 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
  71. 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
  72. 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
  73. 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
  74. 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
  75. };
  76. static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
  77. char *passwd, BIO *out, int quiet, int table,
  78. int reverse, size_t pw_maxlen, int usecrypt, int use1,
  79. int useapr1);
  80. typedef enum OPTION_choice {
  81. OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
  82. OPT_IN,
  83. OPT_NOVERIFY, OPT_QUIET, OPT_TABLE, OPT_REVERSE, OPT_APR1,
  84. OPT_1, OPT_CRYPT, OPT_SALT, OPT_STDIN
  85. } OPTION_CHOICE;
  86. OPTIONS passwd_options[] = {
  87. {"help", OPT_HELP, '-', "Display this summary"},
  88. {"in", OPT_IN, '<', "Pead passwords from file"},
  89. {"noverify", OPT_NOVERIFY, '-',
  90. "Never verify when reading password from terminal"},
  91. {"quiet", OPT_QUIET, '-', "No warnings"},
  92. {"table", OPT_TABLE, '-', "Format output as table"},
  93. {"reverse", OPT_REVERSE, '-', "Switch table columns"},
  94. {"salt", OPT_SALT, 's', "Use provided salt"},
  95. {"stdin", OPT_STDIN, '-', "Read passwords from stdin"},
  96. # ifndef NO_MD5CRYPT_1
  97. {"apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant"},
  98. {"1", OPT_1, '-', "MD5-based password algorithm"},
  99. # endif
  100. # ifndef OPENSSL_NO_DES
  101. {"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"},
  102. # endif
  103. {NULL}
  104. };
  105. int passwd_main(int argc, char **argv)
  106. {
  107. BIO *in = NULL;
  108. char *infile = NULL, *salt = NULL, *passwd = NULL, **passwds = NULL;
  109. char *salt_malloc = NULL, *passwd_malloc = NULL, *prog;
  110. OPTION_CHOICE o;
  111. int in_stdin = 0, in_noverify = 0, pw_source_defined = 0;
  112. int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
  113. int ret = 1, usecrypt = 0, use1 = 0, useapr1 = 0;
  114. size_t passwd_malloc_size = 0, pw_maxlen = 256;
  115. prog = opt_init(argc, argv, passwd_options);
  116. while ((o = opt_next()) != OPT_EOF) {
  117. switch (o) {
  118. case OPT_EOF:
  119. case OPT_ERR:
  120. opthelp:
  121. BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
  122. goto end;
  123. case OPT_HELP:
  124. opt_help(passwd_options);
  125. ret = 0;
  126. goto end;
  127. case OPT_IN:
  128. if (pw_source_defined)
  129. goto opthelp;
  130. infile = opt_arg();
  131. pw_source_defined = 1;
  132. break;
  133. case OPT_NOVERIFY:
  134. in_noverify = 1;
  135. break;
  136. case OPT_QUIET:
  137. quiet = 1;
  138. break;
  139. case OPT_TABLE:
  140. table = 1;
  141. break;
  142. case OPT_REVERSE:
  143. reverse = 1;
  144. break;
  145. case OPT_1:
  146. use1 = 1;
  147. break;
  148. case OPT_APR1:
  149. useapr1 = 1;
  150. break;
  151. case OPT_CRYPT:
  152. usecrypt = 1;
  153. break;
  154. case OPT_SALT:
  155. passed_salt = 1;
  156. salt = opt_arg();
  157. break;
  158. case OPT_STDIN:
  159. if (pw_source_defined)
  160. goto opthelp;
  161. in_stdin = 1;
  162. break;
  163. }
  164. }
  165. argc = opt_num_rest();
  166. argv = opt_rest();
  167. if (*argv) {
  168. if (pw_source_defined)
  169. goto opthelp;
  170. pw_source_defined = 1;
  171. passwds = argv;
  172. }
  173. if (!usecrypt && !use1 && !useapr1) {
  174. /* use default */
  175. usecrypt = 1;
  176. }
  177. if (usecrypt + use1 + useapr1 > 1) {
  178. /* conflict */
  179. goto opthelp;
  180. }
  181. # ifdef OPENSSL_NO_DES
  182. if (usecrypt)
  183. goto opthelp;
  184. # endif
  185. # ifdef NO_MD5CRYPT_1
  186. if (use1 || useapr1)
  187. goto opthelp;
  188. # endif
  189. if (infile && in_stdin) {
  190. BIO_printf(bio_err, "%s: Can't combine -in and -stdin\n", prog);
  191. goto end;
  192. }
  193. in = bio_open_default(infile, 'r', FORMAT_TEXT);
  194. if (in == NULL)
  195. goto end;
  196. if (usecrypt)
  197. pw_maxlen = 8;
  198. else if (use1 || useapr1)
  199. pw_maxlen = 256; /* arbitrary limit, should be enough for most
  200. * passwords */
  201. if (passwds == NULL) {
  202. /* no passwords on the command line */
  203. passwd_malloc_size = pw_maxlen + 2;
  204. /* longer than necessary so that we can warn about truncation */
  205. passwd = passwd_malloc =
  206. app_malloc(passwd_malloc_size, "password buffer");
  207. }
  208. if ((in == NULL) && (passwds == NULL)) {
  209. /* build a null-terminated list */
  210. static char *passwds_static[2] = { NULL, NULL };
  211. passwds = passwds_static;
  212. if (in == NULL)
  213. if (EVP_read_pw_string
  214. (passwd_malloc, passwd_malloc_size, "Password: ",
  215. !(passed_salt || in_noverify)) != 0)
  216. goto end;
  217. passwds[0] = passwd_malloc;
  218. }
  219. if (in == NULL) {
  220. assert(passwds != NULL);
  221. assert(*passwds != NULL);
  222. do { /* loop over list of passwords */
  223. passwd = *passwds++;
  224. if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, bio_out,
  225. quiet, table, reverse, pw_maxlen, usecrypt, use1,
  226. useapr1))
  227. goto end;
  228. }
  229. while (*passwds != NULL);
  230. } else
  231. /* in != NULL */
  232. {
  233. int done;
  234. assert(passwd != NULL);
  235. do {
  236. int r = BIO_gets(in, passwd, pw_maxlen + 1);
  237. if (r > 0) {
  238. char *c = (strchr(passwd, '\n'));
  239. if (c != NULL)
  240. *c = 0; /* truncate at newline */
  241. else {
  242. /* ignore rest of line */
  243. char trash[BUFSIZ];
  244. do
  245. r = BIO_gets(in, trash, sizeof trash);
  246. while ((r > 0) && (!strchr(trash, '\n')));
  247. }
  248. if (!do_passwd
  249. (passed_salt, &salt, &salt_malloc, passwd, bio_out, quiet,
  250. table, reverse, pw_maxlen, usecrypt, use1, useapr1))
  251. goto end;
  252. }
  253. done = (r <= 0);
  254. }
  255. while (!done);
  256. }
  257. ret = 0;
  258. end:
  259. ERR_print_errors(bio_err);
  260. OPENSSL_free(salt_malloc);
  261. OPENSSL_free(passwd_malloc);
  262. BIO_free(in);
  263. return (ret);
  264. }
  265. # ifndef NO_MD5CRYPT_1
  266. /*
  267. * MD5-based password algorithm (should probably be available as a library
  268. * function; then the static buffer would not be acceptable). For magic
  269. * string "1", this should be compatible to the MD5-based BSD password
  270. * algorithm. For 'magic' string "apr1", this is compatible to the MD5-based
  271. * Apache password algorithm. (Apparently, the Apache password algorithm is
  272. * identical except that the 'magic' string was changed -- the laziest
  273. * application of the NIH principle I've ever encountered.)
  274. */
  275. static char *md5crypt(const char *passwd, const char *magic, const char *salt)
  276. {
  277. /* "$apr1$..salt..$.......md5hash..........\0" */
  278. static char out_buf[6 + 9 + 24 + 2];
  279. unsigned char buf[MD5_DIGEST_LENGTH];
  280. char *salt_out;
  281. int n;
  282. unsigned int i;
  283. EVP_MD_CTX *md, *md2;
  284. size_t passwd_len, salt_len;
  285. passwd_len = strlen(passwd);
  286. out_buf[0] = '$';
  287. out_buf[1] = 0;
  288. assert(strlen(magic) <= 4); /* "1" or "apr1" */
  289. OPENSSL_strlcat(out_buf, magic, sizeof out_buf);
  290. OPENSSL_strlcat(out_buf, "$", sizeof out_buf);
  291. OPENSSL_strlcat(out_buf, salt, sizeof out_buf);
  292. assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
  293. salt_out = out_buf + 2 + strlen(magic);
  294. salt_len = strlen(salt_out);
  295. assert(salt_len <= 8);
  296. md = EVP_MD_CTX_new();
  297. if (md == NULL)
  298. return NULL;
  299. EVP_DigestInit_ex(md, EVP_md5(), NULL);
  300. EVP_DigestUpdate(md, passwd, passwd_len);
  301. EVP_DigestUpdate(md, "$", 1);
  302. EVP_DigestUpdate(md, magic, strlen(magic));
  303. EVP_DigestUpdate(md, "$", 1);
  304. EVP_DigestUpdate(md, salt_out, salt_len);
  305. md2 = EVP_MD_CTX_new();
  306. if (md2 == NULL)
  307. return NULL;
  308. EVP_DigestInit_ex(md2, EVP_md5(), NULL);
  309. EVP_DigestUpdate(md2, passwd, passwd_len);
  310. EVP_DigestUpdate(md2, salt_out, salt_len);
  311. EVP_DigestUpdate(md2, passwd, passwd_len);
  312. EVP_DigestFinal_ex(md2, buf, NULL);
  313. for (i = passwd_len; i > sizeof buf; i -= sizeof buf)
  314. EVP_DigestUpdate(md, buf, sizeof buf);
  315. EVP_DigestUpdate(md, buf, i);
  316. n = passwd_len;
  317. while (n) {
  318. EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1);
  319. n >>= 1;
  320. }
  321. EVP_DigestFinal_ex(md, buf, NULL);
  322. for (i = 0; i < 1000; i++) {
  323. EVP_DigestInit_ex(md2, EVP_md5(), NULL);
  324. EVP_DigestUpdate(md2, (i & 1) ? (unsigned const char *)passwd : buf,
  325. (i & 1) ? passwd_len : sizeof buf);
  326. if (i % 3)
  327. EVP_DigestUpdate(md2, salt_out, salt_len);
  328. if (i % 7)
  329. EVP_DigestUpdate(md2, passwd, passwd_len);
  330. EVP_DigestUpdate(md2, (i & 1) ? buf : (unsigned const char *)passwd,
  331. (i & 1) ? sizeof buf : passwd_len);
  332. EVP_DigestFinal_ex(md2, buf, NULL);
  333. }
  334. EVP_MD_CTX_free(md2);
  335. EVP_MD_CTX_free(md);
  336. {
  337. /* transform buf into output string */
  338. unsigned char buf_perm[sizeof buf];
  339. int dest, source;
  340. char *output;
  341. /* silly output permutation */
  342. for (dest = 0, source = 0; dest < 14;
  343. dest++, source = (source + 6) % 17)
  344. buf_perm[dest] = buf[source];
  345. buf_perm[14] = buf[5];
  346. buf_perm[15] = buf[11];
  347. # ifndef PEDANTIC /* Unfortunately, this generates a "no
  348. * effect" warning */
  349. assert(16 == sizeof buf_perm);
  350. # endif
  351. output = salt_out + salt_len;
  352. assert(output == out_buf + strlen(out_buf));
  353. *output++ = '$';
  354. for (i = 0; i < 15; i += 3) {
  355. *output++ = cov_2char[buf_perm[i + 2] & 0x3f];
  356. *output++ = cov_2char[((buf_perm[i + 1] & 0xf) << 2) |
  357. (buf_perm[i + 2] >> 6)];
  358. *output++ = cov_2char[((buf_perm[i] & 3) << 4) |
  359. (buf_perm[i + 1] >> 4)];
  360. *output++ = cov_2char[buf_perm[i] >> 2];
  361. }
  362. assert(i == 15);
  363. *output++ = cov_2char[buf_perm[i] & 0x3f];
  364. *output++ = cov_2char[buf_perm[i] >> 6];
  365. *output = 0;
  366. assert(strlen(out_buf) < sizeof(out_buf));
  367. }
  368. return out_buf;
  369. }
  370. # endif
  371. static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
  372. char *passwd, BIO *out, int quiet, int table,
  373. int reverse, size_t pw_maxlen, int usecrypt, int use1,
  374. int useapr1)
  375. {
  376. char *hash = NULL;
  377. assert(salt_p != NULL);
  378. assert(salt_malloc_p != NULL);
  379. /* first make sure we have a salt */
  380. if (!passed_salt) {
  381. # ifndef OPENSSL_NO_DES
  382. if (usecrypt) {
  383. if (*salt_malloc_p == NULL) {
  384. *salt_p = *salt_malloc_p = app_malloc(3, "salt buffer");
  385. }
  386. if (RAND_bytes((unsigned char *)*salt_p, 2) <= 0)
  387. goto end;
  388. (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
  389. (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
  390. (*salt_p)[2] = 0;
  391. # ifdef CHARSET_EBCDIC
  392. ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert back
  393. * to ASCII */
  394. # endif
  395. }
  396. # endif /* !OPENSSL_NO_DES */
  397. # ifndef NO_MD5CRYPT_1
  398. if (use1 || useapr1) {
  399. int i;
  400. if (*salt_malloc_p == NULL) {
  401. *salt_p = *salt_malloc_p = app_malloc(9, "salt buffer");
  402. }
  403. if (RAND_bytes((unsigned char *)*salt_p, 8) <= 0)
  404. goto end;
  405. for (i = 0; i < 8; i++)
  406. (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
  407. (*salt_p)[8] = 0;
  408. }
  409. # endif /* !NO_MD5CRYPT_1 */
  410. }
  411. assert(*salt_p != NULL);
  412. /* truncate password if necessary */
  413. if ((strlen(passwd) > pw_maxlen)) {
  414. if (!quiet)
  415. /*
  416. * XXX: really we should know how to print a size_t, not cast it
  417. */
  418. BIO_printf(bio_err,
  419. "Warning: truncating password to %u characters\n",
  420. (unsigned)pw_maxlen);
  421. passwd[pw_maxlen] = 0;
  422. }
  423. assert(strlen(passwd) <= pw_maxlen);
  424. /* now compute password hash */
  425. # ifndef OPENSSL_NO_DES
  426. if (usecrypt)
  427. hash = DES_crypt(passwd, *salt_p);
  428. # endif
  429. # ifndef NO_MD5CRYPT_1
  430. if (use1 || useapr1)
  431. hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p);
  432. # endif
  433. assert(hash != NULL);
  434. if (table && !reverse)
  435. BIO_printf(out, "%s\t%s\n", passwd, hash);
  436. else if (table && reverse)
  437. BIO_printf(out, "%s\t%s\n", hash, passwd);
  438. else
  439. BIO_printf(out, "%s\n", hash);
  440. return 0;
  441. end:
  442. return 1;
  443. }
  444. #else
  445. int passwd_main(int argc, char **argv)
  446. {
  447. BIO_printf(bio_err, "Program not available.\n");
  448. return (1);
  449. }
  450. #endif