-/* $OpenBSD: ssh.c,v 1.327 2009/10/24 11:23:42 andreas Exp $ */
+/* $OpenBSD: ssh.c,v 1.332 2010/01/26 01:28:35 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
*/
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.
" [-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);
}
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;
options.gateway_ports = 1;
break;
case 'O':
+ if (stdio_forward_host != NULL)
+ fatal("Cannot specify multiplexing "
+ "command with -W");
+ else if (muxclient_command != 0)
+ fatal("Multiplexing command already specified");
if (strcmp(optarg, "check") == 0)
muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
else if (strcmp(optarg, "exit") == 0)
exit(255);
}
break;
+ case 'W':
+ if (stdio_forward_host != NULL)
+ fatal("stdio forward already specified");
+ if (muxclient_command != 0)
+ fatal("Cannot specify stdio forward with -O");
+ 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;
ac -= optind;
av += optind;
- if (ac > 0 && !host && **av != '-') {
+ if (ac > 0 && !host) {
if (strrchr(*av, '@')) {
p = xstrdup(*av);
cp = strrchr(p, '@');
}
}
+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;
+ int in, out;
+
+ debug3("client_setup_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");
+
+ if ((c = channel_connect_stdio_fwd(host_to_connect, port_to_connect,
+ in, out)) == 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 "