diff options
author | Matthew Vernon <mcv21@cam.ac.uk> | 2014-03-26 15:32:23 +0000 |
---|---|---|
committer | Matthew Vernon <mcv21@cam.ac.uk> | 2014-03-26 15:32:23 +0000 |
commit | 63d5fa28e16d96db6bac2dbe3fcecb65328f8966 (patch) | |
tree | bb4e8a04c5e5346fe0fffa4aeb5c8e9a13377c75 /sshconnect.c | |
parent | 9cbb60f5e4932634db04c330c88abc49cc5567bd (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
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 42 |
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, |