Omar Sandoval
2015-Aug-26 07:14 UTC
[PATCH] Add a ssh_config SetEnv option to override environment variables
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
Peter Stuge
2015-Aug-26 13:50 UTC
[PATCH] Add a ssh_config SetEnv option to override environment variables
Omar Sandoval wrote:> +++ b/readconf.c > @@ -1294,6 +1295,34 @@ parse_keytypes:..> + case oSetEnv:..> + value = 0; > + for (j = 0; j < options->num_send_env; j++) { > + if (match_pattern(arg, options->send_env[j])) { > + value = 1; > + break; > + } > + }Should the above really use pattern matching to compare variable names? //Peter