diff options
author | Damien Miller <djm@mindrot.org> | 2003-11-17 21:19:29 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2003-11-17 21:19:29 +1100 |
commit | 150b55745b5a0790cfc8d5e6560ab5e7f2f94340 (patch) | |
tree | a2e1af4415a75cc498ad8ce318607da5cbf273a5 /dns.c | |
parent | c1f2792bd056dcefef5de55c5cbfdb1f790fd339 (diff) |
- jakob@cvs.openbsd.org 2003/11/12 16:39:58
[dns.c dns.h readconf.c ssh_config.5 sshconnect.c]
update SSHFP validation. ok markus@
Diffstat (limited to 'dns.c')
-rw-r--r-- | dns.c | 68 |
1 files changed, 28 insertions, 40 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: dns.c,v 1.7 2003/10/14 19:42:10 jakob Exp $ */ | 1 | /* $OpenBSD: dns.c,v 1.8 2003/11/12 16:39:58 jakob Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2003 Wesley Griffin. All rights reserved. | 4 | * Copyright (c) 2003 Wesley Griffin. All rights reserved. |
@@ -43,7 +43,7 @@ | |||
43 | #include "uuencode.h" | 43 | #include "uuencode.h" |
44 | 44 | ||
45 | extern char *__progname; | 45 | extern char *__progname; |
46 | RCSID("$OpenBSD: dns.c,v 1.7 2003/10/14 19:42:10 jakob Exp $"); | 46 | RCSID("$OpenBSD: dns.c,v 1.8 2003/11/12 16:39:58 jakob Exp $"); |
47 | 47 | ||
48 | #ifndef LWRES | 48 | #ifndef LWRES |
49 | static const char *errset_text[] = { | 49 | static const char *errset_text[] = { |
@@ -83,7 +83,7 @@ dns_result_totext(unsigned int error) | |||
83 | */ | 83 | */ |
84 | static int | 84 | static int |
85 | dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, | 85 | dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, |
86 | u_char **digest, u_int *digest_len, Key *key) | 86 | u_char **digest, u_int *digest_len, const Key *key) |
87 | { | 87 | { |
88 | int success = 0; | 88 | int success = 0; |
89 | 89 | ||
@@ -145,16 +145,15 @@ dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type, | |||
145 | 145 | ||
146 | /* | 146 | /* |
147 | * Verify the given hostname, address and host key using DNS. | 147 | * Verify the given hostname, address and host key using DNS. |
148 | * Returns 0 if key verifies or -1 if key does NOT verify | 148 | * Returns 0 if lookup succeeds, -1 otherwise |
149 | */ | 149 | */ |
150 | int | 150 | int |
151 | verify_host_key_dns(const char *hostname, struct sockaddr *address, | 151 | verify_host_key_dns(const char *hostname, struct sockaddr *address, |
152 | Key *hostkey) | 152 | const Key *hostkey, int *flags) |
153 | { | 153 | { |
154 | int counter; | 154 | int counter; |
155 | int result; | 155 | int result; |
156 | struct rrsetinfo *fingerprints = NULL; | 156 | struct rrsetinfo *fingerprints = NULL; |
157 | int failures = 0; | ||
158 | 157 | ||
159 | u_int8_t hostkey_algorithm; | 158 | u_int8_t hostkey_algorithm; |
160 | u_int8_t hostkey_digest_type; | 159 | u_int8_t hostkey_digest_type; |
@@ -166,6 +165,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, | |||
166 | u_char *dnskey_digest; | 165 | u_char *dnskey_digest; |
167 | u_int dnskey_digest_len; | 166 | u_int dnskey_digest_len; |
168 | 167 | ||
168 | *flags = 0; | ||
169 | 169 | ||
170 | debug3("verify_hostkey_dns"); | 170 | debug3("verify_hostkey_dns"); |
171 | if (hostkey == NULL) | 171 | if (hostkey == NULL) |
@@ -175,28 +175,29 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, | |||
175 | DNS_RDATATYPE_SSHFP, 0, &fingerprints); | 175 | DNS_RDATATYPE_SSHFP, 0, &fingerprints); |
176 | if (result) { | 176 | if (result) { |
177 | verbose("DNS lookup error: %s", dns_result_totext(result)); | 177 | verbose("DNS lookup error: %s", dns_result_totext(result)); |
178 | return DNS_VERIFY_ERROR; | 178 | return -1; |
179 | } | 179 | } |
180 | 180 | ||
181 | #ifdef DNSSEC | 181 | if (fingerprints->rri_flags & RRSET_VALIDATED) { |
182 | /* Only accept validated answers */ | 182 | *flags |= DNS_VERIFY_SECURE; |
183 | if (!fingerprints->rri_flags & RRSET_VALIDATED) { | 183 | debug("found %d secure fingerprints in DNS", |
184 | error("Ignored unvalidated fingerprint from DNS."); | 184 | fingerprints->rri_nrdatas); |
185 | freerrset(fingerprints); | 185 | } else { |
186 | return DNS_VERIFY_ERROR; | 186 | debug("found %d insecure fingerprints in DNS", |
187 | fingerprints->rri_nrdatas); | ||
187 | } | 188 | } |
188 | #endif | ||
189 | |||
190 | debug("found %d fingerprints in DNS", fingerprints->rri_nrdatas); | ||
191 | 189 | ||
192 | /* Initialize host key parameters */ | 190 | /* Initialize host key parameters */ |
193 | if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type, | 191 | if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type, |
194 | &hostkey_digest, &hostkey_digest_len, hostkey)) { | 192 | &hostkey_digest, &hostkey_digest_len, hostkey)) { |
195 | error("Error calculating host key fingerprint."); | 193 | error("Error calculating host key fingerprint."); |
196 | freerrset(fingerprints); | 194 | freerrset(fingerprints); |
197 | return DNS_VERIFY_ERROR; | 195 | return -1; |
198 | } | 196 | } |
199 | 197 | ||
198 | if (fingerprints->rri_nrdatas) | ||
199 | *flags |= DNS_VERIFY_FOUND; | ||
200 | |||
200 | for (counter = 0 ; counter < fingerprints->rri_nrdatas ; counter++) { | 201 | for (counter = 0 ; counter < fingerprints->rri_nrdatas ; counter++) { |
201 | /* | 202 | /* |
202 | * Extract the key from the answer. Ignore any badly | 203 | * Extract the key from the answer. Ignore any badly |
@@ -218,35 +219,22 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, | |||
218 | memcmp(hostkey_digest, dnskey_digest, | 219 | memcmp(hostkey_digest, dnskey_digest, |
219 | hostkey_digest_len) == 0) { | 220 | hostkey_digest_len) == 0) { |
220 | 221 | ||
221 | /* Matching algoritm and digest. */ | 222 | *flags |= DNS_VERIFY_MATCH; |
222 | freerrset(fingerprints); | ||
223 | debug("matching host key fingerprint found in DNS"); | ||
224 | return DNS_VERIFY_OK; | ||
225 | } else { | ||
226 | /* Correct algorithm but bad digest */ | ||
227 | debug("verify_hostkey_dns: failed"); | ||
228 | failures++; | ||
229 | } | 223 | } |
230 | } | 224 | } |
231 | } | 225 | } |
232 | 226 | ||
233 | freerrset(fingerprints); | 227 | freerrset(fingerprints); |
234 | 228 | ||
235 | if (failures) { | 229 | if (*flags & DNS_VERIFY_FOUND) |
236 | error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); | 230 | if (*flags & DNS_VERIFY_MATCH) |
237 | error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); | 231 | debug("matching host key fingerprint found in DNS"); |
238 | error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); | 232 | else |
239 | error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); | 233 | debug("mismatching host key fingerprint found in DNS"); |
240 | error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); | 234 | else |
241 | error("It is also possible that the %s host key has just been changed.", | 235 | debug("no host key fingerprint found in DNS"); |
242 | key_type(hostkey)); | ||
243 | error("Please contact your system administrator."); | ||
244 | return DNS_VERIFY_FAILED; | ||
245 | } | ||
246 | |||
247 | debug("fingerprints found in DNS, but none of them matched"); | ||
248 | 236 | ||
249 | return DNS_VERIFY_ERROR; | 237 | return 0; |
250 | } | 238 | } |
251 | 239 | ||
252 | 240 | ||
@@ -254,7 +242,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, | |||
254 | * Export the fingerprint of a key as a DNS resource record | 242 | * Export the fingerprint of a key as a DNS resource record |
255 | */ | 243 | */ |
256 | int | 244 | int |
257 | export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) | 245 | export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic) |
258 | { | 246 | { |
259 | u_int8_t rdata_pubkey_algorithm = 0; | 247 | u_int8_t rdata_pubkey_algorithm = 0; |
260 | u_int8_t rdata_digest_type = SSHFP_HASH_SHA1; | 248 | u_int8_t rdata_digest_type = SSHFP_HASH_SHA1; |