X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/97db3be4f673508e214040881556d35f3d65406a..7591b9ff09c8700ce2f8c03ed33d3801668bae02:/ssh.c diff --git a/ssh.c b/ssh.c index 26cfbaa4..7d1ce260 100644 --- a/ssh.c +++ b/ssh.c @@ -167,7 +167,7 @@ const static struct ssh_kex *kex_algs[] = { &ssh_diffiehellman }; extern const struct ssh_hostkey ssh_dss; const static struct ssh_hostkey *hostkey_algs[] = { &ssh_dss }; -extern const struct ssh_mac ssh_sha1; +extern const struct ssh_mac ssh_sha1, ssh_sha1_buggy; static void nullmac_key(unsigned char *key) { } static void nullmac_generate(unsigned char *blk, int len, unsigned long seq) { } @@ -176,6 +176,7 @@ const static struct ssh_mac ssh_mac_none = { nullmac_key, nullmac_key, nullmac_generate, nullmac_verify, "none", 0 }; const static struct ssh_mac *macs[] = { &ssh_sha1, &ssh_mac_none }; +const static struct ssh_mac *buggymacs[] = { &ssh_sha1_buggy, &ssh_mac_none }; const static struct ssh_compress ssh_comp_none = { "none" @@ -810,7 +811,7 @@ static int ssh_versioncmp(char *a, char *b) { * state. */ #include -void sha_string(SHA_State *s, void *str, int len) { +static void sha_string(SHA_State *s, void *str, int len) { unsigned char lenblk[4]; PUT_32BIT(lenblk, len); SHA_Bytes(s, lenblk, 4); @@ -820,7 +821,7 @@ void sha_string(SHA_State *s, void *str, int len) { /* * SSH2 packet construction functions. */ -void ssh2_pkt_adddata(void *data, int len) { +static void ssh2_pkt_adddata(void *data, int len) { pktout.length += len; if (pktout.maxlen < pktout.length) { pktout.maxlen = pktout.length + 256; @@ -831,40 +832,40 @@ void ssh2_pkt_adddata(void *data, int len) { } memcpy(pktout.data+pktout.length-len, data, len); } -void ssh2_pkt_addbyte(unsigned char byte) { +static void ssh2_pkt_addbyte(unsigned char byte) { ssh2_pkt_adddata(&byte, 1); } -void ssh2_pkt_init(int pkt_type) { +static void ssh2_pkt_init(int pkt_type) { pktout.length = 5; ssh2_pkt_addbyte((unsigned char)pkt_type); } -void ssh2_pkt_addbool(unsigned char value) { +static void ssh2_pkt_addbool(unsigned char value) { ssh2_pkt_adddata(&value, 1); } -void ssh2_pkt_adduint32(unsigned long value) { +static void ssh2_pkt_adduint32(unsigned long value) { unsigned char x[4]; PUT_32BIT(x, value); ssh2_pkt_adddata(x, 4); } -void ssh2_pkt_addstring_start(void) { +static void ssh2_pkt_addstring_start(void) { ssh2_pkt_adduint32(0); pktout.savedpos = pktout.length; } -void ssh2_pkt_addstring_str(char *data) { +static void ssh2_pkt_addstring_str(char *data) { ssh2_pkt_adddata(data, strlen(data)); PUT_32BIT(pktout.data + pktout.savedpos - 4, pktout.length - pktout.savedpos); } -void ssh2_pkt_addstring_data(char *data, int len) { +static void ssh2_pkt_addstring_data(char *data, int len) { ssh2_pkt_adddata(data, len); PUT_32BIT(pktout.data + pktout.savedpos - 4, pktout.length - pktout.savedpos); } -void ssh2_pkt_addstring(char *data) { +static void ssh2_pkt_addstring(char *data) { ssh2_pkt_addstring_start(); ssh2_pkt_addstring_str(data); } -char *ssh2_mpint_fmt(Bignum b, int *len) { +static char *ssh2_mpint_fmt(Bignum b, int *len) { unsigned char *p; int i, n = b[0]; p = malloc(n * 2 + 1); @@ -882,7 +883,7 @@ char *ssh2_mpint_fmt(Bignum b, int *len) { *len = n*2+1-i; return p; } -void ssh2_pkt_addmp(Bignum b) { +static void ssh2_pkt_addmp(Bignum b) { unsigned char *p; int len; p = ssh2_mpint_fmt(b, &len); @@ -890,7 +891,7 @@ void ssh2_pkt_addmp(Bignum b) { ssh2_pkt_addstring_data(p, len); free(p); } -void ssh2_pkt_send(void) { +static void ssh2_pkt_send(void) { int cipherblk, maclen, padding, i; static unsigned long outgoing_sequence = 0; @@ -938,7 +939,7 @@ void bndebug(char *string, Bignum b) { } #endif -void sha_mpint(SHA_State *s, Bignum b) { +static void sha_mpint(SHA_State *s, Bignum b) { unsigned char *p; int len; p = ssh2_mpint_fmt(b, &len); @@ -949,7 +950,7 @@ void sha_mpint(SHA_State *s, Bignum b) { /* * SSH2 packet decode functions. */ -unsigned long ssh2_pkt_getuint32(void) { +static unsigned long ssh2_pkt_getuint32(void) { unsigned long value; if (pktin.length - pktin.savedpos < 4) return 0; /* arrgh, no way to decline (FIXME?) */ @@ -957,7 +958,7 @@ unsigned long ssh2_pkt_getuint32(void) { pktin.savedpos += 4; return value; } -void ssh2_pkt_getstring(char **p, int *length) { +static void ssh2_pkt_getstring(char **p, int *length) { *p = NULL; if (pktin.length - pktin.savedpos < 4) return; @@ -968,7 +969,7 @@ void ssh2_pkt_getstring(char **p, int *length) { *p = pktin.data+pktin.savedpos; pktin.savedpos += *length; } -Bignum ssh2_pkt_getmp(void) { +static Bignum ssh2_pkt_getmp(void) { char *p; int i, j, length; Bignum b; @@ -1776,7 +1777,7 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) { /* * Utility routine for decoding comma-separated strings in KEXINIT. */ -int in_commasep_string(char *needle, char *haystack, int haylen) { +static int in_commasep_string(char *needle, char *haystack, int haylen) { int needlen = strlen(needle); while (1) { /* @@ -1803,7 +1804,7 @@ int in_commasep_string(char *needle, char *haystack, int haylen) { /* * SSH2 key creation method. */ -void ssh2_mkkey(Bignum K, char *H, char chr, char *keyspace) { +static void ssh2_mkkey(Bignum K, char *H, char chr, char *keyspace) { SHA_State s; /* First 20 bytes. */ SHA_Init(&s); @@ -1828,6 +1829,7 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) static int i, len; static char *str; static Bignum e, f, K; + static const struct ssh_mac **maclist; static const struct ssh_cipher *cscipher_tobe = NULL; static const struct ssh_cipher *sccipher_tobe = NULL; static const struct ssh_mac *csmac_tobe = NULL; @@ -1858,6 +1860,14 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) preferred_cipher = &ssh_3des_ssh2; } + /* + * Be prepared to work around the buggy MAC problem. + */ + if (cfg.buggymac) + maclist = buggymacs; + else + maclist = macs; + begin_key_exchange: /* * Construct and send our key exchange packet. @@ -1897,16 +1907,16 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) } /* List client->server MAC algorithms. */ ssh2_pkt_addstring_start(); - for (i = 0; i < lenof(macs); i++) { - ssh2_pkt_addstring_str(macs[i]->name); - if (i < lenof(macs)-1) + for (i = 0; i < lenof(maclist); i++) { + ssh2_pkt_addstring_str(maclist[i]->name); + if (i < lenof(maclist)-1) ssh2_pkt_addstring_str(","); } /* List server->client MAC algorithms. */ ssh2_pkt_addstring_start(); - for (i = 0; i < lenof(macs); i++) { - ssh2_pkt_addstring_str(macs[i]->name); - if (i < lenof(macs)-1) + for (i = 0; i < lenof(maclist); i++) { + ssh2_pkt_addstring_str(maclist[i]->name); + if (i < lenof(maclist)-1) ssh2_pkt_addstring_str(","); } /* List client->server compression algorithms. */ @@ -1979,16 +1989,16 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) } } ssh2_pkt_getstring(&str, &len); /* client->server mac */ - for (i = 0; i < lenof(macs); i++) { - if (in_commasep_string(macs[i]->name, str, len)) { - csmac_tobe = macs[i]; + for (i = 0; i < lenof(maclist); i++) { + if (in_commasep_string(maclist[i]->name, str, len)) { + csmac_tobe = maclist[i]; break; } } ssh2_pkt_getstring(&str, &len); /* server->client mac */ - for (i = 0; i < lenof(macs); i++) { - if (in_commasep_string(macs[i]->name, str, len)) { - scmac_tobe = macs[i]; + for (i = 0; i < lenof(maclist); i++) { + if (in_commasep_string(maclist[i]->name, str, len)) { + scmac_tobe = maclist[i]; break; } } @@ -2611,6 +2621,14 @@ static void ssh_special (Telnet_Special code) { ssh2_pkt_send(); } logevent("Sent EOF message"); + } else if (code == TS_PING) { + if (ssh_version == 1) { + send_packet(SSH1_MSG_IGNORE, PKT_STR, "", PKT_END); + } else { + ssh2_pkt_init(SSH2_MSG_IGNORE); + ssh2_pkt_addstring_start(); + ssh2_pkt_send(); + } } else { /* do nothing */ }