- (djm) Sync with OpenBSD:
   - markus@cvs.openbsd.org  2000/10/16 15:46:32
     [ssh.1]
     fixes from pekkas@netcore.fi
   - markus@cvs.openbsd.org  2000/10/17 14:28:11
     [atomicio.c]
     return number of characters processed; ok deraadt@
   - markus@cvs.openbsd.org  2000/10/18 12:04:02
     [atomicio.c]
     undo
   - markus@cvs.openbsd.org  2000/10/18 12:23:02
     [scp.c]
     replace atomicio(read,...) with read(); ok deraadt@
   - markus@cvs.openbsd.org  2000/10/18 12:42:00
     [session.c]
     restore old record login behaviour
   - deraadt@cvs.openbsd.org 2000/10/19 10:41:13
     [auth-skey.c]
     fmt string problem in unused code
   - provos@cvs.openbsd.org  2000/10/19 10:45:16
     [sshconnect2.c]
     don't reference freed memory. okay deraadt@
   - markus@cvs.openbsd.org  2000/10/21 11:04:23
     [canohost.c]
     typo, eramore@era-t.ericsson.se; ok niels@
   - markus@cvs.openbsd.org  2000/10/23 13:31:55
     [cipher.c]
     non-alignment dependent swap_bytes(); from
     simonb@wasabisystems.com/netbsd
   - markus@cvs.openbsd.org  2000/10/26 12:38:28
     [compat.c]
     add older vandyke products
   - markus@cvs.openbsd.org  2000/10/27 01:32:19
     [channels.c channels.h clientloop.c serverloop.c session.c]
     [ssh.c util.c]
     enable non-blocking IO on channels, and tty's (except for the
     client ttys).
   - markus@cvs.openbsd.org  2000/10/27 01:48:22
     channels.c channels.h clientloop.c
     deny agent/x11 forwarding unless requested; thanks to jwl@pobox.com
diff --git a/channels.c b/channels.c
index 96d8dc4..028c09e 100644
--- a/channels.c
+++ b/channels.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.70 2000/09/28 18:03:18 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.72 2000/10/27 07:48:22 markus Exp $");
 
 #include "ssh.h"
 #include "packet.h"
@@ -174,7 +174,8 @@
  */
 
 void
-channel_register_fds(Channel *c, int rfd, int wfd, int efd, int extusage)
+channel_register_fds(Channel *c, int rfd, int wfd, int efd,
+    int extusage, int nonblock)
 {
 	/* Update the maximum file descriptor value. */
 	if (rfd > channel_max_fd_value)
@@ -190,12 +191,16 @@
 	c->sock = (rfd == wfd) ? rfd : -1;
 	c->efd = efd;
 	c->extended_usage = extusage;
-	if (rfd != -1)
-		set_nonblock(rfd);
-	if (wfd != -1)
-		set_nonblock(wfd);
-	if (efd != -1)
-		set_nonblock(efd);
+
+	/* enable nonblocking mode */
+	if (nonblock) {
+		if (rfd != -1)
+			set_nonblock(rfd);
+		if (wfd != -1)
+			set_nonblock(wfd);
+		if (efd != -1)
+			set_nonblock(efd);
+	}
 }
 
 /*
@@ -205,7 +210,7 @@
 
 int
 channel_new(char *ctype, int type, int rfd, int wfd, int efd,
-    int window, int maxpack, int extusage, char *remote_name)
+    int window, int maxpack, int extusage, char *remote_name, int nonblock)
 {
 	int i, found;
 	Channel *c;
@@ -245,7 +250,7 @@
 	buffer_init(&c->output);
 	buffer_init(&c->extended);
 	chan_init_iostates(c);
-	channel_register_fds(c, rfd, wfd, efd, extusage);
+	channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
 	c->self = found;
 	c->type = type;
 	c->ctype = ctype;
@@ -269,7 +274,7 @@
 int
 channel_allocate(int type, int sock, char *remote_name)
 {
-	return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name);
+	return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name, 1);
 }
 
 
@@ -548,7 +553,7 @@
 		newch = channel_new("x11",
 		    SSH_CHANNEL_OPENING, newsock, newsock, -1,
 		    c->local_window_max, c->local_maxpacket,
-		    0, xstrdup(buf));
+		    0, xstrdup(buf), 1);
 		if (compat20) {
 			packet_start(SSH2_MSG_CHANNEL_OPEN);
 			packet_put_cstring("x11");
@@ -606,7 +611,7 @@
 		newch = channel_new("direct-tcpip",
 		    SSH_CHANNEL_OPENING, newsock, newsock, -1,
 		    c->local_window_max, c->local_maxpacket,
-		    0, xstrdup(buf));
+		    0, xstrdup(buf), 1);
 		if (compat20) {
 			packet_start(SSH2_MSG_CHANNEL_OPEN);
 			packet_put_cstring("direct-tcpip");
@@ -1514,7 +1519,7 @@
 		    "port listener", SSH_CHANNEL_PORT_LISTENER,
 		    sock, sock, -1,
 		    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
-		    0, xstrdup("port listener"));
+		    0, xstrdup("port listener"), 1);
 		strlcpy(channels[ch].path, host, sizeof(channels[ch].path));
 		channels[ch].host_port = host_port;
 		channels[ch].listening_port = port;
@@ -1859,7 +1864,7 @@
 		(void) channel_new("x11 listener",
 		    SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
 		    CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
-		    0, xstrdup("X11 inet listener"));
+		    0, xstrdup("X11 inet listener"), 1);
 	}
 
 	/* Return a suitable value for the DISPLAY environment variable. */
@@ -2045,6 +2050,28 @@
 	}
 }
 
+/* dummy protocol handler that denies SSH-1 requests (agent/x11) */
+void
+deny_input_open(int type, int plen, void *ctxt)
+{
+	int rchan = packet_get_int();
+	switch(type){
+	case SSH_SMSG_AGENT_OPEN:
+		error("Warning: ssh server tried agent forwarding.");
+		break;
+	case SSH_SMSG_X11_OPEN:
+		error("Warning: ssh server tried X11 forwarding.");
+		break;
+	default:
+		error("deny_input_open: type %d plen %d", type, plen);
+		break;
+	}
+	error("Warning: this is probably a break in attempt by a malicious server.");
+	packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
+	packet_put_int(rchan);
+	packet_send();
+}
+
 /*
  * Requests forwarding of X11 connections, generates fake authentication
  * data, and enables authentication spoofing.
@@ -2349,13 +2376,13 @@
 }
 
 void
-channel_set_fds(int id, int rfd, int wfd, int efd, int extusage)
+channel_set_fds(int id, int rfd, int wfd, int efd,
+    int extusage, int nonblock)
 {
 	Channel *c = channel_lookup(id);
 	if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
 		fatal("channel_activate for non-larval channel %d.", id);
-
-	channel_register_fds(c, rfd, wfd, efd, extusage);
+	channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
 	c->type = SSH_CHANNEL_OPEN;
 	/* XXX window size? */
 	c->local_window = c->local_window_max = c->local_maxpacket * 2;