
    Add '-Y proxyhost:proxyport' option to ease local VM user nets
---
 cli-main.c    | 14 ++++++++++++--
 cli-runopts.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 dbclient.1    |  6 ++++++
 runopts.h     |  3 ++-
 4 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/cli-main.c b/cli-main.c
index 3db8f2f..84979d9 100644
--- a/cli-main.c
+++ b/cli-main.c
@@ -72,8 +72,18 @@ int main(int argc, char ** argv) {
 	} else
 #endif
 	{
-		int sock = connect_remote(cli_opts.remotehost, cli_opts.remoteport, 
-				0, &error);
+		int sock;
+		char *h, *p;
+
+		if (cli_opts.proxy_host) {
+			h = cli_opts.proxy_host;
+			p = cli_opts.proxy_port;
+		} else {
+			h = cli_opts.remotehost;
+			p = cli_opts.remoteport;
+		}
+
+		sock = connect_remote(h, p, 0, &error);
 		sock_in = sock_out = sock;
 	 	if (cli_opts.wantpty) {
 			set_sock_priority(sock, DROPBEAR_PRIO_LOWDELAY);
diff --git a/cli-runopts.c b/cli-runopts.c
index 9877740..53a16d9 100644
--- a/cli-runopts.c
+++ b/cli-runopts.c
@@ -43,6 +43,7 @@ static void loadidentityfile(const char* filename);
 #ifdef ENABLE_CLI_ANYTCPFWD
 static void addforward(const char* str, m_list *fwdlist);
 #endif
+static void add_proxy(const char *str);
 #ifdef ENABLE_CLI_NETCAT
 static void add_netcat(const char *str);
 #endif
@@ -83,6 +84,7 @@ static void printhelp() {
 #ifdef ENABLE_CLI_NETCAT
 					"-B <endhost:endport> Netcat-alike forwarding\n"
 #endif				
+					"-Y <proxyhost:proxyport> Use proxy socket rather than direct TCP connection\n"
 #ifdef ENABLE_CLI_PROXYCMD
 					"-J <proxy_program> Use program pipe rather than TCP connection\n"
 #endif
@@ -114,6 +116,7 @@ void cli_getopts(int argc, char ** argv) {
 #ifdef ENABLE_CLI_NETCAT
 	int nextisnetcat = 0;
 #endif
+	int nextisproxy = 0;
 	char* dummy = NULL; /* Not used for anything real */
 
 	char* recv_window_arg = NULL;
@@ -148,6 +151,8 @@ void cli_getopts(int argc, char ** argv) {
 	cli_opts.agent_fd = -1;
 	cli_opts.agent_keys_loaded = 0;
 #endif
+	cli_opts.proxy_host = NULL;
+	cli_opts.proxy_port = NULL;
 #ifdef ENABLE_CLI_PROXYCMD
 	cli_opts.proxycmd = NULL;
 #endif
@@ -200,6 +205,12 @@ void cli_getopts(int argc, char ** argv) {
 			continue;
 		}
 #endif
+		if (nextisproxy) {
+			TRACE(("nextisproxy true"))
+			add_proxy(argv[i]);
+			nextisproxy = 0;
+			continue;
+		}
 		if (next) {
 			/* The previous flag set a value to assign */
 			*next = argv[i];
@@ -267,6 +278,9 @@ void cli_getopts(int argc, char ** argv) {
 					nextisnetcat = 1;
 					break;
 #endif
+				case 'Y':
+					nextisproxy = 1;
+					break;
 #ifdef ENABLE_CLI_PROXYCMD
 				case 'J':
 					next = &cli_opts.proxycmd;
@@ -632,6 +646,45 @@ static void parse_hostname(const char* orighostarg) {
 	}
 }
 
+static void add_proxy(const char* origstr) {
+	unsigned int port;
+	char *portstr, *str;
+
+	str = m_strdup(origstr);
+
+	portstr = strchr(str, ':');
+	if (portstr == NULL) {
+		portstr = str;
+		str = m_strdup("localhost");
+	} else {
+		*portstr = '\0';
+		++portstr;
+		portstr = m_strdup(portstr);
+
+		if (strchr(portstr, ':')) {
+			TRACE(("Multiple proxy colons"))
+			goto fail;
+		}
+	}
+
+	if (m_str_to_uint(portstr, &port) == DROPBEAR_FAILURE) {
+		TRACE(("bad proxy port"))
+		goto fail;
+	}
+
+	if (port > 65535) {
+		TRACE(("too large proxy port"))
+		goto fail;
+	}
+
+	cli_opts.proxy_host = str;
+	cli_opts.proxy_port = portstr;
+	return;
+
+fail:
+	dropbear_exit("Bad proxy endpoint '%s'", origstr);
+}
+
 #ifdef ENABLE_CLI_NETCAT
 static void add_netcat(const char* origstr) {
 	char *portstr = NULL;
diff --git a/dbclient.1 b/dbclient.1
index 4839982..a3d5fbc 100644
--- a/dbclient.1
+++ b/dbclient.1
@@ -108,6 +108,12 @@ Use the standard input/output of the program \fIproxy_command\fR rather than usi
 a normal TCP connection. A hostname should be still be provided, as this is used for
 comparing saved hostkeys.
 .TP
+.B \-Y \fI[proxyhost:]proxyport
+Create a network connection to \fI[proxyhost:]proxyport\fR and use that as
+standard input/output. If \fIproxyhost\fR is omitted, \fIlocalhost\fR is
+used.  A hostname should be still be provided, as this is used for
+comparing saved hostkeys.
+.TP
 .B \-B \fIendhost:endport
 "Netcat-alike" mode, where Dropbear will connect to the given host, then create a
 forwarded connection to \fIendhost\fR. This will then be presented as dbclient's
diff --git a/runopts.h b/runopts.h
index 21fc8e5..c72f009 100644
--- a/runopts.h
+++ b/runopts.h
@@ -147,11 +147,12 @@ typedef struct cli_runopts {
 	int agent_fd; /* The agent fd is only set during authentication. Forwarded
 	                 agent sessions have their own file descriptors */
 #endif
-
 #ifdef ENABLE_CLI_NETCAT
 	char *netcat_host;
 	unsigned int netcat_port;
 #endif
+	char *proxy_host;
+	char *proxy_port;
 #ifdef ENABLE_CLI_PROXYCMD
 	char *proxycmd;
 #endif
