]> andersk Git - openssh.git/commitdiff
- jakob@cvs.openbsd.org 2003/05/14 18:16:20
authordjm <djm>
Thu, 15 May 2003 00:19:46 +0000 (00:19 +0000)
committerdjm <djm>
Thu, 15 May 2003 00:19:46 +0000 (00:19 +0000)
     [key.c key.h readconf.c readconf.h ssh_config.5 sshconnect.c]
     [dns.c dns.h README.dns ssh-keygen.1 ssh-keygen.c]
     add experimental support for verifying hos keys using DNS as described
     in draft-ietf-secsh-dns-xx.txt. more information in README.dns.
     ok markus@ and henning@

13 files changed:
ChangeLog
Makefile.in
README.dns [new file with mode: 0644]
dns.c [new file with mode: 0644]
dns.h [new file with mode: 0644]
key.c
key.h
readconf.c
readconf.h
ssh-keygen.1
ssh-keygen.c
ssh_config.5
sshconnect.c

index 5e5905b785412c477e746e1ff927e8ae5a48467d..ac7a0c4d35a52dbf36f41beb8082bd68d0aef689 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,12 @@
      [ssh-agent.1]
      setup -> set up;
      from wiz@netbsd
+   - jakob@cvs.openbsd.org 2003/05/14 18:16:20
+     [key.c key.h readconf.c readconf.h ssh_config.5 sshconnect.c]
+     [dns.c dns.h README.dns ssh-keygen.1 ssh-keygen.c]
+     add experimental support for verifying hos keys using DNS as described
+     in draft-ietf-secsh-dns-xx.txt. more information in README.dns.
+     ok markus@ and henning@
 
 20030514
  - (djm) Bug #117: Don't lie to PAM about username
index 5b3b7be8ebc1281864d854314f7ea401cb9f1e8b..a54c1f8c1600297f3b6f93147d60a7ccd9d5d6e9 100644 (file)
@@ -62,11 +62,11 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keys
 
 LIBSSH_OBJS=authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o \
        cipher.o compat.o compress.o crc32.o deattack.o fatal.o \
-       hostfile.o log.o match.o mpaux.o nchan.o packet.o radix.o readpass.o \
-       rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.o \
+       hostfile.o log.o match.o mpaux.o nchan.o packet.o radix.o \
+       readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.o \
        key.o dispatch.o kex.o mac.o uuencode.o misc.o \
        rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o kexgex.o \
-       kexdhc.o kexgexc.o scard.o msg.o progressmeter.o \
+       kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
        entropy.o
 
 SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
