X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/b672f405dd2bfa3bdd7d11c1d616d674fe8d9d7a..8098d5853359ee5b7b9c1ba3a57619af75a8374f:/ssh.c diff --git a/ssh.c b/ssh.c index 22cea9fd..c55d2174 100644 --- a/ssh.c +++ b/ssh.c @@ -130,21 +130,21 @@ static const char *const ssh2_disconnect_reasons[] = { NULL, - "SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT", - "SSH_DISCONNECT_PROTOCOL_ERROR", - "SSH_DISCONNECT_KEY_EXCHANGE_FAILED", - "SSH_DISCONNECT_HOST_AUTHENTICATION_FAILED", - "SSH_DISCONNECT_MAC_ERROR", - "SSH_DISCONNECT_COMPRESSION_ERROR", - "SSH_DISCONNECT_SERVICE_NOT_AVAILABLE", - "SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED", - "SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE", - "SSH_DISCONNECT_CONNECTION_LOST", - "SSH_DISCONNECT_BY_APPLICATION", - "SSH_DISCONNECT_TOO_MANY_CONNECTIONS", - "SSH_DISCONNECT_AUTH_CANCELLED_BY_USER", - "SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE", - "SSH_DISCONNECT_ILLEGAL_USER_NAME", + "host not allowed to connect", + "protocol error", + "key exchange failed", + "host authentication failed", + "mac error", + "compression error", + "service not available", + "protocol version not supported", + "host key not verifiable", + "connection lost", + "by application", + "too many connections", + "auth cancelled by user", + "no more auth methods available", + "illegal user name", }; #define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 /* 0x1 */ @@ -462,10 +462,10 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, const static struct ssh_signkey *hostkey_algs[] = { &ssh_rsa, &ssh_dss }; const static struct ssh_mac *macs[] = { - &ssh_hmac_sha1, &ssh_hmac_md5 + &ssh_hmac_sha1, &ssh_hmac_sha1_96, &ssh_hmac_md5 }; const static struct ssh_mac *buggymacs[] = { - &ssh_hmac_sha1_buggy, &ssh_hmac_md5 + &ssh_hmac_sha1_buggy, &ssh_hmac_sha1_96_buggy, &ssh_hmac_md5 }; static void *ssh_comp_none_init(void) @@ -705,7 +705,7 @@ struct ssh_tag { void *cs_comp_ctx, *sc_comp_ctx; const struct ssh_kex *kex; const struct ssh_signkey *hostkey; - unsigned char v2_session_id[20]; + unsigned char v2_session_id[32]; int v2_session_id_len; void *kex_ctx; @@ -4994,9 +4994,9 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, char *hostkeydata, *sigdata, *keystr, *fingerprint; int hostkeylen, siglen; void *hkey; /* actual host key */ - unsigned char exchange_hash[20]; + unsigned char exchange_hash[32]; int n_preferred_kex; - const struct ssh_kex *preferred_kex[KEX_MAX]; + const struct ssh_kexes *preferred_kex[KEX_MAX]; int n_preferred_ciphers; const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX]; const struct ssh_compress *preferred_comp; @@ -5119,12 +5119,14 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, ssh2_pkt_addstring_start(s->pktout); commalist_started = 0; for (i = 0; i < s->n_preferred_kex; i++) { - const struct ssh_kex *k = s->preferred_kex[i]; + const struct ssh_kexes *k = s->preferred_kex[i]; if (!k) continue; /* warning flag */ - if (commalist_started) - ssh2_pkt_addstring_str(s->pktout, ","); - ssh2_pkt_addstring_str(s->pktout, s->preferred_kex[i]->name); - commalist_started = 1; + for (j = 0; j < k->nkexes; j++) { + if (commalist_started) + ssh2_pkt_addstring_str(s->pktout, ","); + ssh2_pkt_addstring_str(s->pktout, k->list[j]->name); + commalist_started = 1; + } } /* List server host key algorithms. */ ssh2_pkt_addstring_start(s->pktout); @@ -5241,13 +5243,17 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, preferred = NULL; for (i = 0; i < s->n_preferred_kex; i++) { - const struct ssh_kex *k = s->preferred_kex[i]; + const struct ssh_kexes *k = s->preferred_kex[i]; if (!k) { s->warn_kex = TRUE; } else { - if (!preferred) preferred = k->name; - if (in_commasep_string(k->name, str, len)) - ssh->kex = k; + for (j = 0; j < k->nkexes; j++) { + if (!preferred) preferred = k->list[j]->name; + if (in_commasep_string(k->list[j]->name, str, len)) { + ssh->kex = k->list[j]; + break; + } + } } if (ssh->kex) break; @@ -5528,7 +5534,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, set_busy_status(ssh->frontend, BUSY_NOT); hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen); - if (ssh->kex == &ssh_diffiehellman_gex) { + if (!ssh->kex->pdata) { hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits); hash_mpint(ssh->kex->hash, ssh->exhash, s->p); hash_mpint(ssh->kex->hash, ssh->exhash, s->g); @@ -5602,8 +5608,8 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, assert(sizeof(s->exchange_hash) <= sizeof(ssh->v2_session_id)); memcpy(ssh->v2_session_id, s->exchange_hash, sizeof(s->exchange_hash)); - assert(ssh->v2_session_id_len <= sizeof(ssh->v2_session_id)); ssh->v2_session_id_len = ssh->kex->hash->hlen; + assert(ssh->v2_session_id_len <= sizeof(ssh->v2_session_id)); s->got_session_id = TRUE; } @@ -5717,7 +5723,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen, */ freebn(s->f); freebn(s->K); - if (ssh->kex == &ssh_diffiehellman_gex) { + if (!ssh->kex->pdata) { freebn(s->g); freebn(s->p); }