summaryrefslogtreecommitdiff
path: root/readpass.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-12-09 10:31:37 +1100
committerDamien Miller <djm@mindrot.org>1999-12-09 10:31:37 +1100
commit50945fa861f9b17d0cf88ec7998847bcf1c5eda6 (patch)
tree58757427a77d5775b9aebc7f4a5cb6cf9019da2f /readpass.c
parentbf1c9b2012fadab02392126bece5d21e9ddffda6 (diff)
- OpenBSD CVS updates:
- [readpass.c] avoid stdio; based on work by markus, millert, and I - [sshd.c] make sure the client selects a supported cipher - [sshd.c] fix sighup handling. accept would just restart and daemon handled sighup only after the next connection was accepted. use poll on listen sock now. - [sshd.c] make that a fatal
Diffstat (limited to 'readpass.c')
-rw-r--r--readpass.c167
1 files changed, 71 insertions, 96 deletions
diff --git a/readpass.c b/readpass.c
index 5b7119fd7..5ea3b22dc 100644
--- a/readpass.c
+++ b/readpass.c
@@ -1,119 +1,94 @@
1/* 1/*
2 * 2 * Copyright (c) 1988, 1993
3 * readpass.c 3 * The Regents of the University of California. All rights reserved.
4 * 4 *
5 * Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Redistribution and use in source and binary forms, with or without
6 * 6 * modification, are permitted provided that the following conditions
7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * are met:
8 * All rights reserved 8 * 1. Redistributions of source code must retain the above copyright
9 * 9 * notice, this list of conditions and the following disclaimer.
10 * Created: Mon Jul 10 22:08:59 1995 ylo 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * 11 * notice, this list of conditions and the following disclaimer in the
12 * Functions for reading passphrases and passwords. 12 * documentation and/or other materials provided with the distribution.
13 * 13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
14 */ 32 */
15 33
16#include "includes.h" 34#include "includes.h"
17RCSID("$Id: readpass.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); 35RCSID("$Id: readpass.c,v 1.4 1999/12/08 23:31:37 damien Exp $");
18 36
19#include "xmalloc.h" 37#include "xmalloc.h"
20#include "ssh.h" 38#include "ssh.h"
21 39
22/* Saved old terminal mode for read_passphrase. */
23static struct termios saved_tio;
24
25/* Old interrupt signal handler for read_passphrase. */
26static void (*old_handler) (int sig) = NULL;
27
28/* Interrupt signal handler for read_passphrase. */
29
30void
31intr_handler(int sig)
32{
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);
39}
40
41/* 40/*
42 * Reads a passphrase from /dev/tty with echo turned off. Returns the 41 * Reads a passphrase from /dev/tty with echo turned off. Returns the
43 * passphrase (allocated with xmalloc). Exits if EOF is encountered. The 42 * passphrase (allocated with xmalloc), being very careful to ensure that
44 * passphrase if read from stdin if from_stdin is true (as is the case with 43 * no other userland buffer is storing the password.
45 * ssh-keygen).
46 */ 44 */
47
48char * 45char *
49read_passphrase(const char *prompt, int from_stdin) 46read_passphrase(const char *prompt, int from_stdin)
50{ 47{
51 char buf[1024], *cp; 48 char buf[1024], *p, ch;
52 struct termios tio; 49 struct termios tio, saved_tio;
53 FILE *f; 50 sigset_t oset, nset;
51 int input, output, echo = 0;
52
53 if (from_stdin) {
54 input = STDIN_FILENO;
55 output = STDERR_FILENO;
56 } else
57 input = output = open("/dev/tty", O_RDWR);
58
59 if (input == -1)
60 fatal("You have no controlling tty. Cannot read passphrase.\n");
54 61
55 if (from_stdin) 62 /* block signals, get terminal modes and turn off echo */
56 f = stdin; 63 sigemptyset(&nset);
57 else { 64 sigaddset(&nset, SIGINT);
58 /* 65 sigaddset(&nset, SIGTSTP);
59 * Read the passphrase from /dev/tty to make it possible to 66 (void) sigprocmask(SIG_BLOCK, &nset, &oset);
60 * ask it even when stdin has been redirected. 67
61 */ 68 if (tcgetattr(input, &tio) == 0 && (tio.c_lflag & ECHO)) {
62 f = fopen("/dev/tty", "r"); 69 echo = 1;
63 if (!f) { 70 saved_tio = tio;
64 /* No controlling terminal and no DISPLAY. Nowhere to read. */ 71 tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
65 fprintf(stderr, "You have no controlling tty and no DISPLAY. Cannot read passphrase.\n"); 72 (void) tcsetattr(input, TCSANOW, &tio);
66 exit(1);
67 }
68 } 73 }
69 74
70 /* Display the prompt (on stderr because stdout might be redirected). */
71 fflush(stdout); 75 fflush(stdout);
72 fprintf(stderr, "%s", prompt);
73 fflush(stderr);
74 76
75 /* Get terminal modes. */ 77 (void)write(output, prompt, strlen(prompt));
76 tcgetattr(fileno(f), &tio); 78 for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';)
77 saved_tio = tio; 79 if (p < buf + sizeof(buf) - 1)
78 /* Save signal handler and set the new handler. */ 80 *p++ = ch;
79 old_handler = signal(SIGINT, intr_handler); 81 *p = '\0';
82 (void)write(output, "\n", 1);
80 83
81 /* Set new terminal modes disabling all echo. */ 84 /* restore terminal modes and allow signals */
82 tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 85 if (echo)
83 tcsetattr(fileno(f), TCSANOW, &tio); 86 tcsetattr(input, TCSANOW, &saved_tio);
87 (void) sigprocmask(SIG_SETMASK, &oset, NULL);
84 88
85 /* Read the passphrase from the terminal. */ 89 if (!from_stdin)
86 if (fgets(buf, sizeof(buf), f) == NULL) { 90 (void)close(input);
87 /* Got EOF. Just exit. */ 91 p = xstrdup(buf);
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);
108 /*
109 * Clear the buffer so we don\'t leave copies of the passphrase
110 * laying around.
111 */
112 memset(buf, 0, sizeof(buf)); 92 memset(buf, 0, sizeof(buf));
113 /* Print a newline since the prompt probably didn\'t have one. */ 93 return (p);
114 fprintf(stderr, "\n");
115 /* Close the file. */
116 if (f != stdin)
117 fclose(f);
118 return cp;
119} 94}