155714Skris/* crypto/des/read_pwd.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 59109998Smarkm#include <openssl/e_os2.h> 60109998Smarkm#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WIN32) 6159191Skris#ifdef OPENSSL_UNISTD 6259191Skris# include OPENSSL_UNISTD 6359191Skris#else 6459191Skris# include <unistd.h> 6559191Skris#endif 6655714Skris/* If unistd.h defines _POSIX_VERSION, we conclude that we 6755714Skris * are on a POSIX system and have sigaction and termios. */ 6855714Skris#if defined(_POSIX_VERSION) 6955714Skris 7055714Skris# define SIGACTION 7155714Skris# if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) 7255714Skris# define TERMIOS 7355714Skris# endif 7455714Skris 7555714Skris#endif 7655714Skris#endif 7755714Skris 7855714Skris/* #define SIGACTION */ /* Define this if you have sigaction() */ 7955714Skris 8055714Skris#ifdef WIN16TTY 81109998Smarkm#undef OPENSSL_SYS_WIN16 8255714Skris#undef _WINDOWS 8355714Skris#include <graph.h> 8455714Skris#endif 8555714Skris 8655714Skris/* 06-Apr-92 Luke Brennan Support for VMS */ 8755714Skris#include "des_locl.h" 8855714Skris#include "cryptlib.h" 8955714Skris#include <signal.h> 9055714Skris#include <stdio.h> 9155714Skris#include <string.h> 9255714Skris#include <setjmp.h> 9355714Skris#include <errno.h> 9455714Skris 95109998Smarkm#ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */ 9655714Skris#include <starlet.h> 9755714Skris#ifdef __DECC 9855714Skris#pragma message disable DOLLARID 9955714Skris#endif 10055714Skris#endif 10155714Skris 10255714Skris#ifdef WIN_CONSOLE_BUG 10355714Skris#include <windows.h> 104109998Smarkm#ifndef OPENSSL_SYS_WINCE 10555714Skris#include <wincon.h> 10655714Skris#endif 107109998Smarkm#endif 10855714Skris 10955714Skris 11055714Skris/* There are 5 types of terminal interface supported, 11155714Skris * TERMIO, TERMIOS, VMS, MSDOS and SGTTY 11255714Skris */ 11355714Skris 11455714Skris#if defined(__sgi) && !defined(TERMIOS) 11555714Skris#define TERMIOS 11655714Skris#undef TERMIO 11755714Skris#undef SGTTY 11855714Skris#endif 11955714Skris 12055714Skris#if defined(linux) && !defined(TERMIO) 12155714Skris#undef TERMIOS 12255714Skris#define TERMIO 12355714Skris#undef SGTTY 12455714Skris#endif 12555714Skris 12655714Skris#ifdef _LIBC 12755714Skris#undef TERMIOS 12855714Skris#define TERMIO 12955714Skris#undef SGTTY 13055714Skris#endif 13155714Skris 132109998Smarkm#if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(MAC_OS_pre_X) && !defined(MAC_OS_GUSI_SOURCE) 13355714Skris#undef TERMIOS 13455714Skris#undef TERMIO 13555714Skris#define SGTTY 13655714Skris#endif 13755714Skris 138109998Smarkm#if defined(OPENSSL_SYS_VXWORKS) 139100928Snectar#undef TERMIOS 140100928Snectar#undef TERMIO 141100928Snectar#undef SGTTY 142100928Snectar#endif 143100928Snectar 14455714Skris#ifdef TERMIOS 14555714Skris#include <termios.h> 14655714Skris#define TTY_STRUCT struct termios 14755714Skris#define TTY_FLAGS c_lflag 14855714Skris#define TTY_get(tty,data) tcgetattr(tty,data) 14955714Skris#define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) 15055714Skris#endif 15155714Skris 15255714Skris#ifdef TERMIO 15355714Skris#include <termio.h> 15455714Skris#define TTY_STRUCT struct termio 15555714Skris#define TTY_FLAGS c_lflag 15655714Skris#define TTY_get(tty,data) ioctl(tty,TCGETA,data) 15755714Skris#define TTY_set(tty,data) ioctl(tty,TCSETA,data) 15855714Skris#endif 15955714Skris 16055714Skris#ifdef SGTTY 16155714Skris#include <sgtty.h> 16255714Skris#define TTY_STRUCT struct sgttyb 16355714Skris#define TTY_FLAGS sg_flags 16455714Skris#define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) 16555714Skris#define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) 16655714Skris#endif 16755714Skris 168109998Smarkm#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(MAC_OS_pre_X) 16955714Skris#include <sys/ioctl.h> 17055714Skris#endif 17155714Skris 172109998Smarkm#if defined(OPENSSL_SYS_MSDOS) && !defined(__CYGWIN32__) && !defined(OPENSSL_SYS_WINCE) 17355714Skris#include <conio.h> 17455714Skris#define fgets(a,b,c) noecho_fgets(a,b,c) 17555714Skris#endif 17655714Skris 177109998Smarkm#ifdef OPENSSL_SYS_VMS 17855714Skris#include <ssdef.h> 17955714Skris#include <iodef.h> 18055714Skris#include <ttdef.h> 18155714Skris#include <descrip.h> 18255714Skrisstruct IOSB { 18355714Skris short iosb$w_value; 18455714Skris short iosb$w_count; 18555714Skris long iosb$l_info; 18655714Skris }; 18755714Skris#endif 18855714Skris 18959191Skris#if defined(MAC_OS_pre_X) || defined(MAC_OS_GUSI_SOURCE) 19059191Skris/* 19159191Skris * This one needs work. As a matter of fact the code is unoperational 19259191Skris * and this is only a trick to get it compiled. 19359191Skris * <appro@fy.chalmers.se> 19459191Skris */ 19559191Skris#define TTY_STRUCT int 19659191Skris#endif 19759191Skris 19855714Skris#ifndef NX509_SIG 19955714Skris#define NX509_SIG 32 20055714Skris#endif 20155714Skris 20255714Skrisstatic void read_till_nl(FILE *); 20355714Skrisstatic void recsig(int); 20455714Skrisstatic void pushsig(void); 20555714Skrisstatic void popsig(void); 206109998Smarkm#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) 20755714Skrisstatic int noecho_fgets(char *buf, int size, FILE *tty); 20855714Skris#endif 20955714Skris#ifdef SIGACTION 21055714Skris static struct sigaction savsig[NX509_SIG]; 21155714Skris#else 21255714Skris static void (*savsig[NX509_SIG])(int ); 21355714Skris#endif 21455714Skrisstatic jmp_buf save; 21555714Skris 21655714Skrisint des_read_pw_string(char *buf, int length, const char *prompt, 21755714Skris int verify) 21855714Skris { 21955714Skris char buff[BUFSIZ]; 22055714Skris int ret; 22155714Skris 22255714Skris ret=des_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify); 223109998Smarkm OPENSSL_cleanse(buff,BUFSIZ); 22455714Skris return(ret); 22555714Skris } 22655714Skris 227109998Smarkm#ifdef OPENSSL_SYS_WINCE 22855714Skris 229109998Smarkmint des_read_pw(char *buf, char *buff, int size, const char *prompt, int verify) 230109998Smarkm { 231109998Smarkm memset(buf,0,size); 232109998Smarkm memset(buff,0,size); 233109998Smarkm return(0); 234109998Smarkm } 235109998Smarkm 236109998Smarkm#elif defined(OPENSSL_SYS_WIN16) 237109998Smarkm 238109998Smarkmint des_read_pw(char *buf, char *buff, int size, char *prompt, int verify) 239109998Smarkm { 240109998Smarkm memset(buf,0,size); 241109998Smarkm memset(buff,0,size); 242109998Smarkm return(0); 243109998Smarkm } 244109998Smarkm 245109998Smarkm#else /* !OPENSSL_SYS_WINCE && !OPENSSL_SYS_WIN16 */ 246109998Smarkm 24755714Skrisstatic void read_till_nl(FILE *in) 24855714Skris { 24955714Skris#define SIZE 4 25055714Skris char buf[SIZE+1]; 25155714Skris 25255714Skris do { 25355714Skris fgets(buf,SIZE,in); 25455714Skris } while (strchr(buf,'\n') == NULL); 25555714Skris } 25655714Skris 25755714Skris 25855714Skris/* return 0 if ok, 1 (or -1) otherwise */ 25955714Skrisint des_read_pw(char *buf, char *buff, int size, const char *prompt, 26055714Skris int verify) 26155714Skris { 262109998Smarkm#ifdef OPENSSL_SYS_VMS 26355714Skris struct IOSB iosb; 26455714Skris $DESCRIPTOR(terminal,"TT"); 26555714Skris long tty_orig[3], tty_new[3]; 26655714Skris long status; 26755714Skris unsigned short channel = 0; 26855714Skris#else 269109998Smarkm#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) 27055714Skris TTY_STRUCT tty_orig,tty_new; 27155714Skris#endif 27255714Skris#endif 27355714Skris int number; 27455714Skris int ok; 27555714Skris /* statics are simply to avoid warnings about longjmp clobbering 27655714Skris things */ 27755714Skris static int ps; 27855714Skris int is_a_tty; 27955714Skris static FILE *tty; 28055714Skris char *p; 28155714Skris 28255714Skris if (setjmp(save)) 28355714Skris { 28455714Skris ok=0; 28555714Skris goto error; 28655714Skris } 28755714Skris 28855714Skris number=5; 28955714Skris ok=0; 29055714Skris ps=0; 29155714Skris is_a_tty=1; 29255714Skris tty=NULL; 29355714Skris 294109998Smarkm#ifdef OPENSSL_SYS_MSDOS 29568651Skris if ((tty=fopen("con","r")) == NULL) 29668651Skris tty=stdin; 297109998Smarkm#elif defined(MAC_OS_pre_X) || defined(OPENSSL_SYS_VXWORKS) 29868651Skris tty=stdin; 29968651Skris#else 300109998Smarkm#ifndef OPENSSL_SYS_MPE 30155714Skris if ((tty=fopen("/dev/tty","r")) == NULL) 30268651Skris#endif 30355714Skris tty=stdin; 30468651Skris#endif 30555714Skris 306109998Smarkm#if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) 30755714Skris if (TTY_get(fileno(tty),&tty_orig) == -1) 30855714Skris { 30955714Skris#ifdef ENOTTY 31055714Skris if (errno == ENOTTY) 31155714Skris is_a_tty=0; 31255714Skris else 31355714Skris#endif 31455714Skris#ifdef EINVAL 31555714Skris /* Ariel Glenn ariel@columbia.edu reports that solaris 31655714Skris * can return EINVAL instead. This should be ok */ 31755714Skris if (errno == EINVAL) 31855714Skris is_a_tty=0; 31955714Skris else 32055714Skris#endif 32155714Skris return(-1); 32255714Skris } 32355714Skris memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig)); 32455714Skris#endif 325109998Smarkm#ifdef OPENSSL_SYS_VMS 32655714Skris status = sys$assign(&terminal,&channel,0,0); 32755714Skris if (status != SS$_NORMAL) 32855714Skris return(-1); 32955714Skris status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0); 33055714Skris if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) 33155714Skris return(-1); 33255714Skris#endif 33355714Skris 33455714Skris pushsig(); 33555714Skris ps=1; 33655714Skris 33755714Skris#ifdef TTY_FLAGS 33855714Skris tty_new.TTY_FLAGS &= ~ECHO; 33955714Skris#endif 34055714Skris 341109998Smarkm#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) 34255714Skris if (is_a_tty && (TTY_set(fileno(tty),&tty_new) == -1)) 343109998Smarkm#ifdef OPENSSL_SYS_MPE 34468651Skris ; /* MPE lies -- echo really has been disabled */ 34568651Skris#else 34655714Skris return(-1); 34755714Skris#endif 34868651Skris#endif 349109998Smarkm#ifdef OPENSSL_SYS_VMS 35055714Skris tty_new[0] = tty_orig[0]; 35155714Skris tty_new[1] = tty_orig[1] | TT$M_NOECHO; 35255714Skris tty_new[2] = tty_orig[2]; 35355714Skris status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0); 35455714Skris if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) 35555714Skris return(-1); 35655714Skris#endif 35755714Skris ps=2; 35855714Skris 35955714Skris while ((!ok) && (number--)) 36055714Skris { 36155714Skris fputs(prompt,stderr); 36255714Skris fflush(stderr); 36355714Skris 36455714Skris buf[0]='\0'; 36555714Skris fgets(buf,size,tty); 36655714Skris if (feof(tty)) goto error; 36755714Skris if (ferror(tty)) goto error; 36855714Skris if ((p=(char *)strchr(buf,'\n')) != NULL) 36955714Skris *p='\0'; 37055714Skris else read_till_nl(tty); 37155714Skris if (verify) 37255714Skris { 37355714Skris fprintf(stderr,"\nVerifying password - %s",prompt); 37455714Skris fflush(stderr); 37555714Skris buff[0]='\0'; 37655714Skris fgets(buff,size,tty); 37755714Skris if (feof(tty)) goto error; 37855714Skris if ((p=(char *)strchr(buff,'\n')) != NULL) 37955714Skris *p='\0'; 38055714Skris else read_till_nl(tty); 38155714Skris 38255714Skris if (strcmp(buf,buff) != 0) 38355714Skris { 38455714Skris fprintf(stderr,"\nVerify failure"); 38555714Skris fflush(stderr); 38655714Skris break; 38755714Skris /* continue; */ 38855714Skris } 38955714Skris } 39055714Skris ok=1; 39155714Skris } 39255714Skris 39355714Skriserror: 39455714Skris fprintf(stderr,"\n"); 395100928Snectar#if 0 39655714Skris perror("fgets(tty)"); 39755714Skris#endif 39855714Skris /* What can we do if there is an error? */ 399109998Smarkm#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) 40055714Skris if (ps >= 2) TTY_set(fileno(tty),&tty_orig); 40155714Skris#endif 402109998Smarkm#ifdef OPENSSL_SYS_VMS 40355714Skris if (ps >= 2) 40455714Skris status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0 40555714Skris ,tty_orig,12,0,0,0,0); 40655714Skris#endif 40755714Skris 40855714Skris if (ps >= 1) popsig(); 40955714Skris if (stdin != tty) fclose(tty); 410109998Smarkm#ifdef OPENSSL_SYS_VMS 41155714Skris status = sys$dassgn(channel); 41255714Skris#endif 41355714Skris return(!ok); 41455714Skris } 41555714Skris 41655714Skrisstatic void pushsig(void) 41755714Skris { 41855714Skris int i; 41955714Skris#ifdef SIGACTION 42055714Skris struct sigaction sa; 42155714Skris 42255714Skris memset(&sa,0,sizeof sa); 42355714Skris sa.sa_handler=recsig; 42455714Skris#endif 42555714Skris 42655714Skris for (i=1; i<NX509_SIG; i++) 42755714Skris { 42855714Skris#ifdef SIGUSR1 42955714Skris if (i == SIGUSR1) 43055714Skris continue; 43155714Skris#endif 43255714Skris#ifdef SIGUSR2 43355714Skris if (i == SIGUSR2) 43455714Skris continue; 43555714Skris#endif 43655714Skris#ifdef SIGACTION 43755714Skris sigaction(i,&sa,&savsig[i]); 43855714Skris#else 43955714Skris savsig[i]=signal(i,recsig); 44055714Skris#endif 44155714Skris } 44255714Skris 44355714Skris#ifdef SIGWINCH 44455714Skris signal(SIGWINCH,SIG_DFL); 44555714Skris#endif 44655714Skris } 44755714Skris 44855714Skrisstatic void popsig(void) 44955714Skris { 45055714Skris int i; 45155714Skris 45255714Skris for (i=1; i<NX509_SIG; i++) 45355714Skris { 45455714Skris#ifdef SIGUSR1 45555714Skris if (i == SIGUSR1) 45655714Skris continue; 45755714Skris#endif 45855714Skris#ifdef SIGUSR2 45955714Skris if (i == SIGUSR2) 46055714Skris continue; 46155714Skris#endif 46255714Skris#ifdef SIGACTION 46355714Skris sigaction(i,&savsig[i],NULL); 46455714Skris#else 46555714Skris signal(i,savsig[i]); 46655714Skris#endif 46755714Skris } 46855714Skris } 46955714Skris 47055714Skrisstatic void recsig(int i) 47155714Skris { 47255714Skris longjmp(save,1); 47355714Skris#ifdef LINT 47455714Skris i=i; 47555714Skris#endif 47655714Skris } 47755714Skris 478109998Smarkm#ifdef OPENSSL_SYS_MSDOS 47955714Skrisstatic int noecho_fgets(char *buf, int size, FILE *tty) 48055714Skris { 48155714Skris int i; 48255714Skris char *p; 48355714Skris 48455714Skris p=buf; 48555714Skris for (;;) 48655714Skris { 48755714Skris if (size == 0) 48855714Skris { 48955714Skris *p='\0'; 49055714Skris break; 49155714Skris } 49255714Skris size--; 49355714Skris#ifdef WIN16TTY 49455714Skris i=_inchar(); 49555714Skris#else 49655714Skris i=getch(); 49755714Skris#endif 49855714Skris if (i == '\r') i='\n'; 49955714Skris *(p++)=i; 50055714Skris if (i == '\n') 50155714Skris { 50255714Skris *p='\0'; 50355714Skris break; 50455714Skris } 50555714Skris } 50655714Skris#ifdef WIN_CONSOLE_BUG 50755714Skris/* Win95 has several evil console bugs: one of these is that the 50855714Skris * last character read using getch() is passed to the next read: this is 50955714Skris * usually a CR so this can be trouble. No STDIO fix seems to work but 51055714Skris * flushing the console appears to do the trick. 51155714Skris */ 51255714Skris { 51355714Skris HANDLE inh; 51455714Skris inh = GetStdHandle(STD_INPUT_HANDLE); 51555714Skris FlushConsoleInputBuffer(inh); 51655714Skris } 51755714Skris#endif 51855714Skris return(strlen(buf)); 51955714Skris } 52055714Skris#endif 521109998Smarkm#endif /* !OPENSSL_SYS_WINCE && !WIN16 */ 522