diff --git a/README.dns b/README.dns
new file mode 100644 (file)
index 0000000..d6889b9
--- /dev/null
@@ -0,0 +1,55 @@
+How to verify host keys using OpenSSH and DNS
+---------------------------------------------
+
+OpenSSH contains experimental support for verifying host keys using DNS
+as described in draft-ietf-secsh-dns-xx.txt. The document contains
+very brief instructions on how to test this feature. Configuring DNS
+and DNSSEC is out of the scope of this document.
+
+
+(1) Enable DNS fingerprint support in OpenSSH
+
+Edit /usr/src/usr.bin/ssh/Makefile.inc and uncomment the line containing
+
+       CFLAGS+= -DDNS
+
+
+(2) Generate and publish the DNS RR
+
+To create a DNS resource record (RR) containing a fingerprint of the
+public host key, use the following command:
+
+       ssh-keygen -r hostname -f keyfile -g
+
+where "hostname" is your fully qualified hostname and "keyfile" is the
+file containing the public host key file. If you have multiple keys,
+you should generate one RR for each key.
+
+In the example above, ssh-keygen will print the fingerprint in a
+generic DNS RR format parsable by most modern name server
+implementations. If your nameserver has support for the SSHFP RR, as
+defined by the draft, you can omit the -g flag and ssh-keygen will
+print a standard RR.
+
+To publish the fingerprint using the DNS you must add the generated RR
+to your DNS zone file and sign your zone.
+
+
+(3) Enable the ssh client to verify host keys using DNS
+
+To enable the ssh client to verify host keys using DNS, you have to
+add the following option to the ssh configuration file
+($HOME/.ssh/config or /etc/ssh/ssh_config):
+
+    VerifyHostKeyDNS yes
+
+Upon connection the client will try to look up the fingerprint RR
+using DNS. If the fingerprint received from the DNS server matches
+the remote host key, the user will be notified.
+
+
+       Jakob Schlyter
+       Wesley Griffin
+
+
+$OpenBSD: README.dns,v 1.1 2003/05/14 18:16:20 jakob Exp $
diff --git a/dns.c b/dns.c
new file mode 100644 (file)
index 0000000..9b7a0e7
--- /dev/null
+++ b/dns.c
@@ -0,0 +1,293 @@
+/*     $OpenBSD: dns.c,v 1.4 2003/05/14 23:29:22 jakob Exp $   */
+
+/*
+ * Copyright (c) 2003 Wesley Griffin. All rights reserved.
+ * Copyright (c) 2003 Jakob Schlyter. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "includes.h"
+
+#ifdef DNS
+#include <openssl/bn.h>
+#ifdef LWRES
+#include <lwres/netdb.h>
+#include <dns/result.h>
+#else /* LWRES */
+#include <netdb.h>
+#endif /* LWRES */
+
+#include "xmalloc.h"
+#include "key.h"
+#include "dns.h"
+#include "log.h"
+#include "uuencode.h"
+
+extern char *__progname;
+RCSID("$OpenBSD: dns.c,v 1.4 2003/05/14 23:29:22 jakob Exp $");
+
+#ifndef LWRES
+static const char *errset_text[] = {
+       "success",              /* 0 ERRSET_SUCCESS */
+       "out of memory",        /* 1 ERRSET_NOMEMORY */
+       "general failure",      /* 2 ERRSET_FAIL */
+       "invalid parameter",    /* 3 ERRSET_INVAL */
+       "name does not exist",  /* 4 ERRSET_NONAME */
+       "data does not exist",  /* 5 ERRSET_NODATA */
+};
+
+static const char *
+dns_result_totext(unsigned int error)
+{
+       switch (error) {
+       case ERRSET_SUCCESS:
+               return errset_text[ERRSET_SUCCESS];
+       case ERRSET_NOMEMORY:
+               return errset_text[ERRSET_NOMEMORY];
+       case ERRSET_FAIL:
+               return errset_text[ERRSET_FAIL];
+       case ERRSET_INVAL:
+               return errset_text[ERRSET_INVAL];
+       case ERRSET_NONAME:
+               return errset_text[ERRSET_NONAME];
+       case ERRSET_NODATA:
+               return errset_text[ERRSET_NODATA];
+       default:
+               return "unknown error";
+       }
+}
+#endif /* LWRES */
+
+
+/*
+ * Read SSHFP parameters from key buffer.
+ */
+static int
+dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
+    u_char **digest, u_int *digest_len, Key *key)
+{
+       int success = 0;
+
+       switch (key->type) {
+       case KEY_RSA:
+               *algorithm = SSHFP_KEY_RSA;
+               break;
+       case KEY_DSA:
+               *algorithm = SSHFP_KEY_DSA;
+               break;
+       default:
+               *algorithm = SSHFP_KEY_RESERVED;
+       }
+
+       if (*algorithm) {
+               *digest_type = SSHFP_HASH_SHA1;
+               *digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len);
+               success = 1;
+       } else {
+               *digest_type = SSHFP_HASH_RESERVED;
+               *digest = NULL;
+               *digest_len = 0;
+               success = 0;
+       }
+
+       return success;
+}
+
+/*
+ * Read SSHFP parameters from rdata buffer.
+ */
+static int
+dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type,
+    u_char **digest, u_int *digest_len, u_char *rdata, int rdata_len)
+{
+       int success = 0;
+
+       *algorithm = SSHFP_KEY_RESERVED;
+       *digest_type = SSHFP_HASH_RESERVED;
+
+       if (rdata_len >= 2) {
+               *algorithm = rdata[0];
+               *digest_type = rdata[1];
+               *digest_len = rdata_len - 2;
+
+               if (*digest_len > 0) {
+                       *digest = (u_char *) xmalloc(*digest_len);
+                       memcpy(*digest, rdata + 2, *digest_len);
+               } else {
+                       *digest = NULL;
+               }
+
+               success = 1;
+       }
+
+       return success;
+}
+
+
+/*
+ * Verify the given hostname, address and host key using DNS.
+ * Returns 0 if key verifies or -1 if key does NOT verify
+ */
+int
+verify_host_key_dns(const char *hostname, struct sockaddr *address,
+    Key *hostkey)
+{
+       int counter;
+       int result;
+       struct rrsetinfo *fingerprints = NULL;
+       int failures = 0;
+
+       u_int8_t hostkey_algorithm;
+       u_int8_t hostkey_digest_type;
+       u_char *hostkey_digest;
+       u_int hostkey_digest_len;
+
+       u_int8_t dnskey_algorithm;
+       u_int8_t dnskey_digest_type;
+       u_char *dnskey_digest;
+       u_int dnskey_digest_len;
+
+
+       debug3("verify_hostkey_dns");
+       if (hostkey == NULL)
+               fatal("No key to look up!");
+
+       result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
+           DNS_RDATATYPE_SSHFP, 0, &fingerprints);
+       if (result) {
+               verbose("DNS lookup error: %s", dns_result_totext(result));
+               return DNS_VERIFY_ERROR;
+       }
+
+#ifdef DNSSEC
+       /* Only accept validated answers */
+       if (!fingerprints->rri_flags & RRSET_VALIDATED) {
+               error("Ignored unvalidated fingerprint from DNS.");
+               return DNS_VERIFY_ERROR;
+       }
+#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.");
+               return DNS_VERIFY_ERROR;
+       }
+
+       for (counter = 0 ; counter < fingerprints->rri_nrdatas ; counter++)  {
+               /*
+                * Extract the key from the answer. Ignore any badly
+                * formatted fingerprints.
+                */
+               if (!dns_read_rdata(&dnskey_algorithm, &dnskey_digest_type,
+                   &dnskey_digest, &dnskey_digest_len,
+                   fingerprints->rri_rdatas[counter].rdi_data,
+                   fingerprints->rri_rdatas[counter].rdi_length)) {
+                       verbose("Error parsing fingerprint from DNS.");
+                       continue;
+               }
+
+               /* Check if the current key is the same as the given key */
+               if (hostkey_algorithm == dnskey_algorithm &&
+                   hostkey_digest_type == dnskey_digest_type) {
+
+                       if (hostkey_digest_len == dnskey_digest_len &&
+                           memcmp(hostkey_digest, dnskey_digest,
+                           hostkey_digest_len) == 0) {
+
+                               /* Matching algoritm and digest. */
+                               freerrset(fingerprints);
+#ifdef DNSSEC
+                               debug("matching host key fingerprint found in DNS");
+                               return DNS_VERIFY_OK;
+#else
+                               logit("Matching host key fingerprint found in DNS.");
+                               return DNS_VERIFY_ERROR;
+#endif
+                       } else {
+                               /* Correct algorithm but bad digest */
+                               debug("verify_hostkey_dns: failed");
+                               failures++;
+                       }
+               }
+       }
+
+       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");
+
+       return DNS_VERIFY_ERROR;
+}
+
+
+/*
+ * Export the fingerprint of a key as a DNS resource record
+ */
+int
+export_dns_rr(const char *hostname, Key *key, FILE *f, int generic)
+{
+       u_int8_t rdata_pubkey_algorithm = 0;
+       u_int8_t rdata_digest_type = SSHFP_HASH_SHA1;
+       u_char *rdata_digest;
+       u_int rdata_digest_len;
+
+       int i;
+       int success = 0;
+
+       if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type,
+                        &rdata_digest, &rdata_digest_len, key)) {
+
+               if (generic)
+                       fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", hostname,
+                           DNS_RDATATYPE_SSHFP, 2 + rdata_digest_len,
+                           rdata_pubkey_algorithm, rdata_digest_type);
+               else
+                       fprintf(f, "%s IN SSHFP %d %d ", hostname,
+                           rdata_pubkey_algorithm, rdata_digest_type);
+
+               for (i = 0; i < rdata_digest_len; i++)
+                       fprintf(f, "%02x", rdata_digest[i]);
+               fprintf(f, "\n");
+               success = 1;
+       } else {
+               error("dns_export_rr: unsupported algorithm");
+       }
+
+       return success;
+}
+
+#endif /* DNS */
diff --git a/dns.h b/dns.h
new file mode 100644 (file)
index 0000000..ba0ea9f
--- /dev/null
+++ b/dns.h
@@ -0,0 +1,57 @@
+/*     $OpenBSD: dns.h,v 1.3 2003/05/14 22:56:51 jakob Exp $   */
+
+/*
+ * Copyright (c) 2003 Wesley Griffin. All rights reserved.
+ * Copyright (c) 2003 Jakob Schlyter. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "includes.h"
+
+#ifdef DNS
+#ifndef DNS_H
+#define DNS_H
+
+enum sshfp_types {
+       SSHFP_KEY_RESERVED,
+       SSHFP_KEY_RSA,
+       SSHFP_KEY_DSA
+};
+
+enum sshfp_hashes {
+       SSHFP_HASH_RESERVED,
+       SSHFP_HASH_SHA1
+};
+
+#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
+
+int    verify_host_key_dns(const char *, struct sockaddr *, Key *);
+int    export_dns_rr(const char *, Key *, FILE *, int);
+
+#endif /* DNS_H */
+#endif /* DNS */
diff --git a/key.c b/key.c
index 060b63745a3d2762bbd5b9a14edf4bca8a54463d..d918cfd0a3b5d205275c056dd1630b8d1a5df097 100644 (file)
--- a/key.c
+++ b/key.c
@@ -32,7 +32,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: key.c,v 1.51 2003/02/12 09:33:04 markus Exp $");
+RCSID("$OpenBSD: key.c,v 1.52 2003/05/14 18:16:20 jakob Exp $");
 
 #include <openssl/evp.h>
 
