summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/.git-dpm4
-rw-r--r--debian/changelog3
-rw-r--r--debian/patches/series2
-rw-r--r--debian/patches/sshfp_with_server_cert112
-rw-r--r--debian/patches/sshfp_with_server_cert_upstr83
-rw-r--r--sshconnect.c77
6 files changed, 118 insertions, 163 deletions
diff --git a/debian/.git-dpm b/debian/.git-dpm
index e8c4eb71a..6b27e0a3f 100644
--- a/debian/.git-dpm
+++ b/debian/.git-dpm
@@ -1,6 +1,6 @@
1# see git-dpm(1) from git-dpm package 1# see git-dpm(1) from git-dpm package
2db4cdf7b763414af951c7f4031b10679c54d7988 263d5fa28e16d96db6bac2dbe3fcecb65328f8966
3db4cdf7b763414af951c7f4031b10679c54d7988 363d5fa28e16d96db6bac2dbe3fcecb65328f8966
4796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7 4796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7
5796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7 5796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7
6openssh_6.6p1.orig.tar.gz 6openssh_6.6p1.orig.tar.gz
diff --git a/debian/changelog b/debian/changelog
index d92aac4a7..017f5bb0e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -11,7 +11,8 @@ openssh (1:6.6p1-1) UNRELEASED; urgency=medium
11 11
12 [ Matthew Vernon ] 12 [ Matthew Vernon ]
13 * Fix failure to check SSHFP records if server presents a certificate 13 * Fix failure to check SSHFP records if server presents a certificate
14 (bug reported by me, patch largely by Mark Wooding) (Closes: #742513) 14 (bug reported by me, patch by upstream's Damien Miller; thanks also to
15 Mark Wooding for his help in fixing this) (Closes: #742513)
15 16
16 -- Colin Watson <cjwatson@debian.org> Thu, 20 Mar 2014 00:32:46 +0000 17 -- Colin Watson <cjwatson@debian.org> Thu, 20 Mar 2014 00:32:46 +0000
17 18
diff --git a/debian/patches/series b/debian/patches/series
index 7bd72e6ed..de7c9902d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -26,4 +26,4 @@ no-openssl-version-check.patch
26gnome-ssh-askpass2-icon.patch 26gnome-ssh-askpass2-icon.patch
27sigstop.patch 27sigstop.patch
28debian-config.patch 28debian-config.patch
29sshfp_with_server_cert 29sshfp_with_server_cert_upstr
diff --git a/debian/patches/sshfp_with_server_cert b/debian/patches/sshfp_with_server_cert
deleted file mode 100644
index 7e6a489e6..000000000
--- a/debian/patches/sshfp_with_server_cert
+++ /dev/null
@@ -1,112 +0,0 @@
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,
diff --git a/debian/patches/sshfp_with_server_cert_upstr b/debian/patches/sshfp_with_server_cert_upstr
new file mode 100644
index 000000000..dd642d2a3
--- /dev/null
+++ b/debian/patches/sshfp_with_server_cert_upstr
@@ -0,0 +1,83 @@
1From 63d5fa28e16d96db6bac2dbe3fcecb65328f8966 Mon Sep 17 00:00:00 2001
2From: Matthew Vernon <mcv21@cam.ac.uk>
3Date: Wed, 26 Mar 2014 15:32:23 +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 is by Damien Miller (of openssh upstream). It's simpler
13than the patch by Mark Wooding which I applied yesterday; a copy is
14taken of the proffered key/cert, the key extracted from the cert (if
15necessary), and then the DNS consulted.
16
17Signed-off-by: Matthew Vernon <matthew@debian.org>
18Bug-Debian: http://bugs.debian.org/742513
19Patch-Name: sshfp_with_server_cert_upstr
20---
21 sshconnect.c | 42 ++++++++++++++++++++++++++----------------
22 1 file changed, 26 insertions(+), 16 deletions(-)
23
24diff --git a/sshconnect.c b/sshconnect.c
25index 87c3770..324f5e0 100644
26--- a/sshconnect.c
27+++ b/sshconnect.c
28@@ -1224,29 +1224,39 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
29 {
30 int flags = 0;
31 char *fp;
32+ Key *plain = NULL;
33
34 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
35 debug("Server host key: %s %s", key_type(host_key), fp);
36 free(fp);
37
38- /* XXX certs are not yet supported for DNS */
39- if (!key_is_cert(host_key) && options.verify_host_key_dns &&
40- verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
41- if (flags & DNS_VERIFY_FOUND) {
42-
43- if (options.verify_host_key_dns == 1 &&
44- flags & DNS_VERIFY_MATCH &&
45- flags & DNS_VERIFY_SECURE)
46- return 0;
47-
48- if (flags & DNS_VERIFY_MATCH) {
49- matching_host_key_dns = 1;
50- } else {
51- warn_changed_key(host_key);
52- error("Update the SSHFP RR in DNS with the new "
53- "host key to get rid of this message.");
54+ if (options.verify_host_key_dns) {
55+ /*
56+ * XXX certs are not yet supported for DNS, so downgrade
57+ * them and try the plain key.
58+ */
59+ plain = key_from_private(host_key);
60+ if (key_is_cert(plain))
61+ key_drop_cert(plain);
62+ if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) {
63+ if (flags & DNS_VERIFY_FOUND) {
64+ if (options.verify_host_key_dns == 1 &&
65+ flags & DNS_VERIFY_MATCH &&
66+ flags & DNS_VERIFY_SECURE) {
67+ key_free(plain);
68+ return 0;
69+ }
70+ if (flags & DNS_VERIFY_MATCH) {
71+ matching_host_key_dns = 1;
72+ } else {
73+ warn_changed_key(plain);
74+ error("Update the SSHFP RR in DNS "
75+ "with the new host key to get rid "
76+ "of this message.");
77+ }
78 }
79 }
80+ key_free(plain);
81 }
82
83 return check_host_key(host, hostaddr, options.port, host_key, RDRW,
diff --git a/sshconnect.c b/sshconnect.c
index b8510d201..324f5e0a3 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1218,63 +1218,46 @@ fail:
1218 return -1; 1218 return -1;
1219} 1219}
1220 1220
1221static int
1222check_host_key_sshfp(char *host, struct sockaddr *hostaddr, Key *host_key)
1223{
1224 int rc = -1;
1225 int flags = 0;
1226 Key *raw_key = NULL;
1227
1228 if (!options.verify_host_key_dns)
1229 goto done;
1230
1231 /* XXX certs are not yet supported for DNS; try looking the raw key
1232 * up in the DNS anyway.
1233 */
1234 if (key_is_cert(host_key)) {
1235 debug2("Extracting key from cert for SSHFP lookup");
1236 raw_key = key_from_private(host_key);
1237 if (key_drop_cert(raw_key))
1238 fatal("Couldn't drop certificate");
1239 host_key = raw_key;
1240 }
1241
1242 if (verify_host_key_dns(host, hostaddr, host_key, &flags))
1243 goto done;
1244
1245 if (flags & DNS_VERIFY_FOUND) {
1246
1247 if (options.verify_host_key_dns == 1 &&
1248 flags & DNS_VERIFY_MATCH &&
1249 flags & DNS_VERIFY_SECURE) {
1250 rc = 0;
1251 } else if (flags & DNS_VERIFY_MATCH) {
1252 matching_host_key_dns = 1;
1253 } else {
1254 warn_changed_key(host_key);
1255 error("Update the SSHFP RR in DNS with the new "
1256 "host key to get rid of this message.");
1257 }
1258 }
1259
1260done:
1261 if (raw_key)
1262 key_free(raw_key);
1263 return rc;
1264}
1265
1266/* returns 0 if key verifies or -1 if key does NOT verify */ 1221/* returns 0 if key verifies or -1 if key does NOT verify */
1267int 1222int
1268verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) 1223verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
1269{ 1224{
1225 int flags = 0;
1270 char *fp; 1226 char *fp;
1227 Key *plain = NULL;
1271 1228
1272 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); 1229 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
1273 debug("Server host key: %s %s", key_type(host_key), fp); 1230 debug("Server host key: %s %s", key_type(host_key), fp);
1274 free(fp); 1231 free(fp);
1275 1232
1276 if (check_host_key_sshfp(host, hostaddr, host_key) == 0) 1233 if (options.verify_host_key_dns) {
1277 return 0; 1234 /*
1235 * XXX certs are not yet supported for DNS, so downgrade
1236 * them and try the plain key.
1237 */
1238 plain = key_from_private(host_key);
1239 if (key_is_cert(plain))
1240 key_drop_cert(plain);
1241 if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) {
1242 if (flags & DNS_VERIFY_FOUND) {
1243 if (options.verify_host_key_dns == 1 &&
1244 flags & DNS_VERIFY_MATCH &&
1245 flags & DNS_VERIFY_SECURE) {
1246 key_free(plain);
1247 return 0;
1248 }
1249 if (flags & DNS_VERIFY_MATCH) {
1250 matching_host_key_dns = 1;
1251 } else {
1252 warn_changed_key(plain);
1253 error("Update the SSHFP RR in DNS "
1254 "with the new host key to get rid "
1255 "of this message.");
1256 }
1257 }
1258 }
1259 key_free(plain);
1260 }
1278 1261
1279 return check_host_key(host, hostaddr, options.port, host_key, RDRW, 1262 return check_host_key(host, hostaddr, options.port, host_key, RDRW,
1280 options.user_hostfiles, options.num_user_hostfiles, 1263 options.user_hostfiles, options.num_user_hostfiles,