Brian Wellington
2001-Sep-20 00:04 UTC
Patch to allow local port forwarding from an existing connection
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:
Markus Friedl
2001-Sep-20 10:04 UTC
Patch to allow local port forwarding from an existing connection
On Wed, Sep 19, 2001 at 05:04:51PM -0700, Brian Wellington wrote:> 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? > + fprintf(stderr, "\r\n> "); > + s = fgets(string, sizeof string, stdin);i don't think reading from stdin is correct. you need to read from the same FD as bin. can you get the command line from 'bin' ? or perhaps use readpass.[ch] from -current with echo enabled? -m