On Tue, Feb 17, 2009 at 02:10:20PM +1100, Dylan Jay
wrote:> Just a usecase that I'm sure has been covered before but just in case
> its not an openssh solution would be very helpful.
>
> I was trying to install software on a server that was firewalled so no
> outbound http connections would work. I was also tunnelling via
> another server. Outbound ssh connections also were a convenient option.
>
> What would have been nice would be a remote version of the dynamic
> socks proxy ssh -D, so I could for instance
>
> > ssh me at remote --remote-socks=8123
> remote> export http_proxy=localhost:8123
> remote> wget --spider www.google.com
this patch adds a
ssh me at remote -R 8123
but it requires a patched server, too.
Index: channels.c
==================================================================RCS file:
/cvs/src/usr.bin/ssh/channels.c,v
retrieving revision 1.299
diff -u -p -u -r1.299 channels.c
--- channels.c 11 Nov 2009 21:37:03 -0000 1.299
+++ channels.c 7 Jan 2010 11:44:18 -0000
@@ -2684,7 +2684,8 @@ channel_request_remote_forwarding(const
address_to_bind = listen_host;
packet_start(SSH2_MSG_GLOBAL_REQUEST);
- packet_put_cstring("tcpip-forward");
+ packet_put_cstring(port_to_connect ?
+ "tcpip-forward" : "dynamic-forward at openssh.com");
packet_put_char(1); /* boolean: want reply */
packet_put_cstring(address_to_bind);
packet_put_int(listen_port);
@@ -3018,6 +3019,33 @@ channel_connect_to(const char *host, u_s
return NULL;
}
return connect_to(host, port, ctype, rname);
+}
+
+/* Process a direct-tcpip connect request. */
+Channel *
+channel_input_direct_tcpip(void)
+{
+ Channel *c;
+ char *target, *originator;
+ u_short target_port, originator_port;
+
+ target = packet_get_string(NULL);
+ target_port = packet_get_int();
+ originator = packet_get_string(NULL);
+ originator_port = packet_get_int();
+ packet_check_eom();
+
+ debug("channel_input_direct_tcpip: originator %s port %d, target %s
"
+ "port %d", originator, originator_port, target, target_port);
+
+ /* XXX check permission */
+ c = channel_connect_to(target, target_port,
+ "direct-tcpip", "direct-tcpip");
+
+ xfree(originator);
+ xfree(target);
+
+ return c;
}
void
Index: channels.h
==================================================================RCS file:
/cvs/src/usr.bin/ssh/channels.h,v
retrieving revision 1.100
diff -u -p -u -r1.100 channels.h
--- channels.h 11 Nov 2009 21:37:03 -0000 1.100
+++ channels.h 7 Jan 2010 11:44:18 -0000
@@ -242,6 +242,7 @@ void channel_clear_permitted_opens(void
void channel_clear_adm_permitted_opens(void);
void channel_print_adm_permitted_opens(void);
int channel_input_port_forward_request(int, int);
+Channel *channel_input_direct_tcpip(void);
Channel *channel_connect_to(const char *, u_short, char *, char *);
Channel *channel_connect_by_listen_address(u_short, char *, char *);
int channel_request_remote_forwarding(const char *, u_short,
Index: clientloop.c
==================================================================RCS file:
/cvs/src/usr.bin/ssh/clientloop.c,v
retrieving revision 1.215
diff -u -p -u -r1.215 clientloop.c
--- clientloop.c 17 Nov 2009 05:31:44 -0000 1.215
+++ clientloop.c 7 Jan 2010 11:44:18 -0000
@@ -1784,6 +1784,8 @@ client_input_channel_open(int type, u_in
c = client_request_forwarded_tcpip(ctype, rchan);
} else if (strcmp(ctype, "x11") == 0) {
c = client_request_x11(ctype, rchan);
+ } else if (strcmp(ctype, "direct-tcpip") == 0) {
+ c = channel_input_direct_tcpip();
} else if (strcmp(ctype, "auth-agent at openssh.com") == 0) {
c = client_request_agent(ctype, rchan);
}
Index: readconf.c
==================================================================RCS file:
/cvs/src/usr.bin/ssh/readconf.c,v
retrieving revision 1.181
diff -u -p -u -r1.181 readconf.c
--- readconf.c 29 Dec 2009 16:38:41 -0000 1.181
+++ readconf.c 7 Jan 2010 11:44:18 -0000
@@ -15,6 +15,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <sys/queue.h>
#include <netinet/in.h>
@@ -39,6 +40,7 @@
#include "buffer.h"
#include "kex.h"
#include "mac.h"
+#include "channels.h"
/* Format of the configuration file:
@@ -329,7 +331,7 @@ process_config_line(Options *options, co
int *activep)
{
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
- int opcode, *intptr, value, value2, scale;
+ int opcode, *intptr, value, value2, scale, remotefwd, dynamicfwd;
LogLevel *log_level_ptr;
long long orig, val64;
size_t len;
@@ -718,31 +720,38 @@ parse_int:
fatal("%.200s line %d: Missing port argument.",
filename, linenum);
- if (opcode == oLocalForward ||
- opcode == oRemoteForward) {
+ remotefwd = (opcode == oRemoteForward);
+ dynamicfwd = (opcode == oDynamicForward);
+
+ if (!dynamicfwd) {
arg2 = strdelim(&s);
- if (arg2 == NULL || *arg2 == '\0')
- fatal("%.200s line %d: Missing target argument.",
- filename, linenum);
+ if (arg2 == NULL || *arg2 == '\0') {
+ if (remotefwd)
+ dynamicfwd = 1;
+ else
+ fatal("%.200s line %d: Missing target "
+ "argument.", filename, linenum);
+ }
/* construct a string for parse_forward */
snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
- } else if (opcode == oDynamicForward) {
- strlcpy(fwdarg, arg, sizeof(fwdarg));
}
+ if (dynamicfwd)
+ strlcpy(fwdarg, arg, sizeof(fwdarg));
- if (parse_forward(&fwd, fwdarg,
- opcode == oDynamicForward ? 1 : 0,
- opcode == oRemoteForward ? 1 : 0) == 0)
+ if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
fatal("%.200s line %d: Bad forwarding specification.",
filename, linenum);
if (*activep) {
- if (opcode == oLocalForward ||
- opcode == oDynamicForward)
- add_local_forward(options, &fwd);
- else if (opcode == oRemoteForward)
+ if (remotefwd) {
add_remote_forward(options, &fwd);
+ /* no restrictions for remote dynamic fwds */
+ if (fwd.connect_port == 0)
+ channel_permit_all_opens();
+ } else {
+ add_local_forward(options, &fwd);
+ }
}
break;
Index: serverloop.c
==================================================================RCS file:
/cvs/src/usr.bin/ssh/serverloop.c,v
retrieving revision 1.159
diff -u -p -u -r1.159 serverloop.c
--- serverloop.c 28 May 2009 16:50:16 -0000 1.159
+++ serverloop.c 7 Jan 2010 11:44:18 -0000
@@ -910,32 +910,6 @@ server_input_window_size(int type, u_int
}
static Channel *
-server_request_direct_tcpip(void)
-{
- Channel *c;
- char *target, *originator;
- u_short target_port, originator_port;
-
- target = packet_get_string(NULL);
- target_port = packet_get_int();
- originator = packet_get_string(NULL);
- originator_port = packet_get_int();
- packet_check_eom();
-
- debug("server_request_direct_tcpip: originator %s port %d, target %s
"
- "port %d", originator, originator_port, target, target_port);
-
- /* XXX check permission */
- c = channel_connect_to(target, target_port,
- "direct-tcpip", "direct-tcpip");
-
- xfree(originator);
- xfree(target);
-
- return c;
-}
-
-static Channel *
server_request_tun(void)
{
Channel *c = NULL;
@@ -1026,7 +1000,7 @@ server_input_channel_open(int type, u_in
if (strcmp(ctype, "session") == 0) {
c = server_request_session();
} else if (strcmp(ctype, "direct-tcpip") == 0) {
- c = server_request_direct_tcpip();
+ c = channel_input_direct_tcpip();
} else if (strcmp(ctype, "tun at openssh.com") == 0) {
c = server_request_tun();
}
@@ -1069,7 +1043,8 @@ server_input_global_request(int type, u_
debug("server_input_global_request: rtype %s want_reply %d", rtype,
want_reply);
/* -R style forwarding */
- if (strcmp(rtype, "tcpip-forward") == 0) {
+ if (strcmp(rtype, "tcpip-forward") == 0 ||
+ strcmp(rtype, "dynamic-forward at openssh.com") == 0) {
struct passwd *pw;
char *listen_address;
u_short listen_port;
@@ -1079,8 +1054,8 @@ server_input_global_request(int type, u_
fatal("server_input_global_request: no/invalid user");
listen_address = packet_get_string(NULL);
listen_port = (u_short)packet_get_int();
- debug("server_input_global_request: tcpip-forward listen %s port
%d",
- listen_address, listen_port);
+ debug("server_input_global_request: %s listen %s port %d",
+ rtype, listen_address, listen_port);
/* check permissions */
if (!options.allow_tcp_forwarding ||
@@ -1090,6 +1065,11 @@ server_input_global_request(int type, u_
pw->pw_uid != 0)) {
success = 0;
packet_send_debug("Server has disabled port forwarding.");
+ } else if (!strcmp(rtype, "dynamic-forward at openssh.com")) {
+ /* Listen on socks port */
+ success = channel_setup_local_fwd_listener(
+ listen_address, listen_port,
+ "dynamic", 0, options.gateway_ports);
} else {
/* Start listening on the port */
success = channel_setup_remote_fwd_listener(
Index: ssh.c
==================================================================RCS file:
/cvs/src/usr.bin/ssh/ssh.c,v
retrieving revision 1.329
diff -u -p -u -r1.329 ssh.c
--- ssh.c 20 Dec 2009 07:28:36 -0000 1.329
+++ ssh.c 7 Jan 2010 11:44:18 -0000
@@ -454,8 +454,12 @@ main(int ac, char **av)
break;
case 'R':
- if (parse_forward(&fwd, optarg, 0, 1)) {
+ if (parse_forward(&fwd, optarg, 0, 1) ||
+ parse_forward(&fwd, optarg, 1, 1)) {
add_remote_forward(&options, &fwd);
+ /* no restrictions for remote dynamic fwds */
+ if (fwd.connect_port == 0)
+ channel_permit_all_opens();
} else {
fprintf(stderr,
"Bad remote forwarding specification "