read_pwd.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. /* crypto/des/read_pwd.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. #include <openssl/e_os2.h>
  59. #if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WIN32)
  60. # ifdef OPENSSL_UNISTD
  61. # include OPENSSL_UNISTD
  62. # else
  63. # include <unistd.h>
  64. # endif
  65. /*
  66. * If unistd.h defines _POSIX_VERSION, we conclude that we are on a POSIX
  67. * system and have sigaction and termios.
  68. */
  69. # if defined(_POSIX_VERSION)
  70. # define SIGACTION
  71. # if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
  72. # define TERMIOS
  73. # endif
  74. # endif
  75. #endif
  76. /* Define this if you have sigaction() */
  77. /* #define SIGACTION */
  78. #ifdef WIN16TTY
  79. # undef OPENSSL_SYS_WIN16
  80. # undef _WINDOWS
  81. # include <graph.h>
  82. #endif
  83. /* 06-Apr-92 Luke Brennan Support for VMS */
  84. #include "des_locl.h"
  85. #include "cryptlib.h"
  86. #include <signal.h>
  87. #include <stdio.h>
  88. #include <string.h>
  89. #include <setjmp.h>
  90. #include <errno.h>
  91. #ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */
  92. # include <starlet.h>
  93. # ifdef __DECC
  94. # pragma message disable DOLLARID
  95. # endif
  96. #endif
  97. #ifdef WIN_CONSOLE_BUG
  98. # include <windows.h>
  99. # ifndef OPENSSL_SYS_WINCE
  100. # include <wincon.h>
  101. # endif
  102. #endif
  103. /*
  104. * There are 5 types of terminal interface supported, TERMIO, TERMIOS, VMS,
  105. * MSDOS and SGTTY
  106. */
  107. #if defined(__sgi) && !defined(TERMIOS)
  108. # define TERMIOS
  109. # undef TERMIO
  110. # undef SGTTY
  111. #endif
  112. #if defined(linux) && !defined(TERMIO)
  113. # undef TERMIOS
  114. # define TERMIO
  115. # undef SGTTY
  116. #endif
  117. #ifdef _LIBC
  118. # undef TERMIOS
  119. # define TERMIO
  120. # undef SGTTY
  121. #endif
  122. #if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(MAC_OS_pre_X) && !defined(MAC_OS_GUSI_SOURCE)
  123. # undef TERMIOS
  124. # undef TERMIO
  125. # define SGTTY
  126. #endif
  127. #if defined(OPENSSL_SYS_VXWORKS)
  128. # undef TERMIOS
  129. # undef TERMIO
  130. # undef SGTTY
  131. #endif
  132. #ifdef TERMIOS
  133. # include <termios.h>
  134. # define TTY_STRUCT struct termios
  135. # define TTY_FLAGS c_lflag
  136. # define TTY_get(tty,data) tcgetattr(tty,data)
  137. # define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data)
  138. #endif
  139. #ifdef TERMIO
  140. # include <termio.h>
  141. # define TTY_STRUCT struct termio
  142. # define TTY_FLAGS c_lflag
  143. # define TTY_get(tty,data) ioctl(tty,TCGETA,data)
  144. # define TTY_set(tty,data) ioctl(tty,TCSETA,data)
  145. #endif
  146. #ifdef SGTTY
  147. # include <sgtty.h>
  148. # define TTY_STRUCT struct sgttyb
  149. # define TTY_FLAGS sg_flags
  150. # define TTY_get(tty,data) ioctl(tty,TIOCGETP,data)
  151. # define TTY_set(tty,data) ioctl(tty,TIOCSETP,data)
  152. #endif
  153. #if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(MAC_OS_pre_X)
  154. # include <sys/ioctl.h>
  155. #endif
  156. #if defined(OPENSSL_SYS_MSDOS) && !defined(__CYGWIN32__) && !defined(OPENSSL_SYS_WINCE)
  157. # include <conio.h>
  158. # define fgets(a,b,c) noecho_fgets(a,b,c)
  159. #endif
  160. #ifdef OPENSSL_SYS_VMS
  161. # include <ssdef.h>
  162. # include <iodef.h>
  163. # include <ttdef.h>
  164. # include <descrip.h>
  165. struct IOSB {
  166. short iosb$w_value;
  167. short iosb$w_count;
  168. long iosb$l_info;
  169. };
  170. #endif
  171. #if defined(MAC_OS_pre_X) || defined(MAC_OS_GUSI_SOURCE)
  172. /*
  173. * This one needs work. As a matter of fact the code is unoperational
  174. * and this is only a trick to get it compiled.
  175. * <appro@fy.chalmers.se>
  176. */
  177. # define TTY_STRUCT int
  178. #endif
  179. #ifndef NX509_SIG
  180. # define NX509_SIG 32
  181. #endif
  182. static void read_till_nl(FILE *);
  183. static void recsig(int);
  184. static void pushsig(void);
  185. static void popsig(void);
  186. #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16)
  187. static int noecho_fgets(char *buf, int size, FILE *tty);
  188. #endif
  189. #ifdef SIGACTION
  190. static struct sigaction savsig[NX509_SIG];
  191. #else
  192. static void (*savsig[NX509_SIG]) (int);
  193. #endif
  194. static jmp_buf save;
  195. int des_read_pw_string(char *buf, int length, const char *prompt, int verify)
  196. {
  197. char buff[BUFSIZ];
  198. int ret;
  199. ret =
  200. des_read_pw(buf, buff, (length > BUFSIZ) ? BUFSIZ : length, prompt,
  201. verify);
  202. OPENSSL_cleanse(buff, BUFSIZ);
  203. return (ret);
  204. }
  205. #ifdef OPENSSL_SYS_WINCE
  206. int des_read_pw(char *buf, char *buff, int size, const char *prompt,
  207. int verify)
  208. {
  209. memset(buf, 0, size);
  210. memset(buff, 0, size);
  211. return (0);
  212. }
  213. #elif defined(OPENSSL_SYS_WIN16)
  214. int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify)
  215. {
  216. memset(buf, 0, size);
  217. memset(buff, 0, size);
  218. return (0);
  219. }
  220. #else /* !OPENSSL_SYS_WINCE && !OPENSSL_SYS_WIN16 */
  221. static void read_till_nl(FILE *in)
  222. {
  223. # define SIZE 4
  224. char buf[SIZE + 1];
  225. do {
  226. fgets(buf, SIZE, in);
  227. } while (strchr(buf, '\n') == NULL);
  228. }
  229. /* return 0 if ok, 1 (or -1) otherwise */
  230. int des_read_pw(char *buf, char *buff, int size, const char *prompt,
  231. int verify)
  232. {
  233. # ifdef OPENSSL_SYS_VMS
  234. struct IOSB iosb;
  235. $DESCRIPTOR(terminal, "TT");
  236. long tty_orig[3], tty_new[3];
  237. long status;
  238. unsigned short channel = 0;
  239. # else
  240. # if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__)
  241. TTY_STRUCT tty_orig, tty_new;
  242. # endif
  243. # endif
  244. int number;
  245. int ok;
  246. /*
  247. * statics are simply to avoid warnings about longjmp clobbering things
  248. */
  249. static int ps;
  250. int is_a_tty;
  251. static FILE *tty;
  252. char *p;
  253. if (setjmp(save)) {
  254. ok = 0;
  255. goto error;
  256. }
  257. number = 5;
  258. ok = 0;
  259. ps = 0;
  260. is_a_tty = 1;
  261. tty = NULL;
  262. # ifdef OPENSSL_SYS_MSDOS
  263. if ((tty = fopen("con", "r")) == NULL)
  264. tty = stdin;
  265. # elif defined(MAC_OS_pre_X) || defined(OPENSSL_SYS_VXWORKS)
  266. tty = stdin;
  267. # else
  268. # ifndef OPENSSL_SYS_MPE
  269. if ((tty = fopen("/dev/tty", "r")) == NULL)
  270. # endif
  271. tty = stdin;
  272. # endif
  273. # if defined(TTY_get) && !defined(OPENSSL_SYS_VMS)
  274. if (TTY_get(fileno(tty), &tty_orig) == -1) {
  275. # ifdef ENOTTY
  276. if (errno == ENOTTY)
  277. is_a_tty = 0;
  278. else
  279. # endif
  280. # ifdef EINVAL
  281. /*
  282. * Ariel Glenn ariel@columbia.edu reports that solaris can return
  283. * EINVAL instead. This should be ok
  284. */
  285. if (errno == EINVAL)
  286. is_a_tty = 0;
  287. else
  288. # endif
  289. return (-1);
  290. }
  291. memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig));
  292. # endif
  293. # ifdef OPENSSL_SYS_VMS
  294. status = sys$assign(&terminal, &channel, 0, 0);
  295. if (status != SS$_NORMAL)
  296. return (-1);
  297. status =
  298. sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, 0, 0,
  299. 0, 0);
  300. if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
  301. return (-1);
  302. # endif
  303. pushsig();
  304. ps = 1;
  305. # ifdef TTY_FLAGS
  306. tty_new.TTY_FLAGS &= ~ECHO;
  307. # endif
  308. # if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
  309. if (is_a_tty && (TTY_set(fileno(tty), &tty_new) == -1))
  310. # ifdef OPENSSL_SYS_MPE
  311. ; /* MPE lies -- echo really has been disabled */
  312. # else
  313. return (-1);
  314. # endif
  315. # endif
  316. # ifdef OPENSSL_SYS_VMS
  317. tty_new[0] = tty_orig[0];
  318. tty_new[1] = tty_orig[1] | TT$M_NOECHO;
  319. tty_new[2] = tty_orig[2];
  320. status =
  321. sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0,
  322. 0);
  323. if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
  324. return (-1);
  325. # endif
  326. ps = 2;
  327. while ((!ok) && (number--)) {
  328. fputs(prompt, stderr);
  329. fflush(stderr);
  330. buf[0] = '\0';
  331. fgets(buf, size, tty);
  332. if (feof(tty))
  333. goto error;
  334. if (ferror(tty))
  335. goto error;
  336. if ((p = (char *)strchr(buf, '\n')) != NULL)
  337. *p = '\0';
  338. else
  339. read_till_nl(tty);
  340. if (verify) {
  341. fprintf(stderr, "\nVerifying password - %s", prompt);
  342. fflush(stderr);
  343. buff[0] = '\0';
  344. fgets(buff, size, tty);
  345. if (feof(tty))
  346. goto error;
  347. if ((p = (char *)strchr(buff, '\n')) != NULL)
  348. *p = '\0';
  349. else
  350. read_till_nl(tty);
  351. if (strcmp(buf, buff) != 0) {
  352. fprintf(stderr, "\nVerify failure");
  353. fflush(stderr);
  354. break;
  355. /* continue; */
  356. }
  357. }
  358. ok = 1;
  359. }
  360. error:
  361. fprintf(stderr, "\n");
  362. # if 0
  363. perror("fgets(tty)");
  364. # endif
  365. /* What can we do if there is an error? */
  366. # if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
  367. if (ps >= 2)
  368. TTY_set(fileno(tty), &tty_orig);
  369. # endif
  370. # ifdef OPENSSL_SYS_VMS
  371. if (ps >= 2)
  372. status =
  373. sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_orig, 12, 0, 0,
  374. 0, 0);
  375. # endif
  376. if (ps >= 1)
  377. popsig();
  378. if (stdin != tty)
  379. fclose(tty);
  380. # ifdef OPENSSL_SYS_VMS
  381. status = sys$dassgn(channel);
  382. # endif
  383. return (!ok);
  384. }
  385. static void pushsig(void)
  386. {
  387. int i;
  388. # ifdef SIGACTION
  389. struct sigaction sa;
  390. memset(&sa, 0, sizeof sa);
  391. sa.sa_handler = recsig;
  392. # endif
  393. for (i = 1; i < NX509_SIG; i++) {
  394. # ifdef SIGUSR1
  395. if (i == SIGUSR1)
  396. continue;
  397. # endif
  398. # ifdef SIGUSR2
  399. if (i == SIGUSR2)
  400. continue;
  401. # endif
  402. # ifdef SIGACTION
  403. sigaction(i, &sa, &savsig[i]);
  404. # else
  405. savsig[i] = signal(i, recsig);
  406. # endif
  407. }
  408. # ifdef SIGWINCH
  409. signal(SIGWINCH, SIG_DFL);
  410. # endif
  411. }
  412. static void popsig(void)
  413. {
  414. int i;
  415. for (i = 1; i < NX509_SIG; i++) {
  416. # ifdef SIGUSR1
  417. if (i == SIGUSR1)
  418. continue;
  419. # endif
  420. # ifdef SIGUSR2
  421. if (i == SIGUSR2)
  422. continue;
  423. # endif
  424. # ifdef SIGACTION
  425. sigaction(i, &savsig[i], NULL);
  426. # else
  427. signal(i, savsig[i]);
  428. # endif
  429. }
  430. }
  431. static void recsig(int i)
  432. {
  433. longjmp(save, 1);
  434. # ifdef LINT
  435. i = i;
  436. # endif
  437. }
  438. # ifdef OPENSSL_SYS_MSDOS
  439. static int noecho_fgets(char *buf, int size, FILE *tty)
  440. {
  441. int i;
  442. char *p;
  443. p = buf;
  444. for (;;) {
  445. if (size == 0) {
  446. *p = '\0';
  447. break;
  448. }
  449. size--;
  450. # ifdef WIN16TTY
  451. i = _inchar();
  452. # else
  453. i = getch();
  454. # endif
  455. if (i == '\r')
  456. i = '\n';
  457. *(p++) = i;
  458. if (i == '\n') {
  459. *p = '\0';
  460. break;
  461. }
  462. }
  463. # ifdef WIN_CONSOLE_BUG
  464. /*
  465. * Win95 has several evil console bugs: one of these is that the last
  466. * character read using getch() is passed to the next read: this is
  467. * usually a CR so this can be trouble. No STDIO fix seems to work but
  468. * flushing the console appears to do the trick.
  469. */
  470. {
  471. HANDLE inh;
  472. inh = GetStdHandle(STD_INPUT_HANDLE);
  473. FlushConsoleInputBuffer(inh);
  474. }
  475. # endif
  476. return (strlen(buf));
  477. }
  478. # endif
  479. #endif /* !OPENSSL_SYS_WINCE && !WIN16 */