|
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 <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@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@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 */ |