xref: /minix3/crypto/external/bsd/openssl/lib/libdes/oread_pwd.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1  /* crypto/des/read_pwd.c */
2  /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3   * All rights reserved.
4   *
5   * This package is an SSL implementation written
6   * by Eric Young (eay@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@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@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@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 <unistd.h>
60  /* If unistd.h defines _POSIX_VERSION, we conclude that we
61   * are on a POSIX system and have sigaction and termios. */
62  #if defined(_POSIX_VERSION)
63  
64  # define SIGACTION
65  # if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
66  # define TERMIOS
67  # endif
68  
69  #endif
70  
71  /* #define SIGACTION */ /* Define this if you have sigaction() */
72  
73  #ifdef WIN16TTY
74  #undef WIN16
75  #undef _WINDOWS
76  #include <graph.h>
77  #endif
78  
79  /* 06-Apr-92 Luke Brennan    Support for VMS */
80  #include "des_locl.h"
81  #include <signal.h>
82  #include <stdio.h>
83  #include <string.h>
84  #include <setjmp.h>
85  #include <errno.h>
86  
87  #ifdef VMS			/* prototypes for sys$whatever */
88  #include <starlet.h>
89  #ifdef __DECC
90  #pragma message disable DOLLARID
91  #endif
92  #endif
93  
94  #ifdef WIN_CONSOLE_BUG
95  #include <windows.h>
96  #include <wincon.h>
97  #endif
98  
99  
100  /* There are 5 types of terminal interface supported,
101   * TERMIO, TERMIOS, VMS, MSDOS and SGTTY
102   */
103  
104  #if defined(__sgi) && !defined(TERMIOS)
105  #define TERMIOS
106  #undef  TERMIO
107  #undef  SGTTY
108  #endif
109  
110  #if defined(linux) && !defined(TERMIO)
111  #undef  TERMIOS
112  #define TERMIO
113  #undef  SGTTY
114  #endif
115  
116  #ifdef _LIBC
117  #undef  TERMIOS
118  #define TERMIO
119  #undef  SGTTY
120  #endif
121  
122  #if !defined(TERMIO) && !defined(TERMIOS) && !defined(VMS) && !defined(MSDOS) && !defined(MAC_OS_pre_X) && !defined(MAC_OS_GUSI_SOURCE)
123  #undef  TERMIOS
124  #undef  TERMIO
125  #define SGTTY
126  #endif
127  
128  #if defined(VXWORKS)
129  #undef TERMIOS
130  #undef TERMIO
131  #undef SGTTY
132  #endif
133  
134  #ifdef TERMIOS
135  #include <termios.h>
136  #define TTY_STRUCT		struct termios
137  #define TTY_FLAGS		c_lflag
138  #define	TTY_get(tty,data)	tcgetattr(tty,data)
139  #define TTY_set(tty,data)	tcsetattr(tty,TCSANOW,data)
140  #endif
141  
142  #ifdef TERMIO
143  #include <termio.h>
144  #define TTY_STRUCT		struct termio
145  #define TTY_FLAGS		c_lflag
146  #define TTY_get(tty,data)	ioctl(tty,TCGETA,data)
147  #define TTY_set(tty,data)	ioctl(tty,TCSETA,data)
148  #endif
149  
150  #ifdef SGTTY
151  #include <sgtty.h>
152  #define TTY_STRUCT		struct sgttyb
153  #define TTY_FLAGS		sg_flags
154  #define TTY_get(tty,data)	ioctl(tty,TIOCGETP,data)
155  #define TTY_set(tty,data)	ioctl(tty,TIOCSETP,data)
156  #endif
157  
158  #if !defined(_LIBC) && !defined(MSDOS) && !defined(VMS) && !defined(MAC_OS_pre_X)
159  #include <sys/ioctl.h>
160  #endif
161  
162  #if defined(MSDOS) && !defined(__CYGWIN32__)
163  #include <conio.h>
164  #define fgets(a,b,c) noecho_fgets(a,b,c)
165  #endif
166  
167  #ifdef VMS
168  #include <ssdef.h>
169  #include <iodef.h>
170  #include <ttdef.h>
171  #include <descrip.h>
172  struct IOSB {
173  	short iosb$w_value;
174  	short iosb$w_count;
175  	long  iosb$l_info;
176  	};
177  #endif
178  
179  #if defined(MAC_OS_pre_X) || defined(MAC_OS_GUSI_SOURCE)
180  /*
181   * This one needs work. As a matter of fact the code is unoperational
182   * and this is only a trick to get it compiled.
183   *					<appro@fy.chalmers.se>
184   */
185  #define TTY_STRUCT int
186  #endif
187  
188  #ifndef NX509_SIG
189  #define NX509_SIG 32
190  #endif
191  
192  static void read_till_nl(FILE *);
193  static void recsig(int);
194  static void pushsig(void);
195  static void popsig(void);
196  #if defined(MSDOS) && !defined(WIN16)
197  static int noecho_fgets(char *buf, int size, FILE *tty);
198  #endif
199  #ifdef SIGACTION
200   static struct sigaction savsig[NX509_SIG];
201  #else
202    static void (*savsig[NX509_SIG])(int );
203  #endif
204  static jmp_buf save;
205  
206  int des_read_pw_string(char *buf, int length, const char *prompt,
207  	     int verify)
208  	{
209  	char buff[BUFSIZ];
210  	int ret;
211  
212  	ret=des_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);
213  	OPENSSL_cleanse(buff,BUFSIZ);
214  	return(ret);
215  	}
216  
217  #ifndef WIN16
218  
219  static void read_till_nl(FILE *in)
220  	{
221  #define SIZE 4
222  	char buf[SIZE+1];
223  
224  	do	{
225  		fgets(buf,SIZE,in);
226  		} while (strchr(buf,'\n') == NULL);
227  	}
228  
229  
230  /* return 0 if ok, 1 (or -1) otherwise */
231  int des_read_pw(char *buf, char *buff, int size, const char *prompt,
232  	     int verify)
233  	{
234  #ifdef VMS
235  	struct IOSB iosb;
236  	$DESCRIPTOR(terminal,"TT");
237  	long tty_orig[3], tty_new[3];
238  	long status;
239  	unsigned short channel = 0;
240  #else
241  #if !defined(MSDOS) && !defined(VXWORKS)
242  	TTY_STRUCT tty_orig,tty_new;
243  #endif
244  #endif
245  	int number;
246  	int ok;
247  	/* statics are simply to avoid warnings about longjmp clobbering
248  	   things */
249  	static int ps;
250  	int is_a_tty;
251  	static FILE *tty;
252  	char *p;
253  
254  	if (setjmp(save))
255  		{
256  		ok=0;
257  		goto error;
258  		}
259  
260  	number=5;
261  	ok=0;
262  	ps=0;
263  	is_a_tty=1;
264  	tty=NULL;
265  
266  #ifdef MSDOS
267  	if ((tty=fopen("con","r")) == NULL)
268  		tty=stdin;
269  #elif defined(MAC_OS_pre_X) || defined(VXWORKS)
270  	tty=stdin;
271  #else
272  #ifndef MPE
273  	if ((tty=fopen("/dev/tty","r")) == NULL)
274  #endif
275  		tty=stdin;
276  #endif
277  
278  #if defined(TTY_get) && !defined(VMS)
279  	if (TTY_get(fileno(tty),&tty_orig) == -1)
280  		{
281  #ifdef ENOTTY
282  		if (errno == ENOTTY)
283  			is_a_tty=0;
284  		else
285  #endif
286  #ifdef EINVAL
287  		/* Ariel Glenn ariel@columbia.edu reports that solaris
288  		 * can return EINVAL instead.  This should be ok */
289  		if (errno == EINVAL)
290  			is_a_tty=0;
291  		else
292  #endif
293  			return(-1);
294  		}
295  	memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));
296  #endif
297  #ifdef VMS
298  	status = sys$assign(&terminal,&channel,0,0);
299  	if (status != SS$_NORMAL)
300  		return(-1);
301  	status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);
302  	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
303  		return(-1);
304  #endif
305  
306  	pushsig();
307  	ps=1;
308  
309  #ifdef TTY_FLAGS
310  	tty_new.TTY_FLAGS &= ~ECHO;
311  #endif
312  
313  #if defined(TTY_set) && !defined(VMS)
314  	if (is_a_tty && (TTY_set(fileno(tty),&tty_new) == -1))
315  #ifdef MPE
316  		; /* MPE lies -- echo really has been disabled */
317  #else
318  		return(-1);
319  #endif
320  #endif
321  #ifdef VMS
322  	tty_new[0] = tty_orig[0];
323  	tty_new[1] = tty_orig[1] | TT$M_NOECHO;
324  	tty_new[2] = tty_orig[2];
325  	status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
326  	if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
327  		return(-1);
328  #endif
329  	ps=2;
330  
331  	while ((!ok) && (number--))
332  		{
333  		fputs(prompt,stderr);
334  		fflush(stderr);
335  
336  		buf[0]='\0';
337  		fgets(buf,size,tty);
338  		if (feof(tty)) goto error;
339  		if (ferror(tty)) goto error;
340  		if ((p=(char *)strchr(buf,'\n')) != NULL)
341  			*p='\0';
342  		else	read_till_nl(tty);
343  		if (verify)
344  			{
345  			fprintf(stderr,"\nVerifying password - %s",prompt);
346  			fflush(stderr);
347  			buff[0]='\0';
348  			fgets(buff,size,tty);
349  			if (feof(tty)) goto error;
350  			if ((p=(char *)strchr(buff,'\n')) != NULL)
351  				*p='\0';
352  			else	read_till_nl(tty);
353  
354  			if (strcmp(buf,buff) != 0)
355  				{
356  				fprintf(stderr,"\nVerify failure");
357  				fflush(stderr);
358  				break;
359  				/* continue; */
360  				}
361  			}
362  		ok=1;
363  		}
364  
365  error:
366  	fprintf(stderr,"\n");
367  #if 0
368  	perror("fgets(tty)");
369  #endif
370  	/* What can we do if there is an error? */
371  #if defined(TTY_set) && !defined(VMS)
372  	if (ps >= 2) TTY_set(fileno(tty),&tty_orig);
373  #endif
374  #ifdef VMS
375  	if (ps >= 2)
376  		status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0
377  			,tty_orig,12,0,0,0,0);
378  #endif
379  
380  	if (ps >= 1) popsig();
381  	if (stdin != tty) fclose(tty);
382  #ifdef VMS
383  	status = sys$dassgn(channel);
384  #endif
385  	return(!ok);
386  	}
387  
388  #else /* WIN16 */
389  
390  int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify)
391  	{
392  	memset(buf,0,size);
393  	memset(buff,0,size);
394  	return(0);
395  	}
396  
397  #endif
398  
399  static void pushsig(void)
400  	{
401  	int i;
402  #ifdef SIGACTION
403  	struct sigaction sa;
404  
405  	memset(&sa,0,sizeof sa);
406  	sa.sa_handler=recsig;
407  #endif
408  
409  	for (i=1; i<NX509_SIG; i++)
410  		{
411  #ifdef SIGUSR1
412  		if (i == SIGUSR1)
413  			continue;
414  #endif
415  #ifdef SIGUSR2
416  		if (i == SIGUSR2)
417  			continue;
418  #endif
419  #ifdef SIGACTION
420  		sigaction(i,&sa,&savsig[i]);
421  #else
422  		savsig[i]=signal(i,recsig);
423  #endif
424  		}
425  
426  #ifdef SIGWINCH
427  	signal(SIGWINCH,SIG_DFL);
428  #endif
429  	}
430  
431  static void popsig(void)
432  	{
433  	int i;
434  
435  	for (i=1; i<NX509_SIG; i++)
436  		{
437  #ifdef SIGUSR1
438  		if (i == SIGUSR1)
439  			continue;
440  #endif
441  #ifdef SIGUSR2
442  		if (i == SIGUSR2)
443  			continue;
444  #endif
445  #ifdef SIGACTION
446  		sigaction(i,&savsig[i],NULL);
447  #else
448  		signal(i,savsig[i]);
449  #endif
450  		}
451  	}
452  
453  static void recsig(int i)
454  	{
455  	longjmp(save,1);
456  #ifdef LINT
457  	i=i;
458  #endif
459  	}
460  
461  #if defined(MSDOS) && !defined(WIN16)
462  static int noecho_fgets(char *buf, int size, FILE *tty)
463  	{
464  	int i;
465  	char *p;
466  
467  	p=buf;
468  	for (;;)
469  		{
470  		if (size == 0)
471  			{
472  			*p='\0';
473  			break;
474  			}
475  		size--;
476  #ifdef WIN16TTY
477  		i=_inchar();
478  #else
479  		i=getch();
480  #endif
481  		if (i == '\r') i='\n';
482  		*(p++)=i;
483  		if (i == '\n')
484  			{
485  			*p='\0';
486  			break;
487  			}
488  		}
489  #ifdef WIN_CONSOLE_BUG
490  /* Win95 has several evil console bugs: one of these is that the
491   * last character read using getch() is passed to the next read: this is
492   * usually a CR so this can be trouble. No STDIO fix seems to work but
493   * flushing the console appears to do the trick.
494   */
495  		{
496  			HANDLE inh;
497  			inh = GetStdHandle(STD_INPUT_HANDLE);
498  			FlushConsoleInputBuffer(inh);
499  		}
500  #endif
501  	return(strlen(buf));
502  	}
503  #endif
504