diff options
author | Matt Johnston <matt@ucc.asn.au> | 2015-12-15 21:30:59 +0800 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2015-12-15 21:30:59 +0800 |
commit | ed21e7523580e5139bd5cedd6dea3cd5cb3f3d98 (patch) | |
tree | 85896c40cae38cb90420b0d7f75d0ca20abb5618 | |
parent | 87d2c9c05ce03bd8dd549218f4a67b6569a34fa5 (diff) | |
parent | 4dc1388ac76eee5af402eb751bcae4e38465a9ed (diff) |
Merge pull request #16 from annulen/openssh_options
Implemented ExitOnForwardFailure option for local and remote forwarding.
-rw-r--r-- | cli-runopts.c | 70 | ||||
-rw-r--r-- | cli-tcpfwd.c | 23 | ||||
-rw-r--r-- | dbclient.1 | 14 | ||||
-rw-r--r-- | runopts.h | 3 |
4 files changed, 107 insertions, 3 deletions
diff --git a/cli-runopts.c b/cli-runopts.c index e8cb313..0522221 100644 --- a/cli-runopts.c +++ b/cli-runopts.c @@ -46,6 +46,7 @@ static void addforward(const char* str, m_list *fwdlist); #ifdef ENABLE_CLI_NETCAT static void add_netcat(const char *str); #endif +static void add_extendedopt(const char *str); static void printhelp() { @@ -64,6 +65,7 @@ static void printhelp() { "-y Always accept remote host key if unknown\n" "-y -y Don't perform any remote host key checking (caution)\n" "-s Request a subsystem (use by external sftp)\n" + "-o option Set option in OpenSSH-like format ('-o help' to list options)\n" #ifdef ENABLE_CLI_PUBKEY_AUTH "-i <identityfile> (multiple allowed, default %s)\n" #endif @@ -106,6 +108,7 @@ void cli_getopts(int argc, char ** argv) { unsigned int i, j; char ** next = 0; enum { + OPT_EXTENDED_OPTIONS, #ifdef ENABLE_CLI_PUBKEY_AUTH OPT_AUTHKEY, #endif @@ -145,6 +148,9 @@ void cli_getopts(int argc, char ** argv) { #ifdef ENABLE_CLI_PUBKEY_AUTH cli_opts.privkeys = list_new(); #endif +#ifdef ENABLE_CLI_ANYTCPFWD + cli_opts.exit_on_fwd_failure = 0; +#endif #ifdef ENABLE_CLI_LOCALTCPFWD cli_opts.localfwds = list_new(); opts.listen_fwd_all = 0; @@ -224,6 +230,9 @@ void cli_getopts(int argc, char ** argv) { case 's': cli_opts.is_subsystem = 1; break; + case 'o': + opt = OPT_EXTENDED_OPTIONS; + break; #ifdef ENABLE_CLI_LOCALTCPFWD case 'L': opt = OPT_LOCALTCPFWD; @@ -301,7 +310,6 @@ void cli_getopts(int argc, char ** argv) { print_version(); exit(EXIT_SUCCESS); break; - case 'o': case 'b': next = &dummy; default: @@ -321,6 +329,11 @@ void cli_getopts(int argc, char ** argv) { dropbear_exit("Missing argument"); } + if (opt == OPT_EXTENDED_OPTIONS) { + TRACE(("opt extended")) + add_extendedopt(&argv[i][j]); + } + else #ifdef ENABLE_CLI_PUBKEY_AUTH if (opt == OPT_AUTHKEY) { TRACE(("opt authkey")) @@ -806,3 +819,58 @@ badport: dropbear_exit("Bad TCP port in '%s'", origstr); } #endif + +static int match_extendedopt(const char** strptr, const char *optname) { + int seen_eq = 0; + int optlen = strlen(optname); + const char *str = *strptr; + + while (isspace(*str)) + ++str; + + if (strncasecmp(str, optname, optlen) != 0) + return DROPBEAR_FAILURE; + + str += optlen; + + while (isspace(*str) || (!seen_eq && *str == '=')) { + if (*str == '=') + seen_eq = 1; + ++str; + } + + *strptr = str; + return DROPBEAR_SUCCESS; +} + +static int parse_flag_value(const char *value) +{ + if (strcmp(value, "yes") == 0 || strcmp(value, "true") == 0) + return 1; + else if (strcmp(value, "no") == 0 || strcmp(value, "false") == 0) + return 0; + + dropbear_exit("Bad yes/no argument '%s'", value); +} + +static void add_extendedopt(const char* origstr) { + const char *optstr = origstr; + + if (strcmp(origstr, "help") == 0) { + dropbear_log(LOG_INFO, "Available options:\n" +#ifdef ENABLE_CLI_ANYTCPFWD + "\tExitOnForwardFailure\n" +#endif + ); + exit(EXIT_SUCCESS); + } + +#ifdef ENABLE_CLI_ANYTCPFWD + if (match_extendedopt(&optstr, "ExitOnForwardFailure") == DROPBEAR_SUCCESS) { + cli_opts.exit_on_fwd_failure = parse_flag_value(optstr); + return; + } +#endif + + dropbear_exit("Bad configuration option '%s'", origstr); +} diff --git a/cli-tcpfwd.c b/cli-tcpfwd.c index ec65f41..4d46b94 100644 --- a/cli-tcpfwd.c +++ b/cli-tcpfwd.c @@ -60,6 +60,22 @@ static const struct ChanType cli_chan_tcplocal = { }; #endif +#ifdef ENABLE_CLI_ANYTCPFWD +static void fwd_failed(const char* format, ...) ATTRIB_PRINTF(1,2); +void fwd_failed(const char* format, ...) +{ + va_list param; + va_start(param, format); + + if (cli_opts.exit_on_fwd_failure) + _dropbear_exit(EXIT_FAILURE, format, param); + else + _dropbear_log(LOG_WARNING, format, param); + + va_end(param); +} +#endif + #ifdef ENABLE_CLI_LOCALTCPFWD void setup_localtcp() { m_list_elem *iter; @@ -75,7 +91,7 @@ void setup_localtcp() { fwd->connectaddr, fwd->connectport); if (ret == DROPBEAR_FAILURE) { - dropbear_log(LOG_WARNING, "Failed local port forward %s:%d:%s:%d", + fwd_failed("Failed local port forward %s:%d:%s:%d", fwd->listenaddr, fwd->listenport, fwd->connectaddr, @@ -181,7 +197,10 @@ void cli_recv_msg_request_failure() { struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item; if (!fwd->have_reply) { fwd->have_reply = 1; - dropbear_log(LOG_WARNING, "Remote TCP forward request failed (port %d -> %s:%d)", fwd->listenport, fwd->connectaddr, fwd->connectport); + fwd_failed("Remote TCP forward request failed (port %d -> %s:%d)", + fwd->listenport, + fwd->connectaddr, + fwd->connectport); return; } } @@ -127,6 +127,20 @@ Specify a comma separated list of ciphers to enable. Use \fI-c help\fR to list p .B \-m \fIMAClist Specify a comma separated list of authentication MACs to enable. Use \fI-m help\fR to list possibilities. .TP +.B \-o \fIoption +Can be used to give options in the format used by OpenSSH config file. This is +useful for specifying options for which there is no separate command-line flag. +For full details of the options listed below, and their possible values, see +ssh_config(5). + +For now only following options have been implemented: +.RS +.RS +.TP +ExitOnForwardFailure +.RE +.RE +.TP .B \-s The specified command will be requested as a subsystem, used for sftp. Dropbear doesn't implement sftp itself but the OpenSSH sftp client can be used eg \fIsftp -S dbclient user@host\fR .TP @@ -140,6 +140,9 @@ typedef struct cli_runopts { #ifdef ENABLE_CLI_PUBKEY_AUTH m_list *privkeys; /* Keys to use for public-key auth */ #endif +#ifdef ENABLE_CLI_ANYTCPFWD + int exit_on_fwd_failure; +#endif #ifdef ENABLE_CLI_REMOTETCPFWD m_list * remotefwds; #endif |