summaryrefslogtreecommitdiff
path: root/usr.bin/ssh
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2004-04-27 09:46:38 +0000
committerDamien Miller <djm@cvs.openbsd.org>2004-04-27 09:46:38 +0000
commit958dcf038c05f370c9077b63a2f717585f316329 (patch)
tree1409d35ece6efe3f7ad7feb01c719dfdbe1c5053 /usr.bin/ssh
parentfbf3c3831531c2558d4064afd5c471f35777b62c (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.c18
-rw-r--r--usr.bin/ssh/readconf.h7
-rw-r--r--usr.bin/ssh/servconf.c19
-rw-r--r--usr.bin/ssh/servconf.h6
-rw-r--r--usr.bin/ssh/session.c52
-rw-r--r--usr.bin/ssh/session.h7
-rw-r--r--usr.bin/ssh/ssh.c41
-rw-r--r--usr.bin/ssh/ssh_config.523
-rw-r--r--usr.bin/ssh/sshd_config.525
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.