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