diff options
Diffstat (limited to 'readpass.c')
-rw-r--r-- | readpass.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/readpass.c b/readpass.c index 5ea3b22dc..edeb23864 100644 --- a/readpass.c +++ b/readpass.c | |||
@@ -32,11 +32,19 @@ | |||
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include "includes.h" | 34 | #include "includes.h" |
35 | RCSID("$Id: readpass.c,v 1.4 1999/12/08 23:31:37 damien Exp $"); | 35 | RCSID("$Id: readpass.c,v 1.5 2000/01/22 08:47:21 damien Exp $"); |
36 | 36 | ||
37 | #include "xmalloc.h" | 37 | #include "xmalloc.h" |
38 | #include "ssh.h" | 38 | #include "ssh.h" |
39 | 39 | ||
40 | volatile int intr; | ||
41 | |||
42 | void | ||
43 | intcatch() | ||
44 | { | ||
45 | intr = 1; | ||
46 | } | ||
47 | |||
40 | /* | 48 | /* |
41 | * Reads a passphrase from /dev/tty with echo turned off. Returns the | 49 | * Reads a passphrase from /dev/tty with echo turned off. Returns the |
42 | * passphrase (allocated with xmalloc), being very careful to ensure that | 50 | * passphrase (allocated with xmalloc), being very careful to ensure that |
@@ -48,6 +56,7 @@ read_passphrase(const char *prompt, int from_stdin) | |||
48 | char buf[1024], *p, ch; | 56 | char buf[1024], *p, ch; |
49 | struct termios tio, saved_tio; | 57 | struct termios tio, saved_tio; |
50 | sigset_t oset, nset; | 58 | sigset_t oset, nset; |
59 | struct sigaction sa, osa; | ||
51 | int input, output, echo = 0; | 60 | int input, output, echo = 0; |
52 | 61 | ||
53 | if (from_stdin) { | 62 | if (from_stdin) { |
@@ -61,13 +70,17 @@ read_passphrase(const char *prompt, int from_stdin) | |||
61 | 70 | ||
62 | /* block signals, get terminal modes and turn off echo */ | 71 | /* block signals, get terminal modes and turn off echo */ |
63 | sigemptyset(&nset); | 72 | sigemptyset(&nset); |
64 | sigaddset(&nset, SIGINT); | ||
65 | sigaddset(&nset, SIGTSTP); | 73 | sigaddset(&nset, SIGTSTP); |
66 | (void) sigprocmask(SIG_BLOCK, &nset, &oset); | 74 | (void) sigprocmask(SIG_BLOCK, &nset, &oset); |
75 | memset(&sa, 0, sizeof(sa)); | ||
76 | sa.sa_handler = intcatch; | ||
77 | (void) sigaction(SIGINT, &sa, &osa); | ||
67 | 78 | ||
68 | if (tcgetattr(input, &tio) == 0 && (tio.c_lflag & ECHO)) { | 79 | intr = 0; |
80 | |||
81 | if (tcgetattr(input, &saved_tio) == 0 && (saved_tio.c_lflag & ECHO)) { | ||
69 | echo = 1; | 82 | echo = 1; |
70 | saved_tio = tio; | 83 | tio = saved_tio; |
71 | tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); | 84 | tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); |
72 | (void) tcsetattr(input, TCSANOW, &tio); | 85 | (void) tcsetattr(input, TCSANOW, &tio); |
73 | } | 86 | } |
@@ -75,16 +88,28 @@ read_passphrase(const char *prompt, int from_stdin) | |||
75 | fflush(stdout); | 88 | fflush(stdout); |
76 | 89 | ||
77 | (void)write(output, prompt, strlen(prompt)); | 90 | (void)write(output, prompt, strlen(prompt)); |
78 | for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';) | 91 | for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';) { |
92 | if (intr) | ||
93 | break; | ||
79 | if (p < buf + sizeof(buf) - 1) | 94 | if (p < buf + sizeof(buf) - 1) |
80 | *p++ = ch; | 95 | *p++ = ch; |
96 | } | ||
81 | *p = '\0'; | 97 | *p = '\0'; |
82 | (void)write(output, "\n", 1); | 98 | if (!intr) |
99 | (void)write(output, "\n", 1); | ||
83 | 100 | ||
84 | /* restore terminal modes and allow signals */ | 101 | /* restore terminal modes and allow signals */ |
85 | if (echo) | 102 | if (echo) |
86 | tcsetattr(input, TCSANOW, &saved_tio); | 103 | tcsetattr(input, TCSANOW, &saved_tio); |
87 | (void) sigprocmask(SIG_SETMASK, &oset, NULL); | 104 | (void) sigprocmask(SIG_SETMASK, &oset, NULL); |
105 | (void) sigaction(SIGINT, &osa, NULL); | ||
106 | |||
107 | if (intr) { | ||
108 | kill(getpid(), SIGINT); | ||
109 | sigemptyset(&nset); | ||
110 | /* XXX tty has not neccessarily drained by now? */ | ||
111 | sigsuspend(&nset); | ||
112 | } | ||
88 | 113 | ||
89 | if (!from_stdin) | 114 | if (!from_stdin) |
90 | (void)close(input); | 115 | (void)close(input); |