diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2015-07-29 04:43:07 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2015-07-29 04:43:07 +0000 |
commit | 1552c9d94b11ce9fc6252b0b3e01edd11b281bde (patch) | |
tree | ec998c5500c11955df3e763d907846f1449f8aca /usr.bin/ssh | |
parent | cb5ba5a84b49f77f69c13927c31670bb0e6b5882 (diff) |
include the peer's offer when logging a failure to negotiate a
mutual set of algorithms (kex, pubkey, ciphers, etc.)
ok markus@
Diffstat (limited to 'usr.bin/ssh')
-rw-r--r-- | usr.bin/ssh/kex.c | 31 | ||||
-rw-r--r-- | usr.bin/ssh/kex.h | 3 | ||||
-rw-r--r-- | usr.bin/ssh/packet.c | 13 |
3 files changed, 38 insertions, 9 deletions
diff --git a/usr.bin/ssh/kex.c b/usr.bin/ssh/kex.c index b328e5f0dbe..5499b0aed94 100644 --- a/usr.bin/ssh/kex.c +++ b/usr.bin/ssh/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.106 2015/04/17 13:25:52 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.107 2015/07/29 04:43:06 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -427,6 +427,7 @@ kex_free(struct kex *kex) free(kex->session_id); free(kex->client_version_string); free(kex->server_version_string); + free(kex->failed_choice); free(kex); } @@ -605,17 +606,26 @@ kex_choose_conf(struct ssh *ssh) nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; if ((r = choose_enc(&newkeys->enc, cprop[nenc], - sprop[nenc])) != 0) + sprop[nenc])) != 0) { + kex->failed_choice = peer[nenc]; + peer[nenc] = NULL; goto out; + } authlen = cipher_authlen(newkeys->enc.cipher); /* ignore mac for authenticated encryption */ if (authlen == 0 && (r = choose_mac(ssh, &newkeys->mac, cprop[nmac], - sprop[nmac])) != 0) + sprop[nmac])) != 0) { + kex->failed_choice = peer[nmac]; + peer[nmac] = NULL; goto out; + } if ((r = choose_comp(&newkeys->comp, cprop[ncomp], - sprop[ncomp])) != 0) + sprop[ncomp])) != 0) { + kex->failed_choice = peer[ncomp]; + peer[ncomp] = NULL; goto out; + } debug("kex: %s %s %s %s", ctos ? "client->server" : "server->client", newkeys->enc.name, @@ -623,10 +633,17 @@ kex_choose_conf(struct ssh *ssh) newkeys->comp.name); } if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], - sprop[PROPOSAL_KEX_ALGS])) != 0 || - (r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], - sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) + sprop[PROPOSAL_KEX_ALGS])) != 0) { + kex->failed_choice = peer[PROPOSAL_KEX_ALGS]; + peer[PROPOSAL_KEX_ALGS] = NULL; goto out; + } + if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], + sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) { + kex->failed_choice = cprop[PROPOSAL_SERVER_HOST_KEY_ALGS]; + cprop[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL; + goto out; + } need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { newkeys = kex->newkeys[mode]; diff --git a/usr.bin/ssh/kex.h b/usr.bin/ssh/kex.h index 99a7d55bf83..63455695e8b 100644 --- a/usr.bin/ssh/kex.h +++ b/usr.bin/ssh/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.71 2015/02/16 22:13:32 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.72 2015/07/29 04:43:06 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -127,6 +127,7 @@ struct kex { int ec_nid; char *client_version_string; char *server_version_string; + char *failed_choice; int (*verify_host_key)(struct sshkey *, struct ssh *); struct sshkey *(*load_host_public_key)(int, int, struct ssh *); struct sshkey *(*load_host_private_key)(int, int, struct ssh *); diff --git a/usr.bin/ssh/packet.c b/usr.bin/ssh/packet.c index cca280033ea..f5f1d4f3e1e 100644 --- a/usr.bin/ssh/packet.c +++ b/usr.bin/ssh/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.212 2015/05/01 07:10:01 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.213 2015/07/29 04:43:06 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1921,6 +1921,17 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r) cleanup_exit(255); } /* FALLTHROUGH */ + case SSH_ERR_NO_CIPHER_ALG_MATCH: + case SSH_ERR_NO_MAC_ALG_MATCH: + case SSH_ERR_NO_COMPRESS_ALG_MATCH: + case SSH_ERR_NO_KEX_ALG_MATCH: + case SSH_ERR_NO_HOSTKEY_ALG_MATCH: + if (ssh && ssh->kex && ssh->kex->failed_choice) { + fatal("Unable to negotiate with %.200s: %s. " + "Their offer: %s", ssh_remote_ipaddr(ssh), + ssh_err(r), ssh->kex->failed_choice); + } + /* FALLTHROUGH */ default: fatal("%s%sConnection to %.200s: %s", tag != NULL ? tag : "", tag != NULL ? ": " : "", |