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