From c7bd9ccd8594c6646285e0df840a40bb9ab00d36 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Wed, 17 Sep 2008 14:35:36 +0000 Subject: [PATCH] Don't capture stderr from spawned processes in proxycommand mode --HG-- extra : convert_revision : 636506b73e973b004cc058b07e6f36a25ff902f8 --- cli-main.c | 4 +--- cli-runopts.c | 10 +--------- dbutil.c | 43 ++++++++++++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/cli-main.c b/cli-main.c index 2d9f1c8..4ba43c0 100644 --- a/cli-main.c +++ b/cli-main.c @@ -134,13 +134,11 @@ static void exec_proxy_cmd(void *user_data_cmd) { static void cli_proxy_cmd(int *sock_in, int *sock_out) { int ret; - int errfd; - pid_t pid; fill_passwd(cli_opts.own_user); ret = spawn_command(exec_proxy_cmd, cli_opts.proxycmd, - sock_out, sock_in, &errfd, &pid); + sock_out, sock_in, NULL, NULL); if (ret == DROPBEAR_FAILURE) { dropbear_exit("Failed running proxy command"); *sock_in = *sock_out = -1; diff --git a/cli-runopts.c b/cli-runopts.c index d0c9f3f..611723c 100644 --- a/cli-runopts.c +++ b/cli-runopts.c @@ -67,7 +67,7 @@ static void printhelp() { "-W (default %d, larger may be faster, max 1MB)\n" "-K (0 is never, default %d)\n" #ifdef ENABLE_CLI_PROXYCMD - "-J Use program rather than tcp connection" + "-J Use program rather than tcp connection\n" #endif #ifdef DEBUG_TRACE "-v verbose\n" @@ -297,14 +297,6 @@ void cli_getopts(int argc, char ** argv) { } } -#ifdef ENABLE_CLI_PROXYCMD - if (cli_opts.proxycmd != NULL) { - /* XXX something more useful */ - cli_opts.remotehost = cli_opts.proxycmd; - cli_opts.remoteport = ""; - } -#endif - if (cli_opts.remotehost == NULL) { printhelp(); exit(EXIT_FAILURE); diff --git a/dbutil.c b/dbutil.c index 2dcae6b..0b32182 100644 --- a/dbutil.c +++ b/dbutil.c @@ -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); @@ -391,7 +391,9 @@ int connect_remote(const char* remotehost, const char* remoteport, /* Sets up a pipe for a, returning three non-blocking file descriptors * and the pid. exec_fn is the function that will actually execute the child process, - * it will be run after the child has fork()ed, and is passed exec_data. */ + * it will be run after the child has fork()ed, and is passed exec_data. + * If ret_errfd == NULL then stderr will not be captured. + * ret_pid can be passed as NULL to discard the pid. */ int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid) { int infds[2]; @@ -403,12 +405,15 @@ int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, const int FDOUT = 1; /* redirect stdin/stdout/stderr */ - if (pipe(infds) != 0) + if (pipe(infds) != 0) { return DROPBEAR_FAILURE; - if (pipe(outfds) != 0) + } + if (pipe(outfds) != 0) { return DROPBEAR_FAILURE; - if (pipe(errfds) != 0) + } + if (ret_errfd && pipe(errfds) != 0) { return DROPBEAR_FAILURE; + } #ifdef __uClinux__ pid = vfork(); @@ -416,8 +421,9 @@ int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, pid = fork(); #endif - if (pid < 0) + if (pid < 0) { return DROPBEAR_FAILURE; + } if (!pid) { /* child */ @@ -432,7 +438,7 @@ int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, if ((dup2(infds[FDIN], STDIN_FILENO) < 0) || (dup2(outfds[FDOUT], STDOUT_FILENO) < 0) || - (dup2(errfds[FDOUT], STDERR_FILENO) < 0)) { + (ret_errfd && dup2(errfds[FDOUT], STDERR_FILENO) < 0)) { TRACE(("leave noptycommand: error redirecting FDs")) dropbear_exit("child dup2() failure"); } @@ -441,8 +447,11 @@ int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, close(infds[FDIN]); close(outfds[FDIN]); close(outfds[FDOUT]); - close(errfds[FDIN]); - close(errfds[FDOUT]); + if (ret_errfd) + { + close(errfds[FDIN]); + close(errfds[FDOUT]); + } exec_fn(exec_data); /* not reached */ @@ -451,16 +460,24 @@ int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, /* parent */ close(infds[FDIN]); close(outfds[FDOUT]); - close(errfds[FDOUT]); - setnonblocking(errfds[FDIN]); setnonblocking(outfds[FDIN]); setnonblocking(infds[FDOUT]); - *ret_pid = pid; + if (ret_errfd) { + close(errfds[FDOUT]); + setnonblocking(errfds[FDIN]); + } + + if (ret_pid) { + *ret_pid = pid; + } + *ret_writefd = infds[FDOUT]; *ret_readfd = outfds[FDIN]; - *ret_errfd = errfds[FDIN]; + if (ret_errfd) { + *ret_errfd = errfds[FDIN]; + } return DROPBEAR_SUCCESS; } }