- OpenBSD CVS updates:
   - [packet.c]
     use getpeername() in packet_connection_is_on_socket(), fixes sshd -i;
     from Holger.Trapp@Informatik.TU-Chemnitz.DE
   - [sshd.c]
     log with level log() not fatal() if peer behaves badly.
   - [readpass.c]
     instead of blocking SIGINT, catch it ourselves, so that we can clean
     the tty modes up and kill ourselves -- instead of our process group
     leader (scp, cvs, ...) going away and leaving us in noecho mode.
     people with cbreak shells never even noticed..
diff --git a/ChangeLog b/ChangeLog
index cc05e2a..352ac1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,17 @@
  - Irix uses preformatted manpages
  - Missing htons() in bsd-bindresvport.c, fix from Holger Trapp
    <Holger.Trapp@Informatik.TU-Chemnitz.DE>
+ - OpenBSD CVS updates:
+   - [packet.c]
+     use getpeername() in packet_connection_is_on_socket(), fixes sshd -i;
+     from Holger.Trapp@Informatik.TU-Chemnitz.DE
+   - [sshd.c]
+     log with level log() not fatal() if peer behaves badly.
+   - [readpass.c]
+     instead of blocking SIGINT, catch it ourselves, so that we can clean 
+     the tty modes up and kill ourselves -- instead of our process group 
+     leader (scp, cvs, ...) going away and leaving us in noecho mode.  
+     people with cbreak shells never even noticed..
 
 20000120
  - Don't use getaddrinfo on AIX
diff --git a/packet.c b/packet.c
index bcd2583..3202e7e 100644
--- a/packet.c
+++ b/packet.c
@@ -15,7 +15,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: packet.c,v 1.9 2000/01/14 04:45:50 damien Exp $");
+RCSID("$Id: packet.c,v 1.10 2000/01/22 08:47:21 damien Exp $");
 
 #include "xmalloc.h"
 #include "buffer.h"
@@ -117,11 +117,11 @@
 		return 1;
 	fromlen = sizeof(from);
 	memset(&from, 0, sizeof(from));
-	if (getpeername(connection_in, (struct sockaddr *) & from, &fromlen) < 0)
+	if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0)
 		return 0;
 	tolen = sizeof(to);
 	memset(&to, 0, sizeof(to));
-	if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0)
+	if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0)
 		return 0;
 	if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
 		return 0;
diff --git a/readpass.c b/readpass.c
index 5ea3b22..edeb238 100644
--- a/readpass.c
+++ b/readpass.c
@@ -32,11 +32,19 @@
  */
 
 #include "includes.h"
-RCSID("$Id: readpass.c,v 1.4 1999/12/08 23:31:37 damien Exp $");
+RCSID("$Id: readpass.c,v 1.5 2000/01/22 08:47:21 damien Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
 
+volatile int intr;
+
+void
+intcatch()
+{
+	intr = 1;
+}
+
 /*
  * Reads a passphrase from /dev/tty with echo turned off.  Returns the
  * passphrase (allocated with xmalloc), being very careful to ensure that
@@ -48,6 +56,7 @@
 	char buf[1024], *p, ch;
 	struct termios tio, saved_tio;
 	sigset_t oset, nset;
+	struct sigaction sa, osa;
 	int input, output, echo = 0;
   
 	if (from_stdin) {
@@ -61,13 +70,17 @@
 
 	/* block signals, get terminal modes and turn off echo */
 	sigemptyset(&nset);
-	sigaddset(&nset, SIGINT);
 	sigaddset(&nset, SIGTSTP);
 	(void) sigprocmask(SIG_BLOCK, &nset, &oset);
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = intcatch;
+	(void) sigaction(SIGINT, &sa, &osa);
 
-	if (tcgetattr(input, &tio) == 0 && (tio.c_lflag & ECHO)) {
+	intr = 0;
+
+	if (tcgetattr(input, &saved_tio) == 0 && (saved_tio.c_lflag & ECHO)) {
 		echo = 1;
-		saved_tio = tio;
+		tio = saved_tio;
 		tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
 		(void) tcsetattr(input, TCSANOW, &tio);
 	}
@@ -75,16 +88,28 @@
 	fflush(stdout);
 
 	(void)write(output, prompt, strlen(prompt));
-	for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';)
+	for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';) {
+		if (intr)
+			break;
 		if (p < buf + sizeof(buf) - 1)
 			*p++ = ch;
+	}
 	*p = '\0';
-	(void)write(output, "\n", 1);
+	if (!intr)
+		(void)write(output, "\n", 1);
 
 	/* restore terminal modes and allow signals */
 	if (echo)
 		tcsetattr(input, TCSANOW, &saved_tio);
 	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
+	(void) sigaction(SIGINT, &osa, NULL);
+
+	if (intr) {
+		kill(getpid(), SIGINT);
+		sigemptyset(&nset);
+		/* XXX tty has not neccessarily drained by now? */
+		sigsuspend(&nset);
+	}
 
 	if (!from_stdin)
 		(void)close(input);
diff --git a/sshd.c b/sshd.c
index 03a9ce1..7f761bb 100644
--- a/sshd.c
+++ b/sshd.c
@@ -11,7 +11,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.79 2000/01/18 13:45:05 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.80 2000/01/20 15:19:22 markus Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -784,13 +784,17 @@
 		/* Send our protocol version identification. */
 		snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
 			 PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
-		if (atomicio(write, sock_out, buf, strlen(buf)) != strlen(buf))
-			fatal("Could not write ident string to %s.", remote_ip);
+		if (atomicio(write, sock_out, buf, strlen(buf)) != strlen(buf)) {
+			log("Could not write ident string to %s.", remote_ip);
+			fatal_cleanup();
+		}
 
 		/* Read other side\'s version identification. */
 		for (i = 0; i < sizeof(buf) - 1; i++) {
-			if (read(sock_in, &buf[i], 1) != 1)
-				fatal("Did not receive ident string from %s.", remote_ip);
+			if (read(sock_in, &buf[i], 1) != 1) {
+				log("Did not receive ident string from %s.", remote_ip);
+				fatal_cleanup();
+			}
 			if (buf[i] == '\r') {
 				buf[i] = '\n';
 				buf[i + 1] = 0;
@@ -816,8 +820,9 @@
 		(void) atomicio(write, sock_out, s, strlen(s));
 		close(sock_in);
 		close(sock_out);
-		fatal("Bad protocol version identification '%.100s' from %s",
-		      buf, remote_ip);
+		log("Bad protocol version identification '%.100s' from %s",
+		    buf, remote_ip);
+		fatal_cleanup();
 	}
 	debug("Client protocol version %d.%d; client software version %.100s",
 	      remote_major, remote_minor, remote_version);
@@ -827,8 +832,9 @@
 		(void) atomicio(write, sock_out, s, strlen(s));
 		close(sock_in);
 		close(sock_out);
-		fatal("Protocol major versions differ for %s: %d vs. %d",
-		      remote_ip, PROTOCOL_MAJOR, remote_major);
+		log("Protocol major versions differ for %s: %d vs. %d",
+		    remote_ip, PROTOCOL_MAJOR, remote_major);
+		fatal_cleanup();
 	}
 	/* Check that the client has sufficiently high software version. */
 	if (remote_major == 1 && remote_minor < 3)