read_pwd.c revision 100928
1185029Spjd/* crypto/des/read_pwd.c */ 2185029Spjd/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3185029Spjd * All rights reserved. 4185029Spjd * 5185029Spjd * This package is an SSL implementation written 6185029Spjd * by Eric Young (eay@cryptsoft.com). 7185029Spjd * The implementation was written so as to conform with Netscapes SSL. 8185029Spjd * 9185029Spjd * This library is free for commercial and non-commercial use as long as 10185029Spjd * the following conditions are aheared to. The following conditions 11185029Spjd * apply to all code found in this distribution, be it the RC4, RSA, 12185029Spjd * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13185029Spjd * included with this distribution is covered by the same copyright terms 14185029Spjd * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15185029Spjd * 16185029Spjd * Copyright remains Eric Young's, and as such any Copyright notices in 17185029Spjd * the code are not to be removed. 18185029Spjd * If this package is used in a product, Eric Young should be given attribution 19185029Spjd * as the author of the parts of the library used. 20185029Spjd * This can be in the form of a textual message at program startup or 21185029Spjd * in documentation (online or textual) provided with the package. 22219089Spjd * 23248369Smm * Redistribution and use in source and binary forms, with or without 24185029Spjd * modification, are permitted provided that the following conditions 25185029Spjd * are met: 26185029Spjd * 1. Redistributions of source code must retain the copyright 27185029Spjd * notice, this list of conditions and the following disclaimer. 28185029Spjd * 2. Redistributions in binary form must reproduce the above copyright 29185029Spjd * notice, this list of conditions and the following disclaimer in the 30185029Spjd * documentation and/or other materials provided with the distribution. 31185029Spjd * 3. All advertising materials mentioning features or use of this software 32185029Spjd * must display the following acknowledgement: 33185029Spjd * "This product includes cryptographic software written by 34185029Spjd * Eric Young (eay@cryptsoft.com)" 35185029Spjd * The word 'cryptographic' can be left out if the rouines from the library 36185029Spjd * being used are not cryptographic related :-). 37185029Spjd * 4. If you include any Windows specific code (or a derivative thereof) from 38185029Spjd * the apps directory (application code) you must include an acknowledgement: 39185029Spjd * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40185029Spjd * 41185029Spjd * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42185029Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43185029Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44185029Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45219089Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46219089Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47185029Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48185029Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49185029Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50219089Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51185029Spjd * SUCH DAMAGE. 52185029Spjd * 53185029Spjd * The licence and distribution terms for any publically available version or 54185029Spjd * derivative of this code cannot be changed. i.e. this code cannot simply be 55185029Spjd * copied and put under another distribution licence 56185029Spjd * [including the GNU Public Licence.] 57185029Spjd */ 58185029Spjd 59185029Spjd#if !defined(MSDOS) && !defined(VMS) && !defined(WIN32) && !defined(VXWORKS) 60185029Spjd#include <openssl/opensslconf.h> 61185029Spjd#ifdef OPENSSL_UNISTD 62185029Spjd# include OPENSSL_UNISTD 63185029Spjd#else 64185029Spjd# include <unistd.h> 65185029Spjd#endif 66185029Spjd/* If unistd.h defines _POSIX_VERSION, we conclude that we 67185029Spjd * are on a POSIX system and have sigaction and termios. */ 68185029Spjd#if defined(_POSIX_VERSION) 69185029Spjd 70185029Spjd# define SIGACTION 71185029Spjd# if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) 72185029Spjd# define TERMIOS 73219089Spjd# endif 74185029Spjd 75185029Spjd#endif 76185029Spjd#endif 77185029Spjd 78185029Spjd/* #define SIGACTION */ /* Define this if you have sigaction() */ 79185029Spjd 80185029Spjd#ifdef WIN16TTY 81185029Spjd#undef WIN16 82185029Spjd#undef _WINDOWS 83185029Spjd#include <graph.h> 84185029Spjd#endif 85185029Spjd 86185029Spjd/* 06-Apr-92 Luke Brennan Support for VMS */ 87185029Spjd#include "des_locl.h" 88185029Spjd#include "cryptlib.h" 89185029Spjd#include <signal.h> 90185029Spjd#include <stdio.h> 91185029Spjd#include <string.h> 92185029Spjd#include <setjmp.h> 93185029Spjd#include <errno.h> 94185029Spjd 95185029Spjd#ifdef VMS /* prototypes for sys$whatever */ 96185029Spjd#include <starlet.h> 97185029Spjd#ifdef __DECC 98185029Spjd#pragma message disable DOLLARID 99185029Spjd#endif 100185029Spjd#endif 101185029Spjd 102185029Spjd#ifdef WIN_CONSOLE_BUG 103185029Spjd#include <windows.h> 104185029Spjd#include <wincon.h> 105185029Spjd#endif 106185029Spjd 107185029Spjd 108185029Spjd/* There are 5 types of terminal interface supported, 109185029Spjd * TERMIO, TERMIOS, VMS, MSDOS and SGTTY 110185029Spjd */ 111185029Spjd 112185029Spjd#if defined(__sgi) && !defined(TERMIOS) 113185029Spjd#define TERMIOS 114185029Spjd#undef TERMIO 115185029Spjd#undef SGTTY 116185029Spjd#endif 117185029Spjd 118185029Spjd#if defined(linux) && !defined(TERMIO) 119185029Spjd#undef TERMIOS 120185029Spjd#define TERMIO 121185029Spjd#undef SGTTY 122185029Spjd#endif 123185029Spjd 124185029Spjd#ifdef _LIBC 125185029Spjd#undef TERMIOS 126185029Spjd#define TERMIO 127185029Spjd#undef SGTTY 128185029Spjd#endif 129185029Spjd 130185029Spjd#if !defined(TERMIO) && !defined(TERMIOS) && !defined(VMS) && !defined(MSDOS) && !defined(MAC_OS_pre_X) && !defined(MAC_OS_GUSI_SOURCE) 131185029Spjd#undef TERMIOS 132185029Spjd#undef TERMIO 133185029Spjd#define SGTTY 134185029Spjd#endif 135185029Spjd 136185029Spjd#if defined(VXWORKS) 137185029Spjd#undef TERMIOS 138185029Spjd#undef TERMIO 139185029Spjd#undef SGTTY 140185029Spjd#endif 141185029Spjd 142185029Spjd#ifdef TERMIOS 143185029Spjd#include <termios.h> 144185029Spjd#define TTY_STRUCT struct termios 145185029Spjd#define TTY_FLAGS c_lflag 146185029Spjd#define TTY_get(tty,data) tcgetattr(tty,data) 147186568Srwatson#define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) 148185029Spjd#endif 149185029Spjd 150185029Spjd#ifdef TERMIO 151262102Savg#include <termio.h> 152185029Spjd#define TTY_STRUCT struct termio 153185029Spjd#define TTY_FLAGS c_lflag 154185029Spjd#define TTY_get(tty,data) ioctl(tty,TCGETA,data) 155185029Spjd#define TTY_set(tty,data) ioctl(tty,TCSETA,data) 156185029Spjd#endif 157185029Spjd 158185029Spjd#ifdef SGTTY 159185029Spjd#include <sgtty.h> 160185029Spjd#define TTY_STRUCT struct sgttyb 161185029Spjd#define TTY_FLAGS sg_flags 162185029Spjd#define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) 163185029Spjd#define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) 164185029Spjd#endif 165185029Spjd 166185029Spjd#if !defined(_LIBC) && !defined(MSDOS) && !defined(VMS) && !defined(MAC_OS_pre_X) 167185029Spjd#include <sys/ioctl.h> 168185029Spjd#endif 169185029Spjd 170185029Spjd#if defined(MSDOS) && !defined(__CYGWIN32__) 171219089Spjd#include <conio.h> 172185029Spjd#define fgets(a,b,c) noecho_fgets(a,b,c) 173185029Spjd#endif 174185029Spjd 175219089Spjd#ifdef VMS 176219089Spjd#include <ssdef.h> 177219089Spjd#include <iodef.h> 178185029Spjd#include <ttdef.h> 179185029Spjd#include <descrip.h> 180185029Spjdstruct IOSB { 181185029Spjd short iosb$w_value; 182185029Spjd short iosb$w_count; 183185029Spjd long iosb$l_info; 184185029Spjd }; 185185029Spjd#endif 186185029Spjd 187185029Spjd#if defined(MAC_OS_pre_X) || defined(MAC_OS_GUSI_SOURCE) 188185029Spjd/* 189185029Spjd * This one needs work. As a matter of fact the code is unoperational 190185029Spjd * and this is only a trick to get it compiled. 191185029Spjd * <appro@fy.chalmers.se> 192185029Spjd */ 193185029Spjd#define TTY_STRUCT int 194185029Spjd#endif 195185029Spjd 196185029Spjd#ifndef NX509_SIG 197185029Spjd#define NX509_SIG 32 198185029Spjd#endif 199185029Spjd 200185029Spjdstatic void read_till_nl(FILE *); 201219089Spjdstatic void recsig(int); 202219089Spjdstatic void pushsig(void); 203185029Spjdstatic void popsig(void); 204185029Spjd#if defined(MSDOS) && !defined(WIN16) 205185029Spjdstatic int noecho_fgets(char *buf, int size, FILE *tty); 206185029Spjd#endif 207185029Spjd#ifdef SIGACTION 208185029Spjd static struct sigaction savsig[NX509_SIG]; 209185029Spjd#else 210185029Spjd static void (*savsig[NX509_SIG])(int ); 211185029Spjd#endif 212185029Spjdstatic jmp_buf save; 213185029Spjd 214185029Spjdint des_read_pw_string(char *buf, int length, const char *prompt, 215185029Spjd int verify) 216185029Spjd { 217185029Spjd char buff[BUFSIZ]; 218185029Spjd int ret; 219185029Spjd 220185029Spjd ret=des_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify); 221185029Spjd memset(buff,0,BUFSIZ); 222185029Spjd return(ret); 223185029Spjd } 224185029Spjd 225185029Spjd#ifndef WIN16 226185029Spjd 227185029Spjdstatic void read_till_nl(FILE *in) 228185029Spjd { 229185029Spjd#define SIZE 4 230185029Spjd char buf[SIZE+1]; 231219089Spjd 232219089Spjd do { 233219089Spjd fgets(buf,SIZE,in); 234219089Spjd } while (strchr(buf,'\n') == NULL); 235219089Spjd } 236219089Spjd 237219089Spjd 238185029Spjd/* return 0 if ok, 1 (or -1) otherwise */ 239219089Spjdint des_read_pw(char *buf, char *buff, int size, const char *prompt, 240219089Spjd int verify) 241219089Spjd { 242185029Spjd#ifdef VMS 243219089Spjd struct IOSB iosb; 244219089Spjd $DESCRIPTOR(terminal,"TT"); 245219089Spjd long tty_orig[3], tty_new[3]; 246219089Spjd long status; 247219089Spjd unsigned short channel = 0; 248219089Spjd#else 249219089Spjd#if !defined(MSDOS) && !defined(VXWORKS) 250219089Spjd TTY_STRUCT tty_orig,tty_new; 251219089Spjd#endif 252219089Spjd#endif 253185029Spjd int number; 254185029Spjd int ok; 255185029Spjd /* statics are simply to avoid warnings about longjmp clobbering 256185029Spjd things */ 257185029Spjd static int ps; 258185029Spjd int is_a_tty; 259185029Spjd static FILE *tty; 260185029Spjd char *p; 261185029Spjd 262185029Spjd if (setjmp(save)) 263185029Spjd { 264185029Spjd ok=0; 265185029Spjd goto error; 266185029Spjd } 267185029Spjd 268185029Spjd number=5; 269185029Spjd ok=0; 270185029Spjd ps=0; 271185029Spjd is_a_tty=1; 272185029Spjd tty=NULL; 273185029Spjd 274185029Spjd#ifdef MSDOS 275185029Spjd if ((tty=fopen("con","r")) == NULL) 276185029Spjd tty=stdin; 277185029Spjd#elif defined(MAC_OS_pre_X) || defined(VXWORKS) 278185029Spjd tty=stdin; 279185029Spjd#else 280185029Spjd#ifndef MPE 281185029Spjd if ((tty=fopen("/dev/tty","r")) == NULL) 282185029Spjd#endif 283185029Spjd tty=stdin; 284185029Spjd#endif 285185029Spjd 286185029Spjd#if defined(TTY_get) && !defined(VMS) 287185029Spjd if (TTY_get(fileno(tty),&tty_orig) == -1) 288185029Spjd { 289185029Spjd#ifdef ENOTTY 290185029Spjd if (errno == ENOTTY) 291185029Spjd is_a_tty=0; 292185029Spjd else 293219089Spjd#endif 294185029Spjd#ifdef EINVAL 295185029Spjd /* Ariel Glenn ariel@columbia.edu reports that solaris 296185029Spjd * can return EINVAL instead. This should be ok */ 297185029Spjd if (errno == EINVAL) 298185029Spjd is_a_tty=0; 299185029Spjd else 300185029Spjd#endif 301185029Spjd return(-1); 302243674Smm } 303185029Spjd memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig)); 304185029Spjd#endif 305185029Spjd#ifdef VMS 306185029Spjd status = sys$assign(&terminal,&channel,0,0); 307185029Spjd if (status != SS$_NORMAL) 308185029Spjd return(-1); 309185029Spjd status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0); 310219089Spjd if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) 311219089Spjd return(-1); 312219089Spjd#endif 313219089Spjd 314219089Spjd pushsig(); 315219089Spjd ps=1; 316185029Spjd 317185029Spjd#ifdef TTY_FLAGS 318185029Spjd tty_new.TTY_FLAGS &= ~ECHO; 319185029Spjd#endif 320185029Spjd 321185029Spjd#if defined(TTY_set) && !defined(VMS) 322185029Spjd if (is_a_tty && (TTY_set(fileno(tty),&tty_new) == -1)) 323185029Spjd#ifdef MPE 324185029Spjd ; /* MPE lies -- echo really has been disabled */ 325219089Spjd#else 326185029Spjd return(-1); 327185029Spjd#endif 328185029Spjd#endif 329185029Spjd#ifdef VMS 330185029Spjd tty_new[0] = tty_orig[0]; 331185029Spjd tty_new[1] = tty_orig[1] | TT$M_NOECHO; 332185029Spjd tty_new[2] = tty_orig[2]; 333185029Spjd status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0); 334185029Spjd if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) 335185029Spjd return(-1); 336185029Spjd#endif 337185029Spjd ps=2; 338185029Spjd 339185029Spjd while ((!ok) && (number--)) 340185029Spjd { 341185029Spjd fputs(prompt,stderr); 342185029Spjd fflush(stderr); 343185029Spjd 344185029Spjd buf[0]='\0'; 345185029Spjd fgets(buf,size,tty); 346185029Spjd if (feof(tty)) goto error; 347185029Spjd if (ferror(tty)) goto error; 348185029Spjd if ((p=(char *)strchr(buf,'\n')) != NULL) 349185029Spjd *p='\0'; 350185029Spjd else read_till_nl(tty); 351185029Spjd if (verify) 352185029Spjd { 353185029Spjd fprintf(stderr,"\nVerifying password - %s",prompt); 354185029Spjd fflush(stderr); 355185029Spjd buff[0]='\0'; 356185029Spjd fgets(buff,size,tty); 357219089Spjd if (feof(tty)) goto error; 358185029Spjd if ((p=(char *)strchr(buff,'\n')) != NULL) 359185029Spjd *p='\0'; 360185029Spjd else read_till_nl(tty); 361185029Spjd 362185029Spjd if (strcmp(buf,buff) != 0) 363185029Spjd { 364185029Spjd fprintf(stderr,"\nVerify failure"); 365185029Spjd fflush(stderr); 366185029Spjd break; 367185029Spjd /* continue; */ 368185029Spjd } 369185029Spjd } 370185029Spjd ok=1; 371185029Spjd } 372185029Spjd 373219089Spjderror: 374219089Spjd fprintf(stderr,"\n"); 375219089Spjd#if 0 376219089Spjd perror("fgets(tty)"); 377219089Spjd#endif 378219089Spjd /* What can we do if there is an error? */ 379219089Spjd#if defined(TTY_set) && !defined(VMS) 380219089Spjd if (ps >= 2) TTY_set(fileno(tty),&tty_orig); 381219089Spjd#endif 382219089Spjd#ifdef VMS 383219089Spjd if (ps >= 2) 384219089Spjd status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0 385219089Spjd ,tty_orig,12,0,0,0,0); 386219089Spjd#endif 387219089Spjd 388219089Spjd if (ps >= 1) popsig(); 389219089Spjd if (stdin != tty) fclose(tty); 390219089Spjd#ifdef VMS 391219089Spjd status = sys$dassgn(channel); 392219089Spjd#endif 393219089Spjd return(!ok); 394185029Spjd } 395185029Spjd 396185029Spjd#else /* WIN16 */ 397185029Spjd 398185029Spjdint des_read_pw(char *buf, char *buff, int size, char *prompt, int verify) 399185029Spjd { 400185029Spjd memset(buf,0,size); 401219089Spjd memset(buff,0,size); 402185029Spjd return(0); 403185029Spjd } 404219089Spjd 405219089Spjd#endif 406219089Spjd 407219089Spjdstatic void pushsig(void) 408219089Spjd { 409219089Spjd int i; 410185029Spjd#ifdef SIGACTION 411219089Spjd struct sigaction sa; 412219089Spjd 413219089Spjd memset(&sa,0,sizeof sa); 414219089Spjd sa.sa_handler=recsig; 415219089Spjd#endif 416185029Spjd 417219089Spjd for (i=1; i<NX509_SIG; i++) 418219089Spjd { 419219089Spjd#ifdef SIGUSR1 420185029Spjd if (i == SIGUSR1) 421185029Spjd continue; 422185029Spjd#endif 423185029Spjd#ifdef SIGUSR2 424185029Spjd if (i == SIGUSR2) 425185029Spjd continue; 426185029Spjd#endif 427243674Smm#ifdef SIGACTION 428185029Spjd sigaction(i,&sa,&savsig[i]); 429185029Spjd#else 430185029Spjd savsig[i]=signal(i,recsig); 431185029Spjd#endif 432185029Spjd } 433185029Spjd 434185029Spjd#ifdef SIGWINCH 435185029Spjd signal(SIGWINCH,SIG_DFL); 436185029Spjd#endif 437185029Spjd } 438185029Spjd 439185029Spjdstatic void popsig(void) 440185029Spjd { 441185029Spjd int i; 442185029Spjd 443185029Spjd for (i=1; i<NX509_SIG; i++) 444185029Spjd { 445185029Spjd#ifdef SIGUSR1 446185029Spjd if (i == SIGUSR1) 447185029Spjd continue; 448219089Spjd#endif 449219089Spjd#ifdef SIGUSR2 450185029Spjd if (i == SIGUSR2) 451185029Spjd continue; 452185029Spjd#endif 453185029Spjd#ifdef SIGACTION 454185029Spjd sigaction(i,&savsig[i],NULL); 455185029Spjd#else 456185029Spjd signal(i,savsig[i]); 457185029Spjd#endif 458185029Spjd } 459185029Spjd } 460243674Smm 461185029Spjdstatic void recsig(int i) 462185029Spjd { 463185029Spjd longjmp(save,1); 464185029Spjd#ifdef LINT 465185029Spjd i=i; 466185029Spjd#endif 467185029Spjd } 468185029Spjd 469185029Spjd#if defined(MSDOS) && !defined(WIN16) 470185029Spjdstatic int noecho_fgets(char *buf, int size, FILE *tty) 471185029Spjd { 472185029Spjd int i; 473185029Spjd char *p; 474185029Spjd 475185029Spjd p=buf; 476185029Spjd for (;;) 477185029Spjd { 478185029Spjd if (size == 0) 479185029Spjd { 480185029Spjd *p='\0'; 481185029Spjd break; 482243674Smm } 483185029Spjd size--; 484185029Spjd#ifdef WIN16TTY 485185029Spjd i=_inchar(); 486185029Spjd#else 487185029Spjd i=getch(); 488185029Spjd#endif 489185029Spjd if (i == '\r') i='\n'; 490185029Spjd *(p++)=i; 491185029Spjd if (i == '\n') 492185029Spjd { 493185029Spjd *p='\0'; 494185029Spjd break; 495185029Spjd } 496185029Spjd } 497185029Spjd#ifdef WIN_CONSOLE_BUG 498185029Spjd/* Win95 has several evil console bugs: one of these is that the 499185029Spjd * last character read using getch() is passed to the next read: this is 500185029Spjd * usually a CR so this can be trouble. No STDIO fix seems to work but 501185029Spjd * flushing the console appears to do the trick. 502185029Spjd */ 503185029Spjd { 504185029Spjd HANDLE inh; 505185029Spjd inh = GetStdHandle(STD_INPUT_HANDLE); 506219089Spjd FlushConsoleInputBuffer(inh); 507219089Spjd } 508219089Spjd#endif 509219089Spjd return(strlen(buf)); 510219089Spjd } 511219089Spjd#endif 512219089Spjd