summaryrefslogtreecommitdiff
path: root/debian/patches/sshfp_with_server_cert_upstr
blob: b453081c5a5d99589c0d547e39e120ae83cd73ac (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
From 08a63152deb5deda168aaef870bdb9f56425acb3 Mon Sep 17 00:00:00 2001
From: Matthew Vernon <mcv21@cam.ac.uk>
Date: Wed, 26 Mar 2014 15:32:23 +0000
Subject: Attempt SSHFP lookup even if server presents a certificate

If an ssh server presents a certificate to the client, then the client
does not check the DNS for SSHFP records. This means that a malicious
server can essentially disable DNS-host-key-checking, which means the
client will fall back to asking the user (who will just say "yes" to
the fingerprint, sadly).

This patch is by Damien Miller (of openssh upstream). It's simpler
than the patch by Mark Wooding which I applied yesterday; a copy is
taken of the proffered key/cert, the key extracted from the cert (if
necessary), and then the DNS consulted.

Signed-off-by: Matthew Vernon <matthew@debian.org>
Bug-Debian: http://bugs.debian.org/742513
Patch-Name: sshfp_with_server_cert_upstr
---
 sshconnect.c | 42 ++++++++++++++++++++++++++----------------
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/sshconnect.c b/sshconnect.c
index 87c3770..324f5e0 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1224,29 +1224,39 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
 {
 	int flags = 0;
 	char *fp;
+	Key *plain = NULL;
 
 	fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
 	debug("Server host key: %s %s", key_type(host_key), fp);
 	free(fp);
 
-	/* XXX certs are not yet supported for DNS */
-	if (!key_is_cert(host_key) && options.verify_host_key_dns &&
-	    verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
-		if (flags & DNS_VERIFY_FOUND) {
-
-			if (options.verify_host_key_dns == 1 &&
-			    flags & DNS_VERIFY_MATCH &&
-			    flags & DNS_VERIFY_SECURE)
-				return 0;
-
-			if (flags & DNS_VERIFY_MATCH) {
-				matching_host_key_dns = 1;
-			} else {
-				warn_changed_key(host_key);
-				error("Update the SSHFP RR in DNS with the new "
-				    "host key to get rid of this message.");
+	if (options.verify_host_key_dns) {
+		/*
+		 * XXX certs are not yet supported for DNS, so downgrade
+		 * them and try the plain key.
+		 */
+		plain = key_from_private(host_key);
+		if (key_is_cert(plain))
+			key_drop_cert(plain);
+		if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) {
+			if (flags & DNS_VERIFY_FOUND) {
+				if (options.verify_host_key_dns == 1 &&
+				    flags & DNS_VERIFY_MATCH &&
+				    flags & DNS_VERIFY_SECURE) {
+					key_free(plain);
+					return 0;
+				}
+				if (flags & DNS_VERIFY_MATCH) {
+					matching_host_key_dns = 1;
+				} else {
+					warn_changed_key(plain);
+					error("Update the SSHFP RR in DNS "
+					    "with the new host key to get rid "
+					    "of this message.");
+				}
 			}
 		}
+		key_free(plain);
 	}
 
 	return check_host_key(host, hostaddr, options.port, host_key, RDRW,