The unified diff between revisions [22bbe895..] and [b02ba662..] is displayed below. It can also be downloaded as a raw diff.

#
#
# patch "chansession.h"
#  from [c9c4cc35dbe6c70d3ee6987b1c4dc8a79d5adcae]
#    to [9bb4ad4cd198dbcedf4389aba67135c58acdc0b4]
#
# patch "cli-chansession.c"
#  from [ef81672b45f5f564130f3cdd8e409631cceaf551]
#    to [1f0824bd1ac6cf957bd31aebbd82b50027aef995]
#
# patch "cli-runopts.c"
#  from [1f8cf84cdb17a77e4c71c1b8fa01aa00fb728948]
#    to [b02f7082ddf80d835eeaebf3526a52b146bfa983]
#
# patch "cli-session.c"
#  from [c9e6299dbe5501909a11c40155d5c3537b3ecff8]
#    to [846e9b4e9cbbfad4d5c6d2e2c518fffb97b1a4a0]
#
# patch "dbutil.c"
#  from [d69f7460629fd3d9a94d82f9f5f42198a5a8509e]
#    to [c01c408da0a9cd280559a07bb62cf805a381c482]
#
# patch "options.h"
#  from [5dca66ee7b6a373441fc45b1c070b42608eb17c7]
#    to [364c4e925626c3099e24a06db21576c203553428]
#
# patch "runopts.h"
#  from [28d3dc401244b14fa52cd842c39ee9f6fe3873ba]
#    to [3b87a3d81e378ada9413510f74bad1ea8e0720b9]
#
============================================================
--- chansession.h	c9c4cc35dbe6c70d3ee6987b1c4dc8a79d5adcae
+++ chansession.h	9bb4ad4cd198dbcedf4389aba67135c58acdc0b4
@@ -78,6 +78,9 @@ void cli_chansess_winchange();
 void cli_send_chansess_request();
 void cli_tty_cleanup();
 void cli_chansess_winchange();
+#ifdef ENABLE_CLI_NETCAT
+void cli_send_netcat_request();
+#endif

 void svr_chansessinitialise();
 extern const struct ChanType svrchansess;
============================================================
--- cli-chansession.c	ef81672b45f5f564130f3cdd8e409631cceaf551
+++ cli-chansession.c	1f0824bd1ac6cf957bd31aebbd82b50027aef995
@@ -338,9 +338,8 @@ static void send_chansess_shell_req(stru
 	TRACE(("leave send_chansess_shell_req"))
 }

