[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@
This commit is contained in:
Damien Miller 2003-05-15 10:19:46 +10:00
parent abbae980e7
commit 37876e913a
13 changed files with 523 additions and 16 deletions

View File

@ -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
@ -1479,4 +1485,4 @@
save auth method before monitor_reset_key_state(); bugzilla bug #284;
ok provos@
$Id: ChangeLog,v 1.2701 2003/05/15 00:16:21 djm Exp $
$Id: ChangeLog,v 1.2702 2003/05/15 00:19:46 djm Exp $

View File

@ -1,4 +1,4 @@
# $Id: Makefile.in,v 1.232 2003/05/14 04:31:11 djm Exp $
# $Id: Makefile.in,v 1.233 2003/05/15 00:19:46 djm Exp $
# uncomment if you run a non bourne compatable shell. Ie. csh
#SHELL = @SH@
@ -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 \

55
README.dns Normal file
View File

@ -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 $

293
dns.c Normal file
View File

@ -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 */

57
dns.h Normal file
View File

@ -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 */

4
key.c
View File

@ -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;

3
key.h
View File

@ -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 **);

View 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 */

View 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];

View 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 -*-
.\"
@ -83,6 +83,10 @@
.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

View 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)

View 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

View 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) {