changeset 484:effb4a25b1ae

Don't capture stderr from spawned processes in proxycommand mode
author Matt Johnston <matt@ucc.asn.au>
date Wed, 17 Sep 2008 14:35:36 +0000 (2008-09-17)
parents 738313e73b1c
children d59f628e7baa
files cli-main.c cli-runopts.c dbutil.c
diffstat 3 files changed, 33 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/cli-main.c	Mon Sep 15 14:40:30 2008 +0000
+++ b/cli-main.c	Wed Sep 17 14:35:36 2008 +0000
@@ -134,13 +134,11 @@
 
 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;
--- a/cli-runopts.c	Mon Sep 15 14:40:30 2008 +0000
+++ b/cli-runopts.c	Wed Sep 17 14:35:36 2008 +0000
@@ -67,7 +67,7 @@
 					"-W <receive_window_buffer> (default %d, larger may be faster, max 1MB)\n"
 					"-K <keepalive>  (0 is never, default %d)\n"
 #ifdef ENABLE_CLI_PROXYCMD
-					"-J <proxy_program> Use program rather than tcp connection"
+					"-J <proxy_program> Use program rather than tcp connection\n"
 #endif
 #ifdef DEBUG_TRACE
 					"-v    verbose\n"
@@ -297,14 +297,6 @@
 		}
 	}
 
-#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);
--- a/dbutil.c	Mon Sep 15 14:40:30 2008 +0000
+++ b/dbutil.c	Wed Sep 17 14:35:36 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);
@@ -391,7 +391,9 @@
 
 /* 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 @@
 	const int FDOUT = 1;
 
 	/* redirect stdin/stdout/stderr */
-	if (pipe(infds) != 0)
+	if (pipe(infds) != 0) {
+		return DROPBEAR_FAILURE;
+	}
+	if (pipe(outfds) != 0) {
 		return DROPBEAR_FAILURE;
-	if (pipe(outfds) != 0)
+	}
+	if (ret_errfd && pipe(errfds) != 0) {
 		return DROPBEAR_FAILURE;
-	if (pipe(errfds) != 0)
-		return DROPBEAR_FAILURE;
+	}
 
 #ifdef __uClinux__
 	pid = vfork();
@@ -416,8 +421,9 @@
 	pid = fork();
 #endif
 
-	if (pid < 0)
+	if (pid < 0) {
 		return DROPBEAR_FAILURE;
+	}
 
 	if (!pid) {
 		/* child */
@@ -432,7 +438,7 @@
 
 		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 @@
 		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 @@
 		/* 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;
 	}
 }