1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-06 22:12:47 -05:00

Support RFC 4419.

PuTTY now uses the updated version of Diffie-Hellman group exchange,
except for a few old OpenSSH versions which Darren Tucker reports only
support the old version.

FIXME: this needs further work because the Bugs config panel has now
overflowed.

(cherry picked from commit 62a1bce7cb)
This commit is contained in:
Simon Tatham
2015-04-25 10:46:53 +01:00
parent 5ac299449e
commit 318076a183
7 changed files with 59 additions and 3 deletions

35
ssh.c
View File

@ -76,6 +76,10 @@ static const char *const ssh2_disconnect_reasons[] = {
#define BUG_CHOKES_ON_SSH2_IGNORE 512
#define BUG_CHOKES_ON_WINADJ 1024
#define BUG_SENDS_LATE_REQUEST_REPLY 2048
#define BUG_SSH2_OLDGEX 4096
#define DH_MIN_SIZE 1024
#define DH_MAX_SIZE 8192
/*
* Codes for terminal modes.
@ -247,6 +251,7 @@ static char *ssh2_pkt_type(Pkt_KCtx pkt_kctx, Pkt_ACtx pkt_actx, int type)
translate(SSH2_MSG_NEWKEYS);
translatek(SSH2_MSG_KEXDH_INIT, SSH2_PKTCTX_DHGROUP);
translatek(SSH2_MSG_KEXDH_REPLY, SSH2_PKTCTX_DHGROUP);
translatek(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD, SSH2_PKTCTX_DHGEX);
translatek(SSH2_MSG_KEX_DH_GEX_REQUEST, SSH2_PKTCTX_DHGEX);
translatek(SSH2_MSG_KEX_DH_GEX_GROUP, SSH2_PKTCTX_DHGEX);
translatek(SSH2_MSG_KEX_DH_GEX_INIT, SSH2_PKTCTX_DHGEX);
@ -2805,6 +2810,17 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
logevent("We believe remote version has SSH-2 ignore bug");
}
if (conf_get_int(ssh->conf, CONF_sshbug_oldgex2) == FORCE_ON ||
(conf_get_int(ssh->conf, CONF_sshbug_oldgex2) == AUTO &&
(wc_match("OpenSSH_2.[235]*", imp)))) {
/*
* These versions only support the original (pre-RFC4419)
* SSH-2 GEX request.
*/
ssh->remote_bugs |= BUG_SSH2_OLDGEX;
logevent("We believe remote version has outdated SSH-2 GEX");
}
if (conf_get_int(ssh->conf, CONF_sshbug_winadj) == FORCE_ON) {
/*
* Servers that don't support our winadj request for one
@ -6595,8 +6611,19 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
* much data.
*/
s->pbits = 512 << ((s->nbits - 1) / 64);
s->pktout = ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
ssh2_pkt_adduint32(s->pktout, s->pbits);
if (s->pbits < DH_MIN_SIZE)
s->pbits = DH_MIN_SIZE;
if (s->pbits > DH_MAX_SIZE)
s->pbits = DH_MAX_SIZE;
if ((ssh->remote_bugs & BUG_SSH2_OLDGEX)) {
s->pktout = ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD);
ssh2_pkt_adduint32(s->pktout, s->pbits);
} else {
s->pktout = ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
ssh2_pkt_adduint32(s->pktout, DH_MIN_SIZE);
ssh2_pkt_adduint32(s->pktout, s->pbits);
ssh2_pkt_adduint32(s->pktout, DH_MAX_SIZE);
}
ssh2_pkt_send_noqueue(ssh, s->pktout);
crWaitUntilV(pktin);
@ -6664,7 +6691,11 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen);
if (!ssh->kex->pdata) {
if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX))
hash_uint32(ssh->kex->hash, ssh->exhash, DH_MIN_SIZE);
hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits);
if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX))
hash_uint32(ssh->kex->hash, ssh->exhash, DH_MAX_SIZE);
hash_mpint(ssh->kex->hash, ssh->exhash, s->p);
hash_mpint(ssh->kex->hash, ssh->exhash, s->g);
}