From djm@mindrot.org Wed Jul 29 11:44:30 2015 Delivered-To: david@gwynne.id.au Received: by 10.27.85.227 with SMTP id l96csp2108801wli; Tue, 28 Jul 2015 18:44:33 -0700 (PDT) X-Received: by 10.170.130.69 with SMTP id w66mr41317841ykb.8.1438134273183; Tue, 28 Jul 2015 18:44:33 -0700 (PDT) Return-Path: Received: from cvs.openbsd.org (cvs.openbsd.org. [199.185.137.3]) by mx.google.com with ESMTPS id z138si17231127ywd.46.2015.07.28.18.44.29 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Jul 2015 18:44:30 -0700 (PDT) Received-SPF: neutral (google.com: 199.185.137.3 is neither permitted nor denied by domain of djm@mindrot.org) client-ip=199.185.137.3; Authentication-Results: mx.google.com; spf=neutral (google.com: 199.185.137.3 is neither permitted nor denied by domain of djm@mindrot.org) smtp.mail=djm@mindrot.org Received: from shear.ucar.edu (lists.openbsd.org [192.43.244.163]) by cvs.openbsd.org (OpenSMTPD) with ESMTPS id ff0ee929 TLS version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL for ; Tue, 28 Jul 2015 19:44:28 -0600 (MDT) Received: from newmailhub.uq.edu.au (mailhub1.soe.uq.edu.au [130.102.132.208]) by shear.ucar.edu (8.14.7/8.14.7) with ESMTP id t6T1iQH5030064 for ; Tue, 28 Jul 2015 19:44:27 -0600 (MDT) Received: from smtp1.soe.uq.edu.au (smtp1.soe.uq.edu.au [10.138.113.40]) by newmailhub.uq.edu.au (8.14.5/8.14.5) with ESMTP id t6T1iPbK003579 for ; Wed, 29 Jul 2015 11:44:25 +1000 Received: from mailhub.eait.uq.edu.au (hazel.eait.uq.edu.au [130.102.60.17]) by smtp1.soe.uq.edu.au (8.14.5/8.14.5) with ESMTP id t6T1iP00054496 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 29 Jul 2015 11:44:25 +1000 Received: from natsu.mindrot.org (natsu.mindrot.org [130.102.96.2]) by mailhub.eait.uq.edu.au (8.15.1/8.15.1) with ESMTP id t6T1iOpH032616 for ; Wed, 29 Jul 2015 11:44:24 +1000 (AEST) Received: by natsu.mindrot.org (Postfix, from userid 1000) id 9070CA4F4D; Wed, 29 Jul 2015 11:44:24 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by natsu.mindrot.org (Postfix) with ESMTP id 8F5BEA4F2F for ; Wed, 29 Jul 2015 11:44:24 +1000 (AEST) Date: Wed, 29 Jul 2015 11:44:24 +1000 (AEST) From: Damien Miller To: dlg@openbsd.org Subject: log the failed kex betterer Message-ID: User-Agent: Alpine 2.20 (BSO 67 2015-01-07) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Scanned-By: MIMEDefang 2.73 on UQ Mailhub X-Scanned-By: MIMEDefang 2.75 on 130.102.60.17 X-UQ-FilterTime: 1438134265 Status: RO Content-Length: 3510 Lines: 107 diff --git a/kex.c b/kex.c index b328e5f..f7e456c 100644 --- a/kex.c +++ b/kex.c @@ -427,6 +489,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 +668,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 +695,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/kex.h b/kex.h index 99a7d55..0565fc4 100644 --- a/kex.h +++ b/kex.h @@ -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 *); @@ -145,6 +146,8 @@ struct kex { int kex_names_valid(const char *); char *kex_alg_list(char); +char *kex_names_cat(const char *, const char *); +int kex_assemble_names(const char *, char **); int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); diff --git a/packet.c b/packet.c index cca2800..842de46 100644 --- a/packet.c +++ b/packet.c @@ -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 ? ": " : "",