Home | History | Annotate | Download | only in des
      1 /* crypto/des/read_pwd.c */
      2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) cryptsoft.com).
      7  * The implementation was written so as to conform with Netscapes SSL.
      8  *
      9  * This library is free for commercial and non-commercial use as long as
     10  * the following conditions are aheared to.  The following conditions
     11  * apply to all code found in this distribution, be it the RC4, RSA,
     12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     13  * included with this distribution is covered by the same copyright terms
     14  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     15  *
     16  * Copyright remains Eric Young's, and as such any Copyright notices in
     17  * the code are not to be removed.
     18  * If this package is used in a product, Eric Young should be given attribution
     19  * as the author of the parts of the library used.
     20  * This can be in the form of a textual message at program startup or
     21  * in documentation (online or textual) provided with the package.
     22  *
     23  * Redistribution and use in source and binary forms, with or without
     24  * modification, are permitted provided that the following conditions
     25  * are met:
     26  * 1. Redistributions of source code must retain the copyright
     27  *    notice, this list of conditions and the following disclaimer.
     28  * 2. Redistributions in binary form must reproduce the above copyright
     29  *    notice, this list of conditions and the following disclaimer in the
     30  *    documentation and/or other materials provided with the distribution.
     31  * 3. All advertising materials mentioning features or use of this software
     32  *    must display the following acknowledgement:
     33  *    "This product includes cryptographic software written by
     34  *     Eric Young (eay (at) cryptsoft.com)"
     35  *    The word 'cryptographic' can be left out if the rouines from the library
     36  *    being used are not cryptographic related :-).
     37  * 4. If you include any Windows specific code (or a derivative thereof) from
     38  *    the apps directory (application code) you must include an acknowledgement:
     39  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     40  *
     41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     51  * SUCH DAMAGE.
     52  *
     53  * The licence and distribution terms for any publically available version or
     54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     55  * copied and put under another distribution licence
     56  * [including the GNU Public Licence.]
     57  */
     58 
     59 #include <openssl/e_os2.h>
     60 #if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WIN32)
     61 #ifdef OPENSSL_UNISTD
     62 # include OPENSSL_UNISTD
     63 #else
     64 # include <unistd.h>
     65 #endif
     66 /* If unistd.h defines _POSIX_VERSION, we conclude that we
     67  * are on a POSIX system and have sigaction and termios. */
     68 #if defined(_POSIX_VERSION)
     69 
     70 # define SIGACTION
     71 # if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
     72 # define TERMIOS
     73 # endif
     74 
     75 #endif
     76 #endif
     77 
     78 /* #define SIGACTION */ /* Define this if you have sigaction() */
     79 
     80 #ifdef WIN16TTY
     81 #undef OPENSSL_SYS_WIN16
     82 #undef _WINDOWS
     83 #include <graph.h>
     84 #endif
     85 
     86 /* 06-Apr-92 Luke Brennan    Support for VMS */
     87 #include "des_locl.h"
     88 #include "cryptlib.h"
     89 #include <signal.h>
     90 #include <stdio.h>
     91 #include <string.h>
     92 #include <setjmp.h>
     93 #include <errno.h>
     94 
     95 #ifdef OPENSSL_SYS_VMS			/* prototypes for sys$whatever */
     96 #include <starlet.h>
     97 #ifdef __DECC
     98 #pragma message disable DOLLARID
     99 #endif
    100 #endif
    101 
    102 #ifdef WIN_CONSOLE_BUG
    103 #include <windows.h>
    104 #ifndef OPENSSL_SYS_WINCE
    105 #include <wincon.h>
    106 #endif
    107 #endif
    108 
    109 
    110 /* There are 5 types of terminal interface supported,
    111  * TERMIO, TERMIOS, VMS, MSDOS and SGTTY
    112  */
    113 
    114 #if defined(__sgi) && !defined(TERMIOS)
    115 #define TERMIOS
    116 #undef  TERMIO
    117 #undef  SGTTY
    118 #endif
    119 
    120 #if defined(linux) && !defined(TERMIO)
    121 #undef  TERMIOS
    122 #define TERMIO
    123 #undef  SGTTY
    124 #endif
    125 
    126 #ifdef _LIBC
    127 #undef  TERMIOS
    128 #define TERMIO
    129 #undef  SGTTY
    130 #endif
    131 
    132 #if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(MAC_OS_pre_X) && !defined(MAC_OS_GUSI_SOURCE)
    133 #undef  TERMIOS
    134 #undef  TERMIO
    135 #define SGTTY
    136 #endif
    137 
    138 #if defined(OPENSSL_SYS_VXWORKS)
    139 #undef TERMIOS
    140 #undef TERMIO
    141 #undef SGTTY
    142 #endif
    143 
    144 #ifdef TERMIOS
    145 #include <termios.h>
    146 #define TTY_STRUCT		struct termios
    147 #define TTY_FLAGS		c_lflag
    148 #define	TTY_get(tty,data)	tcgetattr(tty,data)
    149 #define TTY_set(tty,data)	tcsetattr(tty,TCSANOW,data)
    150 #endif
    151 
    152 #ifdef TERMIO
    153 #include <termio.h>
    154 #define TTY_STRUCT		struct termio
    155 #define TTY_FLAGS		c_lflag
    156 #define TTY_get(tty,data)	ioctl(tty,TCGETA,data)
    157 #define TTY_set(tty,data)	ioctl(tty,TCSETA,data)
    158 #endif
    159 
    160 #ifdef SGTTY
    161 #include <sgtty.h>
    162 #define TTY_STRUCT		struct sgttyb
    163 #define TTY_FLAGS		sg_flags
    164 #define TTY_get(tty,data)	ioctl(tty,TIOCGETP,data)
    165 #define TTY_set(tty,data)	ioctl(tty,TIOCSETP,data)
    166 #endif
    167 
    168 #if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(MAC_OS_pre_X)
    169 #include <sys/ioctl.h>
    170 #endif
    171 
    172 #if defined(OPENSSL_SYS_MSDOS) && !defined(__CYGWIN32__) && !defined(OPENSSL_SYS_WINCE)
    173 #include <conio.h>
    174 #define fgets(a,b,c) noecho_fgets(a,b,c)
    175 #endif
    176 
    177 #ifdef OPENSSL_SYS_VMS
    178 #include <ssdef.h>
    179 #include <iodef.h>
    180 #include <ttdef.h>
    181 #include <descrip.h>
    182 struct IOSB {
    183 	short iosb$w_value;
    184 	short iosb$w_count;
    185 	long  iosb$l_info;
    186 	};
    187 #endif
    188 
    189 #if defined(MAC_OS_pre_X) || defined(MAC_OS_GUSI_SOURCE)
    190 /*
    191  * This one needs work. As a matter of fact the code is unoperational
    192  * and this is only a trick to get it compiled.
    193  *					<appro (at) fy.chalmers.se>
    194  */
    195 #define TTY_STRUCT int
    196 #endif
    197 
    198 #ifndef NX509_SIG
    199 #define NX509_SIG 32
    200 #endif
    201 
    202 static void read_till_nl(FILE *);
    203 static void recsig(int);
    204 static void pushsig(void);
    205 static void popsig(void);
    206 #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16)
    207 static int noecho_fgets(char *buf, int size, FILE *tty);
    208 #endif
    209 #ifdef SIGACTION
    210  static struct sigaction savsig[NX509_SIG];
    211 #else
    212   static void (*savsig[NX509_SIG])(int );
    213 #endif
    214 static jmp_buf save;
    215 
    216 int des_read_pw_string(char *buf, int length, const char *prompt,
    217 	     int verify)
    218 	{
    219 	char buff[BUFSIZ];
    220 	int ret;
    221 
    222 	ret=des_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);
    223 	OPENSSL_cleanse(buff,BUFSIZ);
    224 	return(ret);
    225 	}
    226 
    227 #ifdef OPENSSL_SYS_WINCE
    228 
    229 int des_read_pw(char *buf, char *buff, int size, const char *prompt, int verify)
    230 	{
    231 	memset(buf,0,size);
    232 	memset(buff,0,size);
    233 	return(0);
    234 	}
    235 
    236 #elif defined(OPENSSL_SYS_WIN16)
    237 
    238 int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify)
    239 	{
    240 	memset(buf,0,size);
    241 	memset(buff,0,size);
    242 	return(0);
    243 	}
    244 
    245 #else /* !OPENSSL_SYS_WINCE && !OPENSSL_SYS_WIN16 */
    246 
    247 static void read_till_nl(FILE *in)
    248 	{
    249 #define SIZE 4
    250 	char buf[SIZE+1];
    251 
    252 	do	{
    253 		fgets(buf,SIZE,in);
    254 		} while (strchr(buf,'\n') == NULL);
    255 	}
    256 
    257 
    258 /* return 0 if ok, 1 (or -1) otherwise */
    259 int des_read_pw(char *buf, char *buff, int size, const char *prompt,
    260 	     int verify)
    261 	{
    262 #ifdef OPENSSL_SYS_VMS
    263 	struct IOSB iosb;
    264 	$DESCRIPTOR(terminal,"TT");
    265 	long tty_orig[3], tty_new[3];
    266 	long status;
    267 	unsigned short channel = 0;
    268 #else
    269 #if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__)
    270 	TTY_STRUCT tty_orig,tty_new;
    271 #endif
    272 #endif
    273 	int number;
    274 	int ok;
    275 	/* statics are simply to avoid warnings about longjmp clobbering
    276 	   things */
    277 	static int ps;
    278 	int is_a_tty;
    279 	static FILE *tty;
    280 	char *p;
    281 
    282 	if (setjmp(save))
    283 		{
    284 		ok=0;
    285 		goto error;
    286 		}
    287 
    288 	number=5;
    289 	ok=0;
    290 	ps=0;
    291 	is_a_tty=1;
    292 	tty=NULL;
    293 
    294 #ifdef OPENSSL_SYS_MSDOS
    295 	if ((tty=fopen("con","r")) == NULL)
    296 		tty=stdin;
    297 #elif defined(MAC_OS_pre_X) || defined(OPENSSL_SYS_VXWORKS)
    298 	tty=stdin;
    299 #else
    300 #ifndef OPENSSL_SYS_MPE
    301 	if ((tty=fopen("/dev/tty","r")) == NULL)
    302 #endif
    303 		tty=stdin;
    304 #endif
    305 
    306 #if defined(TTY_get) && !defined(OPENSSL_SYS_VMS)
    307 	if (TTY_get(fileno(tty),&tty_orig) == -1)
    308 		{
    309 #ifdef ENOTTY
    310 		if (errno == ENOTTY)
    311 			is_a_tty=0;
    312 		else
    313 #endif
    314 #ifdef EINVAL
    315 		/* Ariel Glenn ariel (at) columbia.edu reports that solaris
    316 		 * can return EINVAL instead.  This should be ok */
    317 		if (errno == EINVAL)
    318 			is_a_tty=0;
    319 		else
    320 #endif
    321 			return(-1);
    322 		}
    323 	memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));
    324 #endif
    325 #ifdef OPENSSL_SYS_VMS
    326 	status = sys$assign(&terminal,&channel,0,0);
    327 	if (status != SS$_NORMAL)
    328 		return(-1);
    329 	status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);
    330 	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
    331 		return(-1);
    332 #endif
    333 
    334 	pushsig();
    335 	ps=1;
    336 
    337 #ifdef TTY_FLAGS
    338 	tty_new.TTY_FLAGS &= ~ECHO;
    339 #endif
    340 
    341 #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
    342 	if (is_a_tty && (TTY_set(fileno(tty),&tty_new) == -1))
    343 #ifdef OPENSSL_SYS_MPE
    344 		; /* MPE lies -- echo really has been disabled */
    345 #else
    346 		return(-1);
    347 #endif
    348 #endif
    349 #ifdef OPENSSL_SYS_VMS
    350 	tty_new[0] = tty_orig[0];
    351 	tty_new[1] = tty_orig[1] | TT$M_NOECHO;
    352 	tty_new[2] = tty_orig[2];
    353 	status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
    354 	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
    355 		return(-1);
    356 #endif
    357 	ps=2;
    358 
    359 	while ((!ok) && (number--))
    360 		{
    361 		fputs(prompt,stderr);
    362 		fflush(stderr);
    363 
    364 		buf[0]='\0';
    365 		fgets(buf,size,tty);
    366 		if (feof(tty)) goto error;
    367 		if (ferror(tty)) goto error;
    368 		if ((p=(char *)strchr(buf,'\n')) != NULL)
    369 			*p='\0';
    370 		else	read_till_nl(tty);
    371 		if (verify)
    372 			{
    373 			fprintf(stderr,"\nVerifying password - %s",prompt);
    374 			fflush(stderr);
    375 			buff[0]='\0';
    376 			fgets(buff,size,tty);
    377 			if (feof(tty)) goto error;
    378 			if ((p=(char *)strchr(buff,'\n')) != NULL)
    379 				*p='\0';
    380 			else	read_till_nl(tty);
    381 
    382 			if (strcmp(buf,buff) != 0)
    383 				{
    384 				fprintf(stderr,"\nVerify failure");
    385 				fflush(stderr);
    386 				break;
    387 				/* continue; */
    388 				}
    389 			}
    390 		ok=1;
    391 		}
    392 
    393 error:
    394 	fprintf(stderr,"\n");
    395 #if 0
    396 	perror("fgets(tty)");
    397 #endif
    398 	/* What can we do if there is an error? */
    399 #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
    400 	if (ps >= 2) TTY_set(fileno(tty),&tty_orig);
    401 #endif
    402 #ifdef OPENSSL_SYS_VMS
    403 	if (ps >= 2)
    404 		status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0
    405 			,tty_orig,12,0,0,0,0);
    406 #endif
    407 
    408 	if (ps >= 1) popsig();
    409 	if (stdin != tty) fclose(tty);
    410 #ifdef OPENSSL_SYS_VMS
    411 	status = sys$dassgn(channel);
    412 #endif
    413 	return(!ok);
    414 	}
    415 
    416 static void pushsig(void)
    417 	{
    418 	int i;
    419 #ifdef SIGACTION
    420 	struct sigaction sa;
    421 
    422 	memset(&sa,0,sizeof sa);
    423 	sa.sa_handler=recsig;
    424 #endif
    425 
    426 	for (i=1; i<NX509_SIG; i++)
    427 		{
    428 #ifdef SIGUSR1
    429 		if (i == SIGUSR1)
    430 			continue;
    431 #endif
    432 #ifdef SIGUSR2
    433 		if (i == SIGUSR2)
    434 			continue;
    435 #endif
    436 #ifdef SIGACTION
    437 		sigaction(i,&sa,&savsig[i]);
    438 #else
    439 		savsig[i]=signal(i,recsig);
    440 #endif
    441 		}
    442 
    443 #ifdef SIGWINCH
    444 	signal(SIGWINCH,SIG_DFL);
    445 #endif
    446 	}
    447 
    448 static void popsig(void)
    449 	{
    450 	int i;
    451 
    452 	for (i=1; i<NX509_SIG; i++)
    453 		{
    454 #ifdef SIGUSR1
    455 		if (i == SIGUSR1)
    456 			continue;
    457 #endif
    458 #ifdef SIGUSR2
    459 		if (i == SIGUSR2)
    460 			continue;
    461 #endif
    462 #ifdef SIGACTION
    463 		sigaction(i,&savsig[i],NULL);
    464 #else
    465 		signal(i,savsig[i]);
    466 #endif
    467 		}
    468 	}
    469 
    470 static void recsig(int i)
    471 	{
    472 	longjmp(save,1);
    473 #ifdef LINT
    474 	i=i;
    475 #endif
    476 	}
    477 
    478 #ifdef OPENSSL_SYS_MSDOS
    479 static int noecho_fgets(char *buf, int size, FILE *tty)
    480 	{
    481 	int i;
    482 	char *p;
    483 
    484 	p=buf;
    485 	for (;;)
    486 		{
    487 		if (size == 0)
    488 			{
    489 			*p='\0';
    490 			break;
    491 			}
    492 		size--;
    493 #ifdef WIN16TTY
    494 		i=_inchar();
    495 #else
    496 		i=getch();
    497 #endif
    498 		if (i == '\r') i='\n';
    499 		*(p++)=i;
    500 		if (i == '\n')
    501 			{
    502 			*p='\0';
    503 			break;
    504 			}
    505 		}
    506 #ifdef WIN_CONSOLE_BUG
    507 /* Win95 has several evil console bugs: one of these is that the
    508  * last character read using getch() is passed to the next read: this is
    509  * usually a CR so this can be trouble. No STDIO fix seems to work but
    510  * flushing the console appears to do the trick.
    511  */
    512 		{
    513 			HANDLE inh;
    514 			inh = GetStdHandle(STD_INPUT_HANDLE);
    515 			FlushConsoleInputBuffer(inh);
    516 		}
    517 #endif
    518 	return(strlen(buf));
    519 	}
    520 #endif
    521 #endif /* !OPENSSL_SYS_WINCE && !WIN16 */
    522