# HG changeset patch # User Matt Johnston # Date 1221662209 0 # Node ID 12d845ab7b5f59663c61187a477f896a08b72cae # Parent d4f32c3443acbb989a4c23cfa1ae517960704a3b Rework netcat-alike to be a proper mode, with -B argument. diff -r d4f32c3443ac -r 12d845ab7b5f chansession.h --- a/chansession.h Sun Sep 14 06:47:51 2008 +0000 +++ b/chansession.h Wed Sep 17 14:36:49 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; diff -r d4f32c3443ac -r 12d845ab7b5f cli-chansession.c --- a/cli-chansession.c Sun Sep 14 06:47:51 2008 +0000 +++ b/cli-chansession.c Wed Sep 17 14:36:49 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,52 +368,60 @@ } return 0; /* Success */ - } -void cli_send_chansess_request() { +#ifdef ENABLE_CLI_NETCAT + +void cli_send_netcat_request() { - unsigned int port = 0; - unsigned char* addr = NULL; - unsigned char* ipstring = "127.0.0.1"; - unsigned char* portstring = "22"; + const unsigned char* source_host = "127.0.0.1"; + const int source_port = 22; - /* hack hack */ - static const struct ChanType cli_chan_tcphack = { + const struct ChanType cli_chan_netcat = { 0, /* sepfds */ "direct-tcpip", - NULL, + cli_init_stdpipe_sess, /* inithandler */ 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); + + /* 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"); } - addr = cli_opts.localfwds->connectaddr; - port = cli_opts.localfwds->connectport; - - buf_putstring(ses.writepayload, addr, strlen(addr)); - buf_putint(ses.writepayload, port); - - /* originator ip */ - buf_putstring(ses.writepayload, ipstring, strlen(ipstring)); - /* originator port */ - buf_putint(ses.writepayload, atol(portstring)); - + /* 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, diff -r d4f32c3443ac -r 12d845ab7b5f cli-runopts.c --- a/cli-runopts.c Sun Sep 14 06:47:51 2008 +0000 +++ b/cli-runopts.c Wed Sep 17 14:36:49 2008 +0000 @@ -33,12 +33,15 @@ 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 @@ #endif "-W (default %d, larger may be faster, max 1MB)\n" "-K (0 is never, default %d)\n" +#ifdef ENABLE_CLI_NETCAT + "-B Netcat-alike bouncing\n" +#endif #ifdef DEBUG_TRACE "-v verbose\n" #endif @@ -87,6 +93,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; @@ -144,6 +153,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]; @@ -199,6 +216,11 @@ 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 @@ #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 @@ } } +#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 @@ /* 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 -r d4f32c3443ac -r 12d845ab7b5f cli-session.c --- a/cli-session.c Sun Sep 14 06:47:51 2008 +0000 +++ b/cli-session.c Wed Sep 17 14:36:49 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) { @@ -230,12 +216,18 @@ } #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")) diff -r d4f32c3443ac -r 12d845ab7b5f dbutil.c --- a/dbutil.c Sun Sep 14 06:47:51 2008 +0000 +++ b/dbutil.c Wed Sep 17 14:36:49 2008 +0000 @@ -146,7 +146,7 @@ } va_start(param, format); - fprintf(stderr, "TRACE: "); + fprintf(stderr, "TRACE (%d): ", getpid()); vfprintf(stderr, format, param); fprintf(stderr, "\n"); va_end(param); diff -r d4f32c3443ac -r 12d845ab7b5f options.h --- a/options.h Sun Sep 14 06:47:51 2008 +0000 +++ b/options.h Wed Sep 17 14:36:49 2008 +0000 @@ -66,6 +66,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 diff -r d4f32c3443ac -r 12d845ab7b5f runopts.h --- a/runopts.h Sun Sep 14 06:47:51 2008 +0000 +++ b/runopts.h Wed Sep 17 14:36:49 2008 +0000 @@ -118,6 +118,11 @@ struct TCPFwdList * localfwds; #endif +#ifdef ENABLE_CLI_NETCAT + char *netcat_host; + unsigned int netcat_port; +#endif + } cli_runopts; extern cli_runopts cli_opts;