diff options
-rw-r--r-- | auth-options.c | 35 | ||||
-rw-r--r-- | auth-options.h | 7 |
2 files changed, 29 insertions, 13 deletions
diff --git a/auth-options.c b/auth-options.c index f68c629d..aa5da78a 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.95 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.96 2021/07/23 03:57:20 djm Exp $ */ /* * Copyright (c) 2018 Damien Miller <djm@mindrot.org> * @@ -324,6 +324,7 @@ sshauthopt_parse(const char *opts, const char **errstrp) struct sshauthopt *ret = NULL; const char *errstr = "unknown error"; uint64_t valid_before; + size_t i, l; if (errstrp != NULL) *errstrp = NULL; @@ -397,7 +398,7 @@ sshauthopt_parse(const char *opts, const char **errstrp) valid_before < ret->valid_before) ret->valid_before = valid_before; } else if (opt_match(&opts, "environment")) { - if (ret->nenv > INT_MAX) { + if (ret->nenv > SSH_AUTHOPT_ENV_MAX) { errstr = "too many environment strings"; goto fail; } @@ -411,23 +412,35 @@ sshauthopt_parse(const char *opts, const char **errstrp) } if ((cp = strdup(opt)) == NULL) goto alloc_fail; - cp[tmp - opt] = '\0'; /* truncate at '=' */ + l = (size_t)(tmp - opt); + cp[l] = '\0'; /* truncate at '=' */ if (!valid_env_name(cp)) { free(cp); free(opt); errstr = "invalid environment string"; goto fail; } + /* Check for duplicates; XXX O(n*log(n)) */ + for (i = 0; i < ret->nenv; i++) { + if (strncmp(ret->env[i], cp, l) == 0 && + ret->env[i][l] == '=') + break; + } free(cp); - /* Append it. */ - oarray = ret->env; - if ((ret->env = recallocarray(ret->env, ret->nenv, - ret->nenv + 1, sizeof(*ret->env))) == NULL) { - free(opt); - ret->env = oarray; /* put it back for cleanup */ - goto alloc_fail; + /* First match wins */ + if (i >= ret->nenv) { + /* Append it. */ + oarray = ret->env; + if ((ret->env = recallocarray(ret->env, + ret->nenv, ret->nenv + 1, + sizeof(*ret->env))) == NULL) { + free(opt); + /* put it back for cleanup */ + ret->env = oarray; + goto alloc_fail; + } + ret->env[ret->nenv++] = opt; } - ret->env[ret->nenv++] = opt; } else if (opt_match(&opts, "permitopen")) { if (handle_permit(&opts, 0, &ret->permitopen, &ret->npermitopen, &errstr) != 0) diff --git a/auth-options.h b/auth-options.h index 118a3208..6e29b727 100644 --- a/auth-options.h +++ b/auth-options.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.h,v 1.30 2020/08/27 01:07:09 djm Exp $ */ +/* $OpenBSD: auth-options.h,v 1.31 2021/07/23 03:57:20 djm Exp $ */ /* * Copyright (c) 2018 Damien Miller <djm@mindrot.org> @@ -23,7 +23,10 @@ struct passwd; struct sshkey; /* Maximum number of permitopen/permitlisten directives to accept */ -#define SSH_AUTHOPT_PERMIT_MAX 4096 +#define SSH_AUTHOPT_PERMIT_MAX 4096 + +/* Maximum number of environment directives to accept */ +#define SSH_AUTHOPT_ENV_MAX 1024 /* * sshauthopt represents key options parsed from authorized_keys or |