@@ -169,7 +169,7 @@ key_equal(Key *a, Key *b)
        return 0;
 }
 
-static u_char *
+u_char*
 key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
 {
        const EVP_MD *md = NULL;
diff --git a/key.h b/key.h
index 725c7a04a7bf2d6cfaf2a488be20c0381c11cbfe..a7b6afe86df10447dfc95ceca380f5c92cf7b3b6 100644 (file)
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: key.h,v 1.20 2003/02/12 09:33:04 markus Exp $ */
+/*     $OpenBSD: key.h,v 1.21 2003/05/14 18:16:20 jakob Exp $  */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -61,6 +61,7 @@ void   key_free(Key *);
 Key    *key_demote(Key *);
 int     key_equal(Key *, Key *);
 char   *key_fingerprint(Key *, enum fp_type, enum fp_rep);
+u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *);
 char   *key_type(Key *);
 int     key_write(Key *, FILE *);
 int     key_read(Key *, char **);
index acdf128f63c63f88eecbd0e6a61a87a540785df6..c9c463b2948dea332268186443798c8c483e6020 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.106 2003/04/09 12:00:37 djm Exp $");
+RCSID("$OpenBSD: readconf.c,v 1.107 2003/05/14 18:16:20 jakob Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -114,7 +114,7 @@ typedef enum {
        oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
        oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
        oClearAllForwardings, oNoHostAuthenticationForLocalhost,
-       oEnableSSHKeysign, oRekeyLimit,
+       oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS,
        oDeprecated
 } OpCodes;
 
