summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--chansession.h3
-rw-r--r--cli-chansession.c60
-rw-r--r--cli-runopts.c79
-rw-r--r--cli-session.c22
-rw-r--r--options.h4
-rw-r--r--runopts.h5
6 files changed, 146 insertions, 27 deletions
diff --git a/chansession.h b/chansession.h
index 213c285..4513b1a 100644
--- a/chansession.h
+++ b/chansession.h
@@ -78,6 +78,9 @@ void addnewvar(const char* param, const char* var);
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;
diff --git a/cli-chansession.c b/cli-chansession.c
index c92f902..07b9b9d 100644
--- a/cli-chansession.c
+++ b/cli-chansession.c
@@ -338,9 +338,8 @@ static void send_chansess_shell_req(struct Channel *channel) {
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 @@ static int cli_initchansess(struct Channel *channel) {
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 @@ static int cli_initchansess(struct Channel *channel) {
}
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 @@ void cli_send_chansess_request() {
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
diff --git a/cli-runopts.c b/cli-runopts.c
index 611723c..b97f12e 100644
--- a/cli-runopts.c
+++ b/cli-runopts.c
@@ -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 @@ 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 ENABLE_CLI_PROXYCMD
"-J <proxy_program> Use program rather than tcp connection\n"
#endif
@@ -91,6 +97,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;
@@ -153,6 +162,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];
@@ -208,6 +225,11 @@ void cli_getopts(int argc, char ** argv) {
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 @@ static void loadidentityfile(const char* filename) {
#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 @@ static void parsehostname(char* orighostarg) {
}
}
+#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 @@ static void fill_own_user() {
#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 @@ static void addforward(char* origstr, struct TCPFwdList** fwdlist) {
/* 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;
diff --git a/cli-session.c b/cli-session.c
index 3d9ce98..d0a7361 100644
--- a/cli-session.c
+++ b/cli-session.c
@@ -197,20 +197,6 @@ 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) {
@@ -235,7 +221,13 @@ static void cli_sessionloop() {
#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"))
diff --git a/options.h b/options.h
index 54cfc65..f393c54 100644
--- a/options.h
+++ b/options.h
@@ -70,6 +70,10 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
/* 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
diff --git a/runopts.h b/runopts.h
index 4ec7534..1be82a6 100644
--- a/runopts.h
+++ b/runopts.h
@@ -118,6 +118,11 @@ typedef struct cli_runopts {
#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