Patch to allow local port forwarding from an existing connection

Brian Wellington bwelling at xbill.org
Thu Sep 20 10:04:51 EST 2001


Hi.  Attached is a patch that introduces a new escape character (~c) that
opens a command line.  From the command line, a command of the form:

	-L port:host:hostport

can be entered, which will forward the local port, as if the same option
has been provided on the command line.  I attempted to allow remote port
forwards to be specified similarly, but the server disconnects with a
protocol error (and the code is disabled now).

This is a bit of a hack, but it works, and it's something that I've been
hoping would be added to ssh for a few years now.

The patch is against openssh-2.9p2.

Comments?  Any chance this will get integrated?

Brian

-----
--- clientloop.c.old	Fri Apr 20 05:50:51 2001
+++ clientloop.c	Wed Sep 19 16:51:40 2001
@@ -67,6 +67,7 @@
 #include "xmalloc.h"
 #include "packet.h"
 #include "buffer.h"
+#include "cli.h"
 #include "compat.h"
 #include "channels.h"
 #include "dispatch.h"
@@ -465,6 +466,75 @@
 	}
 }

+void
+process_cmdline(Buffer *bin, Buffer *bout, Buffer *berr)
+{
+	char string[1024];
+	void (*handler)(int);
+	char *s;
+	u_short fwd_port, fwd_host_port;
+	char buf[256];
+	int local = 0;
+	char *msg;
+	int n;
+
+	leave_raw_mode();
+	handler = signal(SIGINT, SIG_IGN);
+	fprintf(stderr, "\r\n> ");
+	s = fgets(string, sizeof string, stdin);
+	if (s == NULL) {
+		msg = NULL;
+		goto out;
+	}
+
+	while (*s && isspace(*s))
+		s++;
+
+	if (*s == 0)
+		goto out;
+
+	if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) {
+		msg = "Invalid command";
+		goto out;
+	}
+	if (s[1] == 'L')
+		local = 1;
+	else {
+		msg = "Remote forwarding doesn't work";
+		goto out;
+	}
+
+	s += 2;
+
+	if (sscanf(s, "%hu/%255[^/]/%hu", &fwd_port, buf, &fwd_host_port) != 3
+	    &&
+	    sscanf(s, "%hu:%255[^:]:%hu", &fwd_port, buf, &fwd_host_port) != 3)
+	{
+		msg = "Invalid port forward";
+		goto out;
+	}
+	if (local) {
+		n = channel_request_local_forwarding(fwd_port, buf,
+						     fwd_host_port,
+						     options.gateway_ports);
+		if (n <= 0) {
+			msg = "Port forwarding failed";
+			goto out;
+		}
+	}
+	else
+		channel_request_remote_forwarding(fwd_port, buf, fwd_host_port);
+
+	msg = "Forwarding port";
+ out:
+	signal(SIGINT, handler);
+	enter_raw_mode();
+	if (msg) {
+		snprintf(string, sizeof string, "%s\r\n", msg);
+		buffer_append(berr, string, strlen(string));
+	}
+}
+
 /* process the characters one by one */
 int
 process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
@@ -570,6 +640,7 @@
 ~^Z - suspend ssh\r\n\
 ~#  - list forwarded connections\r\n\
 ~&  - background ssh (when waiting for connections to terminate)\r\n\
+~c  - open a command line\r\n
 ~?  - this message\r\n\
 ~~  - send the escape character by typing it twice\r\n\
 (Note that escapes are only recognized immediately after newline.)\r\n",
@@ -583,6 +654,10 @@
 				s = channel_open_message();
 				buffer_append(berr, s, strlen(s));
 				xfree(s);
+				continue;
+
+			case 'c':
+				process_cmdline(bin, bout, berr);
 				continue;

 			default:





More information about the openssh-unix-dev mailing list