1295016Sjkim/* crypto/ui/ui_openssl.c */ 2280304Sjkim/* 3280304Sjkim * Written by Richard Levitte (richard@levitte.org) and others for the 4280304Sjkim * OpenSSL project 2001. 5109998Smarkm */ 6109998Smarkm/* ==================================================================== 7109998Smarkm * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 8109998Smarkm * 9109998Smarkm * Redistribution and use in source and binary forms, with or without 10109998Smarkm * modification, are permitted provided that the following conditions 11109998Smarkm * are met: 12109998Smarkm * 13109998Smarkm * 1. Redistributions of source code must retain the above copyright 14280304Sjkim * notice, this list of conditions and the following disclaimer. 15109998Smarkm * 16109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 17109998Smarkm * notice, this list of conditions and the following disclaimer in 18109998Smarkm * the documentation and/or other materials provided with the 19109998Smarkm * distribution. 20109998Smarkm * 21109998Smarkm * 3. All advertising materials mentioning features or use of this 22109998Smarkm * software must display the following acknowledgment: 23109998Smarkm * "This product includes software developed by the OpenSSL Project 24109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 25109998Smarkm * 26109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27109998Smarkm * endorse or promote products derived from this software without 28109998Smarkm * prior written permission. For written permission, please contact 29109998Smarkm * openssl-core@openssl.org. 30109998Smarkm * 31109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 32109998Smarkm * nor may "OpenSSL" appear in their names without prior written 33109998Smarkm * permission of the OpenSSL Project. 34109998Smarkm * 35109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 36109998Smarkm * acknowledgment: 37109998Smarkm * "This product includes software developed by the OpenSSL Project 38109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 39109998Smarkm * 40109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 52109998Smarkm * ==================================================================== 53109998Smarkm * 54109998Smarkm * This product includes cryptographic software written by Eric Young 55109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 56109998Smarkm * Hudson (tjh@cryptsoft.com). 57109998Smarkm * 58109998Smarkm */ 59109998Smarkm 60280304Sjkim/*- 61280304Sjkim * The lowest level part of this file was previously in crypto/des/read_pwd.c, 62109998Smarkm * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 63109998Smarkm * All rights reserved. 64109998Smarkm * 65109998Smarkm * This package is an SSL implementation written 66109998Smarkm * by Eric Young (eay@cryptsoft.com). 67109998Smarkm * The implementation was written so as to conform with Netscapes SSL. 68280304Sjkim * 69109998Smarkm * This library is free for commercial and non-commercial use as long as 70109998Smarkm * the following conditions are aheared to. The following conditions 71109998Smarkm * apply to all code found in this distribution, be it the RC4, RSA, 72109998Smarkm * lhash, DES, etc., code; not just the SSL code. The SSL documentation 73109998Smarkm * included with this distribution is covered by the same copyright terms 74109998Smarkm * except that the holder is Tim Hudson (tjh@cryptsoft.com). 75280304Sjkim * 76109998Smarkm * Copyright remains Eric Young's, and as such any Copyright notices in 77109998Smarkm * the code are not to be removed. 78109998Smarkm * If this package is used in a product, Eric Young should be given attribution 79109998Smarkm * as the author of the parts of the library used. 80109998Smarkm * This can be in the form of a textual message at program startup or 81109998Smarkm * in documentation (online or textual) provided with the package. 82280304Sjkim * 83109998Smarkm * Redistribution and use in source and binary forms, with or without 84109998Smarkm * modification, are permitted provided that the following conditions 85109998Smarkm * are met: 86109998Smarkm * 1. Redistributions of source code must retain the copyright 87109998Smarkm * notice, this list of conditions and the following disclaimer. 88109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 89109998Smarkm * notice, this list of conditions and the following disclaimer in the 90109998Smarkm * documentation and/or other materials provided with the distribution. 91109998Smarkm * 3. All advertising materials mentioning features or use of this software 92109998Smarkm * must display the following acknowledgement: 93109998Smarkm * "This product includes cryptographic software written by 94109998Smarkm * Eric Young (eay@cryptsoft.com)" 95109998Smarkm * The word 'cryptographic' can be left out if the rouines from the library 96109998Smarkm * being used are not cryptographic related :-). 97280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 98109998Smarkm * the apps directory (application code) you must include an acknowledgement: 99109998Smarkm * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 100280304Sjkim * 101109998Smarkm * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 102109998Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 103109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 104109998Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 105109998Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 106109998Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 107109998Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 108109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 109109998Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 110109998Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 111109998Smarkm * SUCH DAMAGE. 112280304Sjkim * 113109998Smarkm * The licence and distribution terms for any publically available version or 114109998Smarkm * derivative of this code cannot be changed. i.e. this code cannot simply be 115109998Smarkm * copied and put under another distribution licence 116109998Smarkm * [including the GNU Public Licence.] 117109998Smarkm */ 118109998Smarkm 119109998Smarkm#include <openssl/e_os2.h> 120109998Smarkm 121280304Sjkim/* 122280304Sjkim * need for #define _POSIX_C_SOURCE arises whenever you pass -ansi to gcc 123160814Ssimon * [maybe others?], because it masks interfaces not discussed in standard, 124280304Sjkim * sigaction and fileno included. -pedantic would be more appropriate for the 125280304Sjkim * intended purposes, but we can't prevent users from adding -ansi. 126160814Ssimon */ 127246772Sjkim#if defined(OPENSSL_SYSNAME_VXWORKS) 128280304Sjkim# include <sys/types.h> 129246772Sjkim#endif 130246772Sjkim 131238405Sjkim#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) 132280304Sjkim# ifndef _POSIX_C_SOURCE 133280304Sjkim# define _POSIX_C_SOURCE 2 134280304Sjkim# endif 135238405Sjkim#endif 136160814Ssimon#include <signal.h> 137160814Ssimon#include <stdio.h> 138160814Ssimon#include <string.h> 139160814Ssimon#include <errno.h> 140160814Ssimon 141109998Smarkm#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) 142109998Smarkm# ifdef OPENSSL_UNISTD 143109998Smarkm# include OPENSSL_UNISTD 144109998Smarkm# else 145109998Smarkm# include <unistd.h> 146109998Smarkm# endif 147280304Sjkim/* 148280304Sjkim * If unistd.h defines _POSIX_VERSION, we conclude that we are on a POSIX 149280304Sjkim * system and have sigaction and termios. 150280304Sjkim */ 151109998Smarkm# if defined(_POSIX_VERSION) 152109998Smarkm 153109998Smarkm# define SIGACTION 154109998Smarkm# if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) 155109998Smarkm# define TERMIOS 156109998Smarkm# endif 157109998Smarkm 158109998Smarkm# endif 159109998Smarkm#endif 160109998Smarkm 161109998Smarkm#ifdef WIN16TTY 162109998Smarkm# undef OPENSSL_SYS_WIN16 163109998Smarkm# undef WIN16 164109998Smarkm# undef _WINDOWS 165109998Smarkm# include <graph.h> 166109998Smarkm#endif 167109998Smarkm 168109998Smarkm/* 06-Apr-92 Luke Brennan Support for VMS */ 169109998Smarkm#include "ui_locl.h" 170109998Smarkm#include "cryptlib.h" 171109998Smarkm 172280304Sjkim#ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */ 173109998Smarkm# include <starlet.h> 174109998Smarkm# ifdef __DECC 175109998Smarkm# pragma message disable DOLLARID 176109998Smarkm# endif 177109998Smarkm#endif 178109998Smarkm 179109998Smarkm#ifdef WIN_CONSOLE_BUG 180109998Smarkm# include <windows.h> 181280304Sjkim# ifndef OPENSSL_SYS_WINCE 182280304Sjkim# include <wincon.h> 183280304Sjkim# endif 184109998Smarkm#endif 185109998Smarkm 186280304Sjkim/* 187280304Sjkim * There are 5 types of terminal interface supported, TERMIO, TERMIOS, VMS, 188280304Sjkim * MSDOS and SGTTY. 189280304Sjkim * 190280304Sjkim * If someone defines one of the macros TERMIO, TERMIOS or SGTTY, it will 191280304Sjkim * remain respected. Otherwise, we default to TERMIOS except for a few 192280304Sjkim * systems that require something different. 193280304Sjkim * 194280304Sjkim * Note: we do not use SGTTY unless it's defined by the configuration. We 195280304Sjkim * may eventually opt to remove it's use entirely. 196109998Smarkm */ 197109998Smarkm 198280304Sjkim#if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) 199109998Smarkm 200280304Sjkim# if defined(_LIBC) 201280304Sjkim# undef TERMIOS 202280304Sjkim# define TERMIO 203280304Sjkim# undef SGTTY 204280304Sjkim/* 205280304Sjkim * We know that VMS, MSDOS, VXWORKS, NETWARE use entirely other mechanisms. 206280304Sjkim * MAC_OS_GUSI_SOURCE should probably go away, but that needs to be confirmed. 207280304Sjkim */ 208280304Sjkim# elif !defined(OPENSSL_SYS_VMS) \ 209280304Sjkim && !defined(OPENSSL_SYS_MSDOS) \ 210280304Sjkim && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) \ 211280304Sjkim && !defined(MAC_OS_GUSI_SOURCE) \ 212280304Sjkim && !defined(OPENSSL_SYS_VXWORKS) \ 213280304Sjkim && !defined(OPENSSL_SYS_NETWARE) 214280304Sjkim# define TERMIOS 215280304Sjkim# undef TERMIO 216280304Sjkim# undef SGTTY 217280304Sjkim# endif 218109998Smarkm 219109998Smarkm#endif 220109998Smarkm 221109998Smarkm#ifdef TERMIOS 222109998Smarkm# include <termios.h> 223280304Sjkim# define TTY_STRUCT struct termios 224280304Sjkim# define TTY_FLAGS c_lflag 225280304Sjkim# define TTY_get(tty,data) tcgetattr(tty,data) 226280304Sjkim# define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) 227109998Smarkm#endif 228109998Smarkm 229109998Smarkm#ifdef TERMIO 230109998Smarkm# include <termio.h> 231280304Sjkim# define TTY_STRUCT struct termio 232280304Sjkim# define TTY_FLAGS c_lflag 233280304Sjkim# define TTY_get(tty,data) ioctl(tty,TCGETA,data) 234280304Sjkim# define TTY_set(tty,data) ioctl(tty,TCSETA,data) 235109998Smarkm#endif 236109998Smarkm 237109998Smarkm#ifdef SGTTY 238109998Smarkm# include <sgtty.h> 239280304Sjkim# define TTY_STRUCT struct sgttyb 240280304Sjkim# define TTY_FLAGS sg_flags 241280304Sjkim# define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) 242280304Sjkim# define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) 243109998Smarkm#endif 244109998Smarkm 245109998Smarkm#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(OPENSSL_SYS_SUNOS) 246109998Smarkm# include <sys/ioctl.h> 247109998Smarkm#endif 248109998Smarkm 249109998Smarkm#ifdef OPENSSL_SYS_MSDOS 250109998Smarkm# include <conio.h> 251109998Smarkm#endif 252109998Smarkm 253109998Smarkm#ifdef OPENSSL_SYS_VMS 254109998Smarkm# include <ssdef.h> 255109998Smarkm# include <iodef.h> 256109998Smarkm# include <ttdef.h> 257109998Smarkm# include <descrip.h> 258109998Smarkmstruct IOSB { 259280304Sjkim short iosb$w_value; 260280304Sjkim short iosb$w_count; 261280304Sjkim long iosb$l_info; 262280304Sjkim}; 263109998Smarkm#endif 264109998Smarkm 265109998Smarkm#ifdef OPENSSL_SYS_SUNOS 266280304Sjkimtypedef int sig_atomic_t; 267109998Smarkm#endif 268109998Smarkm 269160814Ssimon#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) || defined(OPENSSL_SYS_NETWARE) 270109998Smarkm/* 271109998Smarkm * This one needs work. As a matter of fact the code is unoperational 272109998Smarkm * and this is only a trick to get it compiled. 273280304Sjkim * <appro@fy.chalmers.se> 274109998Smarkm */ 275109998Smarkm# define TTY_STRUCT int 276109998Smarkm#endif 277109998Smarkm 278109998Smarkm#ifndef NX509_SIG 279109998Smarkm# define NX509_SIG 32 280109998Smarkm#endif 281109998Smarkm 282109998Smarkm/* Define globals. They are protected by a lock */ 283109998Smarkm#ifdef SIGACTION 284109998Smarkmstatic struct sigaction savsig[NX509_SIG]; 285109998Smarkm#else 286280304Sjkimstatic void (*savsig[NX509_SIG]) (int); 287109998Smarkm#endif 288109998Smarkm 289109998Smarkm#ifdef OPENSSL_SYS_VMS 290109998Smarkmstatic struct IOSB iosb; 291280304Sjkimstatic $DESCRIPTOR(terminal, "TT"); 292280304Sjkimstatic long tty_orig[3], tty_new[3]; /* XXX Is there any guarantee that this 293280304Sjkim * will always suffice for the actual 294280304Sjkim * structures? */ 295109998Smarkmstatic long status; 296109998Smarkmstatic unsigned short channel = 0; 297109998Smarkm#else 298280304Sjkim# if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) 299280304Sjkimstatic TTY_STRUCT tty_orig, tty_new; 300280304Sjkim# endif 301109998Smarkm#endif 302109998Smarkmstatic FILE *tty_in, *tty_out; 303109998Smarkmstatic int is_a_tty; 304109998Smarkm 305109998Smarkm/* Declare static functions */ 306109998Smarkm#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 307205128Ssimonstatic int read_till_nl(FILE *); 308109998Smarkmstatic void recsig(int); 309109998Smarkmstatic void pushsig(void); 310109998Smarkmstatic void popsig(void); 311109998Smarkm#endif 312109998Smarkm#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) 313109998Smarkmstatic int noecho_fgets(char *buf, int size, FILE *tty); 314109998Smarkm#endif 315109998Smarkmstatic int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl); 316109998Smarkm 317109998Smarkmstatic int read_string(UI *ui, UI_STRING *uis); 318109998Smarkmstatic int write_string(UI *ui, UI_STRING *uis); 319109998Smarkm 320109998Smarkmstatic int open_console(UI *ui); 321109998Smarkmstatic int echo_console(UI *ui); 322109998Smarkmstatic int noecho_console(UI *ui); 323109998Smarkmstatic int close_console(UI *ui); 324109998Smarkm 325280304Sjkimstatic UI_METHOD ui_openssl = { 326280304Sjkim "OpenSSL default user interface", 327280304Sjkim open_console, 328280304Sjkim write_string, 329280304Sjkim NULL, /* No flusher is needed for command lines */ 330280304Sjkim read_string, 331280304Sjkim close_console, 332280304Sjkim NULL 333280304Sjkim}; 334109998Smarkm 335109998Smarkm/* The method with all the built-in thingies */ 336109998SmarkmUI_METHOD *UI_OpenSSL(void) 337280304Sjkim{ 338280304Sjkim return &ui_openssl; 339280304Sjkim} 340109998Smarkm 341280304Sjkim/* 342280304Sjkim * The following function makes sure that info and error strings are printed 343280304Sjkim * before any prompt. 344280304Sjkim */ 345109998Smarkmstatic int write_string(UI *ui, UI_STRING *uis) 346280304Sjkim{ 347280304Sjkim switch (UI_get_string_type(uis)) { 348280304Sjkim case UIT_ERROR: 349280304Sjkim case UIT_INFO: 350280304Sjkim fputs(UI_get0_output_string(uis), tty_out); 351280304Sjkim fflush(tty_out); 352280304Sjkim break; 353280304Sjkim default: 354280304Sjkim break; 355280304Sjkim } 356280304Sjkim return 1; 357280304Sjkim} 358109998Smarkm 359109998Smarkmstatic int read_string(UI *ui, UI_STRING *uis) 360280304Sjkim{ 361280304Sjkim int ok = 0; 362109998Smarkm 363280304Sjkim switch (UI_get_string_type(uis)) { 364280304Sjkim case UIT_BOOLEAN: 365280304Sjkim fputs(UI_get0_output_string(uis), tty_out); 366280304Sjkim fputs(UI_get0_action_string(uis), tty_out); 367280304Sjkim fflush(tty_out); 368280304Sjkim return read_string_inner(ui, uis, 369280304Sjkim UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 370280304Sjkim 0); 371280304Sjkim case UIT_PROMPT: 372280304Sjkim fputs(UI_get0_output_string(uis), tty_out); 373280304Sjkim fflush(tty_out); 374280304Sjkim return read_string_inner(ui, uis, 375280304Sjkim UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 376280304Sjkim 1); 377280304Sjkim case UIT_VERIFY: 378280304Sjkim fprintf(tty_out, "Verifying - %s", UI_get0_output_string(uis)); 379280304Sjkim fflush(tty_out); 380280304Sjkim if ((ok = read_string_inner(ui, uis, 381280304Sjkim UI_get_input_flags(uis) & 382280304Sjkim UI_INPUT_FLAG_ECHO, 1)) <= 0) 383280304Sjkim return ok; 384280304Sjkim if (strcmp(UI_get0_result_string(uis), UI_get0_test_string(uis)) != 0) { 385280304Sjkim fprintf(tty_out, "Verify failure\n"); 386280304Sjkim fflush(tty_out); 387280304Sjkim return 0; 388280304Sjkim } 389280304Sjkim break; 390280304Sjkim default: 391280304Sjkim break; 392280304Sjkim } 393280304Sjkim return 1; 394280304Sjkim} 395109998Smarkm 396109998Smarkm#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 397109998Smarkm/* Internal functions to read a string without echoing */ 398205128Ssimonstatic int read_till_nl(FILE *in) 399280304Sjkim{ 400280304Sjkim# define SIZE 4 401280304Sjkim char buf[SIZE + 1]; 402109998Smarkm 403280304Sjkim do { 404280304Sjkim if (!fgets(buf, SIZE, in)) 405280304Sjkim return 0; 406280304Sjkim } while (strchr(buf, '\n') == NULL); 407280304Sjkim return 1; 408280304Sjkim} 409109998Smarkm 410109998Smarkmstatic volatile sig_atomic_t intr_signal; 411109998Smarkm#endif 412109998Smarkm 413109998Smarkmstatic int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) 414280304Sjkim{ 415280304Sjkim static int ps; 416280304Sjkim int ok; 417280304Sjkim char result[BUFSIZ]; 418280304Sjkim int maxsize = BUFSIZ - 1; 419109998Smarkm#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 420280304Sjkim char *p; 421109998Smarkm 422280304Sjkim intr_signal = 0; 423280304Sjkim ok = 0; 424280304Sjkim ps = 0; 425109998Smarkm 426280304Sjkim pushsig(); 427280304Sjkim ps = 1; 428109998Smarkm 429280304Sjkim if (!echo && !noecho_console(ui)) 430280304Sjkim goto error; 431280304Sjkim ps = 2; 432109998Smarkm 433280304Sjkim result[0] = '\0'; 434280304Sjkim# ifdef OPENSSL_SYS_MSDOS 435280304Sjkim if (!echo) { 436280304Sjkim noecho_fgets(result, maxsize, tty_in); 437280304Sjkim p = result; /* FIXME: noecho_fgets doesn't return errors */ 438280304Sjkim } else 439280304Sjkim p = fgets(result, maxsize, tty_in); 440280304Sjkim# else 441280304Sjkim p = fgets(result, maxsize, tty_in); 442280304Sjkim# endif 443280304Sjkim if (!p) 444280304Sjkim goto error; 445280304Sjkim if (feof(tty_in)) 446280304Sjkim goto error; 447280304Sjkim if (ferror(tty_in)) 448280304Sjkim goto error; 449280304Sjkim if ((p = (char *)strchr(result, '\n')) != NULL) { 450280304Sjkim if (strip_nl) 451280304Sjkim *p = '\0'; 452280304Sjkim } else if (!read_till_nl(tty_in)) 453280304Sjkim goto error; 454280304Sjkim if (UI_set_result(ui, uis, result) >= 0) 455280304Sjkim ok = 1; 456109998Smarkm 457280304Sjkim error: 458280304Sjkim if (intr_signal == SIGINT) 459280304Sjkim ok = -1; 460280304Sjkim if (!echo) 461280304Sjkim fprintf(tty_out, "\n"); 462280304Sjkim if (ps >= 2 && !echo && !echo_console(ui)) 463280304Sjkim ok = 0; 464109998Smarkm 465280304Sjkim if (ps >= 1) 466280304Sjkim popsig(); 467109998Smarkm#else 468280304Sjkim ok = 1; 469109998Smarkm#endif 470109998Smarkm 471280304Sjkim OPENSSL_cleanse(result, BUFSIZ); 472280304Sjkim return ok; 473280304Sjkim} 474109998Smarkm 475109998Smarkm/* Internal functions to open, handle and close a channel to the console. */ 476109998Smarkmstatic int open_console(UI *ui) 477280304Sjkim{ 478280304Sjkim CRYPTO_w_lock(CRYPTO_LOCK_UI); 479280304Sjkim is_a_tty = 1; 480109998Smarkm 481238405Sjkim#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS) 482280304Sjkim tty_in = stdin; 483280304Sjkim tty_out = stderr; 484109998Smarkm#else 485280304Sjkim# ifdef OPENSSL_SYS_MSDOS 486280304Sjkim# define DEV_TTY "con" 487280304Sjkim# else 488280304Sjkim# define DEV_TTY "/dev/tty" 489280304Sjkim# endif 490280304Sjkim if ((tty_in = fopen(DEV_TTY, "r")) == NULL) 491280304Sjkim tty_in = stdin; 492280304Sjkim if ((tty_out = fopen(DEV_TTY, "w")) == NULL) 493280304Sjkim tty_out = stderr; 494109998Smarkm#endif 495109998Smarkm 496109998Smarkm#if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) 497280304Sjkim if (TTY_get(fileno(tty_in), &tty_orig) == -1) { 498280304Sjkim# ifdef ENOTTY 499280304Sjkim if (errno == ENOTTY) 500280304Sjkim is_a_tty = 0; 501280304Sjkim else 502280304Sjkim# endif 503280304Sjkim# ifdef EINVAL 504280304Sjkim /* 505280304Sjkim * Ariel Glenn ariel@columbia.edu reports that solaris can return 506280304Sjkim * EINVAL instead. This should be ok 507280304Sjkim */ 508280304Sjkim if (errno == EINVAL) 509280304Sjkim is_a_tty = 0; 510280304Sjkim else 511280304Sjkim# endif 512280304Sjkim return 0; 513280304Sjkim } 514109998Smarkm#endif 515109998Smarkm#ifdef OPENSSL_SYS_VMS 516280304Sjkim status = sys$assign(&terminal, &channel, 0, 0); 517280304Sjkim if (status != SS$_NORMAL) 518280304Sjkim return 0; 519280304Sjkim status = 520280304Sjkim sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, 0, 0, 521280304Sjkim 0, 0); 522280304Sjkim if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) 523280304Sjkim return 0; 524109998Smarkm#endif 525280304Sjkim return 1; 526280304Sjkim} 527109998Smarkm 528109998Smarkmstatic int noecho_console(UI *ui) 529280304Sjkim{ 530109998Smarkm#ifdef TTY_FLAGS 531280304Sjkim memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); 532280304Sjkim tty_new.TTY_FLAGS &= ~ECHO; 533109998Smarkm#endif 534109998Smarkm 535109998Smarkm#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) 536280304Sjkim if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1)) 537280304Sjkim return 0; 538109998Smarkm#endif 539109998Smarkm#ifdef OPENSSL_SYS_VMS 540280304Sjkim tty_new[0] = tty_orig[0]; 541280304Sjkim tty_new[1] = tty_orig[1] | TT$M_NOECHO; 542280304Sjkim tty_new[2] = tty_orig[2]; 543280304Sjkim status = 544280304Sjkim sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0, 545280304Sjkim 0); 546280304Sjkim if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) 547280304Sjkim return 0; 548109998Smarkm#endif 549280304Sjkim return 1; 550280304Sjkim} 551109998Smarkm 552109998Smarkmstatic int echo_console(UI *ui) 553280304Sjkim{ 554109998Smarkm#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) 555280304Sjkim memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); 556280304Sjkim tty_new.TTY_FLAGS |= ECHO; 557109998Smarkm#endif 558109998Smarkm 559109998Smarkm#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) 560280304Sjkim if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1)) 561280304Sjkim return 0; 562109998Smarkm#endif 563109998Smarkm#ifdef OPENSSL_SYS_VMS 564280304Sjkim tty_new[0] = tty_orig[0]; 565280304Sjkim tty_new[1] = tty_orig[1] & ~TT$M_NOECHO; 566280304Sjkim tty_new[2] = tty_orig[2]; 567280304Sjkim status = 568280304Sjkim sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0, 569280304Sjkim 0); 570280304Sjkim if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) 571280304Sjkim return 0; 572109998Smarkm#endif 573280304Sjkim return 1; 574280304Sjkim} 575109998Smarkm 576109998Smarkmstatic int close_console(UI *ui) 577280304Sjkim{ 578280304Sjkim if (tty_in != stdin) 579280304Sjkim fclose(tty_in); 580280304Sjkim if (tty_out != stderr) 581280304Sjkim fclose(tty_out); 582109998Smarkm#ifdef OPENSSL_SYS_VMS 583280304Sjkim status = sys$dassgn(channel); 584109998Smarkm#endif 585280304Sjkim CRYPTO_w_unlock(CRYPTO_LOCK_UI); 586109998Smarkm 587280304Sjkim return 1; 588280304Sjkim} 589109998Smarkm 590109998Smarkm#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 591109998Smarkm/* Internal functions to handle signals and act on them */ 592109998Smarkmstatic void pushsig(void) 593280304Sjkim{ 594280304Sjkim# ifndef OPENSSL_SYS_WIN32 595280304Sjkim int i; 596280304Sjkim# endif 597280304Sjkim# ifdef SIGACTION 598280304Sjkim struct sigaction sa; 599109998Smarkm 600280304Sjkim memset(&sa, 0, sizeof sa); 601280304Sjkim sa.sa_handler = recsig; 602280304Sjkim# endif 603109998Smarkm 604280304Sjkim# ifdef OPENSSL_SYS_WIN32 605280304Sjkim savsig[SIGABRT] = signal(SIGABRT, recsig); 606280304Sjkim savsig[SIGFPE] = signal(SIGFPE, recsig); 607280304Sjkim savsig[SIGILL] = signal(SIGILL, recsig); 608280304Sjkim savsig[SIGINT] = signal(SIGINT, recsig); 609280304Sjkim savsig[SIGSEGV] = signal(SIGSEGV, recsig); 610280304Sjkim savsig[SIGTERM] = signal(SIGTERM, recsig); 611280304Sjkim# else 612280304Sjkim for (i = 1; i < NX509_SIG; i++) { 613280304Sjkim# ifdef SIGUSR1 614280304Sjkim if (i == SIGUSR1) 615280304Sjkim continue; 616280304Sjkim# endif 617280304Sjkim# ifdef SIGUSR2 618280304Sjkim if (i == SIGUSR2) 619280304Sjkim continue; 620280304Sjkim# endif 621280304Sjkim# ifdef SIGKILL 622280304Sjkim if (i == SIGKILL) /* We can't make any action on that. */ 623280304Sjkim continue; 624280304Sjkim# endif 625280304Sjkim# ifdef SIGACTION 626280304Sjkim sigaction(i, &sa, &savsig[i]); 627280304Sjkim# else 628280304Sjkim savsig[i] = signal(i, recsig); 629280304Sjkim# endif 630280304Sjkim } 631280304Sjkim# endif 632109998Smarkm 633280304Sjkim# ifdef SIGWINCH 634280304Sjkim signal(SIGWINCH, SIG_DFL); 635280304Sjkim# endif 636280304Sjkim} 637109998Smarkm 638109998Smarkmstatic void popsig(void) 639280304Sjkim{ 640280304Sjkim# ifdef OPENSSL_SYS_WIN32 641280304Sjkim signal(SIGABRT, savsig[SIGABRT]); 642280304Sjkim signal(SIGFPE, savsig[SIGFPE]); 643280304Sjkim signal(SIGILL, savsig[SIGILL]); 644280304Sjkim signal(SIGINT, savsig[SIGINT]); 645280304Sjkim signal(SIGSEGV, savsig[SIGSEGV]); 646280304Sjkim signal(SIGTERM, savsig[SIGTERM]); 647280304Sjkim# else 648280304Sjkim int i; 649280304Sjkim for (i = 1; i < NX509_SIG; i++) { 650280304Sjkim# ifdef SIGUSR1 651280304Sjkim if (i == SIGUSR1) 652280304Sjkim continue; 653280304Sjkim# endif 654280304Sjkim# ifdef SIGUSR2 655280304Sjkim if (i == SIGUSR2) 656280304Sjkim continue; 657280304Sjkim# endif 658280304Sjkim# ifdef SIGACTION 659280304Sjkim sigaction(i, &savsig[i], NULL); 660280304Sjkim# else 661280304Sjkim signal(i, savsig[i]); 662280304Sjkim# endif 663280304Sjkim } 664280304Sjkim# endif 665280304Sjkim} 666109998Smarkm 667109998Smarkmstatic void recsig(int i) 668280304Sjkim{ 669280304Sjkim intr_signal = i; 670280304Sjkim} 671109998Smarkm#endif 672109998Smarkm 673109998Smarkm/* Internal functions specific for Windows */ 674109998Smarkm#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) 675109998Smarkmstatic int noecho_fgets(char *buf, int size, FILE *tty) 676280304Sjkim{ 677280304Sjkim int i; 678280304Sjkim char *p; 679109998Smarkm 680280304Sjkim p = buf; 681280304Sjkim for (;;) { 682280304Sjkim if (size == 0) { 683280304Sjkim *p = '\0'; 684280304Sjkim break; 685280304Sjkim } 686280304Sjkim size--; 687280304Sjkim# ifdef WIN16TTY 688280304Sjkim i = _inchar(); 689280304Sjkim# elif defined(_WIN32) 690280304Sjkim i = _getch(); 691280304Sjkim# else 692280304Sjkim i = getch(); 693280304Sjkim# endif 694280304Sjkim if (i == '\r') 695280304Sjkim i = '\n'; 696280304Sjkim *(p++) = i; 697280304Sjkim if (i == '\n') { 698280304Sjkim *p = '\0'; 699280304Sjkim break; 700280304Sjkim } 701280304Sjkim } 702280304Sjkim# ifdef WIN_CONSOLE_BUG 703280304Sjkim /* 704280304Sjkim * Win95 has several evil console bugs: one of these is that the last 705280304Sjkim * character read using getch() is passed to the next read: this is 706280304Sjkim * usually a CR so this can be trouble. No STDIO fix seems to work but 707280304Sjkim * flushing the console appears to do the trick. 708280304Sjkim */ 709280304Sjkim { 710280304Sjkim HANDLE inh; 711280304Sjkim inh = GetStdHandle(STD_INPUT_HANDLE); 712280304Sjkim FlushConsoleInputBuffer(inh); 713280304Sjkim } 714280304Sjkim# endif 715280304Sjkim return (strlen(buf)); 716280304Sjkim} 717109998Smarkm#endif 718