diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2004-04-27 09:46:38 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2004-04-27 09:46:38 +0000 |
commit | 958dcf038c05f370c9077b63a2f717585f316329 (patch) | |
tree | 1409d35ece6efe3f7ad7feb01c719dfdbe1c5053 /usr.bin/ssh | |
parent | fbf3c3831531c2558d4064afd5c471f35777b62c (diff) |
bz #815: implement ability to pass specified environment variables from the
client to the server; ok markus@
Diffstat (limited to 'usr.bin/ssh')
-rw-r--r-- | usr.bin/ssh/readconf.c | 18 | ||||
-rw-r--r-- | usr.bin/ssh/readconf.h | 7 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.c | 19 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.h | 6 | ||||
-rw-r--r-- | usr.bin/ssh/session.c | 52 | ||||
-rw-r--r-- | usr.bin/ssh/session.h | 7 | ||||
-rw-r--r-- | usr.bin/ssh/ssh.c | 41 | ||||
-rw-r--r-- | usr.bin/ssh/ssh_config.5 | 23 | ||||
-rw-r--r-- | usr.bin/ssh/sshd_config.5 | 25 |
9 files changed, 188 insertions, 10 deletions
diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c index a981223b990..0dd37c573d7 100644 --- a/usr.bin/ssh/readconf.c +++ b/usr.bin/ssh/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.129 2004/04/18 23:10:26 djm Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.130 2004/04/27 09:46:36 djm Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -106,6 +106,7 @@ typedef enum { oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, + oSendEnv, oDeprecated, oUnsupported } OpCodes; @@ -193,6 +194,7 @@ static struct { { "addressfamily", oAddressFamily }, { "serveraliveinterval", oServerAliveInterval }, { "serveralivecountmax", oServerAliveCountMax }, + { "sendenv", oSendEnv }, { NULL, oBadOption } }; @@ -747,6 +749,19 @@ parse_int: intptr = &options->server_alive_count_max; goto parse_int; + case oSendEnv: + while ((arg = strdelim(&s)) != NULL && *arg != '\0') { + if (strchr(arg, '=') != NULL) + fatal("%s line %d: Invalid environment name.", + filename, linenum); + if (options->num_send_env >= MAX_SEND_ENV) + fatal("%s line %d: too many send env.", + filename, linenum); + options->send_env[options->num_send_env++] = + xstrdup(arg); + } + break; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -892,6 +907,7 @@ initialize_options(Options * options) options->verify_host_key_dns = -1; options->server_alive_interval = -1; options->server_alive_count_max = -1; + options->num_send_env = 0; } /* diff --git a/usr.bin/ssh/readconf.h b/usr.bin/ssh/readconf.h index 9d70fee6738..6680559433f 100644 --- a/usr.bin/ssh/readconf.h +++ b/usr.bin/ssh/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.61 2004/04/18 23:10:26 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.62 2004/04/27 09:46:37 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -27,6 +27,8 @@ typedef struct { } Forward; /* Data structure for representing option data. */ +#define MAX_SEND_ENV 256 + typedef struct { int forward_agent; /* Forward authentication agent. */ int forward_x11; /* Forward X11 display. */ @@ -103,6 +105,9 @@ typedef struct { int identities_only; int server_alive_interval; int server_alive_count_max; + + int num_send_env; + char *send_env[MAX_SEND_ENV]; } Options; diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c index 2a9ed382a67..0ad5fd2eb8d 100644 --- a/usr.bin/ssh/servconf.c +++ b/usr.bin/ssh/servconf.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.130 2003/12/23 16:12:10 jakob Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.131 2004/04/27 09:46:37 djm Exp $"); #include "ssh.h" #include "log.h" @@ -96,6 +96,7 @@ initialize_server_options(ServerOptions *options) options->client_alive_count_max = -1; options->authorized_keys_file = NULL; options->authorized_keys_file2 = NULL; + options->num_accept_env = 0; /* Needs to be accessable in many places */ use_privsep = -1; @@ -243,7 +244,7 @@ typedef enum { sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, - sGssAuthentication, sGssCleanupCreds, + sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sUsePrivilegeSeparation, sDeprecated, sUnsupported } ServerOpCodes; @@ -331,6 +332,7 @@ static struct { { "authorizedkeysfile", sAuthorizedKeysFile }, { "authorizedkeysfile2", sAuthorizedKeysFile2 }, { "useprivilegeseparation", sUsePrivilegeSeparation}, + { "acceptenv", sAcceptEnv }, { NULL, sBadOption } }; @@ -851,6 +853,19 @@ parse_flag: intptr = &options->client_alive_count_max; goto parse_int; + case sAcceptEnv: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (strchr(arg, '=') != NULL) + fatal("%s line %d: Invalid environment name.", + filename, linenum); + if (options->num_accept_env >= MAX_ACCEPT_ENV) + fatal("%s line %d: too many allow env.", + filename, linenum); + options->accept_env[options->num_accept_env++] = + xstrdup(arg); + } + break; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); diff --git a/usr.bin/ssh/servconf.h b/usr.bin/ssh/servconf.h index 0b32b38f105..1a828243a94 100644 --- a/usr.bin/ssh/servconf.h +++ b/usr.bin/ssh/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.67 2003/12/23 16:12:10 jakob Exp $ */ +/* $OpenBSD: servconf.h,v 1.68 2004/04/27 09:46:37 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -24,6 +24,7 @@ #define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ #define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ #define MAX_HOSTKEYS 256 /* Max # hostkeys. */ +#define MAX_ACCEPT_ENV 256 /* Max # of env vars. */ /* permit_root_login */ #define PERMIT_NOT_SET -1 @@ -107,6 +108,9 @@ typedef struct { char *subsystem_name[MAX_SUBSYSTEMS]; char *subsystem_command[MAX_SUBSYSTEMS]; + u_int num_accept_env; + char *accept_env[MAX_ACCEPT_ENV]; + int max_startups_begin; int max_startups_rate; int max_startups; diff --git a/usr.bin/ssh/session.c b/usr.bin/ssh/session.c index ab425aed95f..bbe37812bb1 100644 --- a/usr.bin/ssh/session.c +++ b/usr.bin/ssh/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.172 2004/01/30 09:48:57 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.173 2004/04/27 09:46:37 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -42,6 +42,7 @@ RCSID("$OpenBSD: session.c,v 1.172 2004/01/30 09:48:57 markus Exp $"); #include "sshpty.h" #include "packet.h" #include "buffer.h" +#include "match.h" #include "mpaux.h" #include "uidswap.h" #include "compat.h" @@ -793,6 +794,10 @@ do_setup_env(Session *s, const char *shell) if (!options.use_login) { /* Set basic environment. */ + for (i = 0; i < s->num_env; i++) + child_set_env(&env, &envsize, s->env[i].name, + s->env[i].val); + child_set_env(&env, &envsize, "USER", pw->pw_name); child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); child_set_env(&env, &envsize, "HOME", pw->pw_dir); @@ -1514,6 +1519,41 @@ session_break_req(Session *s) } static int +session_env_req(Session *s) +{ + char *name, *val; + u_int name_len, val_len, i; + + name = packet_get_string(&name_len); + val = packet_get_string(&val_len); + packet_check_eom(); + + /* Don't set too many environment variables */ + if (s->num_env > 128) { + debug2("Ignoring env request %s: too many env vars", name); + goto fail; + } + + for (i = 0; i < options.num_accept_env; i++) { + if (match_pattern(name, options.accept_env[i])) { + debug2("Setting env %d: %s=%s", s->num_env, name, val); + s->env = xrealloc(s->env, sizeof(*s->env) * + (s->num_env + 1)); + s->env[s->num_env].name = name; + s->env[s->num_env].val = val; + s->num_env++; + return (1); + } + } + debug2("Ignoring env request %s: disallowed name", name); + + fail: + xfree(name); + xfree(val); + return (0); +} + +static int session_auth_agent_req(Session *s) { static int called = 0; @@ -1562,6 +1602,8 @@ session_input_channel_req(Channel *c, const char *rtype) success = session_subsystem_req(s); } else if (strcmp(rtype, "break") == 0) { success = session_break_req(s); + } else if (strcmp(rtype, "env") == 0) { + success = session_env_req(s); } } if (strcmp(rtype, "window-change") == 0) { @@ -1695,6 +1737,8 @@ session_exit_message(Session *s, int status) void session_close(Session *s) { + int i; + debug("session_close: session %d pid %ld", s->self, (long)s->pid); if (s->ttyfd != -1) session_pty_cleanup(s); @@ -1709,6 +1753,12 @@ session_close(Session *s) if (s->auth_proto) xfree(s->auth_proto); s->used = 0; + for (i = 0; i < s->num_env; i++) { + xfree(s->env[i].name); + xfree(s->env[i].val); + } + if (s->env != NULL) + xfree(s->env); session_proctitle(s); } diff --git a/usr.bin/ssh/session.h b/usr.bin/ssh/session.h index 405b8fe8a91..e525066520d 100644 --- a/usr.bin/ssh/session.h +++ b/usr.bin/ssh/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.21 2003/09/23 20:17:11 markus Exp $ */ +/* $OpenBSD: session.h,v 1.22 2004/04/27 09:46:37 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -53,6 +53,11 @@ struct Session { /* proto 2 */ int chanid; int is_subsystem; + int num_env; + struct { + char *name; + char *val; + } *env; }; void do_authenticated(Authctxt *); diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c index bc8c9701da4..47d880e5265 100644 --- a/usr.bin/ssh/ssh.c +++ b/usr.bin/ssh/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.211 2004/04/19 21:51:49 djm Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.212 2004/04/27 09:46:37 djm Exp $"); #include <openssl/evp.h> #include <openssl/err.h> @@ -68,6 +68,7 @@ RCSID("$OpenBSD: ssh.c,v 1.211 2004/04/19 21:51:49 djm Exp $"); #include "kex.h" #include "mac.h" #include "sshtty.h" +#include "match.h" #ifdef SMARTCARD #include "scard.h" @@ -1042,6 +1043,44 @@ ssh_session2_setup(int id, void *arg) packet_send(); } + /* Transfer any environment variables from client to server */ + if (options.num_send_env != 0) { + int i, j, matched; + extern char **environ; + char *name, *val; + + debug("Sending environment."); + for (i = 0; environ && environ[i] != NULL; i++) { + /* Split */ + name = xstrdup(environ[i]); + if ((val = strchr(name, '=')) == NULL) { + free(name); + continue; + } + *val++ = '\0'; + + matched = 0; + for (j = 0; j < options.num_send_env; j++) { + if (match_pattern(name, options.send_env[j])) { + matched = 1; + break; + } + } + if (!matched) { + debug3("Ignored env %s", name); + free(name); + continue; + } + + debug("Sending env %s = %s", name, val); + channel_request_start(id, "env", 0); + packet_put_cstring(name); + packet_put_cstring(val); + packet_send(); + free(name); + } + } + len = buffer_len(&command); if (len > 0) { if (len > 900) diff --git a/usr.bin/ssh/ssh_config.5 b/usr.bin/ssh/ssh_config.5 index df479c63a8d..fbe8c657da7 100644 --- a/usr.bin/ssh/ssh_config.5 +++ b/usr.bin/ssh/ssh_config.5 @@ -34,7 +34,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. .\" -.\" $OpenBSD: ssh_config.5,v 1.31 2004/04/19 16:12:14 jmc Exp $ +.\" $OpenBSD: ssh_config.5,v 1.32 2004/04/27 09:46:37 djm Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -570,6 +570,27 @@ running. The default is .Dq yes . Note that this option applies to protocol version 1 only. +.It Cm SendEnv +Specifies what variables from the local +.Xr environ 7 +should be sent to the server. +Note that environment passing is only supported for protocol 2, the +server must also support it and must be configured to accept these +enviornment variables. +Refer to +.Cm AcceptEnv +in +.Xr sshd_config 5 +for how to configure the server. +Variables are specified by name, which may contain the wildcard characters +.Ql \&* +and +.Ql \&? . +Multiple environment variables may be seperated by whitespace or spread +across multiple +.Cm SendEnv +directives. +The default is not to send any environment variables. .It Cm ServerAliveInterval Sets a timeout interval in seconds after which if no data has been received from the server, diff --git a/usr.bin/ssh/sshd_config.5 b/usr.bin/ssh/sshd_config.5 index e187159054c..9712063cd39 100644 --- a/usr.bin/ssh/sshd_config.5 +++ b/usr.bin/ssh/sshd_config.5 @@ -34,7 +34,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. .\" -.\" $OpenBSD: sshd_config.5,v 1.29 2004/03/08 10:18:57 dtucker Exp $ +.\" $OpenBSD: sshd_config.5,v 1.30 2004/04/27 09:46:37 djm Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -61,6 +61,29 @@ The possible keywords and their meanings are as follows (note that keywords are case-insensitive and arguments are case-sensitive): .Bl -tag -width Ds +.It Cm AcceptEnv +Specifies what environment variables sent by the client will be copied into +the session's +.Xr environ 7 . +See +.Cm SendEnv +in +.Xr ssh_config 5 +for how to configure the client. +Note that environment passingis only supported for protocol 2. +Variables are specified by name, which may contain the wildcard characters +.Ql \&* +and +.Ql \&? . +Multiple environment variables may be seperated by whitespace or spread +across multiple +.Cm AcceptEnv +directives. +Be warned that some enviornment variables could be used to bypass restricted +user environments. +For this reason, care should be taken in the use of this directive. +The default is not to accept any environment variables. +.Pp .It Cm AllowGroups This keyword can be followed by a list of group name patterns, separated by spaces. |