upstream: allow sshd_config PermitUserEnvironment to accept a

pattern-list of whitelisted environment variable names in addition to yes|no.

bz#1800, feedback and ok markus@

OpenBSD-Commit-ID: 77dc2b468e0bf04b53f333434ba257008a1fdf24
This commit is contained in:
djm@openbsd.org 2018-07-03 10:59:35 +00:00 committed by Damien Miller
parent 6f56fe4b95
commit 95344c2574
4 changed files with 62 additions and 11 deletions

View File

@ -1,5 +1,5 @@
/* $OpenBSD: servconf.c,v 1.333 2018/06/19 02:59:41 djm Exp $ */ /* $OpenBSD: servconf.c,v 1.334 2018/07/03 10:59:35 djm Exp $ */
/* /*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -130,6 +130,7 @@ initialize_server_options(ServerOptions *options)
options->challenge_response_authentication = -1; options->challenge_response_authentication = -1;
options->permit_empty_passwd = -1; options->permit_empty_passwd = -1;
options->permit_user_env = -1; options->permit_user_env = -1;
options->permit_user_env_whitelist = NULL;
options->compression = -1; options->compression = -1;
options->rekey_limit = -1; options->rekey_limit = -1;
options->rekey_interval = -1; options->rekey_interval = -1;
@ -329,8 +330,10 @@ fill_default_server_options(ServerOptions *options)
options->challenge_response_authentication = 1; options->challenge_response_authentication = 1;
if (options->permit_empty_passwd == -1) if (options->permit_empty_passwd == -1)
options->permit_empty_passwd = 0; options->permit_empty_passwd = 0;
if (options->permit_user_env == -1) if (options->permit_user_env == -1) {
options->permit_user_env = 0; options->permit_user_env = 0;
options->permit_user_env_whitelist = NULL;
}
if (options->compression == -1) if (options->compression == -1)
options->compression = COMP_DELAYED; options->compression = COMP_DELAYED;
if (options->rekey_limit == -1) if (options->rekey_limit == -1)
@ -1514,7 +1517,29 @@ process_server_config_line(ServerOptions *options, char *line,
case sPermitUserEnvironment: case sPermitUserEnvironment:
intptr = &options->permit_user_env; intptr = &options->permit_user_env;
goto parse_flag; charptr = &options->permit_user_env_whitelist;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing argument.",
filename, linenum);
value = 0;
p = NULL;
if (strcmp(arg, "yes") == 0)
value = 1;
else if (strcmp(arg, "no") == 0)
value = 0;
else {
/* Pattern-list specified */
value = 1;
p = xstrdup(arg);
}
if (*activep && *intptr == -1) {
*intptr = value;
*charptr = p;
p = NULL;
}
free(p);
break;
case sCompression: case sCompression:
intptr = &options->compression; intptr = &options->compression;
@ -2528,7 +2553,6 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sStrictModes, o->strict_modes); dump_cfg_fmtint(sStrictModes, o->strict_modes);
dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
dump_cfg_fmtint(sCompression, o->compression); dump_cfg_fmtint(sCompression, o->compression);
dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
dump_cfg_fmtint(sUseDNS, o->use_dns); dump_cfg_fmtint(sUseDNS, o->use_dns);
@ -2628,4 +2652,12 @@ dump_config(ServerOptions *o)
printf(" %s", o->permitted_listens[i]); printf(" %s", o->permitted_listens[i]);
} }
printf("\n"); printf("\n");
if (o->permit_user_env_whitelist == NULL) {
dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
} else {
printf("permituserenvironment %s\n",
o->permit_user_env_whitelist);
}
} }

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.134 2018/06/09 03:03:10 djm Exp $ */ /* $OpenBSD: servconf.h,v 1.135 2018/07/03 10:59:35 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -133,6 +133,7 @@ typedef struct {
int permit_empty_passwd; /* If false, do not permit empty int permit_empty_passwd; /* If false, do not permit empty
* passwords. */ * passwords. */
int permit_user_env; /* If true, read ~/.ssh/environment */ int permit_user_env; /* If true, read ~/.ssh/environment */
char *permit_user_env_whitelist; /* pattern-list whitelist */
int compression; /* If true, compression is allowed */ int compression; /* If true, compression is allowed */
int allow_tcp_forwarding; /* One of FORWARD_* */ int allow_tcp_forwarding; /* One of FORWARD_* */
int allow_streamlocal_forwarding; /* One of FORWARD_* */ int allow_streamlocal_forwarding; /* One of FORWARD_* */
@ -242,6 +243,7 @@ struct connection_info {
M_CP_STROPT(hostbased_key_types); \ M_CP_STROPT(hostbased_key_types); \
M_CP_STROPT(pubkey_key_types); \ M_CP_STROPT(pubkey_key_types); \
M_CP_STROPT(routing_domain); \ M_CP_STROPT(routing_domain); \
M_CP_STROPT(permit_user_env_whitelist); \
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \ M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
M_CP_STRARRAYOPT(allow_users, num_allow_users); \ M_CP_STRARRAYOPT(allow_users, num_allow_users); \
M_CP_STRARRAYOPT(deny_users, num_deny_users); \ M_CP_STRARRAYOPT(deny_users, num_deny_users); \

View File

@ -1,4 +1,4 @@
/* $OpenBSD: session.c,v 1.300 2018/06/09 03:03:10 djm Exp $ */ /* $OpenBSD: session.c,v 1.301 2018/07/03 10:59:35 djm Exp $ */
/* /*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -867,10 +867,12 @@ check_quietlogin(Session *s, const char *command)
* into the environment. If the file does not exist, this does nothing. * into the environment. If the file does not exist, this does nothing.
* Otherwise, it must consist of empty lines, comments (line starts with '#') * Otherwise, it must consist of empty lines, comments (line starts with '#')
* and assignments of the form name=value. No other forms are allowed. * and assignments of the form name=value. No other forms are allowed.
* If whitelist is not NULL, then it is interpreted as a pattern list and
* only variable names that match it will be accepted.
*/ */
static void static void
read_environment_file(char ***env, u_int *envsize, read_environment_file(char ***env, u_int *envsize,
const char *filename) const char *filename, const char *whitelist)
{ {
FILE *f; FILE *f;
char *line = NULL, *cp, *value; char *line = NULL, *cp, *value;
@ -903,6 +905,9 @@ read_environment_file(char ***env, u_int *envsize,
*/ */
*value = '\0'; *value = '\0';
value++; value++;
if (whitelist != NULL &&
match_pattern_list(cp, whitelist, 0) != 1)
continue;
child_set_env(env, envsize, cp, value); child_set_env(env, envsize, cp, value);
} }
free(line); free(line);
@ -1121,7 +1126,12 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
cp = strchr(ocp, '='); cp = strchr(ocp, '=');
if (*cp == '=') { if (*cp == '=') {
*cp = '\0'; *cp = '\0';
child_set_env(&env, &envsize, ocp, cp + 1); /* Apply PermitUserEnvironment whitelist */
if (options.permit_user_env_whitelist == NULL ||
match_pattern_list(ocp,
options.permit_user_env_whitelist, 0) == 1)
child_set_env(&env, &envsize,
ocp, cp + 1);
} }
free(ocp); free(ocp);
} }
@ -1131,7 +1141,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
if (options.permit_user_env) { if (options.permit_user_env) {
snprintf(buf, sizeof buf, "%.200s/.ssh/environment", snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
pw->pw_dir); pw->pw_dir);
read_environment_file(&env, &envsize, buf); read_environment_file(&env, &envsize, buf,
options.permit_user_env_whitelist);
} }
#ifdef USE_PAM #ifdef USE_PAM

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: sshd_config.5,v 1.277 2018/06/19 05:36:57 jmc Exp $ .\" $OpenBSD: sshd_config.5,v 1.278 2018/07/03 10:59:35 djm Exp $
.Dd $Mdocdate: June 19 2018 $ .Dd $Mdocdate: July 3 2018 $
.Dt SSHD_CONFIG 5 .Dt SSHD_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -1332,6 +1332,12 @@ options in
.Pa ~/.ssh/authorized_keys .Pa ~/.ssh/authorized_keys
are processed by are processed by
.Xr sshd 8 . .Xr sshd 8 .
Valid options are
.Cm yes ,
.Cm no
or a pattern-list specifying which environment variable names to accept
(for example
.Qq LANG,LC_* ) .
The default is The default is
.Cm no . .Cm no .
Enabling environment processing may enable users to bypass access Enabling environment processing may enable users to bypass access