summaryrefslogtreecommitdiff
path: root/dns.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2003-11-17 21:19:29 +1100
committerDamien Miller <djm@mindrot.org>2003-11-17 21:19:29 +1100
commit150b55745b5a0790cfc8d5e6560ab5e7f2f94340 (patch)
treea2e1af4415a75cc498ad8ce318607da5cbf273a5 /dns.c
parentc1f2792bd056dcefef5de55c5cbfdb1f790fd339 (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.c68
1 files changed, 28 insertions, 40 deletions
diff --git a/dns.c b/dns.c
index 2fff1b802..2342b6609 100644
--- a/dns.c
+++ b/dns.c
@@ -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
45extern char *__progname; 45extern char *__progname;
46RCSID("$OpenBSD: dns.c,v 1.7 2003/10/14 19:42:10 jakob Exp $"); 46RCSID("$OpenBSD: dns.c,v 1.8 2003/11/12 16:39:58 jakob Exp $");
47 47
48#ifndef LWRES 48#ifndef LWRES
49static const char *errset_text[] = { 49static const char *errset_text[] = {
@@ -83,7 +83,7 @@ dns_result_totext(unsigned int error)
83 */ 83 */
84static int 84static int
85dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, 85dns_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 */
150int 150int
151verify_host_key_dns(const char *hostname, struct sockaddr *address, 151verify_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 */
256int 244int
257export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) 245export_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;