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