3 * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
6 * For copying and distribution information, please see the file
9 * This routine prints the supplied string to standard
10 * output as a prompt, and reads a password string without
14 #include <afsconfig.h>
15 #include <afs/param.h>
18 #include "mit-cpyright.h"
35 #include <sys/ioctl.h>
50 #include <sys/ttold.h>
63 #ifdef HAVE_SYS_TYPES_H
64 #include <sys/types.h>
68 #if defined(AFS_SGI_ENV) || defined (AFS_AIX_ENV) || defined(AFS_XBSD_ENV) /*|| defined (AFS_HPUX_ENV) || defined(AFS_SUN5_ENV) */
83 static sigtype sig_restore();
84 static push_signals(), pop_signals();
87 #include "des_prototypes.h"
89 /*** Routines ****************************************************** */
91 des_read_password(des_cblock * k, char *prompt, int verify)
94 char key_string[BUFSIZ];
103 ok = des_read_pw_string(key_string, BUFSIZ, prompt, verify);
105 des_string_to_key(key_string, k);
110 memset(key_string, 0, sizeof(key_string));
114 #if defined (AFS_AIX_ENV) || defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
115 static void catch(int);
118 #if !defined(BSDUNIX) && (defined(AFS_AIX_ENV) || defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV))
123 * This version just returns the string, doesn't map to key.
125 * Returns 0 on success, non-zero on failure.
128 des_read_pw_string(char *s, int maxa, char *prompt, int verify)
130 int ok = 0, cnt1 = 0;
132 #if defined(AFS_HPUX_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
134 struct sigaction newsig, oldsig;
135 struct termios save_ttyb, ttyb;
137 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
140 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
142 struct sigaction osa, sa;
147 struct sgttyb tty_state, echo_off_tty_state;
150 #if defined (AFS_AIX_ENV) || defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
159 DWORD oldConMode, newConMode;
160 BOOL resetConMode = FALSE;
162 char key_string[BUFSIZ];
167 #if defined(AFS_HPUX_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
168 if ((fi = fopen("/dev/tty", "r")) == NULL)
170 setbuf(fi, (char *)NULL); /* We don't want any buffering for our i/o. */
172 * Install signal handler for SIGINT so that we can restore
173 * the tty settings after we change them. The handler merely
174 * increments the variable "intrupt" to tell us that an
175 * interrupt signal was received.
177 newsig.sa_handler = catch;
178 sigemptyset(&newsig.sa_mask);
180 sigaction(SIGINT, &newsig, &oldsig);
184 * Get the terminal characters (save for later restoration) and
185 * reset them so that echo is off
188 tcgetattr(fno, &ttyb);
190 ttyb.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
191 tcsetattr(fno, TCSAFLUSH, &ttyb);
193 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
194 if ((fi = fopen("/dev/tty", "r")) == NULL) {
197 setbuf(fi, (char *)NULL);
198 sa.sa_handler = catch;
200 sa.sa_flags = SA_INTERRUPT;
201 (void)sigaction(SIGINT, &sa, &osa);
203 (void)ioctl(fileno(fi), TCGETS, &ttyb);
204 flags = ttyb.c_lflag;
205 ttyb.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
206 (void)ioctl(fileno(fi), TCSETSF, &ttyb);
209 /* XXX assume jmp_buf is typedef'ed to an array */
210 memcpy((char *)env, (char *)old_env, sizeof(env));
213 /* save terminal state */
214 if (ioctl(0, TIOCGETP, (char *)&tty_state) == -1)
218 memcpy(&echo_off_tty_state, &tty_state, sizeof(tty_state));
219 echo_off_tty_state.sg_flags &= ~ECHO;
220 if (ioctl(0, TIOCSETP, (char *)&echo_off_tty_state) == -1)
223 #if defined (AFS_AIX_ENV) || defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
224 if ((fi = fopen("/dev/tty", "r+")) == NULL)
227 setbuf(fi, (char *)NULL);
228 sig = signal(SIGINT, catch);
230 (void)ioctl(fileno(fi), TCGETA, &ttyb);
233 flags = ttyb.c_lflag;
234 ttyb.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
235 (void)ioctl(fileno(fi), TCSETAF, &ttyb);
238 /* turn off console input echoing */
239 if ((hConStdin = GetStdHandle(STD_INPUT_HANDLE)) != INVALID_HANDLE_VALUE) {
240 if (GetConsoleMode(hConStdin, &oldConMode)) {
241 newConMode = (oldConMode & ~(ENABLE_ECHO_INPUT));
242 if (SetConsoleMode(hConStdin, newConMode)) {
253 (void)printf("%s", prompt);
254 (void)fflush(stdout);
256 h19line(s, sizeof(s), 0);
260 if (!fgets(s, maxa, stdin)) {
265 * Otherwise hitting ctrl-d will always leave us inside this loop forever!
271 if ((ptr = strchr(s, '\n')))
275 printf("\nVerifying, please re-enter %s", prompt);
276 (void)fflush(stdout);
278 h19line(key_string, sizeof(key_string), 0);
279 if (!strlen(key_string))
282 if (!fgets(key_string, sizeof(key_string), stdin)) {
286 if ((ptr = strchr(key_string, '\n')))
289 if (strcmp(s, key_string)) {
290 printf("\n\07\07Mismatch - try again\n");
291 (void)fflush(stdout);
304 #if defined(AFS_HPUX_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
306 * Restore the terminal to its previous characteristics.
307 * Restore the old signal handler for SIGINT.
309 tcsetattr(fno, TCSANOW, &save_ttyb);
310 sigaction(SIGINT, &oldsig, NULL);
315 * If we got a SIGINT while we were doing things, send the SIGINT
316 * to ourselves so that the calling program receives it (since we
317 * were intercepting it for a period of time.)
320 kill(getpid(), SIGINT);
322 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
323 ttyb.c_lflag = flags;
324 (void)ioctl(fileno(fi), TCSETSW, &ttyb);
325 (void)sigaction(SIGINT, &osa, (struct sigaction *)NULL);
330 if (ioctl(0, TIOCSETP, (char *)&tty_state))
333 memcpy((char *)old_env, (char *)env, sizeof(env));
335 #if defined (AFS_AIX_ENV) /*|| defined (AFS_HPUX_ENV)*/ || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
336 ttyb.c_lflag = flags;
338 (void)ioctl(fileno(fi), TCSETAW, &ttyb);
339 (void)signal(SIGINT, sig);
343 (void)kill(getpid(), SIGINT);
346 /* restore console to original mode settings */
348 (void)SetConsoleMode(hConStdin, oldConMode);
356 memset(key_string, 0, sizeof(key_string));
357 s[maxa - 1] = 0; /* force termination */
358 return !ok; /* return nonzero if not okay */
363 * this can be static since we should never have more than
367 void static (*old_sigfunc[NSIG]) ();
369 static sigtype(*old_sigfunc[NSIG]) ();
376 for (i = 0; i < NSIG; i++)
377 old_sigfunc[i] = signal(i, sig_restore);
384 for (i = 0; i < NSIG; i++)
385 (void)signal(i, old_sigfunc[i]);
396 #if defined (AFS_AIX_ENV) || defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)