[PATCH] Add a ssh_config SetEnv option to override environment variables

Omar Sandoval osandov at osandov.com
Wed Aug 26 17:14:29 AEST 2015


This can be useful when a server is missing the necessary terminfo or
locale and avoids having to manually set TERM or LANG before invoking
ssh every time.

Signed-off-by: Omar Sandoval <osandov at osandov.com>
---

Per Damien Miller's suggestion, here's a generic solution to the problem
of wanting to set environment variables per host because of missing
terminfo on the server. Now, my example from last time could be done as:

Host machine_i_use_alot
	SendEnv TERM

Host machine_without_my_locale
	SetEnv LANG C

Host *
	SetEnv TERM xterm-256color

Thanks!

 readconf.c   | 33 +++++++++++++++++++++++++++++++--
 ssh_config.5 | 10 ++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/readconf.c b/readconf.c
index 1d03bdf72d92..b1cfc8e48a17 100644
--- a/readconf.c
+++ b/readconf.c
@@ -148,7 +148,7 @@ typedef enum {
 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
-	oSendEnv, oControlPath, oControlMaster, oControlPersist,
+	oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
 	oHashKnownHosts,
 	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
 	oVisualHostKey, oUseRoaming,
@@ -251,6 +251,7 @@ static struct {
 	{ "serveraliveinterval", oServerAliveInterval },
 	{ "serveralivecountmax", oServerAliveCountMax },
 	{ "sendenv", oSendEnv },
+	{ "setenv", oSetEnv },
 	{ "controlpath", oControlPath },
 	{ "controlmaster", oControlMaster },
 	{ "controlpersist", oControlPersist },
@@ -749,7 +750,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
 	char **cpptr, fwdarg[256];
 	u_int i, *uintptr, max_entries = 0;
-	int negated, opcode, *intptr, value, value2, cmdline = 0;
+	int negated, opcode, *intptr, value, value2, cmdline = 0, j;
 	LogLevel *log_level_ptr;
 	long long val64;
 	size_t len;
@@ -1294,6 +1295,34 @@ parse_keytypes:
 		}
 		break;
 
+	case oSetEnv:
+		arg = strdelim(&s);
+		if (arg == NULL || *arg == '\0')
+			fatal("%.200s line %d: Missing environment name.",
+			    filename, linenum);
+		arg2 = strdelim(&s);
+		if (arg2 == NULL || *arg2 == '\0')
+			fatal("%.200s line %d: Missing environment value.",
+			    filename, linenum);
+		value = 0;
+		for (j = 0; j < options->num_send_env; j++) {
+			if (match_pattern(arg, options->send_env[j])) {
+				value = 1;
+				break;
+			}
+		}
+		if (*activep && !value) {
+			if (setenv(arg, arg2, 1) != 0)
+				fatal("%.200s line %d: Bad environment: %s",
+				    filename, linenum, strerror(errno));
+			if (options->num_send_env >= MAX_SEND_ENV)
+				fatal("%.200s line %d: too many send env.",
+				    filename, linenum);
+			options->send_env[options->num_send_env++] =
+			    xstrdup(arg);
+		}
+		break;
+
 	case oControlPath:
 		charptr = &options->control_path;
 		goto parse_string;
diff --git a/ssh_config.5 b/ssh_config.5
index a47f3ca9e3e2..0c578bf6d368 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -1444,6 +1444,16 @@ channel to request a response from the server.
 The default
 is 0, indicating that these messages will not be sent to the server.
 This option applies to protocol version 2 only.
+.It Cm SetEnv
+Overwrite a variable in the local
+.Xr environ 7
+and send it as if given in a
+.Cm SendEnv
+directive. An environment variable set by an earlier
+.Cm SetEnv
+directive or matched by an earlier
+.Cm SendEnv
+directive will not be overwritten.
 .It Cm StreamLocalBindMask
 Sets the octal file creation mode mask
 .Pq umask
-- 
2.5.0



More information about the openssh-unix-dev mailing list