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