Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/crypto/external/bsd/openssh/dist/auth2-pubkey.c,v rcsdiff: /ftp/cvs/cvsroot/src/crypto/external/bsd/openssh/dist/auth2-pubkey.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.14 retrieving revision 1.14.2.3 diff -u -p -r1.14 -r1.14.2.3 --- src/crypto/external/bsd/openssh/dist/auth2-pubkey.c 2016/03/11 01:55:00 1.14 +++ src/crypto/external/bsd/openssh/dist/auth2-pubkey.c 2017/04/26 02:52:14 1.14.2.3 @@ -1,6 +1,5 @@ -/* $NetBSD: auth2-pubkey.c,v 1.14 2016/03/11 01:55:00 christos Exp $ */ -/* $OpenBSD: auth2-pubkey.c,v 1.55 2016/01/27 00:53:12 djm Exp $ */ - +/* $NetBSD: auth2-pubkey.c,v 1.14.2.3 2017/04/26 02:52:14 pgoyette Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.62 2017/01/30 01:03:00 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -26,7 +25,7 @@ */ #include "includes.h" -__RCSID("$NetBSD: auth2-pubkey.c,v 1.14 2016/03/11 01:55:00 christos Exp $"); +__RCSID("$NetBSD: auth2-pubkey.c,v 1.14.2.3 2017/04/26 02:52:14 pgoyette Exp $"); #include #include #include @@ -569,13 +568,16 @@ match_principals_option(const char *prin static int process_principals(FILE *f, char *file, struct passwd *pw, - struct sshkey_cert *cert) + const struct sshkey_cert *cert) { char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; u_long linenum = 0; - u_int i; + u_int i, found_principal = 0; while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { + /* Always consume entire input */ + if (found_principal) + continue; /* Skip leading whitespace. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ; @@ -608,11 +610,12 @@ process_principals(FILE *f, char *file, if (auth_parse_options(pw, line_opts, file, linenum) != 1) continue; - return 1; + found_principal = 1; + continue; } } } - return 0; + return found_principal; } static int @@ -638,14 +641,17 @@ match_principals_file(char *file, struct * returns 1 if the principal is allowed or 0 otherwise. */ static int -match_principals_command(struct passwd *user_pw, struct sshkey_cert *cert) +match_principals_command(struct passwd *user_pw, const struct sshkey *key) { + const struct sshkey_cert *cert = key->cert; FILE *f = NULL; - int ok, found_principal = 0; + int r, ok, found_principal = 0; struct passwd *pw; int i, ac = 0, uid_swapped = 0; pid_t pid; char *tmp, *username = NULL, *command = NULL, **av = NULL; + char *ca_fp = NULL, *key_fp = NULL, *catext = NULL, *keytext = NULL; + char serial_s[16]; void (*osigchld)(int); if (options.authorized_principals_command == NULL) @@ -683,10 +689,38 @@ match_principals_command(struct passwd * command); goto out; } + if ((ca_fp = sshkey_fingerprint(cert->signature_key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { + error("%s: sshkey_fingerprint failed", __func__); + goto out; + } + if ((key_fp = sshkey_fingerprint(key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { + error("%s: sshkey_fingerprint failed", __func__); + goto out; + } + if ((r = sshkey_to_base64(cert->signature_key, &catext)) != 0) { + error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); + goto out; + } + if ((r = sshkey_to_base64(key, &keytext)) != 0) { + error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); + goto out; + } + snprintf(serial_s, sizeof(serial_s), "%llu", + (unsigned long long)cert->serial); for (i = 1; i < ac; i++) { tmp = percent_expand(av[i], "u", user_pw->pw_name, "h", user_pw->pw_dir, + "t", sshkey_ssh_name(key), + "T", sshkey_ssh_name(cert->signature_key), + "f", key_fp, + "F", ca_fp, + "k", keytext, + "K", catext, + "i", cert->key_id, + "s", serial_s, (char *)NULL); if (tmp == NULL) fatal("%s: percent_expand failed", __func__); @@ -705,6 +739,9 @@ match_principals_command(struct passwd * ok = process_principals(f, NULL, pw, cert); + fclose(f); + f = NULL; + if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0) goto out; @@ -721,6 +758,10 @@ match_principals_command(struct passwd * restore_uid(); free(command); free(username); + free(ca_fp); + free(key_fp); + free(catext); + free(keytext); return found_principal; } /* @@ -731,11 +772,9 @@ static int check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) { char line[SSH_MAX_PUBKEY_BYTES]; - const char *reason; int found_key = 0; u_long linenum = 0; Key *found; - char *fp; #ifdef WITH_LDAP_PUBKEY ldap_key_t * k; unsigned int i = 0; @@ -786,7 +825,7 @@ check_authkeys_file(FILE *f, char *file, auth_parse_options(pw, xoptions, file, linenum) == 1) { found_key = 1; debug("[LDAP] matching key found"); - fp = sshkey_fingerprint(found, SSH_FP_HASH_DEFAULT, SSH_FP_HEX); + char *fp = sshkey_fingerprint(found, SSH_FP_HASH_DEFAULT, SSH_FP_HEX); verbose("[LDAP] Found matching %s key: %s", key_type(found), fp); /* restoring memory */ @@ -806,19 +845,17 @@ check_authkeys_file(FILE *f, char *file, } } #endif - debug("trying public key file %s", file); - f = auth_openkeyfile(file, pw, options.strict_modes); - - if (!f) { - restore_uid(); - return 0; - } found_key = 0; found = NULL; while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { - char *cp, *key_options = NULL; + char *cp, *key_options = NULL, *fp = NULL; + const char *reason = NULL; + + /* Always consume entrire file */ + if (found_key) + continue; if (found != NULL) key_free(found); found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); @@ -883,10 +920,8 @@ check_authkeys_file(FILE *f, char *file, authorized_principals == NULL ? pw->pw_name : NULL, &reason) != 0) goto fail_reason; - if (auth_cert_options(key, pw) != 0) { - free(fp); - continue; - } + if (auth_cert_options(key, pw, &reason) != 0) + goto fail_reason; verbose("Accepted certificate ID \"%s\" (serial %llu) " "signed by %s CA %s via %s", key->cert->key_id, (unsigned long long)key->cert->serial, @@ -907,7 +942,7 @@ check_authkeys_file(FILE *f, char *file, file, linenum, key_type(found), fp); free(fp); found_key = 1; - break; + continue; } } if (found != NULL) @@ -949,7 +984,7 @@ user_cert_trusted_ca(struct passwd *pw, found_principal = 1; } /* Try querying command if specified */ - if (!found_principal && match_principals_command(pw, key->cert)) + if (!found_principal && match_principals_command(pw, key)) found_principal = 1; /* If principals file or command is specified, then require a match */ use_authorized_principals = principals_file != NULL || @@ -964,8 +999,8 @@ user_cert_trusted_ca(struct passwd *pw, if (key_cert_check_authority(key, 0, 1, use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) goto fail_reason; - if (auth_cert_options(key, pw) != 0) - goto out; + if (auth_cert_options(key, pw, &reason) != 0) + goto fail_reason; verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " "%s CA %s via %s", key->cert->key_id, @@ -1103,6 +1138,9 @@ user_key_command_allowed2(struct passwd ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); + fclose(f); + f = NULL; + if (exited_cleanly(pid, "AuthorizedKeysCommand", command) != 0) goto out;