changeset 486:d59f628e7baa

propagate from branch 'au.asn.ucc.matt.dropbear.dbclient-netcat-alike' (head b02ba6628cf2095017c60d202ac630f231e6b553) to branch 'au.asn.ucc.matt.dropbear' (head 636506b73e973b004cc058b07e6f36a25ff902f8)
author Matt Johnston <matt@ucc.asn.au>
date Wed, 17 Sep 2008 14:49:12 +0000
parents effb4a25b1ae (current diff) 12d845ab7b5f (diff)
children 2e17f82a7330
files cli-runopts.c cli-session.c dbutil.c debug.h options.h runopts.h
diffstat 6 files changed, 146 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/chansession.h	Wed Sep 17 14:35:36 2008 +0000
+++ b/chansession.h	Wed Sep 17 14:49:12 2008 +0000
@@ -78,6 +78,9 @@
 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;
--- a/cli-chansession.c	Wed Sep 17 14:35:36 2008 +0000
+++ b/cli-chansession.c	Wed Sep 17 14:49:12 2008 +0000
@@ -338,9 +338,8 @@
 	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,6 +350,12 @@
 	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,12 +368,48 @@
 	}
 
 	return 0; /* Success */
+}
 
+#ifdef ENABLE_CLI_NETCAT
+
+void cli_send_netcat_request() {
+
+	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,
+		cli_closechansess
+	};
+
+	cli_opts.wantpty = 0;
+
+	if (send_msg_channel_open_init(STDIN_FILENO, &cli_chan_netcat) 
+			== DROPBEAR_FAILURE) {
+		dropbear_exit("Couldn't open initial channel");
+	}
+
+	buf_putstring(ses.writepayload, cli_opts.netcat_host, 
+			strlen(cli_opts.netcat_host));
+	buf_putint(ses.writepayload, cli_opts.netcat_port);
+
+	/* originator ip - localhost is accurate enough */
+	buf_putstring(ses.writepayload, source_host, strlen(source_host));
+	buf_putint(ses.writepayload, source_port);
+
+	encrypt_packet();
+	TRACE(("leave cli_send_chansess_request"))
 }
+#endif
 
 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");
@@ -379,3 +420,16 @@
 	TRACE(("leave cli_send_chansess_request"))
 
 }
+
+
+#if 0
+	while (cli_opts.localfwds != NULL) {
+		ret = cli_localtcp(cli_opts.localfwds->listenport,
+				cli_opts.localfwds->connectaddr,
+				cli_opts.localfwds->connectport);
+		if (ret == DROPBEAR_FAILURE) {
+			dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
+					cli_opts.localfwds->listenport,
+					cli_opts.localfwds->connectaddr,
+					cli_opts.localfwds->connectport);
+#endif
--- a/cli-runopts.c	Wed Sep 17 14:35:36 2008 +0000
+++ b/cli-runopts.c	Wed Sep 17 14:49:12 2008 +0000
@@ -33,13 +33,16 @@
 cli_runopts cli_opts; /* GLOBAL */
 
 static void printhelp();
-static void parsehostname(char* userhostarg);
+static void parsehostname(const char* orighostarg);
 static void fill_own_user();
 #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() {
@@ -66,6 +69,9 @@
 #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 ENABLE_CLI_PROXYCMD
 					"-J <proxy_program> Use program rather than tcp connection\n"
 #endif
@@ -91,6 +97,9 @@
 #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;
@@ -153,6 +162,14 @@
 			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];
@@ -208,6 +225,11 @@
 					nextisremote = 1;
 					break;
 #endif
+#ifdef ENABLE_CLI_NETCAT
+				case 'B':
+					nextisnetcat = 1;
+					break;
+#endif
 #ifdef ENABLE_CLI_PROXYCMD
 				case 'J':
 					next = &cli_opts.proxycmd;
@@ -362,12 +384,13 @@
 #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, '@');
@@ -390,6 +413,44 @@
 	}
 }
 
+#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
+
 static void fill_own_user() {
 	uid_t uid;
 	struct passwd *pw = NULL; 
@@ -407,7 +468,7 @@
 #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;
@@ -443,13 +504,13 @@
 
 	/* 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;
--- a/cli-session.c	Wed Sep 17 14:35:36 2008 +0000
+++ b/cli-session.c	Wed Sep 17 14:49:12 2008 +0000
@@ -197,20 +197,6 @@
 			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) {
@@ -235,7 +221,13 @@
 #ifdef ENABLE_CLI_REMOTETCPFWD
 			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"))
--- a/options.h	Wed Sep 17 14:35:36 2008 +0000
+++ b/options.h	Wed Sep 17 14:49:12 2008 +0000
@@ -70,6 +70,10 @@
 /* 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 
--- a/runopts.h	Wed Sep 17 14:35:36 2008 +0000
+++ b/runopts.h	Wed Sep 17 14:49:12 2008 +0000
@@ -118,6 +118,11 @@
 #ifdef ENABLE_CLI_LOCALTCPFWD
 	struct TCPFwdList * localfwds;
 #endif
+
+#ifdef ENABLE_CLI_NETCAT
+	char *netcat_host;
+	unsigned int netcat_port;
+#endif
 #ifdef ENABLE_CLI_PROXYCMD
 	char *proxycmd;
 #endif