- 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@
This commit is contained in:
Darren Tucker 2004-05-02 22:11:30 +10:00
parent 47abce45b2
commit 46bc075474
10 changed files with 194 additions and 11 deletions

View File

@ -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 $

View File

@ -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;
}
/*

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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
@ -1831,6 +1836,41 @@ session_break_req(Session *s)
return 1;
}
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)
{
@ -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);
}

View File

@ -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 *);

41
ssh.c
View File

@ -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)

View File

@ -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,

View File

@ -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.