From 2157d5235226c0f03ba0440df1fdf7c0548bf9d8 Mon Sep 17 00:00:00 2001
From: Roland Vollgraf <30869947+rvollgraf@users.noreply.github.com>
Date: Thu, 19 Aug 2021 17:13:41 +0200
Subject: [PATCH] pass on sever process environment to child processes (option
 -e) (#118)

---
 dropbear.8        |  5 +++++
 runopts.h         |  2 ++
 svr-chansession.c | 14 ++++++++------
 svr-runopts.c     |  6 ++++++
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/dropbear.8 b/dropbear.8
index 0348e26..ad9f0ee 100644
--- a/dropbear.8
+++ b/dropbear.8
@@ -35,6 +35,11 @@ Don't fork into background.
 .B \-E
 Log to standard error rather than syslog.
 .TP
+.B \-e
+Pass on the server environment to all child processes. This is required, for example,
+if dropbear is launched on the fly from a SLURM workload manager. The enviroment is not
+passed by default. Note that this can be a potential security risk.
+.TP
 .B \-m
 Don't display the message of the day on login.
 .TP
diff --git a/runopts.h b/runopts.h
index 6a4a94c..f2ae8c6 100644
--- a/runopts.h
+++ b/runopts.h
@@ -130,6 +130,8 @@ typedef struct svr_runopts {
         char *pubkey_plugin_options;
 #endif
 
+	int pass_on_env;
+
 } svr_runopts;
 
 extern svr_runopts svr_opts;
diff --git a/svr-chansession.c b/svr-chansession.c
index 65b8b26..5128c4d 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
@@ -943,19 +943,21 @@ static void execchild(const void *user_data) {
 	seedrandom();
 #endif
 
-	/* clear environment */
+	/* clear environment if -e was not set */
 	/* if we're debugging using valgrind etc, we need to keep the LD_PRELOAD
 	 * etc. This is hazardous, so should only be used for debugging. */
+	if ( !svr_opts.pass_on_env) {
 #ifndef DEBUG_VALGRIND
 #ifdef HAVE_CLEARENV
-	clearenv();
+		clearenv();
 #else /* don't HAVE_CLEARENV */
-	/* Yay for posix. */
-	if (environ) {
-		environ[0] = NULL;
-	}
+		/* Yay for posix. */
+		if (environ) {
+			environ[0] = NULL;
+		}
 #endif /* HAVE_CLEARENV */
 #endif /* DEBUG_VALGRIND */
+	}
 
 #if DROPBEAR_SVR_MULTIUSER
 	/* We can only change uid/gid as root ... */
diff --git a/svr-runopts.c b/svr-runopts.c
index 2c905dd..36ea26b 100644
--- a/svr-runopts.c
+++ b/svr-runopts.c
@@ -64,6 +64,7 @@ static void printhelp(const char * progname) {
 					"-R		Create hostkeys as required\n" 
 #endif
 					"-F		Don't fork into background\n"
+					"-e		Pass on server process environment to child process\n"
 #ifdef DISABLE_SYSLOG
 					"(Syslog support not compiled in, using stderr)\n"
 #else
@@ -173,6 +174,7 @@ void svr_getopts(int argc, char ** argv) {
         svr_opts.pubkey_plugin = NULL;
         svr_opts.pubkey_plugin_options = NULL;
 #endif
+	svr_opts.pass_on_env = 0;
 
 #ifndef DISABLE_ZLIB
 	opts.compress_mode = DROPBEAR_COMPRESS_DELAYED;
@@ -223,6 +225,10 @@ void svr_getopts(int argc, char ** argv) {
 					opts.usingsyslog = 0;
 					break;
 #endif
+				case 'e':
+					svr_opts.pass_on_env = 1;
+					break;
+
 #if DROPBEAR_SVR_LOCALTCPFWD
 				case 'j':
 					svr_opts.nolocaltcp = 1;