]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: add a SetEnv directive to ssh_config that allows setting
authordjm@openbsd.org <djm@openbsd.org>
Sat, 9 Jun 2018 03:01:12 +0000 (03:01 +0000)
committerDamien Miller <djm@mindrot.org>
Sat, 9 Jun 2018 03:11:00 +0000 (13:11 +1000)
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
misc.c
misc.h
mux.c
readconf.c
readconf.h
scp.1
sftp.1
ssh.1
ssh_config.5
sshd_config.5

index 4801f4a773c49736573aa37bb88eef51fd3a8823..247b83979333ccd949f010e7d168556af57922ed 100644 (file)
@@ -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 <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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 3e62320ab62516f76f5f14906bb98a33f6a7d931..1198e70caed449c44fc0078306bcb953f1b25bdd 100644 (file)
--- 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 daa4abc4c601d82b736f7dc0292b68cda69b557a..837b005aacb8c9ce45082dd5480a72ce13ec569e 100644 (file)
--- 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 <ylo@cs.hut.fi>
@@ -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 c591cb154b3d89f75a7d8e10852c0fd049732a4d..8433cd8e5b12785e1b6086490926e541b640229f 100644 (file)
--- 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 <djm@openbsd.org>
  *
@@ -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));
index 733b67f762e01717f1b907c9c9b485d0fe0e167a..8ff23c05c0c4629e4abc69fbb855b3ead879771a 100644 (file)
@@ -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 <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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 */
 
index f4d9e2b2657617747211a116548af31b2e007c86..d8595f07efcced0230b2006c1d52af4cefa03275 100644 (file)
@@ -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 <ylo@cs.hut.fi>
@@ -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 8d251e34a830231cd50d4732b369234957847837..b8886be643ff38cfa18abc585768baaa81a7af9b 100644 (file)
--- 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 43e0442f7bb7197d7459ef5f0bf31fddbc4eb7dc..686844b46f34283e8b44ca582eca030a9b3ab48b 100644 (file)
--- 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 40034463f4815387e7497a390e9c5c7b2f6cb99e..65f4e39669201d19da137d72bdb8c333a03ba3e6 100644 (file)
--- 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
index f6f36c45feb00ccfb43f5cc722c634a5425ccbf7..20a60a2d55991b9be7beb80c24b9e65a0d1a9858 100644 (file)
@@ -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
index 7cf7e63dbbe39690c97efe4e916e22c2174baba1..395f5f6acabfb8b2b7d197bcfe2f9c6cea867764 100644 (file)
@@ -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.