From 22e1a3a71ad6d108ff0c5f07f93c3fcbd30f8b40 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 3 Jun 2022 04:30:46 +0000 Subject: [PATCH] upstream: Make SetEnv directives first-match-wins in both sshd_config and sshd_config; previously if the same name was reused then the last would win (which is the opposite to how the config is supposed to work). While there, make the ssh_config parsing more like sshd_config. bz3438, ok dtucker OpenBSD-Commit-ID: 797909c1e0262c0d00e09280459d7ab00f18273b --- clientloop.c | 9 +++++---- misc.c | 19 ++++++++++++++++++- misc.h | 4 +++- mux.c | 9 +++++---- readconf.c | 41 +++++++++++++++-------------------------- readconf.h | 10 +++++----- servconf.c | 8 +++++++- 7 files changed, 58 insertions(+), 42 deletions(-) diff --git a/clientloop.c b/clientloop.c index 1d80683c0..0050f3eb6 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.379 2022/04/20 04:19:11 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.380 2022/06/03 04:30:46 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -2467,7 +2467,8 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, const char *term, struct termios *tiop, int in_fd, struct sshbuf *cmd, char **env) { - int i, j, matched, len, r; + size_t i, j, len; + int matched, r; char *name, *val; Channel *c = NULL; @@ -2550,13 +2551,13 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, len = 900; if (want_subsystem) { debug("Sending subsystem: %.*s", - len, (const u_char*)sshbuf_ptr(cmd)); + (int)len, (const u_char*)sshbuf_ptr(cmd)); channel_request_start(ssh, id, "subsystem", 1); client_expect_confirm(ssh, id, "subsystem", CONFIRM_CLOSE); } else { debug("Sending command: %.*s", - len, (const u_char*)sshbuf_ptr(cmd)); + (int)len, (const u_char*)sshbuf_ptr(cmd)); channel_request_start(ssh, id, "exec", 1); client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE); } diff --git a/misc.c b/misc.c index 85d223695..a8e87430e 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.175 2022/03/20 08:51:21 djm Exp $ */ +/* $OpenBSD: misc.c,v 1.176 2022/06/03 04:30:47 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005-2020 Damien Miller. All rights reserved. @@ -2793,3 +2793,20 @@ lookup_env_in_list(const char *env, char * const *envs, size_t nenvs) } return NULL; } + +const char * +lookup_setenv_in_list(const char *env, char * const *envs, size_t nenvs) +{ + char *name, *cp; + const char *ret; + + name = xstrdup(env); + if ((cp = strchr(name, '=')) == NULL) { + free(name); + return NULL; /* not env=val */ + } + *cp = '\0'; + ret = lookup_env_in_list(name, envs, nenvs); + free(name); + return ret; +} diff --git a/misc.h b/misc.h index 2e1b5feca..7ef75bd09 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.99 2021/11/13 21:14:13 deraadt Exp $ */ +/* $OpenBSD: misc.h,v 1.100 2022/06/03 04:30:47 djm Exp $ */ /* * Author: Tatu Ylonen @@ -179,6 +179,8 @@ void child_set_env(char ***envp, u_int *envsizep, const char *name, const char *value); const char *lookup_env_in_list(const char *env, char * const *envs, size_t nenvs); +const char *lookup_setenv_in_list(const char *env, + char * const *envs, size_t nenvs); int argv_split(const char *, int *, char ***, int); char *argv_assemble(int, char **argv); diff --git a/mux.c b/mux.c index 924fbead0..3cb387614 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.93 2022/05/05 00:55:11 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.94 2022/06/03 04:30:47 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -242,7 +242,8 @@ mux_master_control_cleanup_cb(struct ssh *ssh, int cid, void *unused) static int env_permitted(const char *env) { - int i, ret; + u_int i; + int ret; char name[1024], *cp; if ((cp = strchr(env, '=')) == NULL || cp == env) @@ -1865,9 +1866,9 @@ mux_client_request_session(int fd) struct sshbuf *m; char *e; const char *term = NULL; - u_int echar, rid, sid, esid, exitval, type, exitval_seen; + u_int i, echar, rid, sid, esid, exitval, type, exitval_seen; extern char **environ; - int r, i, rawmode; + int r, rawmode; debug3_f("entering"); diff --git a/readconf.c b/readconf.c index 55d2b1a38..7f26c6804 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.367 2022/04/20 15:56:49 millert Exp $ */ +/* $OpenBSD: readconf.c,v 1.368 2022/06/03 04:30:47 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -753,7 +753,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, static void rm_env(Options *options, const char *arg, const char *filename, int linenum) { - int i, j, onum_send_env = options->num_send_env; + u_int i, j, onum_send_env = options->num_send_env; /* Remove an environment variable */ for (i = 0; i < options->num_send_env; ) { @@ -1733,20 +1733,10 @@ parse_pubkey_algos: /* Removing an env var */ rm_env(options, arg, filename, linenum); continue; - } else { - /* Adding an env var */ - if (options->num_send_env >= INT_MAX) { - error("%s line %d: too many send env.", - filename, linenum); - goto out; - } - options->send_env = xrecallocarray( - options->send_env, options->num_send_env, - options->num_send_env + 1, - sizeof(*options->send_env)); - options->send_env[options->num_send_env++] = - xstrdup(arg); } + opt_array_append(filename, linenum, + lookup_opcode_name(opcode), + &options->send_env, &options->num_send_env, arg); } break; @@ -1760,16 +1750,15 @@ parse_pubkey_algos: } if (!*activep || value != 0) continue; - /* Adding a setenv var */ - if (options->num_setenv >= INT_MAX) { - error("%s line %d: too many SetEnv.", - filename, linenum); - goto out; + if (lookup_setenv_in_list(arg, options->setenv, + options->num_setenv) != NULL) { + debug2("%s line %d: ignoring duplicate env " + "name \"%.64s\"", filename, linenum, arg); + continue; } - options->setenv = xrecallocarray( - options->setenv, options->num_setenv, - options->num_setenv + 1, sizeof(*options->setenv)); - options->setenv[options->num_setenv++] = xstrdup(arg); + opt_array_append(filename, linenum, + lookup_opcode_name(opcode), + &options->setenv, &options->num_setenv, arg); } break; @@ -2770,9 +2759,9 @@ free_options(Options *o) } free(o->remote_forwards); free(o->stdio_forward_host); - FREE_ARRAY(int, o->num_send_env, o->send_env); + FREE_ARRAY(u_int, o->num_send_env, o->send_env); free(o->send_env); - FREE_ARRAY(int, o->num_setenv, o->setenv); + FREE_ARRAY(u_int, o->num_setenv, o->setenv); free(o->setenv); free(o->control_path); free(o->local_command); diff --git a/readconf.h b/readconf.h index ded13c943..f647bd42a 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.146 2021/12/19 22:14:47 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.147 2022/06/03 04:30:47 djm Exp $ */ /* * Author: Tatu Ylonen @@ -124,10 +124,10 @@ typedef struct { int server_alive_interval; int server_alive_count_max; - int num_send_env; - char **send_env; - int num_setenv; - char **setenv; + u_int num_send_env; + char **send_env; + u_int num_setenv; + char **setenv; char *control_path; int control_master; diff --git a/servconf.c b/servconf.c index 9d9681f15..29df0463d 100644 --- a/servconf.c +++ b/servconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: servconf.c,v 1.384 2022/03/18 04:04:11 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.385 2022/06/03 04:30:47 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -2033,6 +2033,12 @@ process_server_config_line_depth(ServerOptions *options, char *line, filename, linenum); if (!*activep || uvalue != 0) continue; + if (lookup_setenv_in_list(arg, options->setenv, + options->num_setenv) != NULL) { + debug2("%s line %d: ignoring duplicate env " + "name \"%.64s\"", filename, linenum, arg); + continue; + } opt_array_append(filename, linenum, keyword, &options->setenv, &options->num_setenv, arg); }