summaryrefslogtreecommitdiff
path: root/debian/patches/sshfp_with_server_cert
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/sshfp_with_server_cert')
-rw-r--r--debian/patches/sshfp_with_server_cert112
1 files changed, 112 insertions, 0 deletions
diff --git a/debian/patches/sshfp_with_server_cert b/debian/patches/sshfp_with_server_cert
new file mode 100644
index 000000000..7e6a489e6
--- /dev/null
+++ b/debian/patches/sshfp_with_server_cert
@@ -0,0 +1,112 @@
1From db4cdf7b763414af951c7f4031b10679c54d7988 Mon Sep 17 00:00:00 2001
2From: Matthew Vernon <mcv21@cam.ac.uk>
3Date: Tue, 25 Mar 2014 11:02:33 +0000
4Subject: Attempt SSHFP lookup even if server presents a certificate
5
6If an ssh server presents a certificate to the client, then the client
7does not check the DNS for SSHFP records. This means that a malicious
8server can essentially disable DNS-host-key-checking, which means the
9client will fall back to asking the user (who will just say "yes" to
10the fingerprint, sadly).
11
12This patch means that the ssh client will, if necessary, extract the
13server key from the proffered certificate, and attempt to verify it
14against the DNS. The patch was written by Mark Wooding
15<mdw@distorted.org.uk>. I modified it to add one debug2 call, reviewed
16it, and tested it.
17
18Signed-off-by: Matthew Vernon <matthew@debian.org>
19Bug-Debian: http://bugs.debian.org/742513
20Patch-Name: sshfp_with_server_cert
21---
22 sshconnect.c | 67 ++++++++++++++++++++++++++++++++++++++++------------------
23 1 file changed, 47 insertions(+), 20 deletions(-)
24
25diff --git a/sshconnect.c b/sshconnect.c
26index 87c3770..b8510d2 100644
27--- a/sshconnect.c
28+++ b/sshconnect.c
29@@ -1218,36 +1218,63 @@ fail:
30 return -1;
31 }
32
33+static int
34+check_host_key_sshfp(char *host, struct sockaddr *hostaddr, Key *host_key)
35+{
36+ int rc = -1;
37+ int flags = 0;
38+ Key *raw_key = NULL;
39+
40+ if (!options.verify_host_key_dns)
41+ goto done;
42+
43+ /* XXX certs are not yet supported for DNS; try looking the raw key
44+ * up in the DNS anyway.
45+ */
46+ if (key_is_cert(host_key)) {
47+ debug2("Extracting key from cert for SSHFP lookup");
48+ raw_key = key_from_private(host_key);
49+ if (key_drop_cert(raw_key))
50+ fatal("Couldn't drop certificate");
51+ host_key = raw_key;
52+ }
53+
54+ if (verify_host_key_dns(host, hostaddr, host_key, &flags))
55+ goto done;
56+
57+ if (flags & DNS_VERIFY_FOUND) {
58+
59+ if (options.verify_host_key_dns == 1 &&
60+ flags & DNS_VERIFY_MATCH &&
61+ flags & DNS_VERIFY_SECURE) {
62+ rc = 0;
63+ } else if (flags & DNS_VERIFY_MATCH) {
64+ matching_host_key_dns = 1;
65+ } else {
66+ warn_changed_key(host_key);
67+ error("Update the SSHFP RR in DNS with the new "
68+ "host key to get rid of this message.");
69+ }
70+ }
71+
72+done:
73+ if (raw_key)
74+ key_free(raw_key);
75+ return rc;
76+}
77+
78 /* returns 0 if key verifies or -1 if key does NOT verify */
79 int
80 verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
81 {
82- int flags = 0;
83 char *fp;
84
85 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
86 debug("Server host key: %s %s", key_type(host_key), fp);
87 free(fp);
88
89- /* XXX certs are not yet supported for DNS */
90- if (!key_is_cert(host_key) && options.verify_host_key_dns &&
91- verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
92- if (flags & DNS_VERIFY_FOUND) {
93-
94- if (options.verify_host_key_dns == 1 &&
95- flags & DNS_VERIFY_MATCH &&
96- flags & DNS_VERIFY_SECURE)
97- return 0;
98-
99- if (flags & DNS_VERIFY_MATCH) {
100- matching_host_key_dns = 1;
101- } else {
102- warn_changed_key(host_key);
103- error("Update the SSHFP RR in DNS with the new "
104- "host key to get rid of this message.");
105- }
106- }
107- }
108+ if (check_host_key_sshfp(host, hostaddr, host_key) == 0)
109+ return 0;
110
111 return check_host_key(host, hostaddr, options.port, host_key, RDRW,
112 options.user_hostfiles, options.num_user_hostfiles,