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