]> andersk Git - openssh.git/commitdiff
- jakob@cvs.openbsd.org 2003/11/12 16:39:58
authordjm <djm>
Mon, 17 Nov 2003 10:19:29 +0000 (10:19 +0000)
committerdjm <djm>
Mon, 17 Nov 2003 10:19:29 +0000 (10:19 +0000)
     [dns.c dns.h readconf.c ssh_config.5 sshconnect.c]
     update SSHFP validation. ok markus@

ChangeLog
dns.c
dns.h
readconf.c
ssh_config.5
sshconnect.c

index 4a7f64c6c303f004b93a3745493fb84e9b174285..736226c4ac9b921e88f30de8fafc8d1828b988e3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -31,6 +31,9 @@
    - dtucker@cvs.openbsd.org 2003/11/12 10:12:15
      [scp.c]
      When called with -q, pass -q to ssh; suppresses SSH2 banner.  ok markus@
    - dtucker@cvs.openbsd.org 2003/11/12 10:12:15
      [scp.c]
      When called with -q, pass -q to ssh; suppresses SSH2 banner.  ok markus@
+   - 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@
 
 20031115
  - (dtucker) [regress/agent-ptrace.sh] Test for GDB output from Solaris and
 
 20031115
  - (dtucker) [regress/agent-ptrace.sh] Test for GDB output from Solaris and
diff --git a/dns.c b/dns.c
index 2fff1b802dad75b30038fab4cbcf1cf2be6f88ef..2342b6609450a2260e1ec62553a1d96455b00846 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dns.c,v 1.7 2003/10/14 19:42:10 jakob Exp $   */
+/*     $OpenBSD: dns.c,v 1.8 2003/11/12 16:39:58 jakob Exp $   */
 
 /*
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
 
 /*
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -43,7 +43,7 @@
 #include "uuencode.h"
 
 extern char *__progname;
 #include "uuencode.h"
 
 extern char *__progname;
-RCSID("$OpenBSD: dns.c,v 1.7 2003/10/14 19:42:10 jakob Exp $");
+RCSID("$OpenBSD: dns.c,v 1.8 2003/11/12 16:39:58 jakob Exp $");
 
 #ifndef LWRES
 static const char *errset_text[] = {
 
 #ifndef LWRES
 static const char *errset_text[] = {
@@ -83,7 +83,7 @@ dns_result_totext(unsigned int error)
  */
 static int
 dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
  */
 static int
 dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
-    u_char **digest, u_int *digest_len, Key *key)
+    u_char **digest, u_int *digest_len, const Key *key)
 {
        int success = 0;
 
 {
        int success = 0;
 
@@ -145,16 +145,15 @@ dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type,
 
 /*
  * Verify the given hostname, address and host key using DNS.
 
 /*
  * Verify the given hostname, address and host key using DNS.
- * Returns 0 if key verifies or -1 if key does NOT verify
+ * Returns 0 if lookup succeeds, -1 otherwise 
  */
 int
 verify_host_key_dns(const char *hostname, struct sockaddr *address,
  */
 int
 verify_host_key_dns(const char *hostname, struct sockaddr *address,
-    Key *hostkey)
+    const Key *hostkey, int *flags)
 {
        int counter;
        int result;
        struct rrsetinfo *fingerprints = NULL;
 {
        int counter;
        int result;
        struct rrsetinfo *fingerprints = NULL;
-       int failures = 0;
 
        u_int8_t hostkey_algorithm;
        u_int8_t hostkey_digest_type;
 
        u_int8_t hostkey_algorithm;
        u_int8_t hostkey_digest_type;
@@ -166,6 +165,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
        u_char *dnskey_digest;
        u_int dnskey_digest_len;
 
        u_char *dnskey_digest;
        u_int dnskey_digest_len;
 
+       *flags = 0;
 
        debug3("verify_hostkey_dns");
        if (hostkey == NULL)
 
        debug3("verify_hostkey_dns");
        if (hostkey == NULL)
@@ -175,28 +175,29 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
            DNS_RDATATYPE_SSHFP, 0, &fingerprints);
        if (result) {
                verbose("DNS lookup error: %s", dns_result_totext(result));
            DNS_RDATATYPE_SSHFP, 0, &fingerprints);
        if (result) {
                verbose("DNS lookup error: %s", dns_result_totext(result));
-               return DNS_VERIFY_ERROR;
+               return -1;
        }
 
        }
 
-#ifdef DNSSEC
-       /* Only accept validated answers */
-       if (!fingerprints->rri_flags & RRSET_VALIDATED) {
-               error("Ignored unvalidated fingerprint from DNS.");
-               freerrset(fingerprints);
-               return DNS_VERIFY_ERROR;
+       if (fingerprints->rri_flags & RRSET_VALIDATED) {
+               *flags |= DNS_VERIFY_SECURE;
+               debug("found %d secure fingerprints in DNS",
+                   fingerprints->rri_nrdatas);
+       } else {
+               debug("found %d insecure fingerprints in DNS",
+                   fingerprints->rri_nrdatas);
        }
        }
-#endif
-
-       debug("found %d fingerprints in DNS", fingerprints->rri_nrdatas);
 
        /* Initialize host key parameters */
        if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type,
            &hostkey_digest, &hostkey_digest_len, hostkey)) {
                error("Error calculating host key fingerprint.");
                freerrset(fingerprints);
 
        /* Initialize host key parameters */
        if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type,
            &hostkey_digest, &hostkey_digest_len, hostkey)) {
                error("Error calculating host key fingerprint.");
                freerrset(fingerprints);
-               return DNS_VERIFY_ERROR;
+               return -1;
        }
 
        }
 
