ui_openssl.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. /*
  2. * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include "internal/e_os.h"
  10. #include <openssl/e_os2.h>
  11. #include <openssl/err.h>
  12. #include <openssl/ui.h>
  13. #ifndef OPENSSL_NO_UI_CONSOLE
  14. /*
  15. * need for #define _POSIX_C_SOURCE arises whenever you pass -ansi to gcc
  16. * [maybe others?], because it masks interfaces not discussed in standard,
  17. * sigaction and fileno included. -pedantic would be more appropriate for the
  18. * intended purposes, but we can't prevent users from adding -ansi.
  19. */
  20. # if defined(OPENSSL_SYS_VXWORKS)
  21. # include <sys/types.h>
  22. # endif
  23. # if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
  24. # ifndef _POSIX_C_SOURCE
  25. # define _POSIX_C_SOURCE 2
  26. # endif
  27. # endif
  28. # include <signal.h>
  29. # include <stdio.h>
  30. # include <string.h>
  31. # include <errno.h>
  32. # if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS)
  33. # include <unistd.h>
  34. /*
  35. * If unistd.h defines _POSIX_VERSION, we conclude that we are on a POSIX
  36. * system and have sigaction and termios.
  37. */
  38. # if defined(_POSIX_VERSION) && _POSIX_VERSION>=199309L
  39. # define SIGACTION
  40. # if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
  41. # define TERMIOS
  42. # endif
  43. # endif
  44. # endif
  45. # include "ui_local.h"
  46. # include "internal/cryptlib.h"
  47. # ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */
  48. # include <starlet.h>
  49. # ifdef __DECC
  50. # pragma message disable DOLLARID
  51. # endif
  52. # endif
  53. # ifdef WIN_CONSOLE_BUG
  54. # include <windows.h>
  55. # ifndef OPENSSL_SYS_WINCE
  56. # include <wincon.h>
  57. # endif
  58. # endif
  59. /*
  60. * There are 6 types of terminal interface supported, TERMIO, TERMIOS, VMS,
  61. * MSDOS, WIN32 Console and SGTTY.
  62. *
  63. * If someone defines one of the macros TERMIO, TERMIOS or SGTTY, it will
  64. * remain respected. Otherwise, we default to TERMIOS except for a few
  65. * systems that require something different.
  66. *
  67. * Note: we do not use SGTTY unless it's defined by the configuration. We
  68. * may eventually opt to remove its use entirely.
  69. */
  70. # if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
  71. # if defined(_LIBC)
  72. # undef TERMIOS
  73. # define TERMIO
  74. # undef SGTTY
  75. /*
  76. * We know that VMS, MSDOS, VXWORKS, use entirely other mechanisms.
  77. */
  78. # elif !defined(OPENSSL_SYS_VMS) \
  79. && !defined(OPENSSL_SYS_MSDOS) \
  80. && !defined(OPENSSL_SYS_VXWORKS)
  81. # define TERMIOS
  82. # undef TERMIO
  83. # undef SGTTY
  84. # endif
  85. # endif
  86. # if defined(OPENSSL_SYS_VXWORKS)
  87. # undef TERMIOS
  88. # undef TERMIO
  89. # undef SGTTY
  90. # endif
  91. # ifdef TERMIOS
  92. # include <termios.h>
  93. # define TTY_STRUCT struct termios
  94. # define TTY_FLAGS c_lflag
  95. # define TTY_get(tty,data) tcgetattr(tty,data)
  96. # define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data)
  97. # endif
  98. # ifdef TERMIO
  99. # include <termio.h>
  100. # define TTY_STRUCT struct termio
  101. # define TTY_FLAGS c_lflag
  102. # define TTY_get(tty,data) ioctl(tty,TCGETA,data)
  103. # define TTY_set(tty,data) ioctl(tty,TCSETA,data)
  104. # endif
  105. # ifdef SGTTY
  106. # include <sgtty.h>
  107. # define TTY_STRUCT struct sgttyb
  108. # define TTY_FLAGS sg_flags
  109. # define TTY_get(tty,data) ioctl(tty,TIOCGETP,data)
  110. # define TTY_set(tty,data) ioctl(tty,TIOCSETP,data)
  111. # endif
  112. # if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && ! (defined(OPENSSL_SYS_TANDEM) && defined(_SPT_MODEL_))
  113. # include <sys/ioctl.h>
  114. # endif
  115. # ifdef OPENSSL_SYS_MSDOS
  116. # include <conio.h>
  117. # endif
  118. # ifdef OPENSSL_SYS_VMS
  119. # include <ssdef.h>
  120. # include <iodef.h>
  121. # include <ttdef.h>
  122. # include <descrip.h>
  123. struct IOSB {
  124. short iosb$w_value;
  125. short iosb$w_count;
  126. long iosb$l_info;
  127. };
  128. # endif
  129. # ifndef NX509_SIG
  130. # define NX509_SIG 32
  131. # endif
  132. /* Define globals. They are protected by a lock */
  133. # ifdef SIGACTION
  134. static struct sigaction savsig[NX509_SIG];
  135. # else
  136. static void (*savsig[NX509_SIG]) (int);
  137. # endif
  138. # ifdef OPENSSL_SYS_VMS
  139. static struct IOSB iosb;
  140. static $DESCRIPTOR(terminal, "TT");
  141. static long tty_orig[3], tty_new[3]; /* XXX Is there any guarantee that this
  142. * will always suffice for the actual
  143. * structures? */
  144. static long status;
  145. static unsigned short channel = 0;
  146. # elif defined(_WIN32) && !defined(_WIN32_WCE)
  147. static DWORD tty_orig, tty_new;
  148. # else
  149. # if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__)
  150. static TTY_STRUCT tty_orig, tty_new;
  151. # endif
  152. # endif
  153. static FILE *tty_in, *tty_out;
  154. static int is_a_tty;
  155. /* Declare static functions */
  156. # if !defined(OPENSSL_SYS_WINCE)
  157. static int read_till_nl(FILE *);
  158. static void recsig(int);
  159. static void pushsig(void);
  160. static void popsig(void);
  161. # endif
  162. # if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
  163. static int noecho_fgets(char *buf, int size, FILE *tty);
  164. # endif
  165. static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl);
  166. static int read_string(UI *ui, UI_STRING *uis);
  167. static int write_string(UI *ui, UI_STRING *uis);
  168. static int open_console(UI *ui);
  169. static int echo_console(UI *ui);
  170. static int noecho_console(UI *ui);
  171. static int close_console(UI *ui);
  172. /*
  173. * The following function makes sure that info and error strings are printed
  174. * before any prompt.
  175. */
  176. static int write_string(UI *ui, UI_STRING *uis)
  177. {
  178. switch (UI_get_string_type(uis)) {
  179. case UIT_ERROR:
  180. case UIT_INFO:
  181. fputs(UI_get0_output_string(uis), tty_out);
  182. fflush(tty_out);
  183. break;
  184. case UIT_NONE:
  185. case UIT_PROMPT:
  186. case UIT_VERIFY:
  187. case UIT_BOOLEAN:
  188. break;
  189. }
  190. return 1;
  191. }
  192. static int read_string(UI *ui, UI_STRING *uis)
  193. {
  194. int ok = 0;
  195. switch (UI_get_string_type(uis)) {
  196. case UIT_BOOLEAN:
  197. fputs(UI_get0_output_string(uis), tty_out);
  198. fputs(UI_get0_action_string(uis), tty_out);
  199. fflush(tty_out);
  200. return read_string_inner(ui, uis,
  201. UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO,
  202. 0);
  203. case UIT_PROMPT:
  204. fputs(UI_get0_output_string(uis), tty_out);
  205. fflush(tty_out);
  206. return read_string_inner(ui, uis,
  207. UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO,
  208. 1);
  209. case UIT_VERIFY:
  210. fprintf(tty_out, "Verifying - %s", UI_get0_output_string(uis));
  211. fflush(tty_out);
  212. if ((ok = read_string_inner(ui, uis,
  213. UI_get_input_flags(uis) &
  214. UI_INPUT_FLAG_ECHO, 1)) <= 0)
  215. return ok;
  216. if (strcmp(UI_get0_result_string(uis), UI_get0_test_string(uis)) != 0) {
  217. fprintf(tty_out, "Verify failure\n");
  218. fflush(tty_out);
  219. return 0;
  220. }
  221. break;
  222. case UIT_NONE:
  223. case UIT_INFO:
  224. case UIT_ERROR:
  225. break;
  226. }
  227. return 1;
  228. }
  229. # if !defined(OPENSSL_SYS_WINCE)
  230. /* Internal functions to read a string without echoing */
  231. static int read_till_nl(FILE *in)
  232. {
  233. # define SIZE 4
  234. char buf[SIZE + 1];
  235. do {
  236. if (!fgets(buf, SIZE, in))
  237. return 0;
  238. } while (strchr(buf, '\n') == NULL);
  239. return 1;
  240. }
  241. static volatile sig_atomic_t intr_signal;
  242. # endif
  243. static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
  244. {
  245. static int ps;
  246. int ok;
  247. char result[BUFSIZ];
  248. int maxsize = BUFSIZ - 1;
  249. # if !defined(OPENSSL_SYS_WINCE)
  250. char *p = NULL;
  251. int echo_eol = !echo;
  252. intr_signal = 0;
  253. ok = 0;
  254. ps = 0;
  255. pushsig();
  256. ps = 1;
  257. if (!echo && !noecho_console(ui))
  258. goto error;
  259. ps = 2;
  260. result[0] = '\0';
  261. # if defined(_WIN32)
  262. if (is_a_tty) {
  263. DWORD numread;
  264. # if defined(CP_UTF8)
  265. if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) != 0) {
  266. WCHAR wresult[BUFSIZ];
  267. if (ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE),
  268. wresult, maxsize, &numread, NULL)) {
  269. if (numread >= 2 &&
  270. wresult[numread-2] == L'\r' &&
  271. wresult[numread-1] == L'\n') {
  272. wresult[numread-2] = L'\n';
  273. numread--;
  274. }
  275. wresult[numread] = '\0';
  276. if (WideCharToMultiByte(CP_UTF8, 0, wresult, -1,
  277. result, sizeof(result), NULL, 0) > 0)
  278. p = result;
  279. OPENSSL_cleanse(wresult, sizeof(wresult));
  280. }
  281. } else
  282. # endif
  283. if (ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE),
  284. result, maxsize, &numread, NULL)) {
  285. if (numread >= 2 &&
  286. result[numread-2] == '\r' && result[numread-1] == '\n') {
  287. result[numread-2] = '\n';
  288. numread--;
  289. }
  290. result[numread] = '\0';
  291. p = result;
  292. }
  293. } else
  294. # elif defined(OPENSSL_SYS_MSDOS)
  295. if (!echo) {
  296. noecho_fgets(result, maxsize, tty_in);
  297. p = result; /* FIXME: noecho_fgets doesn't return errors */
  298. } else
  299. # endif
  300. p = fgets(result, maxsize, tty_in);
  301. if (p == NULL)
  302. goto error;
  303. if (feof(tty_in))
  304. goto error;
  305. if (ferror(tty_in))
  306. goto error;
  307. if ((p = (char *)strchr(result, '\n')) != NULL) {
  308. if (strip_nl)
  309. *p = '\0';
  310. } else if (!read_till_nl(tty_in))
  311. goto error;
  312. if (UI_set_result(ui, uis, result) >= 0)
  313. ok = 1;
  314. error:
  315. if (intr_signal == SIGINT)
  316. ok = -1;
  317. if (echo_eol)
  318. fprintf(tty_out, "\n");
  319. if (ps >= 2 && !echo && !echo_console(ui))
  320. ok = 0;
  321. if (ps >= 1)
  322. popsig();
  323. # else
  324. ok = 1;
  325. # endif
  326. OPENSSL_cleanse(result, BUFSIZ);
  327. return ok;
  328. }
  329. /* Internal functions to open, handle and close a channel to the console. */
  330. static int open_console(UI *ui)
  331. {
  332. if (!CRYPTO_THREAD_write_lock(ui->lock))
  333. return 0;
  334. is_a_tty = 1;
  335. # if defined(OPENSSL_SYS_VXWORKS)
  336. tty_in = stdin;
  337. tty_out = stderr;
  338. # elif defined(_WIN32) && !defined(_WIN32_WCE)
  339. if ((tty_out = fopen("conout$", "w")) == NULL)
  340. tty_out = stderr;
  341. if (GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &tty_orig)) {
  342. tty_in = stdin;
  343. } else {
  344. is_a_tty = 0;
  345. if ((tty_in = fopen("conin$", "r")) == NULL)
  346. tty_in = stdin;
  347. }
  348. # else
  349. # ifdef OPENSSL_SYS_MSDOS
  350. # define DEV_TTY "con"
  351. # else
  352. # define DEV_TTY "/dev/tty"
  353. # endif
  354. if ((tty_in = fopen(DEV_TTY, "r")) == NULL)
  355. tty_in = stdin;
  356. if ((tty_out = fopen(DEV_TTY, "w")) == NULL)
  357. tty_out = stderr;
  358. # endif
  359. # if defined(TTY_get) && !defined(OPENSSL_SYS_VMS)
  360. if (TTY_get(fileno(tty_in), &tty_orig) == -1) {
  361. # ifdef ENOTTY
  362. if (errno == ENOTTY)
  363. is_a_tty = 0;
  364. else
  365. # endif
  366. # ifdef EINVAL
  367. /*
  368. * Ariel Glenn reports that solaris can return EINVAL instead.
  369. * This should be ok
  370. */
  371. if (errno == EINVAL)
  372. is_a_tty = 0;
  373. else
  374. # endif
  375. # ifdef ENXIO
  376. /*
  377. * Solaris can return ENXIO.
  378. * This should be ok
  379. */
  380. if (errno == ENXIO)
  381. is_a_tty = 0;
  382. else
  383. # endif
  384. # ifdef EIO
  385. /*
  386. * Linux can return EIO.
  387. * This should be ok
  388. */
  389. if (errno == EIO)
  390. is_a_tty = 0;
  391. else
  392. # endif
  393. # ifdef EPERM
  394. /*
  395. * Linux can return EPERM (Operation not permitted),
  396. * e.g. if a daemon executes openssl via fork()+execve()
  397. * This should be ok
  398. */
  399. if (errno == EPERM)
  400. is_a_tty = 0;
  401. else
  402. # endif
  403. # ifdef ENODEV
  404. /*
  405. * MacOS X returns ENODEV (Operation not supported by device),
  406. * which seems appropriate.
  407. */
  408. if (errno == ENODEV)
  409. is_a_tty = 0;
  410. else
  411. # endif
  412. {
  413. ERR_raise_data(ERR_LIB_UI, UI_R_UNKNOWN_TTYGET_ERRNO_VALUE,
  414. "errno=%d", errno);
  415. return 0;
  416. }
  417. }
  418. # endif
  419. # ifdef OPENSSL_SYS_VMS
  420. status = sys$assign(&terminal, &channel, 0, 0);
  421. /* if there isn't a TT device, something is very wrong */
  422. if (status != SS$_NORMAL) {
  423. ERR_raise_data(ERR_LIB_UI, UI_R_SYSASSIGN_ERROR,
  424. "status=%%X%08X", status);
  425. return 0;
  426. }
  427. status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12,
  428. 0, 0, 0, 0);
  429. /* If IO$_SENSEMODE doesn't work, this is not a terminal device */
  430. if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
  431. is_a_tty = 0;
  432. # endif
  433. return 1;
  434. }
  435. static int noecho_console(UI *ui)
  436. {
  437. # ifdef TTY_FLAGS
  438. memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig));
  439. tty_new.TTY_FLAGS &= ~ECHO;
  440. # endif
  441. # if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
  442. if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1))
  443. return 0;
  444. # endif
  445. # ifdef OPENSSL_SYS_VMS
  446. if (is_a_tty) {
  447. tty_new[0] = tty_orig[0];
  448. tty_new[1] = tty_orig[1] | TT$M_NOECHO;
  449. tty_new[2] = tty_orig[2];
  450. status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12,
  451. 0, 0, 0, 0);
  452. if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) {
  453. ERR_raise_data(ERR_LIB_UI, UI_R_SYSQIOW_ERROR,
  454. "status=%%X%08X, iosb.iosb$w_value=%%X%08X",
  455. status, iosb.iosb$w_value);
  456. return 0;
  457. }
  458. }
  459. # endif
  460. # if defined(_WIN32) && !defined(_WIN32_WCE)
  461. if (is_a_tty) {
  462. tty_new = tty_orig;
  463. tty_new &= ~ENABLE_ECHO_INPUT;
  464. SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), tty_new);
  465. }
  466. # endif
  467. return 1;
  468. }
  469. static int echo_console(UI *ui)
  470. {
  471. # if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
  472. memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig));
  473. if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1))
  474. return 0;
  475. # endif
  476. # ifdef OPENSSL_SYS_VMS
  477. if (is_a_tty) {
  478. tty_new[0] = tty_orig[0];
  479. tty_new[1] = tty_orig[1];
  480. tty_new[2] = tty_orig[2];
  481. status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12,
  482. 0, 0, 0, 0);
  483. if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) {
  484. ERR_raise_data(ERR_LIB_UI, UI_R_SYSQIOW_ERROR,
  485. "status=%%X%08X, iosb.iosb$w_value=%%X%08X",
  486. status, iosb.iosb$w_value);
  487. return 0;
  488. }
  489. }
  490. # endif
  491. # if defined(_WIN32) && !defined(_WIN32_WCE)
  492. if (is_a_tty) {
  493. tty_new = tty_orig;
  494. SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), tty_new);
  495. }
  496. # endif
  497. return 1;
  498. }
  499. static int close_console(UI *ui)
  500. {
  501. int ret = 1;
  502. if (tty_in != stdin)
  503. fclose(tty_in);
  504. if (tty_out != stderr)
  505. fclose(tty_out);
  506. # ifdef OPENSSL_SYS_VMS
  507. status = sys$dassgn(channel);
  508. if (status != SS$_NORMAL) {
  509. ERR_raise_data(ERR_LIB_UI, UI_R_SYSDASSGN_ERROR,
  510. "status=%%X%08X", status);
  511. ret = 0;
  512. }
  513. # endif
  514. CRYPTO_THREAD_unlock(ui->lock);
  515. return ret;
  516. }
  517. # if !defined(OPENSSL_SYS_WINCE)
  518. /* Internal functions to handle signals and act on them */
  519. static void pushsig(void)
  520. {
  521. # ifndef OPENSSL_SYS_WIN32
  522. int i;
  523. # endif
  524. # ifdef SIGACTION
  525. struct sigaction sa;
  526. memset(&sa, 0, sizeof(sa));
  527. sa.sa_handler = recsig;
  528. # endif
  529. # ifdef OPENSSL_SYS_WIN32
  530. savsig[SIGABRT] = signal(SIGABRT, recsig);
  531. savsig[SIGFPE] = signal(SIGFPE, recsig);
  532. savsig[SIGILL] = signal(SIGILL, recsig);
  533. savsig[SIGINT] = signal(SIGINT, recsig);
  534. savsig[SIGSEGV] = signal(SIGSEGV, recsig);
  535. savsig[SIGTERM] = signal(SIGTERM, recsig);
  536. # else
  537. for (i = 1; i < NX509_SIG; i++) {
  538. # ifdef SIGUSR1
  539. if (i == SIGUSR1)
  540. continue;
  541. # endif
  542. # ifdef SIGUSR2
  543. if (i == SIGUSR2)
  544. continue;
  545. # endif
  546. # ifdef SIGKILL
  547. if (i == SIGKILL) /* We can't make any action on that. */
  548. continue;
  549. # endif
  550. # ifdef SIGACTION
  551. sigaction(i, &sa, &savsig[i]);
  552. # else
  553. savsig[i] = signal(i, recsig);
  554. # endif
  555. }
  556. # endif
  557. # ifdef SIGWINCH
  558. signal(SIGWINCH, SIG_DFL);
  559. # endif
  560. }
  561. static void popsig(void)
  562. {
  563. # ifdef OPENSSL_SYS_WIN32
  564. signal(SIGABRT, savsig[SIGABRT]);
  565. signal(SIGFPE, savsig[SIGFPE]);
  566. signal(SIGILL, savsig[SIGILL]);
  567. signal(SIGINT, savsig[SIGINT]);
  568. signal(SIGSEGV, savsig[SIGSEGV]);
  569. signal(SIGTERM, savsig[SIGTERM]);
  570. # else
  571. int i;
  572. for (i = 1; i < NX509_SIG; i++) {
  573. # ifdef SIGUSR1
  574. if (i == SIGUSR1)
  575. continue;
  576. # endif
  577. # ifdef SIGUSR2
  578. if (i == SIGUSR2)
  579. continue;
  580. # endif
  581. # ifdef SIGACTION
  582. sigaction(i, &savsig[i], NULL);
  583. # else
  584. signal(i, savsig[i]);
  585. # endif
  586. }
  587. # endif
  588. }
  589. static void recsig(int i)
  590. {
  591. intr_signal = i;
  592. }
  593. # endif
  594. /* Internal functions specific for Windows */
  595. # if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
  596. static int noecho_fgets(char *buf, int size, FILE *tty)
  597. {
  598. int i;
  599. char *p;
  600. p = buf;
  601. for (;;) {
  602. if (size == 0) {
  603. *p = '\0';
  604. break;
  605. }
  606. size--;
  607. # if defined(_WIN32)
  608. i = _getch();
  609. # else
  610. i = getch();
  611. # endif
  612. if (i == '\r')
  613. i = '\n';
  614. *(p++) = i;
  615. if (i == '\n') {
  616. *p = '\0';
  617. break;
  618. }
  619. }
  620. # ifdef WIN_CONSOLE_BUG
  621. /*
  622. * Win95 has several evil console bugs: one of these is that the last
  623. * character read using getch() is passed to the next read: this is
  624. * usually a CR so this can be trouble. No STDIO fix seems to work but
  625. * flushing the console appears to do the trick.
  626. */
  627. {
  628. HANDLE inh;
  629. inh = GetStdHandle(STD_INPUT_HANDLE);
  630. FlushConsoleInputBuffer(inh);
  631. }
  632. # endif
  633. return strlen(buf);
  634. }
  635. # endif
  636. static UI_METHOD ui_openssl = {
  637. "OpenSSL default user interface",
  638. open_console,
  639. write_string,
  640. NULL, /* No flusher is needed for command lines */
  641. read_string,
  642. close_console,
  643. NULL
  644. };
  645. /* The method with all the built-in console thingies */
  646. UI_METHOD *UI_OpenSSL(void)
  647. {
  648. return &ui_openssl;
  649. }
  650. static const UI_METHOD *default_UI_meth = &ui_openssl;
  651. #else
  652. static const UI_METHOD *default_UI_meth = NULL;
  653. #endif
  654. void UI_set_default_method(const UI_METHOD *meth)
  655. {
  656. default_UI_meth = meth;
  657. }
  658. const UI_METHOD *UI_get_default_method(void)
  659. {
  660. return default_UI_meth;
  661. }