From e6780883aaee4b34796ae5f50fa6a83c6bfad4d4 Mon Sep 17 00:00:00 2001 From: dtucker Date: Tue, 12 Jan 2010 08:40:27 +0000 Subject: [PATCH] - dtucker@cvs.openbsd.org 2010/01/11 01:39:46 [ssh_config channels.c ssh.1 channels.h ssh.c] Add a 'netcat mode' (ssh -W). This connects stdio on the client to a single port forward on the server. This allows, for example, using ssh as a ProxyCommand to route connections via intermediate servers. bz #1618, man page help from jmc@, ok markus@ --- ChangeLog | 15 +++++++++++--- channels.c | 31 ++++++++++++++++++++++++++++- channels.h | 3 ++- ssh.1 | 18 ++++++++++++++--- ssh.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++--- ssh_config | 3 ++- 6 files changed, 115 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 40c9647c..72a68a61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,13 @@ -20091210 +20100111 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2010/01/11 01:39:46 + [ssh_config channels.c ssh.1 channels.h ssh.c] + Add a 'netcat mode' (ssh -W). This connects stdio on the client to a + single port forward on the server. This allows, for example, using ssh as + a ProxyCommand to route connections via intermediate servers. + bz #1618, man page help from jmc@, ok markus@ + +20100110 - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Remove hacks add for RoutingDomain in preparation for its removal. - (dtucker) OpenBSD CVS Sync @@ -22,7 +31,7 @@ [auth.c] Output a debug if we can't open an existing keyfile. bz#1694, ok djm@ -20091209 +20100109 - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't have it. - (dtucker) [defines.h] define PRIu64 for platforms that don't have it. @@ -59,7 +68,7 @@ dying. bz#1692, patch from Colin Watson via Ubuntu. - (dtucker) [defines.h] Remove now-undeeded PRIu64 define. -20091208 +20100108 - (dtucker) OpenBSD CVS Sync - andreas@cvs.openbsd.org 2009/10/24 11:11:58 [roaming.h] diff --git a/channels.c b/channels.c index 87dbe96d..e8589d8c 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.300 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: channels.c,v 1.301 2010/01/11 01:39:46 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1217,6 +1217,35 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) return 1; } +Channel * +channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect) +{ + Channel *c; + int in, out; + + debug("channel_connect_stdio_fwd %s:%d", host_to_connect, + port_to_connect); + + in = dup(STDIN_FILENO); + out = dup(STDOUT_FILENO); + if (in < 0 || out < 0) + fatal("channel_connect_stdio_fwd: dup() in/out failed"); + + c = channel_new("stdio-forward", SSH_CHANNEL_OPENING, in, out, + -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, "stdio-forward", /*nonblock*/0); + + c->path = xstrdup(host_to_connect); + c->host_port = port_to_connect; + c->listening_port = 0; + c->force_drain = 1; + + channel_register_fds(c, in, out, -1, 0, 1, 0); + port_open_helper(c, "direct-tcpip"); + + return c; +} + /* dynamic port forwarding */ static void channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset) diff --git a/channels.h b/channels.h index f65a311d..79ebe047 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.101 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: channels.h,v 1.102 2010/01/11 01:39:46 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -243,6 +243,7 @@ void channel_clear_adm_permitted_opens(void); void channel_print_adm_permitted_opens(void); int channel_input_port_forward_request(int, int); Channel *channel_connect_to(const char *, u_short, char *, char *); +Channel *channel_connect_stdio_fwd(const char*, u_short); Channel *channel_connect_by_listen_address(u_short, char *, char *); int channel_request_remote_forwarding(const char *, u_short, const char *, u_short); diff --git a/ssh.1 b/ssh.1 index c0d149de..aa928049 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.289 2010/01/09 23:04:13 dtucker Exp $ +.\" $OpenBSD: ssh.1,v 1.290 2010/01/11 01:39:46 dtucker Exp $ .Dd $Mdocdate$ .Dt SSH 1 .Os @@ -77,12 +77,11 @@ .Sm on .Oc .Op Fl S Ar ctl_path -.Bk -words +.Op Fl W Ar host : Ns Ar port .Oo Fl w Ar local_tun Ns .Op : Ns Ar remote_tun Oc .Oo Ar user Ns @ Oc Ns Ar hostname .Op Ar command -.Ek .Sh DESCRIPTION .Nm (SSH client) is a program for logging into a remote machine and for @@ -594,6 +593,19 @@ Multiple .Fl v options increase the verbosity. The maximum is 3. +.It Fl W Ar host : Ns Ar port +Requests that standard input and output on the client be forwarded to +.Ar host +on +.Ar port +over the secure channel. +Implies +.Fl N , +.Fl T , +.Cm ExitOnForwardFailure +and +.Cm ClearAllForwardings +and works with Protocol version 2 only. .It Fl w Xo .Ar local_tun Ns Op : Ns Ar remote_tun .Xc diff --git a/ssh.c b/ssh.c index ee30e2b2..b86a764f 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.330 2010/01/09 23:04:13 dtucker Exp $ */ +/* $OpenBSD: ssh.c,v 1.331 2010/01/11 01:39:46 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -133,6 +133,10 @@ int stdin_null_flag = 0; */ int fork_after_authentication_flag = 0; +/* forward stdio to remote host and port */ +char *stdio_forward_host = NULL; +int stdio_forward_port = 0; + /* * General data structure for command line options and options configurable * in configuration files. See readconf.h. @@ -186,7 +190,8 @@ usage(void) " [-i identity_file] [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" -" [-w local_tun[:remote_tun]] [user@]hostname [command]\n" +" [-W host:port] [-w local_tun[:remote_tun]]\n" +" [user@]hostname [command]\n" ); exit(255); } @@ -276,7 +281,7 @@ main(int ac, char **av) again: while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" - "ACD:F:I:KL:MNO:PR:S:TVw:XYy")) != -1) { + "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -389,6 +394,22 @@ main(int ac, char **av) exit(255); } break; + case 'W': + if (parse_forward(&fwd, optarg, 1, 0)) { + stdio_forward_host = fwd.listen_host; + stdio_forward_port = fwd.listen_port; + xfree(fwd.connect_host); + } else { + fprintf(stderr, + "Bad stdio forwarding specification '%s'\n", + optarg); + exit(255); + } + no_tty_flag = 1; + no_shell_flag = 1; + options.clear_forwardings = 1; + options.exit_on_forward_failure = 1; + break; case 'q': options.log_level = SYSLOG_LEVEL_QUIET; break; @@ -870,12 +891,42 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) } } +static void +client_cleanup_stdio_fwd(int id, void *arg) +{ + debug("stdio forwarding: done"); + cleanup_exit(0); +} + +static int +client_setup_stdio_fwd(const char *host_to_connect, u_short port_to_connect) +{ + Channel *c; + + debug3("client_setup_stdio_fwd %s:%d", host_to_connect, + port_to_connect); + if ((c = channel_connect_stdio_fwd(host_to_connect, port_to_connect)) + == NULL) + return 0; + channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); + return 1; +} + static void ssh_init_forwarding(void) { int success = 0; int i; + if (stdio_forward_host != NULL) { + if (!compat20) { + fatal("stdio forwarding require Protocol 2"); + } + if (!client_setup_stdio_fwd(stdio_forward_host, + stdio_forward_port)) + fatal("Failed to connect in stdio forward mode."); + } + /* Initiate local TCP/IP port forwardings. */ for (i = 0; i < options.num_local_forwards; i++) { debug("Local connections to %.200s:%d forwarded to remote " diff --git a/ssh_config b/ssh_config index f28d5958..18936740 100644 --- a/ssh_config +++ b/ssh_config @@ -1,4 +1,4 @@ -# $OpenBSD: ssh_config,v 1.25 2009/02/17 01:28:32 djm Exp $ +# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for @@ -44,3 +44,4 @@ # TunnelDevice any:any # PermitLocalCommand no # VisualHostKey no +# ProxyCommand ssh -q -W %h:%p gateway.example.com -- 2.45.1