diff --git a/SOURCES/openssh-7.7p1-fips.patch b/SOURCES/openssh-7.7p1-fips.patch index 32091e3..2fb8200 100644 --- a/SOURCES/openssh-7.7p1-fips.patch +++ b/SOURCES/openssh-7.7p1-fips.patch @@ -296,17 +296,17 @@ diff -up openssh-7.9p1/sshconnect2.c.fips openssh-7.9p1/sshconnect2.c #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" -@@ -117,7 +117,8 @@ order_hostkeyalgs(char *host, struct soc - for (i = 0; i < options.num_system_hostfiles; i++) - load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); - +@@ -148,7 +150,8 @@ order_hostkeyalgs(char *host, struct soc + * Otherwise, prefer the host key algorithms that match known keys + * while keeping the ordering of HostkeyAlgorithms as much as possible. + */ - oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); + oavail = avail = xstrdup((FIPS_mode() + ? KEX_FIPS_PK_ALG : KEX_DEFAULT_PK_ALG)); maxlen = strlen(avail) + 1; first = xmalloc(maxlen); last = xmalloc(maxlen); -@@ -185,14 +185,16 @@ ssh_kex2(char *host, struct sockaddr *ho +@@ -229,14 +232,16 @@ ssh_kex2(struct ssh *ssh, char *host, st if (options.hostkeyalgorithms != NULL) { all_key = sshkey_alg_list(0, 0, 1, ','); if (kex_assemble_names(&options.hostkeyalgorithms, diff --git a/SOURCES/openssh-7.8p1-role-mls.patch b/SOURCES/openssh-7.8p1-role-mls.patch index 84ba9b3..c3bec2a 100644 --- a/SOURCES/openssh-7.8p1-role-mls.patch +++ b/SOURCES/openssh-7.8p1-role-mls.patch @@ -284,7 +284,7 @@ diff -up openssh/monitor.c.role-mls openssh/monitor.c fail++; if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); -+ if ((s = strchr(p, '/')) != NULL) ++ if ((s = strchr(cp, '/')) != NULL) + *s = '\0'; xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", diff --git a/SOURCES/openssh-8.0p1-cve-2020-14145.patch b/SOURCES/openssh-8.0p1-cve-2020-14145.patch new file mode 100644 index 0000000..c296bc4 --- /dev/null +++ b/SOURCES/openssh-8.0p1-cve-2020-14145.patch @@ -0,0 +1,127 @@ +diff -up openssh-8.0p1/hostfile.c.cve-2020-14145 openssh-8.0p1/hostfile.c +--- openssh-8.0p1/hostfile.c.cve-2020-14145 2019-04-18 00:52:57.000000000 +0200 ++++ openssh-8.0p1/hostfile.c 2021-05-17 16:53:38.694577251 +0200 +@@ -409,6 +409,18 @@ lookup_key_in_hostkeys_by_type(struct ho + found) == HOST_FOUND); + } + ++int ++lookup_marker_in_hostkeys(struct hostkeys *hostkeys, int want_marker) ++{ ++ u_int i; ++ ++ for (i = 0; i < hostkeys->num_entries; i++) { ++ if (hostkeys->entries[i].marker == (HostkeyMarker)want_marker) ++ return 1; ++ } ++ return 0; ++} ++ + static int + write_host_entry(FILE *f, const char *host, const char *ip, + const struct sshkey *key, int store_hash) +diff -up openssh-8.0p1/hostfile.h.cve-2020-14145 openssh-8.0p1/hostfile.h +--- openssh-8.0p1/hostfile.h.cve-2020-14145 2019-04-18 00:52:57.000000000 +0200 ++++ openssh-8.0p1/hostfile.h 2021-05-17 16:53:38.694577251 +0200 +@@ -39,6 +39,7 @@ HostStatus check_key_in_hostkeys(struct + const struct hostkey_entry **); + int lookup_key_in_hostkeys_by_type(struct hostkeys *, int, + const struct hostkey_entry **); ++int lookup_marker_in_hostkeys(struct hostkeys *, int); + + int hostfile_read_key(char **, u_int *, struct sshkey *); + int add_host_to_hostfile(const char *, const char *, +diff -up openssh-8.0p1/sshconnect2.c.cve-2020-14145 openssh-8.0p1/sshconnect2.c +--- openssh-8.0p1/sshconnect2.c.cve-2020-14145 2021-05-17 16:53:38.610576561 +0200 ++++ openssh-8.0p1/sshconnect2.c 2021-05-17 16:54:58.169230103 +0200 +@@ -98,12 +98,25 @@ verify_host_key_callback(struct sshkey * + return 0; + } + ++/* Returns the first item from a comma-separated algorithm list */ ++static char * ++first_alg(const char *algs) ++{ ++ char *ret, *cp; ++ ++ ret = xstrdup(algs); ++ if ((cp = strchr(ret, ',')) != NULL) ++ *cp = '\0'; ++ return ret; ++} ++ + static char * + order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) + { +- char *oavail, *avail, *first, *last, *alg, *hostname, *ret; ++ char *oavail = NULL, *avail = NULL, *first = NULL, *last = NULL; ++ char *alg = NULL, *hostname = NULL, *ret = NULL, *best = NULL; + size_t maxlen; +- struct hostkeys *hostkeys; ++ struct hostkeys *hostkeys = NULL; + int ktype; + u_int i; + +@@ -115,6 +128,26 @@ order_hostkeyalgs(char *host, struct soc + for (i = 0; i < options.num_system_hostfiles; i++) + load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); + ++ /* ++ * If a plain public key exists that matches the type of the best ++ * preference HostkeyAlgorithms, then use the whole list as is. ++ * Note that we ignore whether the best preference algorithm is a ++ * certificate type, as sshconnect.c will downgrade certs to ++ * plain keys if necessary. ++ */ ++ best = first_alg(options.hostkeyalgorithms); ++ if (lookup_key_in_hostkeys_by_type(hostkeys, ++ sshkey_type_plain(sshkey_type_from_name(best)), NULL)) { ++ debug3("%s: have matching best-preference key type %s, " ++ "using HostkeyAlgorithms verbatim", __func__, best); ++ ret = xstrdup(options.hostkeyalgorithms); ++ goto out; ++ } ++ ++ /* ++ * Otherwise, prefer the host key algorithms that match known keys ++ * while keeping the ordering of HostkeyAlgorithms as much as possible. ++ */ + oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); + maxlen = strlen(avail) + 1; + first = xmalloc(maxlen); +@@ -131,11 +164,23 @@ order_hostkeyalgs(char *host, struct soc + while ((alg = strsep(&avail, ",")) && *alg != '\0') { + if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) + fatal("%s: unknown alg %s", __func__, alg); ++ /* ++ * If we have a @cert-authority marker in known_hosts then ++ * prefer all certificate algorithms. ++ */ ++ if (sshkey_type_is_cert(ktype) && ++ lookup_marker_in_hostkeys(hostkeys, MRK_CA)) { ++ ALG_APPEND(first, alg); ++ continue; ++ } ++ /* If the key appears in known_hosts then prefer it */ + if (lookup_key_in_hostkeys_by_type(hostkeys, +- sshkey_type_plain(ktype), NULL)) ++ sshkey_type_plain(ktype), NULL)) { + ALG_APPEND(first, alg); +- else +- ALG_APPEND(last, alg); ++ continue; ++ } ++ /* Otherwise, put it last */ ++ ALG_APPEND(last, alg); + } + #undef ALG_APPEND + xasprintf(&ret, "%s%s%s", first, +@@ -143,6 +188,8 @@ order_hostkeyalgs(char *host, struct soc + if (*first != '\0') + debug3("%s: prefer hostkeyalgs: %s", __func__, first); + ++ out: ++ free(best); + free(first); + free(last); + free(hostname); diff --git a/SPECS/openssh.spec b/SPECS/openssh.spec index 46d1f12..a955991 100644 --- a/SPECS/openssh.spec +++ b/SPECS/openssh.spec @@ -66,7 +66,7 @@ # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 %global openssh_ver 8.0p1 -%global openssh_rel 8 +%global openssh_rel 9 %global pam_ssh_agent_ver 0.10.3 %global pam_ssh_agent_rel 7 @@ -241,6 +241,8 @@ Patch974: openssh-8.0p1-keygen-strip-doseol.patch Patch975: openssh-8.0p1-preserve-pam-errors.patch # ssh incorrectly restores the blocking mode on standard output (#1942901) Patch976: openssh-8.0p1-restore-nonblock.patch +# CVE 2020-14145 +Patch977: openssh-8.0p1-cve-2020-14145.patch License: BSD Group: Applications/Internet @@ -464,6 +466,7 @@ popd %patch974 -p1 -b .keygen-strip-doseol %patch975 -p1 -b .preserve-pam-errors %patch976 -p1 -b .restore-nonblock +%patch977 -p1 -b .cve-2020-14145 %patch200 -p1 -b .audit %patch201 -p1 -b .audit-race @@ -755,6 +758,11 @@ getent passwd sshd >/dev/null || \ %endif %changelog +* Wed Jun 02 2021 Dmitry Belyavskiy - 8.0p1-9 +- CVE-2020-14145 openssh: Observable Discrepancy leading to an information + leak in the algorithm negotiation (#1882252) +- Hostbased ssh authentication fails if session ID contains a '/' (#1944125) + * Mon Apr 26 2021 Dmitry Belyavskiy - 8.0p1-8 - ssh doesn't restore the blocking mode on standard output (#1942901)