aboutsummaryrefslogtreecommitdiff
path: root/crypto/openssh/auth2-pubkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/auth2-pubkey.c')
-rw-r--r--crypto/openssh/auth2-pubkey.c91
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;