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 <afs/param.h>
15 #include <mit-cpyright.h>
21 #if defined(AFS_SUN5_ENV) || defined(AFS_NT40_ENV)
31 #if defined(AFS_FBSD_ENV)
34 #include <sys/ioctl.h>
39 #if defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
46 #include <sys/ttold.h>
51 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
55 #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
63 #if defined(AFS_SGI_ENV) || defined (AFS_AIX_ENV) /*|| defined (AFS_HPUX_ENV) || defined(AFS_SUN5_ENV)*/
78 static sigtype sig_restore();
79 static push_signals(), pop_signals();
82 int des_read_pw_string(char *, int, char *, int);
83 int des_string_to_key(char *, des_cblock *);
85 /*** Routines ****************************************************** */
87 des_read_password(k,prompt,verify)
93 char key_string[BUFSIZ];
102 ok = des_read_pw_string(key_string, BUFSIZ, prompt, verify);
104 des_string_to_key(key_string, k);
109 bzero(key_string, sizeof (key_string));
113 #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_FBSD_ENV)
114 static void catch(int);
117 #if !defined(BSDUNIX) && (defined(AFS_AIX_ENV) || defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV))
122 * This version just returns the string, doesn't map to key.
124 * Returns 0 on success, non-zero on failure.
127 des_read_pw_string(s,maxa,prompt,verify)
135 #if defined(AFS_HPUX_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
137 struct sigaction newsig, oldsig;
138 struct termios save_ttyb, ttyb;
140 #if defined(AFS_DARWIN_ENV)
143 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
145 struct sigaction osa, sa;
150 struct sgttyb tty_state, echo_off_tty_state;
153 #if defined (AFS_AIX_ENV) || defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
158 extern void setbuf();
159 extern int kill(), fclose();
164 DWORD oldConMode, newConMode;
165 BOOL resetConMode = FALSE;
167 char key_string[BUFSIZ];
173 #if defined(AFS_HPUX_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
174 if ((fi = fopen("/dev/tty", "r")) == NULL)
176 setbuf(fi, (char *)NULL); /* We don't want any buffering for our i/o. */
178 * Install signal handler for SIGINT so that we can restore
179 * the tty settings after we change them. The handler merely
180 * increments the variable "intrupt" to tell us that an
181 * interrupt signal was received.
183 newsig.sa_handler = catch;
184 sigemptyset(&newsig.sa_mask);
186 sigaction(SIGINT, &newsig, &oldsig);
190 * Get the terminal characters (save for later restoration) and
191 * reset them so that echo is off
194 tcgetattr(fno, &ttyb);
196 ttyb.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
197 tcsetattr(fno, TCSAFLUSH, &ttyb);
199 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
200 if((fi = fopen("/dev/tty", "r")) == NULL) {
204 setbuf(fi, (char*)NULL);
205 sa.sa_handler = catch;
207 sa.sa_flags = SA_INTERRUPT;
208 (void) sigaction(SIGINT, &sa, &osa);
210 (void) ioctl(fileno(fi), TCGETS, &ttyb);
211 flags = ttyb.c_lflag;
212 ttyb.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
213 (void) ioctl(fileno(fi), TCSETSF, &ttyb);
216 /* XXX assume jmp_buf is typedef'ed to an array */
217 bcopy((char *)old_env, (char *)env, sizeof(env));
220 /* save terminal state*/
221 if (ioctl(0,TIOCGETP,(char *)&tty_state) == -1)
225 bcopy (&tty_state, &echo_off_tty_state, sizeof (tty_state));
226 echo_off_tty_state.sg_flags &= ~ECHO;
227 if (ioctl(0,TIOCSETP,(char *)&echo_off_tty_state) == -1)
230 #if defined (AFS_AIX_ENV) || defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
231 if((fi = fopen("/dev/tty", "r+")) == NULL)
234 setbuf(fi, (char*)NULL);
235 sig = signal(SIGINT, catch);
237 (void) ioctl(fileno(fi), TCGETA, &ttyb);
240 flags = ttyb.c_lflag;
241 ttyb.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
242 (void) ioctl(fileno(fi), TCSETAF, &ttyb);
245 /* turn off console input echoing */
246 if ((hConStdin = GetStdHandle(STD_INPUT_HANDLE)) != INVALID_HANDLE_VALUE) {
247 if (GetConsoleMode(hConStdin, &oldConMode)) {
248 newConMode = (oldConMode & ~(ENABLE_ECHO_INPUT));
249 if (SetConsoleMode(hConStdin, newConMode)) {
260 (void) printf(prompt);
261 (void) fflush(stdout);
263 h19line(s,sizeof(s),0);
267 if (!fgets(s, maxa, stdin)) {
272 * Otherwise hitting ctrl-d will always leave us inside this loop forever!
278 if ((ptr = index(s, '\n')))
282 printf("\nVerifying, please re-enter %s",prompt);
283 (void) fflush(stdout);
285 h19line(key_string,sizeof(key_string),0);
286 if (!strlen(key_string))
289 if (!fgets(key_string, sizeof(key_string), stdin)) {
293 if ((ptr = index(key_string, '\n')))
296 if (strcmp(s,key_string)) {
297 printf("\n\07\07Mismatch - try again\n");
298 (void) fflush(stdout);
313 * Restore the terminal to its previous characteristics.
314 * Restore the old signal handler for SIGINT.
316 tcsetattr(fno, TCSANOW, &save_ttyb);
317 sigaction(SIGINT, &oldsig, (struct sigaction *)0);
322 * If we got a SIGINT while we were doing things, send the SIGINT
323 * to ourselves so that the calling program receives it (since we
324 * were intercepting it for a period of time.)
327 kill(getpid(), SIGINT);
329 #if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
330 ttyb.c_lflag = flags;
331 (void) ioctl(fileno(fi), TCSETSW, &ttyb);
332 (void) sigaction(SIGINT, &osa, (struct sigaction *)NULL);
337 if (ioctl(0,TIOCSETP,(char *)&tty_state))
340 bcopy((char *)env, (char *)old_env, sizeof(env));
342 #if defined (AFS_AIX_ENV) /*|| defined (AFS_HPUX_ENV)*/ || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
343 ttyb.c_lflag = flags;
345 (void) ioctl(fileno(fi), TCSETAW, &ttyb);
346 (void) signal(SIGINT, sig);
350 (void) kill(getpid(), SIGINT);
353 /* restore console to original mode settings */
355 (void)SetConsoleMode(hConStdin, oldConMode);
363 bzero(key_string, sizeof (key_string));
364 s[maxa-1] = 0; /* force termination */
365 return !ok; /* return nonzero if not okay */
370 * this can be static since we should never have more than
374 void static (*old_sigfunc[NSIG])();
376 static sigtype (*old_sigfunc[NSIG])();
379 static push_signals()
382 for (i = 0; i < NSIG; i++)
383 old_sigfunc[i] = signal(i,sig_restore);
389 for (i = 0; i < NSIG; i++)
390 (void) signal(i,old_sigfunc[i]);
401 #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_FBSD_ENV)