This commit was generated by cvs2svn to track changes on a CVS vendor
[openssl.git] / crypto / des / read_pwd.c
1 /* crypto/des/read_pwd.c */
2 /* Copyright (C) 1995-1997 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 #ifdef WIN16TTY
60 #undef WIN16
61 #undef _WINDOWS
62 #include <graph.h>
63 #endif
64
65 /* 06-Apr-92 Luke Brennan    Support for VMS */
66 #include "des_locl.h"
67 #include <signal.h>
68 #include <string.h>
69 #include <setjmp.h>
70 #include <errno.h>
71
72 /* There are 5 types of terminal interface supported,
73  * TERMIO, TERMIOS, VMS, MSDOS and SGTTY
74  */
75
76 #if defined(__sgi) && !defined(TERMIOS)
77 #define TERMIOS
78 #undef  TERMIO
79 #undef  SGTTY
80 #endif
81
82 #if defined(linux) && !defined(TERMIO)
83 #undef  TERMIOS
84 #define TERMIO
85 #undef  SGTTY
86 #endif
87
88 #ifdef _LIBC
89 #undef  TERMIOS
90 #define TERMIO
91 #undef  SGTTY
92 #endif
93
94 #if !defined(TERMIO) && !defined(TERMIOS) && !defined(VMS) && !defined(MSDOS)
95 #undef  TERMIOS
96 #undef  TERMIO
97 #define SGTTY
98 #endif
99
100 #ifdef TERMIOS
101 #include <termios.h>
102 #define TTY_STRUCT              struct termios
103 #define TTY_FLAGS               c_lflag
104 #define TTY_get(tty,data)       tcgetattr(tty,data)
105 #define TTY_set(tty,data)       tcsetattr(tty,TCSANOW,data)
106 #endif
107
108 #ifdef TERMIO
109 #include <termio.h>
110 #define TTY_STRUCT              struct termio
111 #define TTY_FLAGS               c_lflag
112 #define TTY_get(tty,data)       ioctl(tty,TCGETA,data)
113 #define TTY_set(tty,data)       ioctl(tty,TCSETA,data)
114 #endif
115
116 #ifdef SGTTY
117 #include <sgtty.h>
118 #define TTY_STRUCT              struct sgttyb
119 #define TTY_FLAGS               sg_flags
120 #define TTY_get(tty,data)       ioctl(tty,TIOCGETP,data)
121 #define TTY_set(tty,data)       ioctl(tty,TIOCSETP,data)
122 #endif
123
124 #if !defined(_LIBC) && !defined(MSDOS) && !defined(VMS)
125 #include <sys/ioctl.h>
126 #endif
127
128 #ifdef MSDOS
129 #include <conio.h>
130 #define fgets(a,b,c) noecho_fgets(a,b,c)
131 #endif
132
133 #ifdef VMS
134 #include <ssdef.h>
135 #include <iodef.h>
136 #include <ttdef.h>
137 #include <descrip.h>
138 struct IOSB {
139         short iosb$w_value;
140         short iosb$w_count;
141         long  iosb$l_info;
142         };
143 #endif
144
145 #ifndef NX509_SIG
146 #define NX509_SIG 32
147 #endif
148
149 #ifndef NOPROTO
150 static void read_till_nl(FILE *);
151 static void recsig(int);
152 static void pushsig(void);
153 static void popsig(void);
154 #if defined(MSDOS) && !defined(WIN16)
155 static int noecho_fgets(char *buf, int size, FILE *tty);
156 #endif
157 #else
158 static void read_till_nl();
159 static void recsig();
160 static void pushsig();
161 static void popsig();
162 #if defined(MSDOS) && !defined(WIN16)
163 static int noecho_fgets();
164 #endif
165 #endif
166
167 #ifndef NOPROTO
168 static void (*savsig[NX509_SIG])(int );
169 #else
170 static void (*savsig[NX509_SIG])();
171 #endif
172 static jmp_buf save;
173
174 int des_read_pw_string(buf, length, prompt, verify)
175 char *buf;
176 int length;
177 char *prompt;
178 int verify;
179         {
180         char buff[BUFSIZ];
181         int ret;
182
183         ret=des_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);
184         memset(buff,0,BUFSIZ);
185         return(ret);
186         }
187
188 #ifndef WIN16
189
190 static void read_till_nl(in)
191 FILE *in;
192         {
193 #define SIZE 4
194         char buf[SIZE+1];
195
196         do      {
197                 fgets(buf,SIZE,in);
198                 } while (strchr(buf,'\n') == NULL);
199         }
200
201
202 /* return 0 if ok, 1 (or -1) otherwise */
203 int des_read_pw(buf, buff, size, prompt, verify)
204 char *buf;
205 char *buff;
206 int size;
207 char *prompt;
208 int verify;
209         {
210 #ifdef VMS
211         struct IOSB iosb;
212         $DESCRIPTOR(terminal,"TT");
213         long tty_orig[3], tty_new[3];
214         long status;
215         unsigned short channel = 0;
216 #else
217 #ifndef MSDOS
218         TTY_STRUCT tty_orig,tty_new;
219 #endif
220 #endif
221         int number=5;
222         int ok=0;
223         int ps=0;
224         int is_a_tty=1;
225
226         FILE *tty=NULL;
227         char *p;
228
229 #ifndef MSDOS
230         if ((tty=fopen("/dev/tty","r")) == NULL)
231                 tty=stdin;
232 #else /* MSDOS */
233         if ((tty=fopen("con","r")) == NULL)
234                 tty=stdin;
235 #endif /* MSDOS */
236
237 #if defined(TTY_get) && !defined(VMS)
238         if (TTY_get(fileno(tty),&tty_orig) == -1)
239                 {
240 #ifdef ENOTTY
241                 if (errno == ENOTTY)
242                         is_a_tty=0;
243                 else
244 #endif
245                         return(-1);
246                 }
247         memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));
248 #endif
249 #ifdef VMS
250         status = SYS$ASSIGN(&terminal,&channel,0,0);
251         if (status != SS$_NORMAL)
252                 return(-1);
253         status=SYS$QIOW(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);
254         if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
255                 return(-1);
256 #endif
257
258         if (setjmp(save))
259                 {
260                 ok=0;
261                 goto error;
262                 }
263         pushsig();
264         ps=1;
265
266 #ifdef TTY_FLAGS
267         tty_new.TTY_FLAGS &= ~ECHO;
268 #endif
269
270 #if defined(TTY_set) && !defined(VMS)
271         if (is_a_tty && (TTY_set(fileno(tty),&tty_new) == -1))
272                 return(-1);
273 #endif
274 #ifdef VMS
275         tty_new[0] = tty_orig[0];
276         tty_new[1] = tty_orig[1] | TT$M_NOECHO;
277         tty_new[2] = tty_orig[2];
278         status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);
279         if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
280                 return(-1);
281 #endif
282         ps=2;
283
284         while ((!ok) && (number--))
285                 {
286                 fputs(prompt,stderr);
287                 fflush(stderr);
288
289                 buf[0]='\0';
290                 fgets(buf,size,tty);
291                 if (feof(tty)) goto error;
292                 if (ferror(tty)) goto error;
293                 if ((p=(char *)strchr(buf,'\n')) != NULL)
294                         *p='\0';
295                 else    read_till_nl(tty);
296                 if (verify)
297                         {
298                         fprintf(stderr,"\nVerifying password - %s",prompt);
299                         fflush(stderr);
300                         buff[0]='\0';
301                         fgets(buff,size,tty);
302                         if (feof(tty)) goto error;
303                         if ((p=(char *)strchr(buff,'\n')) != NULL)
304                                 *p='\0';
305                         else    read_till_nl(tty);
306                                 
307                         if (strcmp(buf,buff) != 0)
308                                 {
309                                 fprintf(stderr,"\nVerify failure");
310                                 fflush(stderr);
311                                 break;
312                                 /* continue; */
313                                 }
314                         }
315                 ok=1;
316                 }
317
318 error:
319         fprintf(stderr,"\n");
320 #ifdef DEBUG
321         perror("fgets(tty)");
322 #endif
323         /* What can we do if there is an error? */
324 #if defined(TTY_set) && !defined(VMS) 
325         if (ps >= 2) TTY_set(fileno(tty),&tty_orig);
326 #endif
327 #ifdef VMS
328         if (ps >= 2)
329                 status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0
330                         ,tty_orig,12,0,0,0,0);
331 #endif
332         
333         if (ps >= 1) popsig();
334         if (stdin != tty) fclose(tty);
335 #ifdef VMS
336         status = SYS$DASSGN(channel);
337 #endif
338         return(!ok);
339         }
340
341 #else /* WIN16 */
342
343 int des_read_pw(buf, buff, size, prompt, verify)
344 char *buf;
345 char *buff;
346 int size;
347 char *prompt;
348 int verify;
349         { 
350         memset(buf,0,size);
351         memset(buff,0,size);
352         return(0);
353         }
354
355 #endif
356
357 static void pushsig()
358         {
359         int i;
360
361         for (i=1; i<NX509_SIG; i++)
362                 savsig[i]=signal(i,recsig);
363
364 #ifdef SIGWINCH
365         signal(SIGWINCH,SIG_DFL);
366 #endif
367         }
368
369 static void popsig()
370         {
371         int i;
372
373         for (i=1; i<NX509_SIG; i++)
374                 signal(i,savsig[i]);
375         }
376
377 static void recsig(i)
378 int i;
379         {
380         longjmp(save,1);
381 #ifdef LINT
382         i=i;
383 #endif
384         }
385
386 #if defined(MSDOS) && !defined(WIN16)
387 static int noecho_fgets(buf,size,tty)
388 char *buf;
389 int size;
390 FILE *tty;
391         {
392         int i;
393         char *p;
394
395         p=buf;
396         for (;;)
397                 {
398                 if (size == 0)
399                         {
400                         *p='\0';
401                         break;
402                         }
403                 size--;
404 #ifdef WIN16TTY
405                 i=_inchar();
406 #else
407                 i=getch();
408 #endif
409                 if (i == '\r') i='\n';
410                 *(p++)=i;
411                 if (i == '\n')
412                         {
413                         *p='\0';
414                         break;
415                         }
416                 }
417         return(strlen(buf));
418         }
419 #endif