diff --git a/compat.c b/compat.c index 0934de90f..cea63d268 100644 --- a/compat.c +++ b/compat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.c,v 1.89 2015/04/10 05:16:50 dtucker Exp $ */ +/* $OpenBSD: compat.c,v 1.90 2015/04/13 02:04:08 djm Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -165,6 +165,7 @@ compat_datafellows(const char *version) "OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD }, { "*SSH_Version_Mapper*", SSH_BUG_SCANNER }, + { "PuTTY*", SSH_OLD_DHGEX }, { "Probe-*", SSH_BUG_PROBE }, { "TeraTerm SSH*," @@ -284,15 +285,20 @@ compat_pkalg_proposal(char *pkalg_prop) } char * -compat_kex_proposal(char *kex_prop) +compat_kex_proposal(char *p) { - if (!(datafellows & SSH_BUG_CURVE25519PAD)) - return kex_prop; - debug2("%s: original KEX proposal: %s", __func__, kex_prop); - kex_prop = filter_proposal(kex_prop, "curve25519-sha256@libssh.org"); - debug2("%s: compat KEX proposal: %s", __func__, kex_prop); - if (*kex_prop == '\0') + if ((datafellows & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) + return p; + debug2("%s: original KEX proposal: %s", __func__, p); + if ((datafellows & SSH_BUG_CURVE25519PAD) != 0) + p = filter_proposal(p, "curve25519-sha256@libssh.org"); + if ((datafellows & SSH_OLD_DHGEX) != 0) { + p = filter_proposal(p, "diffie-hellman-group-exchange-sha256"); + p = filter_proposal(p, "diffie-hellman-group-exchange-sha1"); + } + debug2("%s: compat KEX proposal: %s", __func__, p); + if (*p == '\0') fatal("No supported key exchange algorithms found"); - return kex_prop; + return p; } diff --git a/kexgexc.c b/kexgexc.c index e8e059a88..3f20491c4 100644 --- a/kexgexc.c +++ b/kexgexc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexc.c,v 1.20 2015/01/26 06:10:03 djm Exp $ */ +/* $OpenBSD: kexgexc.c,v 1.21 2015/04/13 02:04:08 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -65,25 +65,15 @@ kexgex_client(struct ssh *ssh) kex->min = DH_GRP_MIN; kex->max = DH_GRP_MAX; kex->nbits = nbits; - if (ssh->compat & SSH_OLD_DHGEX) { - /* Old GEX request */ - if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)) - != 0 || - (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 || - (r = sshpkt_send(ssh)) != 0) - goto out; - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", kex->nbits); - } else { - /* New GEX request */ - if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST)) != 0 || - (r = sshpkt_put_u32(ssh, kex->min)) != 0 || - (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 || - (r = sshpkt_put_u32(ssh, kex->max)) != 0 || - (r = sshpkt_send(ssh)) != 0) - goto out; - debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent", - kex->min, kex->nbits, kex->max); - } + /* New GEX request */ + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST)) != 0 || + (r = sshpkt_put_u32(ssh, kex->min)) != 0 || + (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 || + (r = sshpkt_put_u32(ssh, kex->max)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; + debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent", + kex->min, kex->nbits, kex->max); #ifdef DEBUG_KEXDH fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", kex->min, kex->nbits, kex->max); diff --git a/kexgexs.c b/kexgexs.c index 9c281d288..ff6c6879e 100644 --- a/kexgexs.c +++ b/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.24 2015/01/26 06:10:03 djm Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.25 2015/04/13 02:04:08 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -60,8 +60,6 @@ static int input_kex_dh_gex_init(int, u_int32_t, void *); int kexgex_server(struct ssh *ssh) { - ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST_OLD, - &input_kex_dh_gex_request); ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST, &input_kex_dh_gex_request); debug("expecting SSH2_MSG_KEX_DH_GEX_REQUEST"); @@ -76,36 +74,19 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt) int r; u_int min = 0, max = 0, nbits = 0; - switch (type) { - case SSH2_MSG_KEX_DH_GEX_REQUEST: - debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); - if ((r = sshpkt_get_u32(ssh, &min)) != 0 || - (r = sshpkt_get_u32(ssh, &nbits)) != 0 || - (r = sshpkt_get_u32(ssh, &max)) != 0 || - (r = sshpkt_get_end(ssh)) != 0) - goto out; - kex->nbits = nbits; - kex->min = min; - kex->max = max; - min = MAX(DH_GRP_MIN, min); - max = MIN(DH_GRP_MAX, max); - nbits = MAX(DH_GRP_MIN, nbits); - nbits = MIN(DH_GRP_MAX, nbits); - break; - case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); - if ((r = sshpkt_get_u32(ssh, &nbits)) != 0 || - (r = sshpkt_get_end(ssh)) != 0) - goto out; - kex->nbits = nbits; - /* unused for old GEX */ - kex->min = min = DH_GRP_MIN; - kex->max = max = DH_GRP_MAX; - break; - default: - r = SSH_ERR_INVALID_ARGUMENT; + debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); + if ((r = sshpkt_get_u32(ssh, &min)) != 0 || + (r = sshpkt_get_u32(ssh, &nbits)) != 0 || + (r = sshpkt_get_u32(ssh, &max)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) goto out; - } + kex->nbits = nbits; + kex->min = min; + kex->max = max; + min = MAX(DH_GRP_MIN, min); + max = MIN(DH_GRP_MAX, max); + nbits = MAX(DH_GRP_MIN, nbits); + nbits = MIN(DH_GRP_MAX, nbits); if (kex->max < kex->min || kex->nbits < kex->min || kex->max < kex->nbits) { @@ -131,10 +112,6 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt) if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) goto out; - /* old KEX does not use min/max in kexgex_hash() */ - if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) - kex->min = kex->max = -1; - debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init); r = 0;