diff options
author | djm@openbsd.org <djm@openbsd.org> | 2014-12-04 02:24:32 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2014-12-05 09:29:47 +1100 |
commit | 5e39a49930d885aac9c76af3129332b6e772cd75 (patch) | |
tree | 0d3613d35ba5478ff9f7889cc1912a70ee3b2e32 /sshconnect.c | |
parent | 74de254bb92c684cf53461da97f52d5ba34ded80 (diff) |
upstream commit
add RevokedHostKeys option for the client
Allow textfile or KRL-based revocation of hostkeys.
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 64 |
1 files changed, 47 insertions, 17 deletions
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 | ||
66 | char *client_version_string = NULL; | 68 | char *client_version_string = NULL; |
67 | char *server_version_string = NULL; | 69 | char *server_version_string = NULL; |
@@ -1219,16 +1221,44 @@ int | |||
1219 | verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | 1221 | verify_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 | ||
1268 | done: | 1296 | out: |
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); |