diff options
author | Damien Miller <djm@mindrot.org> | 1999-12-09 10:31:37 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 1999-12-09 10:31:37 +1100 |
commit | 50945fa861f9b17d0cf88ec7998847bcf1c5eda6 (patch) | |
tree | 58757427a77d5775b9aebc7f4a5cb6cf9019da2f | |
parent | bf1c9b2012fadab02392126bece5d21e9ddffda6 (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
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | readpass.c | 167 | ||||
-rw-r--r-- | sshd.c | 23 |
3 files changed, 102 insertions, 99 deletions
@@ -4,6 +4,17 @@ | |||
4 | - "uninstall" rule for Makefile | 4 | - "uninstall" rule for Makefile |
5 | - utmpx support | 5 | - utmpx support |
6 | - Should fix PAM problems on Solaris | 6 | - Should fix PAM problems on Solaris |
7 | - OpenBSD CVS updates: | ||
8 | - [readpass.c] | ||
9 | avoid stdio; based on work by markus, millert, and I | ||
10 | - [sshd.c] | ||
11 | make sure the client selects a supported cipher | ||
12 | - [sshd.c] | ||
13 | fix sighup handling. accept would just restart and daemon handled | ||
14 | sighup only after the next connection was accepted. use poll on | ||
15 | listen sock now. | ||
16 | - [sshd.c] | ||
17 | make that a fatal | ||
7 | 18 | ||
8 | 19991208 | 19 | 19991208 |
9 | - Compile fix for Solaris with /dev/ptmx from | 20 | - Compile fix for Solaris with /dev/ptmx from |
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" |
17 | RCSID("$Id: readpass.c,v 1.3 1999/11/25 00:54:59 damien Exp $"); | 35 | RCSID("$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. */ | ||
23 | static struct termios saved_tio; | ||
24 | |||
25 | /* Old interrupt signal handler for read_passphrase. */ | ||
26 | static void (*old_handler) (int sig) = NULL; | ||
27 | |||
28 | /* Interrupt signal handler for read_passphrase. */ | ||
29 | |||
30 | void | ||
31 | intr_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 | |||
48 | char * | 45 | char * |
49 | read_passphrase(const char *prompt, int from_stdin) | 46 | read_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 | } |
@@ -11,7 +11,9 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: sshd.c,v 1.36 1999/12/08 23:16:55 damien Exp $"); | 14 | RCSID("$Id: sshd.c,v 1.37 1999/12/08 23:31:37 damien Exp $"); |
15 | |||
16 | #include <poll.h> | ||
15 | 17 | ||
16 | #include "xmalloc.h" | 18 | #include "xmalloc.h" |
17 | #include "rsa.h" | 19 | #include "rsa.h" |
@@ -419,6 +421,7 @@ main(int ac, char **av) | |||
419 | int opt, aux, sock_in, sock_out, newsock, i, pid, on = 1; | 421 | int opt, aux, sock_in, sock_out, newsock, i, pid, on = 1; |
420 | int remote_major, remote_minor; | 422 | int remote_major, remote_minor; |
421 | int silentrsa = 0; | 423 | int silentrsa = 0; |
424 | struct pollfd fds; | ||
422 | struct sockaddr_in sin; | 425 | struct sockaddr_in sin; |
423 | char buf[100]; /* Must not be larger than remote_version. */ | 426 | char buf[100]; /* Must not be larger than remote_version. */ |
424 | char remote_version[100]; /* Must be at least as big as buf. */ | 427 | char remote_version[100]; /* Must be at least as big as buf. */ |
@@ -688,7 +691,18 @@ main(int ac, char **av) | |||
688 | for (;;) { | 691 | for (;;) { |
689 | if (received_sighup) | 692 | if (received_sighup) |
690 | sighup_restart(); | 693 | sighup_restart(); |
691 | /* Wait in accept until there is a connection. */ | 694 | /* Wait in poll until there is a connection. */ |
695 | memset(&fds, 0, sizeof(fds)); | ||
696 | fds.fd = listen_sock; | ||
697 | fds.events = POLLIN; | ||
698 | if (poll(&fds, 1, -1) == -1) { | ||
699 | if (errno == EINTR) | ||
700 | continue; | ||
701 | fatal("poll: %.100s", strerror(errno)); | ||
702 | /*NOTREACHED*/ | ||
703 | } | ||
704 | if (fds.revents == 0) | ||
705 | continue; | ||
692 | aux = sizeof(sin); | 706 | aux = sizeof(sin); |
693 | newsock = accept(listen_sock, (struct sockaddr *) & sin, &aux); | 707 | newsock = accept(listen_sock, (struct sockaddr *) & sin, &aux); |
694 | if (received_sighup) | 708 | if (received_sighup) |
@@ -1026,9 +1040,12 @@ do_connection() | |||
1026 | /* Read clients reply (cipher type and session key). */ | 1040 | /* Read clients reply (cipher type and session key). */ |
1027 | packet_read_expect(&plen, SSH_CMSG_SESSION_KEY); | 1041 | packet_read_expect(&plen, SSH_CMSG_SESSION_KEY); |
1028 | 1042 | ||
1029 | /* Get cipher type. */ | 1043 | /* Get cipher type and check whether we accept this. */ |
1030 | cipher_type = packet_get_char(); | 1044 | cipher_type = packet_get_char(); |
1031 | 1045 | ||
1046 | if (!(cipher_mask() & (1 << cipher_type))) | ||
1047 | packet_disconnect("Warning: client selects unsupported cipher."); | ||
1048 | |||
1032 | /* Get check bytes from the packet. These must match those we | 1049 | /* Get check bytes from the packet. These must match those we |
1033 | sent earlier with the public key packet. */ | 1050 | sent earlier with the public key packet. */ |
1034 | for (i = 0; i < 8; i++) | 1051 | for (i = 0; i < 8; i++) |