ui_openssl.c 19 KB

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