summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2004-05-02 22:11:30 +1000
committerDarren Tucker <dtucker@zip.com.au>2004-05-02 22:11:30 +1000
commit46bc075474211c711b102f6278783bb68d7530a8 (patch)
tree5f099d7bdc006926bf393dfc51f7545d0787b33e
parent47abce45b20ba52c0eb7f19240851f45bc1babc2 (diff)
downloadopenssh-git-46bc075474211c711b102f6278783bb68d7530a8.tar.gz
- djm@cvs.openbsd.org 2004/04/27 09:46:37
[readconf.c readconf.h servconf.c servconf.h session.c session.h ssh.c ssh_config.5 sshd_config.5] bz #815: implement ability to pass specified environment variables from the client to the server; ok markus@
-rw-r--r--ChangeLog7
-rw-r--r--readconf.c18
-rw-r--r--readconf.h7
-rw-r--r--servconf.c19
-rw-r--r--servconf.h6
-rw-r--r--session.c52
-rw-r--r--session.h7
-rw-r--r--ssh.c41
-rw-r--r--ssh_config.523
-rw-r--r--sshd_config.525
10 files changed, 194 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 3457022c..52c9eabd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,11 @@
[moduli.c]
Bugzilla #850: Sophie Germain is the correct name of the French
mathematician, "Sophie Germaine" isn't; from Luc.Maisonobe@c-s.fr
+ - djm@cvs.openbsd.org 2004/04/27 09:46:37
+ [readconf.c readconf.h servconf.c servconf.h session.c session.h ssh.c
+ ssh_config.5 sshd_config.5]
+ bz #815: implement ability to pass specified environment variables from
+ the client to the server; ok markus@
20040423
- (dtucker) [configure.ac openbsd-compat/getrrsetbyname.c] Declare h_errno
@@ -1045,4 +1050,4 @@
- (djm) Trim deprecated options from INSTALL. Mention UsePAM
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
-$Id: ChangeLog,v 1.3333 2004/05/02 12:09:00 dtucker Exp $
+$Id: ChangeLog,v 1.3334 2004/05/02 12:11:30 dtucker Exp $
diff --git a/readconf.c b/readconf.c
index 096d1a71..f4710e83 100644
--- a/readconf.c
+++ b/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 }
};
@@ -749,6 +751,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);
@@ -894,6 +909,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/readconf.h b/readconf.h
index 9d70fee6..66805594 100644
--- a/readconf.h
+++ b/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/servconf.c b/servconf.c
index a72246b6..ae380f52 100644
--- a/servconf.c
+++ b/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"
@@ -101,6 +101,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;
@@ -266,7 +267,7 @@ typedef enum {
sBanner, sUseDNS, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
- sGssAuthentication, sGssCleanupCreds,
+ sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
sUsePrivilegeSeparation,
sDeprecated, sUnsupported
} ServerOpCodes;
@@ -366,6 +367,7 @@ static struct {
{ "authorizedkeysfile", sAuthorizedKeysFile },
{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
{ "useprivilegeseparation", sUsePrivilegeSeparation},
+ { "acceptenv", sAcceptEnv },
{ NULL, sBadOption }
};
@@ -892,6 +894,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/servconf.h b/servconf.h
index 57c7e5fa..1c6296ac 100644
--- a/servconf.h
+++ b/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/session.c b/session.c
index 55db2ffd..da11e554 100644
--- a/session.c
+++ b/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"
@@ -996,6 +997,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);
#ifdef _AIX
@@ -1832,6 +1837,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;
@@ -1880,6 +1920,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) {
@@ -2017,6 +2059,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);
@@ -2031,6 +2075,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/session.h b/session.h
index 405b8fe8..e5250665 100644
--- a/session.h
+++ b/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/ssh.c b/ssh.c
index 9658e4af..df3b64b1 100644
--- a/ssh.c
+++ b/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"
@@ -1057,6 +1058,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/ssh_config.5 b/ssh_config.5
index df479c63..fbe8c657 100644
--- a/ssh_config.5
+++ b/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/sshd_config.5 b/sshd_config.5
index e15a225f..b702e5ad 100644
--- a/sshd_config.5
+++ b/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.