sl@0: /* crypto/des/read_pwd.c */ sl@0: /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) sl@0: * All rights reserved. sl@0: * sl@0: * This package is an SSL implementation written sl@0: * by Eric Young (eay@cryptsoft.com). sl@0: * The implementation was written so as to conform with Netscapes SSL. sl@0: * sl@0: * This library is free for commercial and non-commercial use as long as sl@0: * the following conditions are aheared to. The following conditions sl@0: * apply to all code found in this distribution, be it the RC4, RSA, sl@0: * lhash, DES, etc., code; not just the SSL code. The SSL documentation sl@0: * included with this distribution is covered by the same copyright terms sl@0: * except that the holder is Tim Hudson (tjh@cryptsoft.com). sl@0: * sl@0: * Copyright remains Eric Young's, and as such any Copyright notices in sl@0: * the code are not to be removed. sl@0: * If this package is used in a product, Eric Young should be given attribution sl@0: * as the author of the parts of the library used. sl@0: * This can be in the form of a textual message at program startup or sl@0: * in documentation (online or textual) provided with the package. sl@0: * sl@0: * Redistribution and use in source and binary forms, with or without sl@0: * modification, are permitted provided that the following conditions sl@0: * are met: sl@0: * 1. Redistributions of source code must retain the copyright sl@0: * notice, this list of conditions and the following disclaimer. sl@0: * 2. Redistributions in binary form must reproduce the above copyright sl@0: * notice, this list of conditions and the following disclaimer in the sl@0: * documentation and/or other materials provided with the distribution. sl@0: * 3. All advertising materials mentioning features or use of this software sl@0: * must display the following acknowledgement: sl@0: * "This product includes cryptographic software written by sl@0: * Eric Young (eay@cryptsoft.com)" sl@0: * The word 'cryptographic' can be left out if the rouines from the library sl@0: * being used are not cryptographic related :-). sl@0: * 4. If you include any Windows specific code (or a derivative thereof) from sl@0: * the apps directory (application code) you must include an acknowledgement: sl@0: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" sl@0: * sl@0: * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND sl@0: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE sl@0: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE sl@0: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE sl@0: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL sl@0: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS sl@0: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) sl@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT sl@0: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY sl@0: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF sl@0: * SUCH DAMAGE. sl@0: * sl@0: * The licence and distribution terms for any publically available version or sl@0: * derivative of this code cannot be changed. i.e. this code cannot simply be sl@0: * copied and put under another distribution licence sl@0: * [including the GNU Public Licence.] sl@0: */ sl@0: sl@0: #include sl@0: #if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WIN32) sl@0: #ifdef OPENSSL_UNISTD sl@0: # include OPENSSL_UNISTD sl@0: #else sl@0: # include sl@0: #endif sl@0: /* If unistd.h defines _POSIX_VERSION, we conclude that we sl@0: * are on a POSIX system and have sigaction and termios. */ sl@0: #if defined(_POSIX_VERSION) sl@0: sl@0: # define SIGACTION sl@0: # if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) sl@0: # define TERMIOS sl@0: # endif sl@0: sl@0: #endif sl@0: #endif sl@0: sl@0: /* #define SIGACTION */ /* Define this if you have sigaction() */ sl@0: sl@0: #ifdef WIN16TTY sl@0: #undef OPENSSL_SYS_WIN16 sl@0: #undef _WINDOWS sl@0: #include sl@0: #endif sl@0: sl@0: /* 06-Apr-92 Luke Brennan Support for VMS */ sl@0: #include "des_locl.h" sl@0: #include "cryptlib.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */ sl@0: #include sl@0: #ifdef __DECC sl@0: #pragma message disable DOLLARID sl@0: #endif sl@0: #endif sl@0: sl@0: #ifdef WIN_CONSOLE_BUG sl@0: #include sl@0: #ifndef OPENSSL_SYS_WINCE sl@0: #include sl@0: #endif sl@0: #endif sl@0: sl@0: sl@0: /* There are 5 types of terminal interface supported, sl@0: * TERMIO, TERMIOS, VMS, MSDOS and SGTTY sl@0: */ sl@0: sl@0: #if defined(__sgi) && !defined(TERMIOS) sl@0: #define TERMIOS sl@0: #undef TERMIO sl@0: #undef SGTTY sl@0: #endif sl@0: sl@0: #if defined(linux) && !defined(TERMIO) sl@0: #undef TERMIOS sl@0: #define TERMIO sl@0: #undef SGTTY sl@0: #endif sl@0: sl@0: #ifdef _LIBC sl@0: #undef TERMIOS sl@0: #define TERMIO sl@0: #undef SGTTY sl@0: #endif sl@0: sl@0: #if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(MAC_OS_pre_X) && !defined(MAC_OS_GUSI_SOURCE) sl@0: #undef TERMIOS sl@0: #undef TERMIO sl@0: #define SGTTY sl@0: #endif sl@0: sl@0: #if defined(OPENSSL_SYS_VXWORKS) sl@0: #undef TERMIOS sl@0: #undef TERMIO sl@0: #undef SGTTY sl@0: #endif sl@0: sl@0: #ifdef TERMIOS sl@0: #include sl@0: #define TTY_STRUCT struct termios sl@0: #define TTY_FLAGS c_lflag sl@0: #define TTY_get(tty,data) tcgetattr(tty,data) sl@0: #define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) sl@0: #endif sl@0: sl@0: #ifdef TERMIO sl@0: #include sl@0: #define TTY_STRUCT struct termio sl@0: #define TTY_FLAGS c_lflag sl@0: #define TTY_get(tty,data) ioctl(tty,TCGETA,data) sl@0: #define TTY_set(tty,data) ioctl(tty,TCSETA,data) sl@0: #endif sl@0: sl@0: #ifdef SGTTY sl@0: #include sl@0: #define TTY_STRUCT struct sgttyb sl@0: #define TTY_FLAGS sg_flags sl@0: #define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) sl@0: #define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) sl@0: #endif sl@0: sl@0: #if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(MAC_OS_pre_X) sl@0: #include sl@0: #endif sl@0: sl@0: #if defined(OPENSSL_SYS_MSDOS) && !defined(__CYGWIN32__) && !defined(OPENSSL_SYS_WINCE) sl@0: #include sl@0: #define fgets(a,b,c) noecho_fgets(a,b,c) sl@0: #endif sl@0: sl@0: #ifdef OPENSSL_SYS_VMS sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: struct IOSB { sl@0: short iosb$w_value; sl@0: short iosb$w_count; sl@0: long iosb$l_info; sl@0: }; sl@0: #endif sl@0: sl@0: #if defined(MAC_OS_pre_X) || defined(MAC_OS_GUSI_SOURCE) sl@0: /* sl@0: * This one needs work. As a matter of fact the code is unoperational sl@0: * and this is only a trick to get it compiled. sl@0: * sl@0: */ sl@0: #define TTY_STRUCT int sl@0: #endif sl@0: sl@0: #ifndef NX509_SIG sl@0: #define NX509_SIG 32 sl@0: #endif sl@0: sl@0: static void read_till_nl(FILE *); sl@0: static void recsig(int); sl@0: static void pushsig(void); sl@0: static void popsig(void); sl@0: #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) sl@0: static int noecho_fgets(char *buf, int size, FILE *tty); sl@0: #endif sl@0: #ifdef SIGACTION sl@0: static struct sigaction savsig[NX509_SIG]; sl@0: #else sl@0: static void (*savsig[NX509_SIG])(int ); sl@0: #endif sl@0: static jmp_buf save; sl@0: sl@0: int des_read_pw_string(char *buf, int length, const char *prompt, sl@0: int verify) sl@0: { sl@0: char buff[BUFSIZ]; sl@0: int ret; sl@0: sl@0: ret=des_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify); sl@0: OPENSSL_cleanse(buff,BUFSIZ); sl@0: return(ret); sl@0: } sl@0: sl@0: #ifdef OPENSSL_SYS_WINCE sl@0: sl@0: int des_read_pw(char *buf, char *buff, int size, const char *prompt, int verify) sl@0: { sl@0: memset(buf,0,size); sl@0: memset(buff,0,size); sl@0: return(0); sl@0: } sl@0: sl@0: #elif defined(OPENSSL_SYS_WIN16) sl@0: sl@0: int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify) sl@0: { sl@0: memset(buf,0,size); sl@0: memset(buff,0,size); sl@0: return(0); sl@0: } sl@0: sl@0: #else /* !OPENSSL_SYS_WINCE && !OPENSSL_SYS_WIN16 */ sl@0: sl@0: static void read_till_nl(FILE *in) sl@0: { sl@0: #define SIZE 4 sl@0: char buf[SIZE+1]; sl@0: sl@0: do { sl@0: fgets(buf,SIZE,in); sl@0: } while (strchr(buf,'\n') == NULL); sl@0: } sl@0: sl@0: sl@0: /* return 0 if ok, 1 (or -1) otherwise */ sl@0: int des_read_pw(char *buf, char *buff, int size, const char *prompt, sl@0: int verify) sl@0: { sl@0: #ifdef OPENSSL_SYS_VMS sl@0: struct IOSB iosb; sl@0: $DESCRIPTOR(terminal,"TT"); sl@0: long tty_orig[3], tty_new[3]; sl@0: long status; sl@0: unsigned short channel = 0; sl@0: #else sl@0: #if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) sl@0: TTY_STRUCT tty_orig,tty_new; sl@0: #endif sl@0: #endif sl@0: int number; sl@0: int ok; sl@0: /* statics are simply to avoid warnings about longjmp clobbering sl@0: things */ sl@0: static int ps; sl@0: int is_a_tty; sl@0: static FILE *tty; sl@0: char *p; sl@0: sl@0: if (setjmp(save)) sl@0: { sl@0: ok=0; sl@0: goto error; sl@0: } sl@0: sl@0: number=5; sl@0: ok=0; sl@0: ps=0; sl@0: is_a_tty=1; sl@0: tty=NULL; sl@0: sl@0: #ifdef OPENSSL_SYS_MSDOS sl@0: if ((tty=fopen("con","r")) == NULL) sl@0: tty=stdin; sl@0: #elif defined(MAC_OS_pre_X) || defined(OPENSSL_SYS_VXWORKS) sl@0: tty=stdin; sl@0: #else sl@0: #ifndef OPENSSL_SYS_MPE sl@0: if ((tty=fopen("/dev/tty","r")) == NULL) sl@0: #endif sl@0: tty=stdin; sl@0: #endif sl@0: sl@0: #if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) sl@0: if (TTY_get(fileno(tty),&tty_orig) == -1) sl@0: { sl@0: #ifdef ENOTTY sl@0: if (errno == ENOTTY) sl@0: is_a_tty=0; sl@0: else sl@0: #endif sl@0: #ifdef EINVAL sl@0: /* Ariel Glenn ariel@columbia.edu reports that solaris sl@0: * can return EINVAL instead. This should be ok */ sl@0: if (errno == EINVAL) sl@0: is_a_tty=0; sl@0: else sl@0: #endif sl@0: return(-1); sl@0: } sl@0: memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig)); sl@0: #endif sl@0: #ifdef OPENSSL_SYS_VMS sl@0: status = sys$assign(&terminal,&channel,0,0); sl@0: if (status != SS$_NORMAL) sl@0: return(-1); sl@0: status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0); sl@0: if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) sl@0: return(-1); sl@0: #endif sl@0: sl@0: pushsig(); sl@0: ps=1; sl@0: sl@0: #ifdef TTY_FLAGS sl@0: tty_new.TTY_FLAGS &= ~ECHO; sl@0: #endif sl@0: sl@0: #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) sl@0: if (is_a_tty && (TTY_set(fileno(tty),&tty_new) == -1)) sl@0: #ifdef OPENSSL_SYS_MPE sl@0: ; /* MPE lies -- echo really has been disabled */ sl@0: #else sl@0: return(-1); sl@0: #endif sl@0: #endif sl@0: #ifdef OPENSSL_SYS_VMS sl@0: tty_new[0] = tty_orig[0]; sl@0: tty_new[1] = tty_orig[1] | TT$M_NOECHO; sl@0: tty_new[2] = tty_orig[2]; sl@0: status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0); sl@0: if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) sl@0: return(-1); sl@0: #endif sl@0: ps=2; sl@0: sl@0: while ((!ok) && (number--)) sl@0: { sl@0: fputs(prompt,stderr); sl@0: fflush(stderr); sl@0: sl@0: buf[0]='\0'; sl@0: fgets(buf,size,tty); sl@0: if (feof(tty)) goto error; sl@0: if (ferror(tty)) goto error; sl@0: if ((p=(char *)strchr(buf,'\n')) != NULL) sl@0: *p='\0'; sl@0: else read_till_nl(tty); sl@0: if (verify) sl@0: { sl@0: fprintf(stderr,"\nVerifying password - %s",prompt); sl@0: fflush(stderr); sl@0: buff[0]='\0'; sl@0: fgets(buff,size,tty); sl@0: if (feof(tty)) goto error; sl@0: if ((p=(char *)strchr(buff,'\n')) != NULL) sl@0: *p='\0'; sl@0: else read_till_nl(tty); sl@0: sl@0: if (strcmp(buf,buff) != 0) sl@0: { sl@0: fprintf(stderr,"\nVerify failure"); sl@0: fflush(stderr); sl@0: break; sl@0: /* continue; */ sl@0: } sl@0: } sl@0: ok=1; sl@0: } sl@0: sl@0: error: sl@0: fprintf(stderr,"\n"); sl@0: #if 0 sl@0: perror("fgets(tty)"); sl@0: #endif sl@0: /* What can we do if there is an error? */ sl@0: #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) sl@0: if (ps >= 2) TTY_set(fileno(tty),&tty_orig); sl@0: #endif sl@0: #ifdef OPENSSL_SYS_VMS sl@0: if (ps >= 2) sl@0: status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0 sl@0: ,tty_orig,12,0,0,0,0); sl@0: #endif sl@0: sl@0: if (ps >= 1) popsig(); sl@0: if (stdin != tty) fclose(tty); sl@0: #ifdef OPENSSL_SYS_VMS sl@0: status = sys$dassgn(channel); sl@0: #endif sl@0: return(!ok); sl@0: } sl@0: sl@0: static void pushsig(void) sl@0: { sl@0: int i; sl@0: #ifdef SIGACTION sl@0: struct sigaction sa; sl@0: sl@0: memset(&sa,0,sizeof sa); sl@0: sa.sa_handler=recsig; sl@0: #endif sl@0: sl@0: for (i=1; i