From 95344c257412b51199ead18d54eaed5bafb75617 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Tue, 3 Jul 2018 10:59:35 +0000 Subject: [PATCH] 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 --- servconf.c | 40 ++++++++++++++++++++++++++++++++++++---- servconf.h | 4 +++- session.c | 19 +++++++++++++++---- sshd_config.5 | 10 ++++++++-- 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/servconf.c b/servconf.c index cb5786583..a41fdc26a 100644 --- a/servconf.c +++ b/servconf.c @@ -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 , Espoo, Finland * All rights reserved @@ -130,6 +130,7 @@ initialize_server_options(ServerOptions *options) options->challenge_response_authentication = -1; options->permit_empty_passwd = -1; options->permit_user_env = -1; + options->permit_user_env_whitelist = NULL; options->compression = -1; options->rekey_limit = -1; options->rekey_interval = -1; @@ -329,8 +330,10 @@ fill_default_server_options(ServerOptions *options) options->challenge_response_authentication = 1; if (options->permit_empty_passwd == -1) 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_whitelist = NULL; + } if (options->compression == -1) options->compression = COMP_DELAYED; if (options->rekey_limit == -1) @@ -1514,7 +1517,29 @@ process_server_config_line(ServerOptions *options, char *line, case sPermitUserEnvironment: 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: intptr = &options->compression; @@ -2528,7 +2553,6 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sStrictModes, o->strict_modes); dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); 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(sGatewayPorts, o->fwd_opts.gateway_ports); dump_cfg_fmtint(sUseDNS, o->use_dns); @@ -2628,4 +2652,12 @@ dump_config(ServerOptions *o) printf(" %s", o->permitted_listens[i]); } 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); + } + } diff --git a/servconf.h b/servconf.h index db8362c60..73327135b 100644 --- a/servconf.h +++ b/servconf.h @@ -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 @@ -133,6 +133,7 @@ typedef struct { int permit_empty_passwd; /* If false, do not permit empty * passwords. */ 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 allow_tcp_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(pubkey_key_types); \ M_CP_STROPT(routing_domain); \ + M_CP_STROPT(permit_user_env_whitelist); \ M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \ M_CP_STRARRAYOPT(allow_users, num_allow_users); \ M_CP_STRARRAYOPT(deny_users, num_deny_users); \ diff --git a/session.c b/session.c index 85df6a272..3c4e9c440 100644 --- a/session.c +++ b/session.c @@ -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 , Espoo, Finland * 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. * Otherwise, it must consist of empty lines, comments (line starts with '#') * 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 read_environment_file(char ***env, u_int *envsize, - const char *filename) + const char *filename, const char *whitelist) { FILE *f; char *line = NULL, *cp, *value; @@ -903,6 +905,9 @@ read_environment_file(char ***env, u_int *envsize, */ *value = '\0'; value++; + if (whitelist != NULL && + match_pattern_list(cp, whitelist, 0) != 1) + continue; child_set_env(env, envsize, cp, value); } free(line); @@ -1121,7 +1126,12 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) cp = strchr(ocp, '='); if (*cp == '=') { *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); } @@ -1131,7 +1141,8 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) if (options.permit_user_env) { snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir); - read_environment_file(&env, &envsize, buf); + read_environment_file(&env, &envsize, buf, + options.permit_user_env_whitelist); } #ifdef USE_PAM diff --git a/sshd_config.5 b/sshd_config.5 index 86d2d421b..60c5f4bd3 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (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.277 2018/06/19 05:36:57 jmc Exp $ -.Dd $Mdocdate: June 19 2018 $ +.\" $OpenBSD: sshd_config.5,v 1.278 2018/07/03 10:59:35 djm Exp $ +.Dd $Mdocdate: July 3 2018 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -1332,6 +1332,12 @@ options in .Pa ~/.ssh/authorized_keys are processed by .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 .Cm no . Enabling environment processing may enable users to bypass access