summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auth.c62
-rw-r--r--auth2-pubkey.c6
-rw-r--r--authfile.c58
-rw-r--r--authfile.h5
-rw-r--r--readconf.c12
-rw-r--r--readconf.h4
-rw-r--r--ssh_config.514
-rw-r--r--sshconnect.c64
8 files changed, 155 insertions, 70 deletions
diff --git a/auth.c b/auth.c
index 5e60682ce..348ddc398 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.c,v 1.106 2014/07/15 15:54:14 millert Exp $ */ 1/* $OpenBSD: auth.c,v 1.107 2014/12/04 02:24:32 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -71,7 +71,8 @@
71#endif 71#endif
72#include "authfile.h" 72#include "authfile.h"
73#include "monitor_wrap.h" 73#include "monitor_wrap.h"
74#include "krl.h" 74#include "authfile.h"
75#include "ssherr.h"
75#include "compat.h" 76#include "compat.h"
76 77
77/* import */ 78/* import */
@@ -673,43 +674,38 @@ getpwnamallow(const char *user)
673int 674int
674auth_key_is_revoked(Key *key) 675auth_key_is_revoked(Key *key)
675{ 676{
676#ifdef WITH_OPENSSL 677 char *fp = NULL;
677 char *key_fp; 678 int r;
678 679
679 if (options.revoked_keys_file == NULL) 680 if (options.revoked_keys_file == NULL)
680 return 0; 681 return 0;
681 switch (ssh_krl_file_contains_key(options.revoked_keys_file, key)) { 682 if ((fp = sshkey_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX)) == NULL) {
682 case 0: 683 r = SSH_ERR_ALLOC_FAIL;
683 return 0; /* Not revoked */ 684 error("%s: fingerprint key: %s", __func__, ssh_err(r));
684 case -2: 685 goto out;
685 break; /* Not a KRL */
686 default:
687 goto revoked;
688 } 686 }
689#endif 687
690 debug3("%s: treating %s as a key list", __func__, 688 r = sshkey_check_revoked(key, options.revoked_keys_file);
691 options.revoked_keys_file); 689 switch (r) {
692 switch (key_in_file(key, options.revoked_keys_file, 0)) {
693 case 0: 690 case 0:
694 /* key not revoked */ 691 break; /* not revoked */
695 return 0; 692 case SSH_ERR_KEY_REVOKED:
696 case -1: 693 error("Authentication key %s %s revoked by file %s",
697 /* Error opening revoked_keys_file: refuse all keys */ 694 sshkey_type(key), fp, options.revoked_keys_file);
698 error("Revoked keys file is unreadable: refusing public key " 695 goto out;
699 "authentication"); 696 default:
700 return 1; 697 error("Error checking authentication key %s %s in "
701#ifdef WITH_OPENSSL 698 "revoked keys file %s: %s", sshkey_type(key), fp,
702 case 1: 699 options.revoked_keys_file, ssh_err(r));
703 revoked: 700 goto out;
704 /* Key revoked */
705 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
706 error("WARNING: authentication attempt with a revoked "
707 "%s key %s ", key_type(key), key_fp);
708 free(key_fp);
709 return 1;
710#endif
711 } 701 }
712 fatal("key_in_file returned junk"); 702
703 /* Success */
704 r = 0;
705
706 out:
707 free(fp);
708 return r == 0 ? 0 : 1;
713} 709}
714 710
715void 711void
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index f3ca96592..0a3c1deee 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-pubkey.c,v 1.41 2014/07/15 15:54:14 millert Exp $ */ 1/* $OpenBSD: auth2-pubkey.c,v 1.42 2014/12/04 02:24:32 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -434,8 +434,8 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
434 ca_fp = key_fingerprint(key->cert->signature_key, 434 ca_fp = key_fingerprint(key->cert->signature_key,
435 SSH_FP_MD5, SSH_FP_HEX); 435 SSH_FP_MD5, SSH_FP_HEX);
436 436
437 if (key_in_file(key->cert->signature_key, 437 if (sshkey_in_file(key->cert->signature_key,
438 options.trusted_user_ca_keys, 1) != 1) { 438 options.trusted_user_ca_keys, 1, 0) != 0) {
439 debug2("%s: CA %s %s is not listed in %s", __func__, 439 debug2("%s: CA %s %s is not listed in %s", __func__,
440 key_type(key->cert->signature_key), ca_fp, 440 key_type(key->cert->signature_key), ca_fp,
441 options.trusted_user_ca_keys); 441 options.trusted_user_ca_keys);
diff --git a/authfile.c b/authfile.c
index e93d86738..95877e159 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.107 2014/06/24 01:13:21 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.108 2014/12/04 02:24:32 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
4 * 4 *
@@ -48,6 +48,7 @@
48#include "atomicio.h" 48#include "atomicio.h"
49#include "sshbuf.h" 49#include "sshbuf.h"
50#include "ssherr.h" 50#include "ssherr.h"
51#include "krl.h"
51 52
52#define MAX_KEY_FILE_SIZE (1024 * 1024) 53#define MAX_KEY_FILE_SIZE (1024 * 1024)
53 54
@@ -494,11 +495,14 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
494/* 495/*
495 * Returns success if the specified "key" is listed in the file "filename", 496 * Returns success if the specified "key" is listed in the file "filename",
496 * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error. 497 * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error.
497 * If strict_type is set then the key type must match exactly, 498 * If "strict_type" is set then the key type must match exactly,
498 * otherwise a comparison that ignores certficiate data is performed. 499 * otherwise a comparison that ignores certficiate data is performed.
500 * If "check_ca" is set and "key" is a certificate, then its CA key is
501 * also checked and sshkey_in_file() will return success if either is found.
499 */ 502 */
500int 503int
501sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) 504sshkey_in_file(struct sshkey *key, const char *filename, int strict_type,
505 int check_ca)
502{ 506{
503 FILE *f; 507 FILE *f;
504 char line[SSH_MAX_PUBKEY_BYTES]; 508 char line[SSH_MAX_PUBKEY_BYTES];
@@ -509,12 +513,8 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
509 int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) = 513 int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =
510 strict_type ? sshkey_equal : sshkey_equal_public; 514 strict_type ? sshkey_equal : sshkey_equal_public;
511 515
512 if ((f = fopen(filename, "r")) == NULL) { 516 if ((f = fopen(filename, "r")) == NULL)
513 if (errno == ENOENT) 517 return SSH_ERR_SYSTEM_ERROR;
514 return SSH_ERR_KEY_NOT_FOUND;
515 else
516 return SSH_ERR_SYSTEM_ERROR;
517 }
518 518
519 while (read_keyfile_line(f, filename, line, sizeof(line), 519 while (read_keyfile_line(f, filename, line, sizeof(line),
520 &linenum) != -1) { 520 &linenum) != -1) {
@@ -538,7 +538,9 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
538 } 538 }
539 if ((r = sshkey_read(pub, &cp)) != 0) 539 if ((r = sshkey_read(pub, &cp)) != 0)
540 goto out; 540 goto out;
541 if (sshkey_compare(key, pub)) { 541 if (sshkey_compare(key, pub) ||
542 (check_ca && sshkey_is_cert(key) &&
543 sshkey_compare(key->cert->signature_key, pub))) {
542 r = 0; 544 r = 0;
543 goto out; 545 goto out;
544 } 546 }
@@ -553,3 +555,39 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type)
553 return r; 555 return r;
554} 556}
555 557
558/*
559 * Checks whether the specified key is revoked, returning 0 if not,
560 * SSH_ERR_KEY_REVOKED if it is or another error code if something
561 * unexpected happened.
562 * This will check both the key and, if it is a certificate, its CA key too.
563 * "revoked_keys_file" may be a KRL or a one-per-line list of public keys.
564 */
565int
566sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file)
567{
568 int r;
569
570#ifdef WITH_OPENSSL
571 r = ssh_krl_file_contains_key(revoked_keys_file, key);
572 /* If this was not a KRL to begin with then continue below */
573 if (r != SSH_ERR_KRL_BAD_MAGIC)
574 return r;
575#endif
576
577 /*
578 * If the file is not a KRL or we can't handle KRLs then attempt to
579 * parse the file as a flat list of keys.
580 */
581 switch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) {
582 case 0:
583 /* Key found => revoked */
584 return SSH_ERR_KEY_REVOKED;
585 case SSH_ERR_KEY_NOT_FOUND:
586 /* Key not found => not revoked */
587 return 0;
588 default:
589 /* Some other error occurred */
590 return r;
591 }
592}
593
diff --git a/authfile.h b/authfile.h
index 03bc3958c..645404e61 100644
--- a/authfile.h
+++ b/authfile.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.h,v 1.19 2014/07/03 23:18:35 djm Exp $ */ 1/* $OpenBSD: authfile.h,v 1.20 2014/12/04 02:24:32 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
@@ -42,6 +42,7 @@ int sshkey_load_private_type(int, const char *, const char *,
42 struct sshkey **, char **, int *); 42 struct sshkey **, char **, int *);
43int sshkey_load_private_pem(int, int, const char *, struct sshkey **, char **); 43int sshkey_load_private_pem(int, int, const char *, struct sshkey **, char **);
44int sshkey_perm_ok(int, const char *); 44int sshkey_perm_ok(int, const char *);
45int sshkey_in_file(struct sshkey *, const char *, int); 45int sshkey_in_file(struct sshkey *, const char *, int, int);
46int sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file);
46 47
47#endif 48#endif
diff --git a/readconf.c b/readconf.c
index 922c57454..e0386935f 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.222 2014/10/24 02:01:20 lteo Exp $ */ 1/* $OpenBSD: readconf.c,v 1.223 2014/12/04 02:24:32 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -154,7 +154,7 @@ typedef enum {
154 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, 154 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
155 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, 155 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
156 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, 156 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
157 oStreamLocalBindMask, oStreamLocalBindUnlink, 157 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
158 oIgnoredUnknownOption, oDeprecated, oUnsupported 158 oIgnoredUnknownOption, oDeprecated, oUnsupported
159} OpCodes; 159} OpCodes;
160 160
@@ -269,6 +269,7 @@ static struct {
269 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, 269 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
270 { "streamlocalbindmask", oStreamLocalBindMask }, 270 { "streamlocalbindmask", oStreamLocalBindMask },
271 { "streamlocalbindunlink", oStreamLocalBindUnlink }, 271 { "streamlocalbindunlink", oStreamLocalBindUnlink },
272 { "revokedhostkeys", oRevokedHostKeys },
272 { "ignoreunknown", oIgnoreUnknown }, 273 { "ignoreunknown", oIgnoreUnknown },
273 274
274 { NULL, oBadOption } 275 { NULL, oBadOption }
@@ -1455,6 +1456,10 @@ parse_int:
1455 intptr = &options->fwd_opts.streamlocal_bind_unlink; 1456 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1456 goto parse_flag; 1457 goto parse_flag;
1457 1458
1459 case oRevokedHostKeys:
1460 charptr = &options->revoked_host_keys;
1461 goto parse_string;
1462
1458 case oDeprecated: 1463 case oDeprecated:
1459 debug("%s line %d: Deprecated option \"%s\"", 1464 debug("%s line %d: Deprecated option \"%s\"",
1460 filename, linenum, keyword); 1465 filename, linenum, keyword);
@@ -1631,6 +1636,7 @@ initialize_options(Options * options)
1631 options->canonicalize_max_dots = -1; 1636 options->canonicalize_max_dots = -1;
1632 options->canonicalize_fallback_local = -1; 1637 options->canonicalize_fallback_local = -1;
1633 options->canonicalize_hostname = -1; 1638 options->canonicalize_hostname = -1;
1639 options->revoked_host_keys = NULL;
1634} 1640}
1635 1641
1636/* 1642/*
@@ -1818,6 +1824,7 @@ fill_default_options(Options * options)
1818 CLEAR_ON_NONE(options->local_command); 1824 CLEAR_ON_NONE(options->local_command);
1819 CLEAR_ON_NONE(options->proxy_command); 1825 CLEAR_ON_NONE(options->proxy_command);
1820 CLEAR_ON_NONE(options->control_path); 1826 CLEAR_ON_NONE(options->control_path);
1827 CLEAR_ON_NONE(options->revoked_host_keys);
1821 /* options->user will be set in the main program if appropriate */ 1828 /* options->user will be set in the main program if appropriate */
1822 /* options->hostname will be set in the main program if appropriate */ 1829 /* options->hostname will be set in the main program if appropriate */
1823 /* options->host_key_alias should not be set by default */ 1830 /* options->host_key_alias should not be set by default */
@@ -2251,6 +2258,7 @@ dump_client_config(Options *o, const char *host)
2251 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); 2258 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2252 dump_cfg_string(oProxyCommand, o->proxy_command); 2259 dump_cfg_string(oProxyCommand, o->proxy_command);
2253 dump_cfg_string(oXAuthLocation, o->xauth_location); 2260 dump_cfg_string(oXAuthLocation, o->xauth_location);
2261 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2254 2262
2255 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); 2263 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2256 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); 2264 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
diff --git a/readconf.h b/readconf.h
index 7b58d01f3..49858bff3 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.103 2014/10/08 22:20:25 djm Exp $ */ 1/* $OpenBSD: readconf.h,v 1.104 2014/12/04 02:24:32 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -144,6 +144,8 @@ typedef struct {
144 int num_permitted_cnames; 144 int num_permitted_cnames;
145 struct allowed_cname permitted_cnames[MAX_CANON_DOMAINS]; 145 struct allowed_cname permitted_cnames[MAX_CANON_DOMAINS];
146 146
147 char *revoked_host_keys;
148
147 char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ 149 char *ignored_unknown; /* Pattern list of unknown tokens to ignore */
148} Options; 150} Options;
149 151
diff --git a/ssh_config.5 b/ssh_config.5
index d8f980b68..f0a4b293a 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh_config.5,v 1.195 2014/11/10 22:25:49 djm Exp $ 36.\" $OpenBSD: ssh_config.5,v 1.196 2014/12/04 02:24:32 djm Exp $
37.Dd $Mdocdate: November 10 2014 $ 37.Dd $Mdocdate: December 4 2014 $
38.Dt SSH_CONFIG 5 38.Dt SSH_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -1253,6 +1253,16 @@ and
1253.Fl T 1253.Fl T
1254flags for 1254flags for
1255.Xr ssh 1 . 1255.Xr ssh 1 .
1256.It Cm RevokedHostKeys
1257Specifies revoked host public keys.
1258Keys listed in this file will be refused for host authentication.
1259Note that if this file does not exist or is not readable,
1260then host authentication will be refused for all hosts.
1261Keys may be specified as a text file, listing one public key per line, or as
1262an OpenSSH Key Revocation List (KRL) as generated by
1263.Xr ssh-keygen 1 .
1264For more information on KRLs, see the KEY REVOCATION LISTS section in
1265.Xr ssh-keygen 1 .
1256.It Cm RhostsRSAAuthentication 1266.It Cm RhostsRSAAuthentication
1257Specifies whether to try rhosts based authentication with RSA host 1267Specifies whether to try rhosts based authentication with RSA host
1258authentication. 1268authentication.
diff --git a/sshconnect.c b/sshconnect.c
index ac09eae67..f9a59372c 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.251 2014/07/15 15:54:14 millert Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.252 2014/12/04 02:24:32 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -62,6 +62,8 @@
62#include "monitor_fdpass.h" 62#include "monitor_fdpass.h"
63#include "ssh2.h" 63#include "ssh2.h"
64#include "version.h" 64#include "version.h"
65#include "authfile.h"
66#include "ssherr.h"
65 67
66char *client_version_string = NULL; 68char *client_version_string = NULL;
67char *server_version_string = NULL; 69char *server_version_string = NULL;
@@ -1219,16 +1221,44 @@ int
1219verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) 1221verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
1220{ 1222{
1221 int r = -1, flags = 0; 1223 int r = -1, flags = 0;
1222 char *fp; 1224 char *fp = NULL;
1223 Key *plain = NULL; 1225 struct sshkey *plain = NULL;
1226
1227 if ((fp = sshkey_fingerprint(host_key,
1228 SSH_FP_MD5, SSH_FP_HEX)) == NULL) {
1229 error("%s: fingerprint host key: %s", __func__, ssh_err(r));
1230 r = -1;
1231 goto out;
1232 }
1224 1233
1225 fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); 1234 debug("Server host key: %s %s", sshkey_type(host_key), fp);
1226 debug("Server host key: %s %s", key_type(host_key), fp);
1227 free(fp);
1228 1235
1229 if (key_equal(previous_host_key, host_key)) { 1236 if (sshkey_equal(previous_host_key, host_key)) {
1230 debug("%s: server host key matches cached key", __func__); 1237 debug2("%s: server host key %s %s matches cached key",
1231 return 0; 1238 __func__, sshkey_type(host_key), fp);
1239 r = 0;
1240 goto out;
1241 }
1242
1243 /* Check in RevokedHostKeys file if specified */
1244 if (options.revoked_host_keys != NULL) {
1245 r = sshkey_check_revoked(host_key, options.revoked_host_keys);
1246 switch (r) {
1247 case 0:
1248 break; /* not revoked */
1249 case SSH_ERR_KEY_REVOKED:
1250 error("Host key %s %s revoked by file %s",
1251 sshkey_type(host_key), fp,
1252 options.revoked_host_keys);
1253 r = -1;
1254 goto out;
1255 default:
1256 error("Error checking host key %s %s in "
1257 "revoked keys file %s: %s", sshkey_type(host_key),
1258 fp, options.revoked_host_keys, ssh_err(r));
1259 r = -1;
1260 goto out;
1261 }
1232 } 1262 }
1233 1263
1234 if (options.verify_host_key_dns) { 1264 if (options.verify_host_key_dns) {
@@ -1236,17 +1266,17 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
1236 * XXX certs are not yet supported for DNS, so downgrade 1266 * XXX certs are not yet supported for DNS, so downgrade
1237 * them and try the plain key. 1267 * them and try the plain key.
1238 */ 1268 */
1239 plain = key_from_private(host_key); 1269 if ((r = sshkey_from_private(host_key, &plain)) != 0)
1240 if (key_is_cert(plain)) 1270 goto out;
1241 key_drop_cert(plain); 1271 if (sshkey_is_cert(plain))
1272 sshkey_drop_cert(plain);
1242 if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) { 1273 if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) {
1243 if (flags & DNS_VERIFY_FOUND) { 1274 if (flags & DNS_VERIFY_FOUND) {
1244 if (options.verify_host_key_dns == 1 && 1275 if (options.verify_host_key_dns == 1 &&
1245 flags & DNS_VERIFY_MATCH && 1276 flags & DNS_VERIFY_MATCH &&
1246 flags & DNS_VERIFY_SECURE) { 1277 flags & DNS_VERIFY_SECURE) {
1247 key_free(plain);
1248 r = 0; 1278 r = 0;
1249 goto done; 1279 goto out;
1250 } 1280 }
1251 if (flags & DNS_VERIFY_MATCH) { 1281 if (flags & DNS_VERIFY_MATCH) {
1252 matching_host_key_dns = 1; 1282 matching_host_key_dns = 1;
@@ -1258,14 +1288,14 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
1258 } 1288 }
1259 } 1289 }
1260 } 1290 }
1261 key_free(plain);
1262 } 1291 }
1263
1264 r = check_host_key(host, hostaddr, options.port, host_key, RDRW, 1292 r = check_host_key(host, hostaddr, options.port, host_key, RDRW,
1265 options.user_hostfiles, options.num_user_hostfiles, 1293 options.user_hostfiles, options.num_user_hostfiles,
1266 options.system_hostfiles, options.num_system_hostfiles); 1294 options.system_hostfiles, options.num_system_hostfiles);
1267 1295
1268done: 1296out:
1297 sshkey_free(plain);
1298 free(fp);
1269 if (r == 0 && host_key != NULL) { 1299 if (r == 0 && host_key != NULL) {
1270 key_free(previous_host_key); 1300 key_free(previous_host_key);
1271 previous_host_key = key_from_private(host_key); 1301 previous_host_key = key_from_private(host_key);