Annotation of src/usr.bin/ssh/readpass.c, Revision 1.7
1.1 deraadt 1: /*
1.6 deraadt 2: *
3: * readpass.c
4: *
5: * Author: Tatu Ylonen <ylo@cs.hut.fi>
6: *
7: * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8: * All rights reserved
9: *
10: * Created: Mon Jul 10 22:08:59 1995 ylo
11: *
12: * Functions for reading passphrases and passwords.
13: *
14: */
1.1 deraadt 15:
16: #include "includes.h"
1.7 ! markus 17: RCSID("$Id: readpass.c,v 1.6 1999/11/24 00:26:03 deraadt Exp $");
1.1 deraadt 18:
19: #include "xmalloc.h"
20: #include "ssh.h"
21:
22: /* Saved old terminal mode for read_passphrase. */
23: static struct termios saved_tio;
24:
25: /* Old interrupt signal handler for read_passphrase. */
1.5 markus 26: static void (*old_handler) (int sig) = NULL;
1.1 deraadt 27:
28: /* Interrupt signal handler for read_passphrase. */
29:
1.5 markus 30: void
31: intr_handler(int sig)
1.1 deraadt 32: {
1.5 markus 33: /* Restore terminal modes. */
34: tcsetattr(fileno(stdin), TCSANOW, &saved_tio);
35: /* Restore the old signal handler. */
36: signal(sig, old_handler);
37: /* Resend the signal, with the old handler. */
38: kill(getpid(), sig);
1.1 deraadt 39: }
40:
1.7 ! markus 41: /*
! 42: * Reads a passphrase from /dev/tty with echo turned off. Returns the
! 43: * passphrase (allocated with xmalloc). Exits if EOF is encountered. The
! 44: * passphrase if read from stdin if from_stdin is true (as is the case with
! 45: * ssh-keygen).
! 46: */
1.1 deraadt 47:
1.5 markus 48: char *
49: read_passphrase(const char *prompt, int from_stdin)
1.1 deraadt 50: {
1.5 markus 51: char buf[1024], *cp;
52: struct termios tio;
53: FILE *f;
54:
55: if (from_stdin)
56: f = stdin;
57: else {
1.7 ! markus 58: /*
! 59: * Read the passphrase from /dev/tty to make it possible to
! 60: * ask it even when stdin has been redirected.
! 61: */
1.5 markus 62: f = fopen("/dev/tty", "r");
63: if (!f) {
64: /* No controlling terminal and no DISPLAY. Nowhere to read. */
65: fprintf(stderr, "You have no controlling tty and no DISPLAY. Cannot read passphrase.\n");
66: exit(1);
67: }
1.1 deraadt 68: }
69:
1.5 markus 70: /* Display the prompt (on stderr because stdout might be redirected). */
71: fflush(stdout);
72: fprintf(stderr, "%s", prompt);
73: fflush(stderr);
74:
75: /* Get terminal modes. */
76: tcgetattr(fileno(f), &tio);
77: saved_tio = tio;
78: /* Save signal handler and set the new handler. */
79: old_handler = signal(SIGINT, intr_handler);
80:
81: /* Set new terminal modes disabling all echo. */
82: tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
83: tcsetattr(fileno(f), TCSANOW, &tio);
84:
85: /* Read the passphrase from the terminal. */
86: if (fgets(buf, sizeof(buf), f) == NULL) {
87: /* Got EOF. Just exit. */
88: /* Restore terminal modes. */
89: tcsetattr(fileno(f), TCSANOW, &saved_tio);
90: /* Restore the signal handler. */
91: signal(SIGINT, old_handler);
92: /* Print a newline (the prompt probably didn\'t have one). */
93: fprintf(stderr, "\n");
94: /* Close the file. */
95: if (f != stdin)
96: fclose(f);
97: exit(1);
98: }
99: /* Restore terminal modes. */
100: tcsetattr(fileno(f), TCSANOW, &saved_tio);
101: /* Restore the signal handler. */
102: (void) signal(SIGINT, old_handler);
103: /* Remove newline from the passphrase. */
104: if (strchr(buf, '\n'))
105: *strchr(buf, '\n') = 0;
106: /* Allocate a copy of the passphrase. */
107: cp = xstrdup(buf);
1.7 ! markus 108: /*
! 109: * Clear the buffer so we don\'t leave copies of the passphrase
! 110: * laying around.
! 111: */
1.5 markus 112: memset(buf, 0, sizeof(buf));
113: /* Print a newline since the prompt probably didn\'t have one. */
114: fprintf(stderr, "\n");
115: /* Close the file. */
116: if (f != stdin)
117: fclose(f);
118: return cp;
1.1 deraadt 119: }