summaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/openssh/openssh/CVE-2020-14145.patch
blob: 0046ee1a5131a612a9d60ca9dabb97178a6253bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
From b3855ff053f5078ec3d3c653cdaedefaa5fc362d Mon Sep 17 00:00:00 2001
From: "djm@openbsd.org" <djm@openbsd.org>
Date: Fri, 18 Sep 2020 05:23:03 +0000
Subject: [PATCH] upstream: tweak the client hostkey preference ordering
 algorithm to

prefer the default ordering if the user has a key that matches the
best-preference default algorithm.

feedback and ok markus@

OpenBSD-Commit-ID: a92dd7d7520ddd95c0a16786a7519e6d0167d35f

Upstream-Status: Backport
[https://github.com/openssh/openssh-portable/commit/b3855ff053f5078ec3d3c653cdaedefaa5fc362d]
CVE: CVE-2020-14145
Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>

---
 sshconnect2.c | 41 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/sshconnect2.c b/sshconnect2.c
index 347e348c60..f64aae66af 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -102,12 +102,25 @@ verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
 	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;
 
@@ -119,6 +132,26 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
 	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(options.hostkeyalgorithms);
 	maxlen = strlen(avail) + 1;
 	first = xmalloc(maxlen);
@@ -159,6 +192,8 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
 	if (*first != '\0')
 		debug3("%s: prefer hostkeyalgs: %s", __func__, first);
 
+ out:
+	free(best);
 	free(first);
 	free(last);
 	free(hostname);