diff options
Diffstat (limited to 'crypto/openssh/auth2-pubkey.c')
-rw-r--r-- | crypto/openssh/auth2-pubkey.c | 91 |
1 files changed, 75 insertions, 16 deletions
diff --git a/crypto/openssh/auth2-pubkey.c b/crypto/openssh/auth2-pubkey.c index 7580db78dfd5..aa24fda05753 100644 --- a/crypto/openssh/auth2-pubkey.c +++ b/crypto/openssh/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.120 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.122 2024/12/12 09:09:09 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -41,6 +41,11 @@ #include <time.h> #include <unistd.h> #include <limits.h> +#ifdef USE_SYSTEM_GLOB +# include <glob.h> +#else +# include "openbsd-compat/glob.h" +#endif #include "xmalloc.h" #include "ssh.h" @@ -319,20 +324,51 @@ match_principals_file(struct passwd *pw, char *file, struct sshkey_cert *cert, struct sshauthopt **authoptsp) { FILE *f; - int success; + int r, success = 0; + size_t i; + glob_t gl; + struct sshauthopt *opts = NULL; if (authoptsp != NULL) *authoptsp = NULL; temporarily_use_uid(pw); - debug("trying authorized principals file %s", file); - if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) { - restore_uid(); + r = glob(file, 0, NULL, &gl); + restore_uid(); + if (r != 0) { + if (r != GLOB_NOMATCH) { + logit_f("glob \"%s\" failed", file); + } return 0; + } else if (gl.gl_pathc > INT_MAX) { + fatal_f("too many glob results for \"%s\"", file); + } else if (gl.gl_pathc > 1) { + debug2_f("glob \"%s\" returned %zu matches", file, + gl.gl_pathc); + } + for (i = 0; !success && i < gl.gl_pathc; i++) { + temporarily_use_uid(pw); + debug("trying authorized principals file %s", file); + if ((f = auth_openprincipals(gl.gl_pathv[i], pw, + options.strict_modes)) == NULL) { + restore_uid(); + continue; + } + success = auth_process_principals(f, gl.gl_pathv[i], + cert, &opts); + fclose(f); + restore_uid(); + if (!success) { + sshauthopt_free(opts); + opts = NULL; + } } - success = auth_process_principals(f, file, cert, authoptsp); - fclose(f); - restore_uid(); + globfree(&gl); + if (success && authoptsp != NULL) { + *authoptsp = opts; + opts = NULL; + } + sshauthopt_free(opts); return success; } @@ -753,8 +789,8 @@ int user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, int auth_attempt, struct sshauthopt **authoptsp) { - u_int success = 0, i; - char *file, *conn_id; + u_int success = 0, i, j; + char *file = NULL, *conn_id; struct sshauthopt *opts = NULL; const char *rdomain, *remote_ip, *remote_host; @@ -776,17 +812,40 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, remote_ip, ssh_remote_port(ssh)); for (i = 0; !success && i < options.num_authkeys_files; i++) { + int r; + glob_t gl; + if (strcasecmp(options.authorized_keys_files[i], "none") == 0) continue; file = expand_authorized_keys( options.authorized_keys_files[i], pw); - success = user_key_allowed2(pw, key, file, - remote_ip, remote_host, &opts); - free(file); - if (!success) { - sshauthopt_free(opts); - opts = NULL; + temporarily_use_uid(pw); + r = glob(file, 0, NULL, &gl); + restore_uid(); + if (r != 0) { + if (r != GLOB_NOMATCH) { + logit_f("glob \"%s\" failed", file); + } + free(file); + file = NULL; + continue; + } else if (gl.gl_pathc > INT_MAX) { + fatal_f("too many glob results for \"%s\"", file); + } else if (gl.gl_pathc > 1) { + debug2_f("glob \"%s\" returned %zu matches", file, + gl.gl_pathc); } + for (j = 0; !success && j < gl.gl_pathc; j++) { + success = user_key_allowed2(pw, key, gl.gl_pathv[j], + remote_ip, remote_host, &opts); + if (!success) { + sshauthopt_free(opts); + opts = NULL; + } + } + free(file); + file = NULL; + globfree(&gl); } if (success) goto out; |