summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/sshconnect.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/sshconnect.c')
-rw-r--r--crypto/openssh/sshconnect.c110
1 files changed, 82 insertions, 28 deletions
diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c
index 88ea7be..44bfa2d 100644
--- a/crypto/openssh/sshconnect.c
+++ b/crypto/openssh/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.251 2014/07/15 15:54:14 millert Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.259 2015/01/28 22:36:00 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -16,6 +16,7 @@
#include "includes.h"
__RCSID("$FreeBSD$");
+#include <sys/param.h> /* roundup */
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
@@ -64,6 +65,8 @@ __RCSID("$FreeBSD$");
#include "monitor_fdpass.h"
#include "ssh2.h"
#include "version.h"
+#include "authfile.h"
+#include "ssherr.h"
char *client_version_string = NULL;
char *server_version_string = NULL;
@@ -626,7 +629,7 @@ ssh_exchange_identification(int timeout_ms)
debug("Remote protocol version %d.%d, remote software version %.100s",
remote_major, remote_minor, remote_version);
- compat_datafellows(remote_version);
+ active_state->compat = compat_datafellows(remote_version);
mismatch = 0;
switch (remote_major) {
@@ -768,7 +771,7 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
if (options.proxy_command == NULL) {
if (getnameinfo(hostaddr, addrlen,
ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0)
- fatal("check_host_key: getnameinfo failed");
+ fatal("%s: getnameinfo failed", __func__);
*hostfile_ipaddr = put_host_port(ntop, port);
} else {
*hostfile_ipaddr = xstrdup("<no hostip for proxy "
@@ -816,6 +819,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
int len, cancelled_forwarding = 0;
int local = sockaddr_is_local(hostaddr);
int r, want_cert = key_is_cert(host_key), host_ip_differ = 0;
+ int hostkey_trusted = 0; /* Known or explicitly accepted by user */
struct hostkeys *host_hostkeys, *ip_hostkeys;
u_int i;
@@ -916,13 +920,17 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
"key for IP address '%.128s' to the list "
"of known hosts.", type, ip);
} else if (options.visual_host_key) {
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
- ra = key_fingerprint(host_key, SSH_FP_MD5,
- SSH_FP_RANDOMART);
+ fp = sshkey_fingerprint(host_key,
+ options.fingerprint_hash, SSH_FP_DEFAULT);
+ ra = sshkey_fingerprint(host_key,
+ options.fingerprint_hash, SSH_FP_RANDOMART);
+ if (fp == NULL || ra == NULL)
+ fatal("%s: sshkey_fingerprint fail", __func__);
logit("Host key fingerprint is %s\n%s\n", fp, ra);
free(ra);
free(fp);
}
+ hostkey_trusted = 1;
break;
case HOST_NEW:
if (options.host_key_alias == NULL && port != 0 &&
@@ -957,9 +965,12 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
else
snprintf(msg1, sizeof(msg1), ".");
/* The default */
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
- ra = key_fingerprint(host_key, SSH_FP_MD5,
- SSH_FP_RANDOMART);
+ fp = sshkey_fingerprint(host_key,
+ options.fingerprint_hash, SSH_FP_DEFAULT);
+ ra = sshkey_fingerprint(host_key,
+ options.fingerprint_hash, SSH_FP_RANDOMART);
+ if (fp == NULL || ra == NULL)
+ fatal("%s: sshkey_fingerprint fail", __func__);
msg2[0] = '\0';
if (options.verify_host_key_dns) {
if (matching_host_key_dns)
@@ -985,6 +996,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
free(fp);
if (!confirm(msg))
goto fail;
+ hostkey_trusted = 1; /* user explicitly confirmed */
}
/*
* If not in strict mode, add the key automatically to the
@@ -1183,6 +1195,12 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
}
}
+ if (!hostkey_trusted && options.update_hostkeys) {
+ debug("%s: hostkey not known or explicitly trusted: "
+ "disabling UpdateHostkeys", __func__);
+ options.update_hostkeys = 0;
+ }
+
free(ip);
free(host);
if (host_hostkeys != NULL)
@@ -1220,16 +1238,45 @@ int
verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
{
int r = -1, flags = 0;
- char *fp;
- Key *plain = NULL;
+ char *fp = NULL;
+ struct sshkey *plain = NULL;
+
+ if ((fp = sshkey_fingerprint(host_key,
+ options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
+ error("%s: fingerprint host key: %s", __func__, ssh_err(r));
+ r = -1;
+ goto out;
+ }
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
- debug("Server host key: %s %s", key_type(host_key), fp);
- free(fp);
+ debug("Server host key: %s %s",
+ compat20 ? sshkey_ssh_name(host_key) : sshkey_type(host_key), fp);
- if (key_equal(previous_host_key, host_key)) {
- debug("%s: server host key matches cached key", __func__);
- return 0;
+ if (sshkey_equal(previous_host_key, host_key)) {
+ debug2("%s: server host key %s %s matches cached key",
+ __func__, sshkey_type(host_key), fp);
+ r = 0;
+ goto out;
+ }
+
+ /* Check in RevokedHostKeys file if specified */
+ if (options.revoked_host_keys != NULL) {
+ r = sshkey_check_revoked(host_key, options.revoked_host_keys);
+ switch (r) {
+ case 0:
+ break; /* not revoked */
+ case SSH_ERR_KEY_REVOKED:
+ error("Host key %s %s revoked by file %s",
+ sshkey_type(host_key), fp,
+ options.revoked_host_keys);
+ r = -1;
+ goto out;
+ default:
+ error("Error checking host key %s %s in "
+ "revoked keys file %s: %s", sshkey_type(host_key),
+ fp, options.revoked_host_keys, ssh_err(r));
+ r = -1;
+ goto out;
+ }
}
if (options.verify_host_key_dns) {
@@ -1237,17 +1284,17 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
* XXX certs are not yet supported for DNS, so downgrade
* them and try the plain key.
*/
- plain = key_from_private(host_key);
- if (key_is_cert(plain))
- key_drop_cert(plain);
+ if ((r = sshkey_from_private(host_key, &plain)) != 0)
+ goto out;
+ if (sshkey_is_cert(plain))
+ sshkey_drop_cert(plain);
if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) {
if (flags & DNS_VERIFY_FOUND) {
if (options.verify_host_key_dns == 1 &&
flags & DNS_VERIFY_MATCH &&
flags & DNS_VERIFY_SECURE) {
- key_free(plain);
r = 0;
- goto done;
+ goto out;
}
if (flags & DNS_VERIFY_MATCH) {
matching_host_key_dns = 1;
@@ -1259,14 +1306,14 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
}
}
}
- key_free(plain);
}
-
r = check_host_key(host, hostaddr, options.port, host_key, RDRW,
options.user_hostfiles, options.num_user_hostfiles,
options.system_hostfiles, options.num_system_hostfiles);
-done:
+out:
+ sshkey_free(plain);
+ free(fp);
if (r == 0 && host_key != NULL) {
key_free(previous_host_key);
previous_host_key = key_from_private(host_key);
@@ -1357,8 +1404,12 @@ show_other_keys(struct hostkeys *hostkeys, Key *key)
continue;
if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found))
continue;
- fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX);
- ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART);
+ fp = sshkey_fingerprint(found->key,
+ options.fingerprint_hash, SSH_FP_DEFAULT);
+ ra = sshkey_fingerprint(found->key,
+ options.fingerprint_hash, SSH_FP_RANDOMART);
+ if (fp == NULL || ra == NULL)
+ fatal("%s: sshkey_fingerprint fail", __func__);
logit("WARNING: %s key found for host %s\n"
"in %s:%lu\n"
"%s key fingerprint %s.",
@@ -1379,7 +1430,10 @@ warn_changed_key(Key *host_key)
{
char *fp;
- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
+ fp = sshkey_fingerprint(host_key, options.fingerprint_hash,
+ SSH_FP_DEFAULT);
+ if (fp == NULL)
+ fatal("%s: sshkey_fingerprint fail", __func__);
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @");
OpenPOWER on IntegriCloud