@@ -187,6 +187,7 @@ static struct {
        { "smartcarddevice", oSmartcardDevice },
        { "clearallforwardings", oClearAllForwardings },
        { "enablesshkeysign", oEnableSSHKeysign },
+       { "verifyhostkeydns", oVerifyHostKeyDNS },
        { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
        { "rekeylimit", oRekeyLimit },
        { NULL, oBadOption }
@@ -392,6 +393,10 @@ parse_flag:
                intptr = &options->check_host_ip;
                goto parse_flag;
 
+       case oVerifyHostKeyDNS:
+               intptr = &options->verify_host_key_dns;
+               goto parse_flag;
+
        case oStrictHostKeyChecking:
                intptr = &options->strict_host_key_checking;
                arg = strdelim(&s);
@@ -829,6 +834,7 @@ initialize_options(Options * options)
        options->enable_ssh_keysign = - 1;
        options->no_host_authentication_for_localhost = - 1;
        options->rekey_limit = - 1;
+       options->verify_host_key_dns = -1;
 }
 
 /*
@@ -947,6 +953,8 @@ fill_default_options(Options * options)
                options->enable_ssh_keysign = 0;
        if (options->rekey_limit == -1)
                options->rekey_limit = 0;
+       if (options->verify_host_key_dns == -1)
+               options->verify_host_key_dns = 0;
        /* options->proxy_command should not be set by default */
        /* options->user will be set in the main program if appropriate */
        /* options->hostname will be set in the main program if appropriate */
index d35472117f622952e0cfa407c9abd7e9c2fa61f3..d141b8c00f1b83f7b4236d72735d583b28187d56 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: readconf.h,v 1.47 2003/04/02 09:48:07 markus Exp $    */
+/*     $OpenBSD: readconf.h,v 1.48 2003/05/14 18:16:20 jakob Exp $     */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -86,6 +86,7 @@ typedef struct {
        char   *preferred_authentications;
        char   *bind_address;   /* local socket address for connection to sshd */
        char   *smartcard_device; /* Smartcard reader device */
+       int     verify_host_key_dns;    /* Verify host key using DNS */
 
        int     num_identity_files;     /* Number of files for RSA/DSA identities. */
        char   *identity_files[SSH_MAX_IDENTITY_FILES];
index 000e8ff2a461271b8b2f4c5cfdfbe0cfef68bca7..613d71a07727be70e9070b83a41d0c2971d32bbf 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ssh-keygen.1,v 1.56 2003/03/28 10:11:43 jmc Exp $
+.\"    $OpenBSD: ssh-keygen.1,v 1.57 2003/05/14 18:16:20 jakob Exp $
 .\"
 .\"  -*- nroff -*-
 .\"
 .Nm ssh-keygen
 .Fl U Ar reader
 .Op Fl f Ar input_keyfile
+.Nm ssh-keygen
+.Fl r Ar hostname
+.Op Fl f Ar input_keyfile
+.Op Fl g
 .Sh DESCRIPTION
 .Nm
 generates, manages and converts authentication keys for
@@ -163,6 +167,8 @@ print the key in a
 to stdout.
 This option allows exporting keys for use by several commercial
 SSH implementations.
+.It Fl g
+Use generic DNS resource record format.
 .It Fl f Ar filename
 Specifies the filename of the key file.
 .It Fl i
@@ -218,6 +224,9 @@ Provides the (old) passphrase.
 .It Fl U Ar reader
 Upload an existing RSA private key into the smartcard in
 .Ar reader .
+.It Fl r Ar hostname
+Print DNS resource record with the specified
+.Ar hostname .
 .El
 .Sh FILES
 .Bl -tag -width Ds
index 1d08c7cece96a30a48f53ebab90e916dd32376ed..f3ea4f1fdee6dd9fd83a90f775a9261d90dd8245 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keygen.c,v 1.104 2003/05/11 16:56:48 markus Exp $");
+RCSID("$OpenBSD: ssh-keygen.c,v 1.105 2003/05/14 18:16:20 jakob Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/pem.h>
@@ -70,6 +70,7 @@ char *identity_comment = NULL;
 int convert_to_ssh2 = 0;
 int convert_from_ssh2 = 0;
 int print_public = 0;
+int print_generic = 0;
 
 char *key_type_name = NULL;
 
@@ -620,6 +621,38 @@ do_change_passphrase(struct passwd *pw)
        exit(0);
 }
 
+#ifdef DNS
+/*
+ * Print the SSHFP RR.
+ */
+static void
+do_print_resource_record(struct passwd *pw, char *hostname)
+{
+       Key *public;
+       char *comment = NULL;
+       struct stat st;
+
+       if (!have_identity)
+               ask_filename(pw, "Enter file in which the key is");
+       if (stat(identity_file, &st) < 0) {
+               perror(identity_file);
+               exit(1);
+       }
+       public = key_load_public(identity_file, &comment);
+       if (public != NULL) {
+               export_dns_rr(hostname, public, stdout, print_generic);
+               key_free(public);
+               xfree(comment);
+               exit(0);
+       }
+       if (comment)
+               xfree(comment);
+
+       printf("failed to read v2 public key from %s.\n", identity_file);
+       exit(1);
+}
+#endif /* DNS */
+
 /*
  * Change the comment of a private key file.
  */
@@ -726,6 +759,7 @@ usage(void)
        fprintf(stderr, "  -c          Change comment in private and public key files.\n");
        fprintf(stderr, "  -e          Convert OpenSSH to IETF SECSH key file.\n");
        fprintf(stderr, "  -f filename Filename of the key file.\n");
+       fprintf(stderr, "  -g          Use generic DNS resource record format.\n");
        fprintf(stderr, "  -i          Convert IETF SECSH to OpenSSH key file.\n");
        fprintf(stderr, "  -l          Show fingerprint of key file.\n");
        fprintf(stderr, "  -p          Change passphrase of private key file.\n");
@@ -736,6 +770,9 @@ usage(void)
        fprintf(stderr, "  -C comment  Provide new comment.\n");
        fprintf(stderr, "  -N phrase   Provide new passphrase.\n");
        fprintf(stderr, "  -P phrase   Provide old passphrase.\n");
+#ifdef DNS
+       fprintf(stderr, "  -r hostname Print DNS resource record.\n");
+#endif /* DNS */
 #ifdef SMARTCARD
        fprintf(stderr, "  -D reader   Download public key from smartcard.\n");
        fprintf(stderr, "  -U reader   Upload private key to smartcard.\n");
@@ -752,6 +789,7 @@ main(int ac, char **av)
 {
        char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
        char *reader_id = NULL;
+       char *resource_record_hostname = NULL;
        Key *private, *public;
        struct passwd *pw;
        struct stat st;
@@ -778,7 +816,7 @@ main(int ac, char **av)
                exit(1);
        }
 
-       while ((opt = getopt(ac, av, "deiqpclBRxXyb:f:t:U:D:P:N:C:")) != -1) {
+       while ((opt = getopt(ac, av, "degiqpclBRxXyb:f:t:U:D:P:N:C:r:")) != -1) {
                switch (opt) {
                case 'b':
                        bits = atoi(optarg);
@@ -803,6 +841,9 @@ main(int ac, char **av)
                        strlcpy(identity_file, optarg, sizeof(identity_file));
                        have_identity = 1;
                        break;
+               case 'g':
+                       print_generic = 1;
+                       break;
                case 'P':
                        identity_passphrase = optarg;
                        break;
@@ -843,6 +884,9 @@ main(int ac, char **av)
                case 'U':
                        reader_id = optarg;
                        break;
+               case 'r':
+                       resource_record_hostname = optarg;
+                       break;
                case '?':
                default:
                        usage();
@@ -868,6 +912,13 @@ main(int ac, char **av)
                do_convert_from_ssh2(pw);
        if (print_public)
                do_print_public(pw);
+       if (resource_record_hostname != NULL) {
+#ifdef DNS
+               do_print_resource_record(pw, resource_record_hostname);
+#else /* DNS */
+               fatal("no DNS support.");
+#endif /* DNS */
+       }
        if (reader_id != NULL) {
 #ifdef SMARTCARD
                if (download)
index 44208b431f59ee6703c23bfd54e78d961a7c6558..2f33aa3f3fdf2c17796a44103ea7ed98abbef726 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.
 .\"
-.\" $OpenBSD: ssh_config.5,v 1.7 2003/03/28 10:11:43 jmc Exp $
+.\" $OpenBSD: ssh_config.5,v 1.8 2003/05/14 18:16:20 jakob Exp $
 .Dd September 25, 1999
 .Dt SSH_CONFIG 5
 .Os
@@ -618,6 +618,11 @@ having to remember to give the user name on the command line.
 Specifies a file to use for the user
 host key database instead of
 .Pa $HOME/.ssh/known_hosts .
+.It Cm VerifyHostKeyDNS
+Specifies whether to verify the remote key using DNS and SSHFP resource
+records.
+The default is
+.Dq no .
 .It Cm XAuthLocation
 Specifies the full pathname of the
 .Xr xauth 1
index 33d9c727fc05a0a644417d3a4d381659a3ca3a1c..32bef7d079c197166c3faa633267b39ee91d2ff8 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.139 2003/04/14 14:17:50 markus Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.140 2003/05/14 18:16:21 jakob Exp $");
 
 #include <openssl/bn.h>
 
@@ -33,6 +33,10 @@ RCSID("$OpenBSD: sshconnect.c,v 1.139 2003/04/14 14:17:50 markus Exp $");
 #include "misc.h"
 #include "readpass.h"
 
+#ifdef DNS
+#include "dns.h"
+#endif
+
 char *client_version_string = NULL;
 char *server_version_string = NULL;
 
@@ -797,11 +801,28 @@ fail:
        return -1;
 }
 
+/* returns 0 if key verifies or -1 if key does NOT verify */
 int
 verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
 {
        struct stat st;
 
+#ifdef DNS
+       if (options.verify_host_key_dns) {
+               switch(verify_host_key_dns(host, hostaddr, host_key)) {
+               case DNS_VERIFY_OK:
+                       return 0;
+               case DNS_VERIFY_FAILED:
+                       return -1;
+               case DNS_VERIFY_ERROR:
+                       break;
+               default:
+                       debug3("bad return value from verify_host_key_dns");
+                       break;
+               }
+       }
+#endif /* DNS */
+
        /* return ok if the key can be found in an old keyfile */
        if (stat(options.system_hostfile2, &st) == 0 ||
            stat(options.user_hostfile2, &st) == 0) {
This page took 0.332053 seconds and 5 git commands to generate.