/src/openssl/crypto/ui/ui_openssl.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* crypto/ui/ui_openssl.c */ |
2 | | /* |
3 | | * Written by Richard Levitte (richard@levitte.org) and others for the |
4 | | * OpenSSL project 2001. |
5 | | */ |
6 | | /* ==================================================================== |
7 | | * Copyright (c) 2001 The OpenSSL Project. All rights reserved. |
8 | | * |
9 | | * Redistribution and use in source and binary forms, with or without |
10 | | * modification, are permitted provided that the following conditions |
11 | | * are met: |
12 | | * |
13 | | * 1. Redistributions of source code must retain the above copyright |
14 | | * notice, this list of conditions and the following disclaimer. |
15 | | * |
16 | | * 2. Redistributions in binary form must reproduce the above copyright |
17 | | * notice, this list of conditions and the following disclaimer in |
18 | | * the documentation and/or other materials provided with the |
19 | | * distribution. |
20 | | * |
21 | | * 3. All advertising materials mentioning features or use of this |
22 | | * software must display the following acknowledgment: |
23 | | * "This product includes software developed by the OpenSSL Project |
24 | | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
25 | | * |
26 | | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
27 | | * endorse or promote products derived from this software without |
28 | | * prior written permission. For written permission, please contact |
29 | | * openssl-core@openssl.org. |
30 | | * |
31 | | * 5. Products derived from this software may not be called "OpenSSL" |
32 | | * nor may "OpenSSL" appear in their names without prior written |
33 | | * permission of the OpenSSL Project. |
34 | | * |
35 | | * 6. Redistributions of any form whatsoever must retain the following |
36 | | * acknowledgment: |
37 | | * "This product includes software developed by the OpenSSL Project |
38 | | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
39 | | * |
40 | | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
41 | | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
42 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
43 | | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
44 | | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
45 | | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
46 | | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
47 | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
48 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
49 | | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
50 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
51 | | * OF THE POSSIBILITY OF SUCH DAMAGE. |
52 | | * ==================================================================== |
53 | | * |
54 | | * This product includes cryptographic software written by Eric Young |
55 | | * (eay@cryptsoft.com). This product includes software written by Tim |
56 | | * Hudson (tjh@cryptsoft.com). |
57 | | * |
58 | | */ |
59 | | |
60 | | /*- |
61 | | * The lowest level part of this file was previously in crypto/des/read_pwd.c, |
62 | | * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
63 | | * All rights reserved. |
64 | | * |
65 | | * This package is an SSL implementation written |
66 | | * by Eric Young (eay@cryptsoft.com). |
67 | | * The implementation was written so as to conform with Netscapes SSL. |
68 | | * |
69 | | * This library is free for commercial and non-commercial use as long as |
70 | | * the following conditions are aheared to. The following conditions |
71 | | * apply to all code found in this distribution, be it the RC4, RSA, |
72 | | * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
73 | | * included with this distribution is covered by the same copyright terms |
74 | | * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
75 | | * |
76 | | * Copyright remains Eric Young's, and as such any Copyright notices in |
77 | | * the code are not to be removed. |
78 | | * If this package is used in a product, Eric Young should be given attribution |
79 | | * as the author of the parts of the library used. |
80 | | * This can be in the form of a textual message at program startup or |
81 | | * in documentation (online or textual) provided with the package. |
82 | | * |
83 | | * Redistribution and use in source and binary forms, with or without |
84 | | * modification, are permitted provided that the following conditions |
85 | | * are met: |
86 | | * 1. Redistributions of source code must retain the copyright |
87 | | * notice, this list of conditions and the following disclaimer. |
88 | | * 2. Redistributions in binary form must reproduce the above copyright |
89 | | * notice, this list of conditions and the following disclaimer in the |
90 | | * documentation and/or other materials provided with the distribution. |
91 | | * 3. All advertising materials mentioning features or use of this software |
92 | | * must display the following acknowledgement: |
93 | | * "This product includes cryptographic software written by |
94 | | * Eric Young (eay@cryptsoft.com)" |
95 | | * The word 'cryptographic' can be left out if the rouines from the library |
96 | | * being used are not cryptographic related :-). |
97 | | * 4. If you include any Windows specific code (or a derivative thereof) from |
98 | | * the apps directory (application code) you must include an acknowledgement: |
99 | | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
100 | | * |
101 | | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
102 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
103 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
104 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
105 | | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
106 | | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
107 | | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
108 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
109 | | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
110 | | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
111 | | * SUCH DAMAGE. |
112 | | * |
113 | | * The licence and distribution terms for any publically available version or |
114 | | * derivative of this code cannot be changed. i.e. this code cannot simply be |
115 | | * copied and put under another distribution licence |
116 | | * [including the GNU Public Licence.] |
117 | | */ |
118 | | |
119 | | #include <openssl/e_os2.h> |
120 | | |
121 | | /* |
122 | | * need for #define _POSIX_C_SOURCE arises whenever you pass -ansi to gcc |
123 | | * [maybe others?], because it masks interfaces not discussed in standard, |
124 | | * sigaction and fileno included. -pedantic would be more appropriate for the |
125 | | * intended purposes, but we can't prevent users from adding -ansi. |
126 | | */ |
127 | | #if defined(OPENSSL_SYSNAME_VXWORKS) |
128 | | # include <sys/types.h> |
129 | | #endif |
130 | | |
131 | | #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) |
132 | | # ifndef _POSIX_C_SOURCE |
133 | | # define _POSIX_C_SOURCE 2 |
134 | | # endif |
135 | | #endif |
136 | | #include <signal.h> |
137 | | #include <stdio.h> |
138 | | #include <string.h> |
139 | | #include <errno.h> |
140 | | |
141 | | #if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) |
142 | | # ifdef OPENSSL_UNISTD |
143 | | # include OPENSSL_UNISTD |
144 | | # else |
145 | | # include <unistd.h> |
146 | | # endif |
147 | | /* |
148 | | * If unistd.h defines _POSIX_VERSION, we conclude that we are on a POSIX |
149 | | * system and have sigaction and termios. |
150 | | */ |
151 | | # if defined(_POSIX_VERSION) |
152 | | |
153 | | # define SIGACTION |
154 | | # if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) |
155 | | # define TERMIOS |
156 | | # endif |
157 | | |
158 | | # endif |
159 | | #endif |
160 | | |
161 | | #ifdef WIN16TTY |
162 | | # undef OPENSSL_SYS_WIN16 |
163 | | # undef WIN16 |
164 | | # undef _WINDOWS |
165 | | # include <graph.h> |
166 | | #endif |
167 | | |
168 | | /* 06-Apr-92 Luke Brennan Support for VMS */ |
169 | | #include "ui_locl.h" |
170 | | #include "cryptlib.h" |
171 | | |
172 | | #ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */ |
173 | | # include <starlet.h> |
174 | | # ifdef __DECC |
175 | | # pragma message disable DOLLARID |
176 | | # endif |
177 | | #endif |
178 | | |
179 | | #ifdef WIN_CONSOLE_BUG |
180 | | # include <windows.h> |
181 | | # ifndef OPENSSL_SYS_WINCE |
182 | | # include <wincon.h> |
183 | | # endif |
184 | | #endif |
185 | | |
186 | | /* |
187 | | * There are 5 types of terminal interface supported, TERMIO, TERMIOS, VMS, |
188 | | * MSDOS and SGTTY. |
189 | | * |
190 | | * If someone defines one of the macros TERMIO, TERMIOS or SGTTY, it will |
191 | | * remain respected. Otherwise, we default to TERMIOS except for a few |
192 | | * systems that require something different. |
193 | | * |
194 | | * Note: we do not use SGTTY unless it's defined by the configuration. We |
195 | | * may eventually opt to remove it's use entirely. |
196 | | */ |
197 | | |
198 | | #if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) |
199 | | |
200 | | # if defined(_LIBC) |
201 | | # undef TERMIOS |
202 | | # define TERMIO |
203 | | # undef SGTTY |
204 | | /* |
205 | | * We know that VMS, MSDOS, VXWORKS, NETWARE use entirely other mechanisms. |
206 | | * MAC_OS_GUSI_SOURCE should probably go away, but that needs to be confirmed. |
207 | | */ |
208 | | # elif !defined(OPENSSL_SYS_VMS) \ |
209 | | && !defined(OPENSSL_SYS_MSDOS) \ |
210 | | && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) \ |
211 | | && !defined(MAC_OS_GUSI_SOURCE) \ |
212 | | && !defined(OPENSSL_SYS_VXWORKS) \ |
213 | | && !defined(OPENSSL_SYS_NETWARE) |
214 | | # define TERMIOS |
215 | | # undef TERMIO |
216 | | # undef SGTTY |
217 | | # endif |
218 | | |
219 | | #endif |
220 | | |
221 | | #ifdef TERMIOS |
222 | | # include <termios.h> |
223 | | # define TTY_STRUCT struct termios |
224 | 0 | # define TTY_FLAGS c_lflag |
225 | 0 | # define TTY_get(tty,data) tcgetattr(tty,data) |
226 | 0 | # define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) |
227 | | #endif |
228 | | |
229 | | #ifdef TERMIO |
230 | | # include <termio.h> |
231 | | # define TTY_STRUCT struct termio |
232 | | # define TTY_FLAGS c_lflag |
233 | | # define TTY_get(tty,data) ioctl(tty,TCGETA,data) |
234 | | # define TTY_set(tty,data) ioctl(tty,TCSETA,data) |
235 | | #endif |
236 | | |
237 | | #ifdef SGTTY |
238 | | # include <sgtty.h> |
239 | | # define TTY_STRUCT struct sgttyb |
240 | | # define TTY_FLAGS sg_flags |
241 | | # define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) |
242 | | # define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) |
243 | | #endif |
244 | | |
245 | | #if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(OPENSSL_SYS_SUNOS) |
246 | | # include <sys/ioctl.h> |
247 | | #endif |
248 | | |
249 | | #ifdef OPENSSL_SYS_MSDOS |
250 | | # include <conio.h> |
251 | | #endif |
252 | | |
253 | | #ifdef OPENSSL_SYS_VMS |
254 | | # include <ssdef.h> |
255 | | # include <iodef.h> |
256 | | # include <ttdef.h> |
257 | | # include <descrip.h> |
258 | | struct IOSB { |
259 | | short iosb$w_value; |
260 | | short iosb$w_count; |
261 | | long iosb$l_info; |
262 | | }; |
263 | | #endif |
264 | | |
265 | | #ifdef OPENSSL_SYS_SUNOS |
266 | | typedef int sig_atomic_t; |
267 | | #endif |
268 | | |
269 | | #if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) || defined(OPENSSL_SYS_NETWARE) |
270 | | /* |
271 | | * This one needs work. As a matter of fact the code is unoperational |
272 | | * and this is only a trick to get it compiled. |
273 | | * <appro@fy.chalmers.se> |
274 | | */ |
275 | | # define TTY_STRUCT int |
276 | | #endif |
277 | | |
278 | | #ifndef NX509_SIG |
279 | 0 | # define NX509_SIG 32 |
280 | | #endif |
281 | | |
282 | | /* Define globals. They are protected by a lock */ |
283 | | #ifdef SIGACTION |
284 | | static struct sigaction savsig[NX509_SIG]; |
285 | | #else |
286 | | static void (*savsig[NX509_SIG]) (int); |
287 | | #endif |
288 | | |
289 | | #ifdef OPENSSL_SYS_VMS |
290 | | static struct IOSB iosb; |
291 | | static $DESCRIPTOR(terminal, "TT"); |
292 | | static long tty_orig[3], tty_new[3]; /* XXX Is there any guarantee that this |
293 | | * will always suffice for the actual |
294 | | * structures? */ |
295 | | static long status; |
296 | | static unsigned short channel = 0; |
297 | | #else |
298 | | # if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) |
299 | | static TTY_STRUCT tty_orig, tty_new; |
300 | | # endif |
301 | | #endif |
302 | | static FILE *tty_in, *tty_out; |
303 | | static int is_a_tty; |
304 | | |
305 | | /* Declare static functions */ |
306 | | #if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) |
307 | | static int read_till_nl(FILE *); |
308 | | static void recsig(int); |
309 | | static void pushsig(void); |
310 | | static void popsig(void); |
311 | | #endif |
312 | | #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) |
313 | | static int noecho_fgets(char *buf, int size, FILE *tty); |
314 | | #endif |
315 | | static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl); |
316 | | |
317 | | static int read_string(UI *ui, UI_STRING *uis); |
318 | | static int write_string(UI *ui, UI_STRING *uis); |
319 | | |
320 | | static int open_console(UI *ui); |
321 | | static int echo_console(UI *ui); |
322 | | static int noecho_console(UI *ui); |
323 | | static int close_console(UI *ui); |
324 | | |
325 | | static UI_METHOD ui_openssl = { |
326 | | "OpenSSL default user interface", |
327 | | open_console, |
328 | | write_string, |
329 | | NULL, /* No flusher is needed for command lines */ |
330 | | read_string, |
331 | | close_console, |
332 | | NULL |
333 | | }; |
334 | | |
335 | | /* The method with all the built-in thingies */ |
336 | | UI_METHOD *UI_OpenSSL(void) |
337 | 0 | { |
338 | 0 | return &ui_openssl; |
339 | 0 | } |
340 | | |
341 | | /* |
342 | | * The following function makes sure that info and error strings are printed |
343 | | * before any prompt. |
344 | | */ |
345 | | static int write_string(UI *ui, UI_STRING *uis) |
346 | 0 | { |
347 | 0 | switch (UI_get_string_type(uis)) { |
348 | 0 | case UIT_ERROR: |
349 | 0 | case UIT_INFO: |
350 | 0 | fputs(UI_get0_output_string(uis), tty_out); |
351 | 0 | fflush(tty_out); |
352 | 0 | break; |
353 | 0 | default: |
354 | 0 | break; |
355 | 0 | } |
356 | 0 | return 1; |
357 | 0 | } |
358 | | |
359 | | static int read_string(UI *ui, UI_STRING *uis) |
360 | 0 | { |
361 | 0 | int ok = 0; |
362 | |
|
363 | 0 | switch (UI_get_string_type(uis)) { |
364 | 0 | case UIT_BOOLEAN: |
365 | 0 | fputs(UI_get0_output_string(uis), tty_out); |
366 | 0 | fputs(UI_get0_action_string(uis), tty_out); |
367 | 0 | fflush(tty_out); |
368 | 0 | return read_string_inner(ui, uis, |
369 | 0 | UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, |
370 | 0 | 0); |
371 | 0 | case UIT_PROMPT: |
372 | 0 | fputs(UI_get0_output_string(uis), tty_out); |
373 | 0 | fflush(tty_out); |
374 | 0 | return read_string_inner(ui, uis, |
375 | 0 | UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, |
376 | 0 | 1); |
377 | 0 | case UIT_VERIFY: |
378 | 0 | fprintf(tty_out, "Verifying - %s", UI_get0_output_string(uis)); |
379 | 0 | fflush(tty_out); |
380 | 0 | if ((ok = read_string_inner(ui, uis, |
381 | 0 | UI_get_input_flags(uis) & |
382 | 0 | UI_INPUT_FLAG_ECHO, 1)) <= 0) |
383 | 0 | return ok; |
384 | 0 | if (strcmp(UI_get0_result_string(uis), UI_get0_test_string(uis)) != 0) { |
385 | 0 | fprintf(tty_out, "Verify failure\n"); |
386 | 0 | fflush(tty_out); |
387 | 0 | return 0; |
388 | 0 | } |
389 | 0 | break; |
390 | 0 | default: |
391 | 0 | break; |
392 | 0 | } |
393 | 0 | return 1; |
394 | 0 | } |
395 | | |
396 | | #if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) |
397 | | /* Internal functions to read a string without echoing */ |
398 | | static int read_till_nl(FILE *in) |
399 | 0 | { |
400 | 0 | # define SIZE 4 |
401 | 0 | char buf[SIZE + 1]; |
402 | |
|
403 | 0 | do { |
404 | 0 | if (!fgets(buf, SIZE, in)) |
405 | 0 | return 0; |
406 | 0 | } while (strchr(buf, '\n') == NULL); |
407 | 0 | return 1; |
408 | 0 | } |
409 | | |
410 | | static volatile sig_atomic_t intr_signal; |
411 | | #endif |
412 | | |
413 | | static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) |
414 | 0 | { |
415 | 0 | static int ps; |
416 | 0 | int ok; |
417 | 0 | char result[BUFSIZ]; |
418 | 0 | int maxsize = BUFSIZ - 1; |
419 | 0 | #if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) |
420 | 0 | char *p; |
421 | |
|
422 | 0 | intr_signal = 0; |
423 | 0 | ok = 0; |
424 | 0 | ps = 0; |
425 | |
|
426 | 0 | pushsig(); |
427 | 0 | ps = 1; |
428 | |
|
429 | 0 | if (!echo && !noecho_console(ui)) |
430 | 0 | goto error; |
431 | 0 | ps = 2; |
432 | |
|
433 | 0 | result[0] = '\0'; |
434 | | # ifdef OPENSSL_SYS_MSDOS |
435 | | if (!echo) { |
436 | | noecho_fgets(result, maxsize, tty_in); |
437 | | p = result; /* FIXME: noecho_fgets doesn't return errors */ |
438 | | } else |
439 | | p = fgets(result, maxsize, tty_in); |
440 | | # else |
441 | 0 | p = fgets(result, maxsize, tty_in); |
442 | 0 | # endif |
443 | 0 | if (p == NULL) |
444 | 0 | goto error; |
445 | 0 | if (feof(tty_in)) |
446 | 0 | goto error; |
447 | 0 | if (ferror(tty_in)) |
448 | 0 | goto error; |
449 | 0 | if ((p = (char *)strchr(result, '\n')) != NULL) { |
450 | 0 | if (strip_nl) |
451 | 0 | *p = '\0'; |
452 | 0 | } else if (!read_till_nl(tty_in)) |
453 | 0 | goto error; |
454 | 0 | if (UI_set_result(ui, uis, result) >= 0) |
455 | 0 | ok = 1; |
456 | |
|
457 | 0 | error: |
458 | 0 | if (intr_signal == SIGINT) |
459 | 0 | ok = -1; |
460 | 0 | if (!echo) |
461 | 0 | fprintf(tty_out, "\n"); |
462 | 0 | if (ps >= 2 && !echo && !echo_console(ui)) |
463 | 0 | ok = 0; |
464 | |
|
465 | 0 | if (ps >= 1) |
466 | 0 | popsig(); |
467 | | #else |
468 | | ok = 1; |
469 | | #endif |
470 | |
|
471 | 0 | OPENSSL_cleanse(result, BUFSIZ); |
472 | 0 | return ok; |
473 | 0 | } |
474 | | |
475 | | /* Internal functions to open, handle and close a channel to the console. */ |
476 | | static int open_console(UI *ui) |
477 | 0 | { |
478 | 0 | CRYPTO_w_lock(CRYPTO_LOCK_UI); |
479 | 0 | is_a_tty = 1; |
480 | |
|
481 | | #if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS) |
482 | | tty_in = stdin; |
483 | | tty_out = stderr; |
484 | | #else |
485 | | # ifdef OPENSSL_SYS_MSDOS |
486 | | # define DEV_TTY "con" |
487 | | # else |
488 | 0 | # define DEV_TTY "/dev/tty" |
489 | 0 | # endif |
490 | 0 | if ((tty_in = fopen(DEV_TTY, "r")) == NULL) |
491 | 0 | tty_in = stdin; |
492 | 0 | if ((tty_out = fopen(DEV_TTY, "w")) == NULL) |
493 | 0 | tty_out = stderr; |
494 | 0 | #endif |
495 | |
|
496 | 0 | #if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) |
497 | 0 | if (TTY_get(fileno(tty_in), &tty_orig) == -1) { |
498 | 0 | # ifdef ENOTTY |
499 | 0 | if (errno == ENOTTY) |
500 | 0 | is_a_tty = 0; |
501 | 0 | else |
502 | 0 | # endif |
503 | 0 | # ifdef EINVAL |
504 | | /* |
505 | | * Ariel Glenn ariel@columbia.edu reports that solaris can return |
506 | | * EINVAL instead. This should be ok |
507 | | */ |
508 | 0 | if (errno == EINVAL) |
509 | 0 | is_a_tty = 0; |
510 | 0 | else |
511 | 0 | # endif |
512 | 0 | # ifdef ENODEV |
513 | | /* |
514 | | * MacOS X returns ENODEV (Operation not supported by device), |
515 | | * which seems appropriate. |
516 | | */ |
517 | 0 | if (errno == ENODEV) |
518 | 0 | is_a_tty = 0; |
519 | 0 | else |
520 | 0 | # endif |
521 | 0 | return 0; |
522 | 0 | } |
523 | 0 | #endif |
524 | | #ifdef OPENSSL_SYS_VMS |
525 | | status = sys$assign(&terminal, &channel, 0, 0); |
526 | | |
527 | | /* if there isn't a TT device, something is very wrong */ |
528 | | if (status != SS$_NORMAL) |
529 | | return 0; |
530 | | |
531 | | status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, |
532 | | 0, 0, 0, 0); |
533 | | |
534 | | /* If IO$_SENSEMODE doesn't work, this is not a terminal device */ |
535 | | if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) |
536 | | is_a_tty = 0; |
537 | | #endif |
538 | 0 | return 1; |
539 | 0 | } |
540 | | |
541 | | static int noecho_console(UI *ui) |
542 | 0 | { |
543 | 0 | #ifdef TTY_FLAGS |
544 | 0 | memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); |
545 | 0 | tty_new.TTY_FLAGS &= ~ECHO; |
546 | 0 | #endif |
547 | |
|
548 | 0 | #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) |
549 | 0 | if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1)) |
550 | 0 | return 0; |
551 | 0 | #endif |
552 | | #ifdef OPENSSL_SYS_VMS |
553 | | if (is_a_tty) { |
554 | | tty_new[0] = tty_orig[0]; |
555 | | tty_new[1] = tty_orig[1] | TT$M_NOECHO; |
556 | | tty_new[2] = tty_orig[2]; |
557 | | status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, |
558 | | 0, 0, 0, 0); |
559 | | if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) |
560 | | return 0; |
561 | | } |
562 | | #endif |
563 | 0 | return 1; |
564 | 0 | } |
565 | | |
566 | | static int echo_console(UI *ui) |
567 | 0 | { |
568 | 0 | #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) |
569 | 0 | memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); |
570 | 0 | tty_new.TTY_FLAGS |= ECHO; |
571 | 0 | #endif |
572 | |
|
573 | 0 | #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) |
574 | 0 | if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1)) |
575 | 0 | return 0; |
576 | 0 | #endif |
577 | | #ifdef OPENSSL_SYS_VMS |
578 | | if (is_a_tty) { |
579 | | tty_new[0] = tty_orig[0]; |
580 | | tty_new[1] = tty_orig[1] & ~TT$M_NOECHO; |
581 | | tty_new[2] = tty_orig[2]; |
582 | | status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, |
583 | | 0, 0, 0, 0); |
584 | | if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) |
585 | | return 0; |
586 | | } |
587 | | #endif |
588 | 0 | return 1; |
589 | 0 | } |
590 | | |
591 | | static int close_console(UI *ui) |
592 | 0 | { |
593 | 0 | if (tty_in != stdin) |
594 | 0 | fclose(tty_in); |
595 | 0 | if (tty_out != stderr) |
596 | 0 | fclose(tty_out); |
597 | | #ifdef OPENSSL_SYS_VMS |
598 | | status = sys$dassgn(channel); |
599 | | if (status != SS$_NORMAL) |
600 | | return 0; |
601 | | #endif |
602 | 0 | CRYPTO_w_unlock(CRYPTO_LOCK_UI); |
603 | |
|
604 | 0 | return 1; |
605 | 0 | } |
606 | | |
607 | | #if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) |
608 | | /* Internal functions to handle signals and act on them */ |
609 | | static void pushsig(void) |
610 | 0 | { |
611 | 0 | # ifndef OPENSSL_SYS_WIN32 |
612 | 0 | int i; |
613 | 0 | # endif |
614 | 0 | # ifdef SIGACTION |
615 | 0 | struct sigaction sa; |
616 | |
|
617 | 0 | memset(&sa, 0, sizeof sa); |
618 | 0 | sa.sa_handler = recsig; |
619 | 0 | # endif |
620 | |
|
621 | | # ifdef OPENSSL_SYS_WIN32 |
622 | | savsig[SIGABRT] = signal(SIGABRT, recsig); |
623 | | savsig[SIGFPE] = signal(SIGFPE, recsig); |
624 | | savsig[SIGILL] = signal(SIGILL, recsig); |
625 | | savsig[SIGINT] = signal(SIGINT, recsig); |
626 | | savsig[SIGSEGV] = signal(SIGSEGV, recsig); |
627 | | savsig[SIGTERM] = signal(SIGTERM, recsig); |
628 | | # else |
629 | 0 | for (i = 1; i < NX509_SIG; i++) { |
630 | 0 | # ifdef SIGUSR1 |
631 | 0 | if (i == SIGUSR1) |
632 | 0 | continue; |
633 | 0 | # endif |
634 | 0 | # ifdef SIGUSR2 |
635 | 0 | if (i == SIGUSR2) |
636 | 0 | continue; |
637 | 0 | # endif |
638 | 0 | # ifdef SIGKILL |
639 | 0 | if (i == SIGKILL) /* We can't make any action on that. */ |
640 | 0 | continue; |
641 | 0 | # endif |
642 | 0 | # ifdef SIGACTION |
643 | 0 | sigaction(i, &sa, &savsig[i]); |
644 | | # else |
645 | | savsig[i] = signal(i, recsig); |
646 | | # endif |
647 | 0 | } |
648 | 0 | # endif |
649 | |
|
650 | 0 | # ifdef SIGWINCH |
651 | 0 | signal(SIGWINCH, SIG_DFL); |
652 | 0 | # endif |
653 | 0 | } |
654 | | |
655 | | static void popsig(void) |
656 | 0 | { |
657 | | # ifdef OPENSSL_SYS_WIN32 |
658 | | signal(SIGABRT, savsig[SIGABRT]); |
659 | | signal(SIGFPE, savsig[SIGFPE]); |
660 | | signal(SIGILL, savsig[SIGILL]); |
661 | | signal(SIGINT, savsig[SIGINT]); |
662 | | signal(SIGSEGV, savsig[SIGSEGV]); |
663 | | signal(SIGTERM, savsig[SIGTERM]); |
664 | | # else |
665 | 0 | int i; |
666 | 0 | for (i = 1; i < NX509_SIG; i++) { |
667 | 0 | # ifdef SIGUSR1 |
668 | 0 | if (i == SIGUSR1) |
669 | 0 | continue; |
670 | 0 | # endif |
671 | 0 | # ifdef SIGUSR2 |
672 | 0 | if (i == SIGUSR2) |
673 | 0 | continue; |
674 | 0 | # endif |
675 | 0 | # ifdef SIGACTION |
676 | 0 | sigaction(i, &savsig[i], NULL); |
677 | | # else |
678 | | signal(i, savsig[i]); |
679 | | # endif |
680 | 0 | } |
681 | 0 | # endif |
682 | 0 | } |
683 | | |
684 | | static void recsig(int i) |
685 | 0 | { |
686 | 0 | intr_signal = i; |
687 | 0 | } |
688 | | #endif |
689 | | |
690 | | /* Internal functions specific for Windows */ |
691 | | #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) |
692 | | static int noecho_fgets(char *buf, int size, FILE *tty) |
693 | | { |
694 | | int i; |
695 | | char *p; |
696 | | |
697 | | p = buf; |
698 | | for (;;) { |
699 | | if (size == 0) { |
700 | | *p = '\0'; |
701 | | break; |
702 | | } |
703 | | size--; |
704 | | # ifdef WIN16TTY |
705 | | i = _inchar(); |
706 | | # elif defined(_WIN32) |
707 | | i = _getch(); |
708 | | # else |
709 | | i = getch(); |
710 | | # endif |
711 | | if (i == '\r') |
712 | | i = '\n'; |
713 | | *(p++) = i; |
714 | | if (i == '\n') { |
715 | | *p = '\0'; |
716 | | break; |
717 | | } |
718 | | } |
719 | | # ifdef WIN_CONSOLE_BUG |
720 | | /* |
721 | | * Win95 has several evil console bugs: one of these is that the last |
722 | | * character read using getch() is passed to the next read: this is |
723 | | * usually a CR so this can be trouble. No STDIO fix seems to work but |
724 | | * flushing the console appears to do the trick. |
725 | | */ |
726 | | { |
727 | | HANDLE inh; |
728 | | inh = GetStdHandle(STD_INPUT_HANDLE); |
729 | | FlushConsoleInputBuffer(inh); |
730 | | } |
731 | | # endif |
732 | | return (strlen(buf)); |
733 | | } |
734 | | #endif |