+       if (fingerprints->rri_nrdatas)
+               *flags |= DNS_VERIFY_FOUND;
+
        for (counter = 0 ; counter < fingerprints->rri_nrdatas ; counter++)  {
                /*
                 * Extract the key from the answer. Ignore any badly
        for (counter = 0 ; counter < fingerprints->rri_nrdatas ; counter++)  {
                /*
                 * Extract the key from the answer. Ignore any badly
@@ -218,35 +219,22 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
                            memcmp(hostkey_digest, dnskey_digest,
                            hostkey_digest_len) == 0) {
 
                            memcmp(hostkey_digest, dnskey_digest,
                            hostkey_digest_len) == 0) {
 
-                               /* Matching algoritm and digest. */
-                               freerrset(fingerprints);
-                               debug("matching host key fingerprint found in DNS");
-                               return DNS_VERIFY_OK;
-                       } else {
-                               /* Correct algorithm but bad digest */
-                               debug("verify_hostkey_dns: failed");
-                               failures++;
+                               *flags |= DNS_VERIFY_MATCH;
                        }
                }
        }
 
        freerrset(fingerprints);
 
                        }
                }
        }
 
        freerrset(fingerprints);
 
-       if (failures) {
-               error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
-               error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");
-               error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
-               error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
-               error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
-               error("It is also possible that the %s host key has just been changed.",
-                   key_type(hostkey));
-               error("Please contact your system administrator.");
-               return DNS_VERIFY_FAILED;
-       }
-
-       debug("fingerprints found in DNS, but none of them matched");
+       if (*flags & DNS_VERIFY_FOUND)
+               if (*flags & DNS_VERIFY_MATCH)
+                       debug("matching host key fingerprint found in DNS");
+               else
+                       debug("mismatching host key fingerprint found in DNS");
+       else
+               debug("no host key fingerprint found in DNS");
 
 
-       return DNS_VERIFY_ERROR;
+       return 0;
 }
 
 
 }
 
 
@@ -254,7 +242,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
  * Export the fingerprint of a key as a DNS resource record
  */
 int
  * Export the fingerprint of a key as a DNS resource record
  */
 int
