]> andersk Git - openssh.git/blobdiff - dns.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / dns.c
diff --git a/dns.c b/dns.c
index ad634f1f75a758a6326c7c5661104bc4ccd1bf85..a7da03fa3efd14ce5feb2199995a2f344d01dbe0 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dns.c,v 1.9 2003/11/21 11:57:03 djm Exp $     */
+/* $OpenBSD: dns.c,v 1.25 2008/06/12 00:03:49 dtucker Exp $ */
 
 /*
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-
 #include "includes.h"
 
-#include <openssl/bn.h>
-#ifdef LWRES
-#include <lwres/netdb.h>
-#include <dns/result.h>
-#else /* LWRES */
+#include <sys/types.h>
+#include <sys/socket.h>
+
 #include <netdb.h>
-#endif /* LWRES */
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
 
 #include "xmalloc.h"
 #include "key.h"
 #include "dns.h"
 #include "log.h"
-#include "uuencode.h"
-
-extern char *__progname;
-RCSID("$OpenBSD: dns.c,v 1.9 2003/11/21 11:57:03 djm Exp $");
 
-#ifndef LWRES
 static const char *errset_text[] = {
        "success",              /* 0 ERRSET_SUCCESS */
        "out of memory",        /* 1 ERRSET_NOMEMORY */
@@ -56,9 +50,9 @@ static const char *errset_text[] = {
 };
 
 static const char *
-dns_result_totext(unsigned int error)
+dns_result_totext(unsigned int res)
 {
-       switch (error) {
+       switch (res) {
        case ERRSET_SUCCESS:
                return errset_text[ERRSET_SUCCESS];
        case ERRSET_NOMEMORY:
@@ -75,8 +69,6 @@ dns_result_totext(unsigned int error)
                return "unknown error";
        }
 }
-#endif /* LWRES */
-
 
 /*
  * Read SSHFP parameters from key buffer.
@@ -95,12 +87,14 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
                *algorithm = SSHFP_KEY_DSA;
                break;
        default:
-               *algorithm = SSHFP_KEY_RESERVED;
+               *algorithm = SSHFP_KEY_RESERVED; /* 0 */
        }
 
        if (*algorithm) {
                *digest_type = SSHFP_HASH_SHA1;
                *digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len);
+               if (*digest == NULL)
+                       fatal("dns_read_key: null from key_fingerprint_raw()");
                success = 1;
        } else {
                *digest_type = SSHFP_HASH_RESERVED;
@@ -133,7 +127,7 @@ dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type,
                        *digest = (u_char *) xmalloc(*digest_len);
                        memcpy(*digest, rdata + 2, *digest_len);
                } else {
-                       *digest = NULL;
+                       *digest = (u_char *)xstrdup("");
                }
 
                success = 1;
@@ -142,6 +136,35 @@ dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type,
        return success;
 }
 
+/*
+ * Check if hostname is numerical.
+ * Returns -1 if hostname is numeric, 0 otherwise
+ */
+static int
+is_numeric_hostname(const char *hostname)
+{
+       struct addrinfo hints, *ai;
+
+       /*
+        * We shouldn't ever get a null host but if we do then log an error
+        * and return -1 which stops DNS key fingerprint processing.
+        */
+       if (hostname == NULL) {
+               error("is_numeric_hostname called with NULL hostname");
+               return -1;
+       }
+
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_socktype = SOCK_DGRAM;
+       hints.ai_flags = AI_NUMERICHOST;
+
+       if (getaddrinfo(hostname, NULL, &hints, &ai) == 0) {
+               freeaddrinfo(ai);
+               return -1;
+       }
+
+       return 0;
+}
 
 /*
  * Verify the given hostname, address and host key using DNS.
@@ -151,7 +174,7 @@ int
 verify_host_key_dns(const char *hostname, struct sockaddr *address,
     const Key *hostkey, int *flags)
 {
-       int counter;
+       u_int counter;
        int result;
        struct rrsetinfo *fingerprints = NULL;
 
@@ -167,10 +190,15 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
 
        *flags = 0;
 
-       debug3("verify_hostkey_dns");
+       debug3("verify_host_key_dns");
        if (hostkey == NULL)
                fatal("No key to look up!");
 
+       if (is_numeric_hostname(hostname)) {
+               debug("skipped DNS lookup for numerical hostname");
+               return -1;
+       }
+
        result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
            DNS_RDATATYPE_SSHFP, 0, &fingerprints);
        if (result) {
@@ -198,7 +226,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
        if (fingerprints->rri_nrdatas)
                *flags |= DNS_VERIFY_FOUND;
 
-       for (counter = 0 ; counter < fingerprints->rri_nrdatas ; counter++)  {
+       for (counter = 0; counter < fingerprints->rri_nrdatas; counter++) {
                /*
                 * Extract the key from the answer. Ignore any badly
                 * formatted fingerprints.
@@ -222,8 +250,10 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
                                *flags |= DNS_VERIFY_MATCH;
                        }
                }
+               xfree(dnskey_digest);
        }
 
+       xfree(hostkey_digest); /* from key_fingerprint_raw() */
        freerrset(fingerprints);
 
        if (*flags & DNS_VERIFY_FOUND)
@@ -237,7 +267,6 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
        return 0;
 }
 
-
 /*
  * Export the fingerprint of a key as a DNS resource record
  */
@@ -249,11 +278,11 @@ export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic)
        u_char *rdata_digest;
        u_int rdata_digest_len;
 
-       int i;
+       u_int i;
        int success = 0;
 
        if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type,
-                        &rdata_digest, &rdata_digest_len, key)) {
+           &rdata_digest, &rdata_digest_len, key)) {
 
                if (generic)
                        fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", hostname,
@@ -266,9 +295,10 @@ export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic)
                for (i = 0; i < rdata_digest_len; i++)
                        fprintf(f, "%02x", rdata_digest[i]);
                fprintf(f, "\n");
+               xfree(rdata_digest); /* from key_fingerprint_raw() */
                success = 1;
        } else {
-               error("dns_export_rr: unsupported algorithm");
+               error("export_dns_rr: unsupported algorithm");
        }
 
        return success;
This page took 0.289486 seconds and 4 git commands to generate.