From 7082bb58a2eb878d23ec674587c742e5e9673c36 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sat, 9 Jun 2018 03:01:12 +0000 Subject: upstream: add a SetEnv directive to ssh_config that allows setting environment variables for the remote session (subject to the server accepting them) refactor SendEnv to remove the arbitrary limit of variable names. ok markus@ OpenBSD-Commit-ID: cfbb00d9b0e10c1ffff1d83424351fd961d1f2be --- clientloop.c | 24 +++++++++++++++++++----- misc.c | 32 ++++++++++++++++++++++++++------ misc.h | 3 ++- mux.c | 10 ++++++---- readconf.c | 34 +++++++++++++++++++++++++++++++--- readconf.h | 7 ++++--- scp.1 | 5 +++-- sftp.1 | 5 +++-- ssh.1 | 5 +++-- ssh_config.5 | 10 ++++++++-- sshd_config.5 | 6 ++++-- 11 files changed, 109 insertions(+), 32 deletions(-) diff --git a/clientloop.c b/clientloop.c index 4801f4a77..247b83979 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.312 2018/04/10 00:10:49 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.313 2018/06/09 03:01:12 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -2158,7 +2158,8 @@ void client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env) { - int len; + int i, j, matched, len; + char *name, *val; Channel *c = NULL; debug2("%s: id %d", __func__, id); @@ -2193,9 +2194,6 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, /* Transfer any environment variables from client to server */ if (options.num_send_env != 0 && env != NULL) { - int i, j, matched; - char *name, *val; - debug("Sending environment."); for (i = 0; env[i] != NULL; i++) { /* Split */ @@ -2227,6 +2225,22 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, free(name); } } + for (i = 0; i < options.num_setenv; i++) { + /* Split */ + name = xstrdup(options.setenv[i]); + if ((val = strchr(name, '=')) == NULL) { + free(name); + continue; + } + *val++ = '\0'; + + debug("Setting env %s = %s", name, val); + channel_request_start(ssh, id, "env", 0); + packet_put_cstring(name); + packet_put_cstring(val); + packet_send(); + free(name); + } len = buffer_len(cmd); if (len > 0) { diff --git a/misc.c b/misc.c index 3e62320ab..1198e70ca 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.128 2018/06/06 18:29:18 markus Exp $ */ +/* $OpenBSD: misc.c,v 1.129 2018/06/09 03:01:12 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -239,8 +239,8 @@ set_rdomain(int fd, const char *name) #define QUOTE "\"" /* return next token in configuration line */ -char * -strdelim(char **s) +static char * +strdelim_internal(char **s, int split_equals) { char *old; int wspace = 0; @@ -250,7 +250,8 @@ strdelim(char **s) old = *s; - *s = strpbrk(*s, WHITESPACE QUOTE "="); + *s = strpbrk(*s, + split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE); if (*s == NULL) return (old); @@ -267,18 +268,37 @@ strdelim(char **s) } /* Allow only one '=' to be skipped */ - if (*s[0] == '=') + if (split_equals && *s[0] == '=') wspace = 1; *s[0] = '\0'; /* Skip any extra whitespace after first token */ *s += strspn(*s + 1, WHITESPACE) + 1; - if (*s[0] == '=' && !wspace) + if (split_equals && *s[0] == '=' && !wspace) *s += strspn(*s + 1, WHITESPACE) + 1; return (old); } +/* + * Return next token in configuration line; splts on whitespace or a + * single '=' character. + */ +char * +strdelim(char **s) +{ + return strdelim_internal(s, 1); +} + +/* + * Return next token in configuration line; splts on whitespace only. + */ +char * +strdelimw(char **s) +{ + return strdelim_internal(s, 0); +} + struct passwd * pwcopy(struct passwd *pw) { diff --git a/misc.h b/misc.h index daa4abc4c..837b005aa 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.72 2018/06/06 18:29:18 markus Exp $ */ +/* $OpenBSD: misc.h,v 1.73 2018/06/09 03:01:12 djm Exp $ */ /* * Author: Tatu Ylonen @@ -45,6 +45,7 @@ struct ForwardOptions { char *chop(char *); char *strdelim(char **); +char *strdelimw(char **); int set_nonblock(int); int unset_nonblock(int); void set_nodelay(int); diff --git a/mux.c b/mux.c index c591cb154..8433cd8e5 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.70 2018/06/06 18:22:41 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.71 2018/06/09 03:01:12 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -1852,9 +1852,9 @@ mux_client_request_session(int fd) { Buffer m; char *e, *term; - u_int i, rid, sid, esid, exitval, type, exitval_seen; + u_int rid, sid, esid, exitval, type, exitval_seen; extern char **environ; - int devnull, rawmode; + int i, devnull, rawmode; debug3("%s: entering", __func__); @@ -1889,14 +1889,16 @@ mux_client_request_session(int fd) buffer_put_cstring(&m, term == NULL ? "" : term); buffer_put_string(&m, buffer_ptr(&command), buffer_len(&command)); + /* Pass environment */ if (options.num_send_env > 0 && environ != NULL) { - /* Pass environment */ for (i = 0; environ[i] != NULL; i++) { if (env_permitted(environ[i])) { buffer_put_cstring(&m, environ[i]); } } } + for (i = 0; i < options.num_setenv; i++) + buffer_put_cstring(&m, options.setenv[i]); if (mux_client_write_packet(fd, &m) != 0) fatal("%s: write packet: %s", __func__, strerror(errno)); diff --git a/readconf.c b/readconf.c index 733b67f76..8ff23c05c 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.289 2018/06/06 18:29:18 markus Exp $ */ +/* $OpenBSD: readconf.c,v 1.290 2018/06/09 03:01:12 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -161,7 +161,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, oRemoteCommand, @@ -277,6 +277,7 @@ static struct { { "serveraliveinterval", oServerAliveInterval }, { "serveralivecountmax", oServerAliveCountMax }, { "sendenv", oSendEnv }, + { "setenv", oSetEnv }, { "controlpath", oControlPath }, { "controlmaster", oControlMaster }, { "controlpersist", oControlPersist }, @@ -1398,15 +1399,38 @@ parse_keytypes: continue; } else { /* Adding an env var */ - if (options->num_send_env >= MAX_SEND_ENV) + if (options->num_send_env >= INT_MAX) fatal("%s line %d: too many send env.", filename, linenum); + options->send_env = xrecallocarray( + options->send_env, options->num_send_env, + options->num_send_env, + sizeof(*options->send_env)); options->send_env[options->num_send_env++] = xstrdup(arg); } } break; + case oSetEnv: + value = options->num_setenv; + while ((arg = strdelimw(&s)) != NULL && *arg != '\0') { + if (strchr(arg, '=') == NULL) + fatal("%s line %d: Invalid SetEnv.", + filename, linenum); + if (!*activep || value != 0) + continue; + /* Adding a setenv var */ + if (options->num_setenv >= INT_MAX) + fatal("%s line %d: too many SetEnv.", + filename, linenum); + options->setenv = xrecallocarray( + options->setenv, options->num_setenv, + options->num_setenv + 1, sizeof(*options->setenv)); + options->setenv[options->num_setenv++] = xstrdup(arg); + } + break; + case oControlPath: charptr = &options->control_path; goto parse_string; @@ -1855,7 +1879,10 @@ initialize_options(Options * options) options->verify_host_key_dns = -1; options->server_alive_interval = -1; options->server_alive_count_max = -1; + options->send_env = NULL; options->num_send_env = 0; + options->setenv = NULL; + options->num_setenv = 0; options->control_path = NULL; options->control_master = -1; options->control_persist = -1; @@ -2606,6 +2633,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); + dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv); /* Special cases */ diff --git a/readconf.h b/readconf.h index f4d9e2b26..d8595f07e 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.125 2018/02/23 02:34:33 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.126 2018/06/09 03:01:12 djm Exp $ */ /* * Author: Tatu Ylonen @@ -18,7 +18,6 @@ /* Data structure for representing option data. */ -#define MAX_SEND_ENV 256 #define SSH_MAX_HOSTS_FILES 32 #define MAX_CANON_DOMAINS 32 #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) @@ -120,7 +119,9 @@ typedef struct { int server_alive_count_max; int num_send_env; - char *send_env[MAX_SEND_ENV]; + char **send_env; + int num_setenv; + char **setenv; char *control_path; int control_master; diff --git a/scp.1 b/scp.1 index 8d251e34a..b8886be64 100644 --- a/scp.1 +++ b/scp.1 @@ -8,9 +8,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.77 2018/02/23 07:38:09 jmc Exp $ +.\" $OpenBSD: scp.1,v 1.78 2018/06/09 03:01:12 djm Exp $ .\" -.Dd $Mdocdate: February 23 2018 $ +.Dd $Mdocdate: June 9 2018 $ .Dt SCP 1 .Os .Sh NAME @@ -171,6 +171,7 @@ For full details of the options listed below, and their possible values, see .It PubkeyAuthentication .It RekeyLimit .It SendEnv +.It SetEnv .It ServerAliveInterval .It ServerAliveCountMax .It StrictHostKeyChecking diff --git a/sftp.1 b/sftp.1 index 43e0442f7..686844b46 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.114 2018/02/23 07:38:09 jmc Exp $ +.\" $OpenBSD: sftp.1,v 1.115 2018/06/09 03:01:12 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: February 23 2018 $ +.Dd $Mdocdate: June 9 2018 $ .Dt SFTP 1 .Os .Sh NAME @@ -241,6 +241,7 @@ For full details of the options listed below, and their possible values, see .It PubkeyAuthentication .It RekeyLimit .It SendEnv +.It SetEnv .It ServerAliveInterval .It ServerAliveCountMax .It StrictHostKeyChecking diff --git a/ssh.1 b/ssh.1 index 40034463f..65f4e3966 100644 --- a/ssh.1 +++ b/ssh.1 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.393 2018/05/11 04:01:11 djm Exp $ -.Dd $Mdocdate: May 11 2018 $ +.\" $OpenBSD: ssh.1,v 1.394 2018/06/09 03:01:12 djm Exp $ +.Dd $Mdocdate: June 9 2018 $ .Dt SSH 1 .Os .Sh NAME @@ -525,6 +525,7 @@ For full details of the options listed below, and their possible values, see .It RemoteForward .It RequestTTY .It SendEnv +.It SetEnv .It ServerAliveInterval .It ServerAliveCountMax .It StreamLocalBindMask diff --git a/ssh_config.5 b/ssh_config.5 index f6f36c45f..20a60a2d5 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.275 2018/06/01 06:23:10 jmc Exp $ -.Dd $Mdocdate: June 1 2018 $ +.\" $OpenBSD: ssh_config.5,v 1.276 2018/06/09 03:01:12 djm Exp $ +.Dd $Mdocdate: June 9 2018 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -1404,6 +1404,12 @@ It is possible to clear previously set variable names by prefixing patterns with .Pa - . The default is not to send any environment variables. +.It Cm SetEnv +Directly specify one or more environment variables and their contents to +be sent to the server. +Similarly to +.Cm SendEnv , +the server must be prepared to accept the environment variable. .It Cm ServerAliveCountMax Sets the number of server alive messages (see below) which may be sent without diff --git a/sshd_config.5 b/sshd_config.5 index 7cf7e63db..395f5f6ac 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.272 2018/06/07 11:26:14 jmc Exp $ -.Dd $Mdocdate: June 7 2018 $ +.\" $OpenBSD: sshd_config.5,v 1.273 2018/06/09 03:01:12 djm Exp $ +.Dd $Mdocdate: June 9 2018 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -66,6 +66,8 @@ the session's .Xr environ 7 . See .Cm SendEnv +and +.Cm SetEnv in .Xr ssh_config 5 for how to configure the client. -- cgit v1.2.3