-export_dns_rr(const char *hostname, Key *key, FILE *f, int generic)
+export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic)
 {
        u_int8_t rdata_pubkey_algorithm = 0;
        u_int8_t rdata_digest_type = SSHFP_HASH_SHA1;
 {
        u_int8_t rdata_pubkey_algorithm = 0;
        u_int8_t rdata_digest_type = SSHFP_HASH_SHA1;
diff --git a/dns.h b/dns.h
index 1eb07d96ead445043763ff3ecb856880cf9ff2af..c5da22ef61a4de067f53a3a5851fe68b7dcf5947 100644 (file)
--- a/dns.h
+++ b/dns.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dns.h,v 1.4 2003/10/14 19:42:10 jakob Exp $   */
+/*     $OpenBSD: dns.h,v 1.5 2003/11/12 16:39:58 jakob Exp $   */
 
 /*
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
 
 /*
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -45,11 +45,12 @@ enum sshfp_hashes {
 #define DNS_RDATACLASS_IN      1
 #define DNS_RDATATYPE_SSHFP    44
 
 #define DNS_RDATACLASS_IN      1
 #define DNS_RDATATYPE_SSHFP    44
 
-#define DNS_VERIFY_FAILED      -1
-#define DNS_VERIFY_OK          0
-#define DNS_VERIFY_ERROR       1
+#define DNS_VERIFY_FOUND       0x00000001
+#define DNS_VERIFY_MATCH       0x00000002
+#define DNS_VERIFY_SECURE      0x00000004
 
 
-int    verify_host_key_dns(const char *, struct sockaddr *, Key *);
-int    export_dns_rr(const char *, Key *, FILE *, int);
+
+int    verify_host_key_dns(const char *, struct sockaddr *, const Key *, int *);
+int    export_dns_rr(const char *, const Key *, FILE *, int);
 
 #endif /* DNS_H */
 
 #endif /* DNS_H */
index 86d28bc8d55657e310c01b856bbe4c03ec77e8bc..da49a3944a929f2d31925bcbc073185d658d3dbb 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.124 2003/10/14 19:42:10 jakob Exp $");
+RCSID("$OpenBSD: readconf.c,v 1.125 2003/11/12 16:39:58 jakob Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -401,10 +401,11 @@ parse_flag:
 
        case oVerifyHostKeyDNS:
                intptr = &options->verify_host_key_dns;
 
        case oVerifyHostKeyDNS:
                intptr = &options->verify_host_key_dns;
-               goto parse_flag;
+               goto parse_yesnoask;
 
        case oStrictHostKeyChecking:
                intptr = &options->strict_host_key_checking;
 
        case oStrictHostKeyChecking:
                intptr = &options->strict_host_key_checking;
+parse_yesnoask:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing yes/no/ask argument.",
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing yes/no/ask argument.",
index 9073ce51f5608e0dec7790cdaf9457891e2df0e7..55ca907eb439424bdcb7c49fdbf7c8d3504e45d7 100644 (file)
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh_config.5,v 1.23 2003/10/12 13:12:13 jmc Exp $
+.\" $OpenBSD: ssh_config.5,v 1.24 2003/11/12 16:39:58 jakob Exp $
 .Dd September 25, 1999
 .Dt SSH_CONFIG 5
 .Os
 .Dd September 25, 1999
 .Dt SSH_CONFIG 5
 .Os
@@ -642,6 +642,23 @@ host key database instead of
 .It Cm VerifyHostKeyDNS
 Specifies whether to verify the remote key using DNS and SSHFP resource
 records.
 .It Cm VerifyHostKeyDNS
 Specifies whether to verify the remote key using DNS and SSHFP resource
 records.
+If this option is set to
+.Dq yes ,
+the client will implicitly trust keys that matches a secure fingerprint
+from DNS.
+Insecure fingerprints will be handled as if this option was set to
+.Dq ask .
+If this option is set to
+.Dq ask ,
+information on fingerprint match will be displayed, but the user will still
+need to confirm new host keys according to the
+.Cm StrictHostKeyChecking
+option.
+The argument must be
+.Dq yes ,
+.Dq no
+or  
+.Dq ask  .
 The default is
 .Dq no .
 Note that this option applies to protocol version 2 only.
 The default is
 .Dq no .
 Note that this option applies to protocol version 2 only.
index bf8c23d739e28d1f9e4250cbe4f16738e2ec6064..5972e2ba963bc37fa9138fd5ae04e0d07e7bcd84 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.152 2003/11/10 16:23:41 jakob Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.153 2003/11/12 16:39:58 jakob Exp $");
 
 #include <openssl/bn.h>
 
 
 #include <openssl/bn.h>
 
@@ -38,7 +38,7 @@ RCSID("$OpenBSD: sshconnect.c,v 1.152 2003/11/10 16:23:41 jakob Exp $");
 char *client_version_string = NULL;
 char *server_version_string = NULL;
 
 char *client_version_string = NULL;
 char *server_version_string = NULL;
 
-int verified_host_key_dns = 0;
+int matching_host_key_dns = 0;
 
 /* import */
 extern Options options;
 
 /* import */
 extern Options options;
@@ -728,7 +728,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                        fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
                        msg2[0] = '\0';
                        if (options.verify_host_key_dns) {
                        fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
                        msg2[0] = '\0';
                        if (options.verify_host_key_dns) {
-                               if (verified_host_key_dns)
+                               if (matching_host_key_dns)
                                        snprintf(msg2, sizeof(msg2),
                                            "Matching host key fingerprint"
                                            " found in DNS.\n");
                                        snprintf(msg2, sizeof(msg2),
                                            "Matching host key fingerprint"
                                            " found in DNS.\n");
@@ -892,23 +892,25 @@ int
 verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
 {
        struct stat st;
 verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
 {
        struct stat st;
+       int flags = 0;
 
 
-       if (options.verify_host_key_dns) {
-               switch(verify_host_key_dns(host, hostaddr, host_key)) {
-               case DNS_VERIFY_OK:
-#ifdef DNSSEC
-                       return 0;
-#else
-                       verified_host_key_dns = 1;
-                       break;
-#endif
-               case DNS_VERIFY_FAILED:
-                       return -1;
-               case DNS_VERIFY_ERROR:
-                       break;
-               default:
-                       debug3("bad return value from verify_host_key_dns");
-                       break;
+       if (options.verify_host_key_dns &&
+           verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
+
+               if (flags & DNS_VERIFY_FOUND) {
+
+                       if (options.verify_host_key_dns == 1 &&
+                           flags & DNS_VERIFY_MATCH &&
+                           flags & DNS_VERIFY_SECURE)
+                               return 0;
+
+                       if (flags & DNS_VERIFY_MATCH) {
+                               matching_host_key_dns = 1;
+                       } else {
+                               warn_changed_key(host_key);
+                               error("Update the SSHFP RR in DNS with the new "
+                                   "host key to get rid of this message.");
+                       }
                }
        }
 
                }
        }
 
This page took 0.063666 seconds and 5 git commands to generate.