- (djm) Merge OpenBSD changes:
   - markus@cvs.openbsd.org  2000/11/06 16:04:56
     [channels.c channels.h clientloop.c nchan.c serverloop.c]
     [session.c ssh.c]
     agent forwarding and -R for ssh2, based on work from
     jhuuskon@messi.uku.fi
   - markus@cvs.openbsd.org  2000/11/06 16:13:27
     [ssh.c sshconnect.c sshd.c]
     do not disabled rhosts(rsa) if server port > 1024; from
     pekkas@netcore.fi
   - markus@cvs.openbsd.org  2000/11/06 16:16:35
     [sshconnect.c]
     downgrade client to 1.3 if server is 1.4; help from mdb@juniper.net
   - markus@cvs.openbsd.org  2000/11/09 18:04:40
     [auth1.c]
     typo; from mouring@pconline.com
   - markus@cvs.openbsd.org  2000/11/12 12:03:28
     [ssh-agent.c]
     off-by-one when removing a key from the agent
   - markus@cvs.openbsd.org  2000/11/12 12:50:39
     [auth-rh-rsa.c auth2.c authfd.c authfd.h]
     [authfile.c hostfile.c kex.c kex.h key.c key.h myproposal.h]
     [readconf.c readconf.h rsa.c rsa.h servconf.c servconf.h ssh-add.c]
     [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config]
     [sshconnect1.c sshconnect2.c sshd.8 sshd.c sshd_config ssh-dss.c]
     [ssh-dss.h ssh-rsa.c ssh-rsa.h dsa.c dsa.h]
     add support for RSA to SSH2.  please test.
     there are now 3 types of keys: RSA1 is used by ssh-1 only,
     RSA and DSA are used by SSH2.
     you can use 'ssh-keygen -t rsa -f ssh2_rsa_file' to generate RSA
     keys for SSH2 and use the RSA keys for hostkeys or for user keys.
     SSH2 RSA or DSA keys are added to .ssh/authorised_keys2 as before.
 - (djm) Fix up Makefile and Redhat init script to create RSA host keys
 - (djm) Change to interim version
diff --git a/clientloop.c b/clientloop.c
index bccb9be..8f16d2f 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.39 2000/10/27 07:48:22 markus Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.40 2000/11/06 23:04:56 markus Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -75,6 +75,10 @@
 #include "buffer.h"
 #include "bufaux.h"
 
+#include <openssl/dsa.h>
+#include <openssl/rsa.h>
+#include "key.h"
+#include "authfd.h"
 
 /* import options */
 extern Options options;
@@ -1016,13 +1020,99 @@
 	quit_pending = 1;
 }
 
+Channel *
+client_request_forwarded_tcpip(const char *request_type, int rchan)
+{
+	Channel* c = NULL;
+	char *listen_address, *originator_address;
+	int listen_port, originator_port;
+	int sock, newch;
+
+	/* Get rest of the packet */
+	listen_address = packet_get_string(NULL);
+	listen_port = packet_get_int();
+	originator_address = packet_get_string(NULL);
+	originator_port = packet_get_int();
+	packet_done();
+
+	debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d",
+	    listen_address, listen_port, originator_address, originator_port);
+
+	sock = channel_connect_by_listen_adress(listen_port);
+	if (sock >= 0) {
+		newch = channel_new("forwarded-tcpip",
+		    SSH_CHANNEL_OPEN, sock, sock, -1,
+		    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
+		    xstrdup(originator_address), 1);
+		c = channel_lookup(newch);
+	}
+	xfree(originator_address);
+	xfree(listen_address);
+	return c;
+}
+
+Channel*
+client_request_x11(const char *request_type, int rchan)
+{
+	Channel *c = NULL;
+	char *originator;
+	int originator_port;
+	int sock, newch;
+
+	if (!options.forward_x11) {
+		error("Warning: ssh server tried X11 forwarding.");
+		error("Warning: this is probably a break in attempt by a malicious server.");
+		return NULL;
+	}
+	originator = packet_get_string(NULL);
+	if (datafellows & SSH_BUG_X11FWD) {
+		debug2("buggy server: x11 request w/o originator_port");
+		originator_port = 0;
+	} else {
+		originator_port = packet_get_int();
+	}
+	packet_done();
+	/* XXX check permission */
+	sock = x11_connect_display();
+	if (sock >= 0) {
+		newch = channel_new("x11",
+		    SSH_CHANNEL_X11_OPEN, sock, sock, -1,
+		    CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0,
+		    xstrdup("x11"), 1);
+		c = channel_lookup(newch);
+	}
+	xfree(originator);
+	return c;
+}
+
+Channel*
+client_request_agent(const char *request_type, int rchan)
+{
+	Channel *c = NULL;
+	int sock, newch;
+
+	if (!options.forward_agent) {
+		error("Warning: ssh server tried agent forwarding.");
+		error("Warning: this is probably a break in attempt by a malicious server.");
+		return NULL;
+	}
+	sock =  ssh_get_authentication_socket();
+	if (sock >= 0) {
+		newch = channel_new("authentication agent connection",
+		    SSH_CHANNEL_OPEN, sock, sock, -1,
+		    CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
+		    xstrdup("authentication agent connection"), 1);
+		c = channel_lookup(newch);
+	}
+	return c;
+}
+
 /* XXXX move to generic input handler */
 void
 client_input_channel_open(int type, int plen, void *ctxt)
 {
 	Channel *c = NULL;
 	char *ctype;
-	int id;
 	unsigned int len;
 	int rchan;
 	int rmaxpack;
@@ -1036,28 +1126,12 @@
 	debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
 	    ctype, rchan, rwindow, rmaxpack);
 
-	if (strcmp(ctype, "x11") == 0 && options.forward_x11) {
-		int sock;
-		char *originator;
-		int originator_port;
-		originator = packet_get_string(NULL);
-		if (datafellows & SSH_BUG_X11FWD) {
-			debug2("buggy server: x11 request w/o originator_port");
-			originator_port = 0;
-		} else {
-			originator_port = packet_get_int();
-		}
-		packet_done();
-		/* XXX check permission */
-		xfree(originator);
-		/* XXX move to channels.c */
-		sock = x11_connect_display();
-		if (sock >= 0) {
-			id = channel_new("x11", SSH_CHANNEL_X11_OPEN,
-			    sock, sock, -1, CHAN_X11_WINDOW_DEFAULT,
-			    CHAN_X11_PACKET_DEFAULT, 0, xstrdup("x11"), 1);
-			c = channel_lookup(id);
-		}
+	if (strcmp(ctype, "forwarded-tcpip") == 0) {
+		c = client_request_forwarded_tcpip(ctype, rchan);
+	} else if (strcmp(ctype, "x11") == 0) {
+		c = client_request_x11(ctype, rchan);
+	} else if (strcmp(ctype, "auth-agent@openssh.com") == 0) {
+		c = client_request_agent(ctype, rchan);
 	}
 /* XXX duplicate : */
 	if (c != NULL) {