summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Vernon <mcv21@cam.ac.uk>2014-03-26 15:32:23 +0000
committerColin Watson <cjwatson@debian.org>2014-04-14 12:11:00 +0100
commit08a63152deb5deda168aaef870bdb9f56425acb3 (patch)
treea4863747b299069b17b1a4875d07f8b7a5f050c4
parentdf5c8d109fb3d9ec16a487107a44300ed3006849 (diff)
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
-rw-r--r--sshconnect.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/sshconnect.c b/sshconnect.c
index 87c3770c0..324f5e0a3 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1224,29 +1224,39 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
1224{ 1224{
1225 int flags = 0; 1225 int flags = 0;
1226 char *fp; 1226 char *fp;
1227 Key *plain = NULL;
1227 1228
1228 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); 1229 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
1229 debug("Server host key: %s %s", key_type(host_key), fp); 1230 debug("Server host key: %s %s", key_type(host_key), fp);
1230 free(fp); 1231 free(fp);
1231 1232
1232 /* XXX certs are not yet supported for DNS */ 1233 if (options.verify_host_key_dns) {
1233 if (!key_is_cert(host_key) && options.verify_host_key_dns && 1234 /*
1234 verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { 1235 * XXX certs are not yet supported for DNS, so downgrade
1235 if (flags & DNS_VERIFY_FOUND) { 1236 * them and try the plain key.
1236 1237 */
1237 if (options.verify_host_key_dns == 1 && 1238 plain = key_from_private(host_key);
1238 flags & DNS_VERIFY_MATCH && 1239 if (key_is_cert(plain))
1239 flags & DNS_VERIFY_SECURE) 1240 key_drop_cert(plain);
1240 return 0; 1241 if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) {
1241 1242 if (flags & DNS_VERIFY_FOUND) {
1242 if (flags & DNS_VERIFY_MATCH) { 1243 if (options.verify_host_key_dns == 1 &&
1243 matching_host_key_dns = 1; 1244 flags & DNS_VERIFY_MATCH &&
1244 } else { 1245 flags & DNS_VERIFY_SECURE) {
1245 warn_changed_key(host_key); 1246 key_free(plain);
1246 error("Update the SSHFP RR in DNS with the new " 1247 return 0;
1247 "host key to get rid of this message."); 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 }
1248 } 1257 }
1249 } 1258 }
1259 key_free(plain);
1250 } 1260 }
1251 1261
1252 return check_host_key(host, hostaddr, options.port, host_key, RDRW, 1262 return check_host_key(host, hostaddr, options.port, host_key, RDRW,