diff --git a/openssh-8.7p1-host-based-auth.patch b/openssh-8.7p1-host-based-auth.patch new file mode 100644 index 0000000..23efe91 --- /dev/null +++ b/openssh-8.7p1-host-based-auth.patch @@ -0,0 +1,151 @@ +diff --color -rup a/sshconnect2.c b/sshconnect2.c +--- a/sshconnect2.c 2022-07-11 17:00:02.618575727 +0200 ++++ b/sshconnect2.c 2022-07-11 17:03:05.096085690 +0200 +@@ -2288,9 +2288,9 @@ userauth_hostbased(struct ssh *ssh) + if (authctxt->sensitive->keys[i] == NULL || + authctxt->sensitive->keys[i]->type == KEY_UNSPEC) + continue; +- if (match_pattern_list( ++ if (!sshkey_match_keyname_to_sigalgs( + sshkey_ssh_name(authctxt->sensitive->keys[i]), +- authctxt->active_ktype, 0) != 1) ++ authctxt->active_ktype)) + continue; + /* we take and free the key */ + private = authctxt->sensitive->keys[i]; +@@ -2316,7 +2316,8 @@ userauth_hostbased(struct ssh *ssh) + error_f("sshkey_fingerprint failed"); + goto out; + } +- debug_f("trying hostkey %s %s", sshkey_ssh_name(private), fp); ++ debug_f("trying hostkey %s %s using sigalg %s", ++ sshkey_ssh_name(private), fp, authctxt->active_ktype); + + /* figure out a name for the client host */ + lname = get_local_name(ssh_packet_get_connection_in(ssh)); +diff --color -rup a/sshkey.c b/sshkey.c +--- a/sshkey.c 2022-07-11 17:00:02.609575554 +0200 ++++ b/sshkey.c 2022-07-11 17:12:30.905976443 +0200 +@@ -252,6 +252,29 @@ sshkey_ecdsa_nid_from_name(const char *n + return -1; + } + ++int ++sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs) ++{ ++ int ktype; ++ ++ if (sigalgs == NULL || *sigalgs == '\0' || ++ (ktype = sshkey_type_from_name(keyname)) == KEY_UNSPEC) ++ return 0; ++ else if (ktype == KEY_RSA) { ++ return match_pattern_list("ssh-rsa", sigalgs, 0) == 1 || ++ match_pattern_list("rsa-sha2-256", sigalgs, 0) == 1 || ++ match_pattern_list("rsa-sha2-512", sigalgs, 0) == 1; ++ } else if (ktype == KEY_RSA_CERT) { ++ return match_pattern_list("ssh-rsa-cert-v01@openssh.com", ++ sigalgs, 0) == 1 || ++ match_pattern_list("rsa-sha2-256-cert-v01@openssh.com", ++ sigalgs, 0) == 1 || ++ match_pattern_list("rsa-sha2-512-cert-v01@openssh.com", ++ sigalgs, 0) == 1; ++ } else ++ return match_pattern_list(keyname, sigalgs, 0) == 1; ++} ++ + char * + sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) + { +diff --color -rup a/sshkey.h b/sshkey.h +--- a/sshkey.h 2022-07-11 17:00:02.603575438 +0200 ++++ b/sshkey.h 2022-07-11 17:13:01.052556879 +0200 +@@ -194,6 +194,10 @@ int sshkey_is_cert(const struct sshkey + int sshkey_is_sk(const struct sshkey *); + int sshkey_type_is_cert(int); + int sshkey_type_plain(int); ++ ++/* Returns non-zero if key name match sigalgs pattern list. (handles RSA) */ ++int sshkey_match_keyname_to_sigalgs(const char *, const char *); ++ + int sshkey_to_certified(struct sshkey *); + int sshkey_drop_cert(struct sshkey *); + int sshkey_cert_copy(const struct sshkey *, struct sshkey *); +diff --color -rup a/ssh-keysign.c b/ssh-keysign.c +--- a/ssh-keysign.c 2021-08-20 06:03:49.000000000 +0200 ++++ b/ssh-keysign.c 2022-07-11 17:00:23.306973667 +0200 +@@ -62,7 +62,7 @@ + extern char *__progname; + + static int +-valid_request(struct passwd *pw, char *host, struct sshkey **ret, ++valid_request(struct passwd *pw, char *host, struct sshkey **ret, char **pkalgp, + u_char *data, size_t datalen) + { + struct sshbuf *b; +@@ -75,6 +75,8 @@ valid_request(struct passwd *pw, char *h + + if (ret != NULL) + *ret = NULL; ++ if (pkalgp != NULL) ++ *pkalgp = NULL; + fail = 0; + + if ((b = sshbuf_from(data, datalen)) == NULL) +@@ -122,8 +124,6 @@ valid_request(struct passwd *pw, char *h + fail++; + } else if (key->type != pktype) + fail++; +- free(pkalg); +- free(pkblob); + + /* client host name, handle trailing dot */ + if ((r = sshbuf_get_cstring(b, &p, &len)) != 0) +@@ -154,8 +154,19 @@ valid_request(struct passwd *pw, char *h + + if (fail) + sshkey_free(key); +- else if (ret != NULL) +- *ret = key; ++ else { ++ if (ret != NULL) { ++ *ret = key; ++ key = NULL; ++ } ++ if (pkalgp != NULL) { ++ *pkalgp = pkalg; ++ pkalg = NULL; ++ } ++ } ++ sshkey_free(key); ++ free(pkalg); ++ free(pkblob); + + return (fail ? -1 : 0); + } +@@ -170,7 +181,7 @@ main(int argc, char **argv) + struct passwd *pw; + int r, key_fd[NUM_KEYTYPES], i, found, version = 2, fd; + u_char *signature, *data, rver; +- char *host, *fp; ++ char *host, *fp, *pkalg; + size_t slen, dlen; + + if (pledge("stdio rpath getpw dns id", NULL) != 0) +@@ -258,7 +269,7 @@ main(int argc, char **argv) + + if ((r = sshbuf_get_string(b, &data, &dlen)) != 0) + fatal_r(r, "%s: buffer error", __progname); +- if (valid_request(pw, host, &key, data, dlen) < 0) ++ if (valid_request(pw, host, &key, &pkalg, data, dlen) < 0) + fatal("%s: not a valid request", __progname); + free(host); + +@@ -279,7 +290,7 @@ main(int argc, char **argv) + } + + if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, +- NULL, NULL, NULL, 0)) != 0) ++ pkalg, NULL, NULL, 0)) != 0) + fatal_r(r, "%s: sshkey_sign failed", __progname); + free(data); + diff --git a/openssh.spec b/openssh.spec index 7610156..eb824bf 100644 --- a/openssh.spec +++ b/openssh.spec @@ -240,6 +240,12 @@ Patch1003: openssh-8.7p1-mem-leak.patch # upstream MR: # https://github.com/openssh-gsskex/openssh-gsskex/pull/21 Patch1004: openssh-8.7p1-gssapi-auth.patch +# Fix host-based authentication with rsa keys +# upstream commits: +# 7aa7b096cf2bafe2777085abdeed5ce00581f641 +# d9dbb5d9a0326e252d3c7bc13beb9c2434f59409 +# fdb1d58d0d3888b042e5a500f6ce524486aaf782 +Patch1005: openssh-8.7p1-host-based-auth.patch License: BSD Requires: /sbin/nologin @@ -433,6 +439,7 @@ popd %patch1002 -p1 -b .ssh-manpage %patch1003 -p1 -b .mem-leak %patch1004 -p1 -b .gssapi-auth +%patch1005 -p1 -b .host-based-auth %patch100 -p1 -b .coverity @@ -722,6 +729,8 @@ test -f %{sysconfig_anaconda} && \ Related: rhbz#2068423 - Fix gssapi authentication failures Resolves: rhbz#2091023 +- Fix host-based authentication with rsa keys + Resolves: rhbz#2088916 * Wed Jun 29 2022 Dmitry Belyavskiy - 8.7p1-10 - Set minimal value of RSA key length via configuration option