-static int cli_initchansess(struct Channel *channel) {
-
-
+/* Shared for normal client channel and netcat-alike */
+static int cli_init_stdpipe_sess(struct Channel *channel) {
 	channel->writefd = STDOUT_FILENO;
 	setnonblocking(STDOUT_FILENO);

@@ -351,7 +350,13 @@ static int cli_initchansess(struct Chann
 	setnonblocking(STDERR_FILENO);

 	channel->extrabuf = cbuf_new(opts.recv_window);
+	return 0;
+}

+static int cli_initchansess(struct Channel *channel) {
+
+	cli_init_stdpipe_sess(channel);
+
 	if (cli_opts.wantpty) {
 		send_chansess_pty_req(channel);
 	}
@@ -363,52 +368,60 @@ static int cli_initchansess(struct Chann
 	}

 	return 0; /* Success */
-
 }

-void cli_send_chansess_request() {
+#ifdef ENABLE_CLI_NETCAT

-	unsigned int port = 0;
-	unsigned char* addr = NULL;
-	unsigned char* ipstring = "127.0.0.1";
-	unsigned char* portstring = "22";
+void cli_send_netcat_request() {

-	/* hack hack */
-	static const struct ChanType cli_chan_tcphack = {
+	const unsigned char* source_host = "127.0.0.1";
+	const int source_port = 22;
+
+	const struct ChanType cli_chan_netcat = {
 		0, /* sepfds */
 		"direct-tcpip",
+		cli_init_stdpipe_sess, /* inithandler */
 		NULL,
 		NULL,
-		NULL,
 		cli_closechansess
 	};

-	TRACE(("enter cli_send_chansess_request"))
-	if (send_msg_channel_open_init(STDIN_FILENO, &cli_chan_tcphack)
+	cli_opts.wantpty = 0;
+
+	if (send_msg_channel_open_init(STDIN_FILENO, &cli_chan_netcat)
 			== DROPBEAR_FAILURE) {
 		dropbear_exit("Couldn't open initial channel");
 	}

-	if (cli_opts.localfwds == NULL) {
-		dropbear_exit("You need to give a \"-L ignored:host:port\" option with this hacked up dbclient.");
-	}
+	buf_putstring(ses.writepayload, cli_opts.netcat_host,
+			strlen(cli_opts.netcat_host));
+	buf_putint(ses.writepayload, cli_opts.netcat_port);

-	addr = cli_opts.localfwds->connectaddr;
-	port = cli_opts.localfwds->connectport;
+	/* originator ip - localhost is accurate enough */
+	buf_putstring(ses.writepayload, source_host, strlen(source_host));
+	buf_putint(ses.writepayload, source_port);

-	buf_putstring(ses.writepayload, addr, strlen(addr));
-	buf_putint(ses.writepayload, port);
+	encrypt_packet();
+	TRACE(("leave cli_send_chansess_request"))
+}
+#endif

-	/* originator ip */
-	buf_putstring(ses.writepayload, ipstring, strlen(ipstring));
-	/* originator port */
-	buf_putint(ses.writepayload, atol(portstring));
+void cli_send_chansess_request() {

+	TRACE(("enter cli_send_chansess_request"))
+
+	if (send_msg_channel_open_init(STDIN_FILENO, &clichansess)
+			== DROPBEAR_FAILURE) {
+		dropbear_exit("Couldn't open initial channel");
+	}
+
+	/* No special channel request data */
 	encrypt_packet();
 	TRACE(("leave cli_send_chansess_request"))

 }

+
 #if 0
 	while (cli_opts.localfwds != NULL) {
 		ret = cli_localtcp(cli_opts.localfwds->listenport,
============================================================
--- cli-runopts.c	1f8cf84cdb17a77e4c71c1b8fa01aa00fb728948
+++ cli-runopts.c	b02f7082ddf80d835eeaebf3526a52b146bfa983
@@ -33,13 +33,16 @@ static void printhelp();
 cli_runopts cli_opts; /* GLOBAL */

 static void printhelp();
-static void parsehostname(char* userhostarg);
+static void parsehostname(const char* orighostarg);
 #ifdef ENABLE_CLI_PUBKEY_AUTH
 static void loadidentityfile(const char* filename);
 #endif
 #ifdef ENABLE_CLI_ANYTCPFWD
-static void addforward(char* str, struct TCPFwdList** fwdlist);
+static void addforward(const char* str, struct TCPFwdList** fwdlist);
 #endif
+#ifdef ENABLE_CLI_NETCAT
+static void add_netcat(const char *str);
+#endif

 static void printhelp() {

@@ -65,6 +68,9 @@ static void printhelp() {
 #endif
 					"-W <receive_window_buffer> (default %d, larger may be faster, max 1MB)\n"
 					"-K <keepalive>  (0 is never, default %d)\n"
+#ifdef ENABLE_CLI_NETCAT
+					"-B <endhost:endport> Netcat-alike bouncing\n"
+#endif
 #ifdef DEBUG_TRACE
 					"-v    verbose\n"
 #endif
@@ -87,6 +93,9 @@ void cli_getopts(int argc, char ** argv)
 #ifdef ENABLE_CLI_REMOTETCPFWD
 	int nextisremote = 0;
 #endif
+#ifdef ENABLE_CLI_NETCAT
+	int nextisnetcat = 0;
+#endif
 	char* dummy = NULL; /* Not used for anything real */

 	char* recv_window_arg = NULL;
@@ -144,6 +153,14 @@ void cli_getopts(int argc, char ** argv)
 			continue;
 		}
 #endif
+#ifdef ENABLE_CLI_NETCAT
+		if (nextisnetcat) {
+			TRACE(("nextisnetcat true"))
+			add_netcat(argv[i]);
+			nextisnetcat = 0;
+			continue;
+		}
+#endif
 		if (next) {
 			/* The previous flag set a value to assign */
 			*next = argv[i];
@@ -199,6 +216,11 @@ void cli_getopts(int argc, char ** argv)
 					nextisremote = 1;
 					break;
 #endif
+#ifdef ENABLE_CLI_NETCAT
+				case 'B':
+					nextisnetcat = 1;
+					break;
+#endif
 				case 'l':
 					next = &cli_opts.username;
 					break;
@@ -351,15 +373,13 @@ static void loadidentityfile(const char*
 #endif


-/* Parses a [user@]hostname argument. userhostarg is the argv[i] corresponding
- * - note that it will be modified */
-static void parsehostname(char* orighostarg) {
+/* Parses a [user@]hostname argument. orighostarg is the argv[i] corresponding */
+static void parsehostname(const char* orighostarg) {

 	uid_t uid;
 	struct passwd *pw = NULL;
 	char *userhostarg = NULL;

-	/* We probably don't want to be editing argvs */
 	userhostarg = m_strdup(orighostarg);

 	cli_opts.remotehost = strchr(userhostarg, '@');
@@ -389,10 +409,48 @@ static void parsehostname(char* orighost
 	}
 }

+#ifdef ENABLE_CLI_NETCAT
+static void add_netcat(const char* origstr) {
+	char *portstr = NULL;
+
+	char * str = m_strdup(origstr);
+
+	portstr = strchr(str, ':');
+	if (portstr == NULL) {
+		TRACE(("No netcat port"))
+		goto fail;
+	}
+	*portstr = '\0';
+	portstr++;
+
+	if (strchr(portstr, ':')) {
+		TRACE(("Multiple netcat colons"))
+		goto fail;
+	}
+
+	cli_opts.netcat_port = strtoul(portstr, NULL, 10);
+	if (errno != 0) {
+		TRACE(("bad netcat port"))
+		goto fail;
+	}
+
+	if (cli_opts.netcat_port > 65535) {
+		TRACE(("too large netcat port"))
+		goto fail;
+	}
+
+	cli_opts.netcat_host = str;
+	return;
+
+fail:
+	dropbear_exit("Bad netcat endpoint '%s'", origstr);
+}
+#endif
+
 #ifdef ENABLE_CLI_ANYTCPFWD
 /* Turn a "listenport:remoteaddr:remoteport" string into into a forwarding
  * set, and add it to the forwarding list */
-static void addforward(char* origstr, struct TCPFwdList** fwdlist) {
+static void addforward(const char* origstr, struct TCPFwdList** fwdlist) {

 	char * listenport = NULL;
 	char * connectport = NULL;
@@ -428,13 +486,13 @@ static void addforward(char* origstr, st

 	/* Now we check the ports - note that the port ints are unsigned,
 	 * the check later only checks for >= MAX_PORT */
-	newfwd->listenport = strtol(listenport, NULL, 10);
+	newfwd->listenport = strtoul(listenport, NULL, 10);
 	if (errno != 0) {
 		TRACE(("bad listenport strtol"))
 		goto fail;
 	}

-	newfwd->connectport = strtol(connectport, NULL, 10);
+	newfwd->connectport = strtoul(connectport, NULL, 10);
 	if (errno != 0) {
 		TRACE(("bad connectport strtol"))
 		goto fail;
============================================================
--- cli-session.c	c9e6299dbe5501909a11c40155d5c3537b3ecff8
+++ cli-session.c	846e9b4e9cbbfad4d5c6d2e2c518fffb97b1a4a0
@@ -197,22 +197,8 @@ static void cli_sessionloop() {
 			TRACE(("leave cli_sessionloop: cli_auth_try"))
 			return;

-			/*
 		case USERAUTH_SUCCESS_RCVD:
-			send_msg_service_request(SSH_SERVICE_CONNECTION);
-			cli_ses.state = SERVICE_CONN_REQ_SENT;
-			TRACE(("leave cli_sessionloop: sent ssh-connection service req"))
-			return;

-		case SERVICE_CONN_ACCEPT_RCVD:
-			cli_send_chansess_request();
-			TRACE(("leave cli_sessionloop: cli_send_chansess_request"))
-			cli_ses.state = SESSION_RUNNING;
-			return;
-			*/
-
-		case USERAUTH_SUCCESS_RCVD:
-
 			if (cli_opts.backgrounded) {
 				int devnull;
 				/* keeping stdin open steals input from the terminal and
@@ -230,12 +216,18 @@ static void cli_sessionloop() {
 			}

 #ifdef ENABLE_CLI_LOCALTCPFWD
-			//setup_localtcp();
+			setup_localtcp();
 #endif
 #ifdef ENABLE_CLI_REMOTETCPFWD
-			//setup_remotetcp();
+			setup_remotetcp();
 #endif
-			if (!cli_opts.no_cmd) {
+
+#ifdef ENABLE_CLI_NETCAT
+			if (cli_opts.netcat_host) {
+				cli_send_netcat_request();
+			} else
+#endif
+				if (!cli_opts.no_cmd) {
 				cli_send_chansess_request();
 			}
 			TRACE(("leave cli_sessionloop: running"))
============================================================
--- dbutil.c	d69f7460629fd3d9a94d82f9f5f42198a5a8509e
+++ dbutil.c	c01c408da0a9cd280559a07bb62cf805a381c482
@@ -146,7 +146,7 @@ void dropbear_trace(const char* format,
 	}

 	va_start(param, format);
-	fprintf(stderr, "TRACE: ");
+	fprintf(stderr, "TRACE (%d): ", getpid());
 	vfprintf(stderr, format, param);
 	fprintf(stderr, "\n");
 	va_end(param);
============================================================
--- options.h	5dca66ee7b6a373441fc45b1c070b42608eb17c7
+++ options.h	364c4e925626c3099e24a06db21576c203553428
@@ -66,6 +66,10 @@ etc) slower (perhaps by 50%). Recommende
 /* Enable Authentication Agent Forwarding - server only for now */
 #define ENABLE_AGENTFWD

+/* Enable "Netcat mode". TODO describe here. */
+#define ENABLE_CLI_NETCAT
+
+
 /* Encryption - at least one required.
  * RFC Draft requires 3DES and recommends AES128 for interoperability.
  * Including multiple keysize variants the same cipher
============================================================
--- runopts.h	28d3dc401244b14fa52cd842c39ee9f6fe3873ba
+++ runopts.h	3b87a3d81e378ada9413510f74bad1ea8e0720b9
@@ -118,6 +118,11 @@ typedef struct cli_runopts {
 	struct TCPFwdList * localfwds;
 #endif

+#ifdef ENABLE_CLI_NETCAT
+	char *netcat_host;
+	unsigned int netcat_port;
+#endif
+
 } cli_runopts;

 extern cli_runopts cli_opts;