X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=ssh.c;h=a6fba8b87af423f91a6985c9213f9e0f2a299e0a;hb=56d5dc7eecf52bb1fcb164be161f419dd15c3284;hp=07d06f1f1a07b351eed3dfbf1e86393459315c93;hpb=8c69ba067266beedd7740132f8ae558cc6ebc641;p=PuTTY.git diff --git a/ssh.c b/ssh.c index 07d06f1f..a6fba8b8 100644 --- a/ssh.c +++ b/ssh.c @@ -104,7 +104,7 @@ * Packet type contexts, so that ssh2_pkt_type can correctly decode * the ambiguous type numbers back into the correct type strings. */ -#define SSH2_PKTCTX_DHGROUP1 0x0001 +#define SSH2_PKTCTX_DHGROUP 0x0001 #define SSH2_PKTCTX_DHGEX 0x0002 #define SSH2_PKTCTX_PUBLICKEY 0x0010 #define SSH2_PKTCTX_PASSWORD 0x0020 @@ -222,8 +222,8 @@ static char *ssh2_pkt_type(int pkt_ctx, int type) translate(SSH2_MSG_SERVICE_ACCEPT); translate(SSH2_MSG_KEXINIT); translate(SSH2_MSG_NEWKEYS); - translatec(SSH2_MSG_KEXDH_INIT, SSH2_PKTCTX_DHGROUP1); - translatec(SSH2_MSG_KEXDH_REPLY, SSH2_PKTCTX_DHGROUP1); + translatec(SSH2_MSG_KEXDH_INIT, SSH2_PKTCTX_DHGROUP); + translatec(SSH2_MSG_KEXDH_REPLY, SSH2_PKTCTX_DHGROUP); translatec(SSH2_MSG_KEX_DH_GEX_REQUEST, SSH2_PKTCTX_DHGEX); translatec(SSH2_MSG_KEX_DH_GEX_GROUP, SSH2_PKTCTX_DHGEX); translatec(SSH2_MSG_KEX_DH_GEX_INIT, SSH2_PKTCTX_DHGEX); @@ -362,7 +362,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, const static struct ssh_kex *kex_algs[] = { &ssh_diffiehellman_gex, - &ssh_diffiehellman + &ssh_diffiehellman_group14, + &ssh_diffiehellman_group1, }; const static struct ssh_signkey *hostkey_algs[] = { &ssh_rsa, &ssh_dss }; @@ -2067,6 +2068,29 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring) } } +/* + * The `software version' part of an SSH version string is required + * to contain no spaces or minus signs. + */ +static void ssh_fix_verstring(char *str) +{ + /* Eat "SSH--". */ + assert(*str == 'S'); str++; + assert(*str == 'S'); str++; + assert(*str == 'H'); str++; + assert(*str == '-'); str++; + while (*str && *str != '-') str++; + assert(*str == '-'); str++; + + /* Convert minus signs and spaces in the remaining string into + * underscores. */ + while (*str) { + if (*str == '-' || *str == ' ') + *str = '_'; + str++; + } +} + static int do_ssh_init(Ssh ssh, unsigned char c) { struct do_ssh_init_state { @@ -2126,7 +2150,7 @@ static int do_ssh_init(Ssh ssh, unsigned char c) ssh->rdpkt2_state.incoming_sequence = 0; s->vstring[s->vslen] = 0; - s->vstring[strcspn(s->vstring, "\r\n")] = '\0';/* remove EOL chars */ + s->vstring[strcspn(s->vstring, "\015\012")] = '\0';/* remove EOL chars */ { char *vlog; vlog = snewn(20 + s->vslen, char); @@ -2154,46 +2178,60 @@ static int do_ssh_init(Ssh ssh, unsigned char c) crStop(0); } - if (s->proto2 && (ssh->cfg.sshprot >= 2 || !s->proto1)) { - /* - * Use v2 protocol. - */ - char verstring[80], vlog[100]; - sprintf(verstring, "SSH-2.0-%s", sshver); - SHA_Init(&ssh->exhashbase); - /* - * Hash our version string and their version string. - */ - sha_string(&ssh->exhashbase, verstring, strlen(verstring)); - sha_string(&ssh->exhashbase, s->vstring, strcspn(s->vstring, "\r\n")); - sprintf(vlog, "We claim version: %s", verstring); - logevent(vlog); - strcat(verstring, "\012"); - logevent("Using SSH protocol version 2"); - sk_write(ssh->s, verstring, strlen(verstring)); - ssh->protocol = ssh2_protocol; - ssh2_protocol_setup(ssh); - ssh->version = 2; - ssh->s_rdpkt = ssh2_rdpkt; - } else { - /* - * Use v1 protocol. - */ - char verstring[80], vlog[100]; - sprintf(verstring, "SSH-%s-%s", - (ssh_versioncmp(s->version, "1.5") <= 0 ? s->version : "1.5"), - sshver); - sprintf(vlog, "We claim version: %s", verstring); - logevent(vlog); - strcat(verstring, "\012"); - - logevent("Using SSH protocol version 1"); + { + char *verstring; + + if (s->proto2 && (ssh->cfg.sshprot >= 2 || !s->proto1)) { + /* + * Construct a v2 version string. + */ + verstring = dupprintf("SSH-2.0-%s\015\012", sshver); + ssh->version = 2; + } else { + /* + * Construct a v1 version string. + */ + verstring = dupprintf("SSH-%s-%s\012", + (ssh_versioncmp(s->version, "1.5") <= 0 ? + s->version : "1.5"), + sshver); + ssh->version = 1; + } + + ssh_fix_verstring(verstring); + + if (ssh->version == 2) { + /* + * Hash our version string and their version string. + */ + SHA_Init(&ssh->exhashbase); + sha_string(&ssh->exhashbase, verstring, + strcspn(verstring, "\015\012")); + sha_string(&ssh->exhashbase, s->vstring, + strcspn(s->vstring, "\015\012")); + + /* + * Initialise SSHv2 protocol. + */ + ssh->protocol = ssh2_protocol; + ssh2_protocol_setup(ssh); + ssh->s_rdpkt = ssh2_rdpkt; + } else { + /* + * Initialise SSHv1 protocol. + */ + ssh->protocol = ssh1_protocol; + ssh1_protocol_setup(ssh); + ssh->s_rdpkt = ssh1_rdpkt; + } + logeventf(ssh, "We claim version: %.*s", + strcspn(verstring, "\015\012"), verstring); sk_write(ssh->s, verstring, strlen(verstring)); - ssh->protocol = ssh1_protocol; - ssh1_protocol_setup(ssh); - ssh->version = 1; - ssh->s_rdpkt = ssh1_rdpkt; + sfree(verstring); } + + logeventf(ssh, "Using SSH protocol version %d", ssh->version); + update_specials_menu(ssh->frontend); ssh->state = SSH_STATE_BEFORE_SIZE; ssh->pinger = pinger_new(&ssh->cfg, &ssh_backend, ssh); @@ -4613,7 +4651,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, * If we're doing Diffie-Hellman group exchange, start by * requesting a group. */ - if (ssh->kex == &ssh_diffiehellman_gex) { + if (!ssh->kex->pdata) { logevent("Doing Diffie-Hellman group exchange"); ssh->pkt_ctx |= SSH2_PKTCTX_DHGEX; /* @@ -4636,14 +4674,16 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, bombout(("unable to read mp-ints from incoming group packet")); crStop(0); } - ssh->kex_ctx = dh_setup_group(s->p, s->g); + ssh->kex_ctx = dh_setup_gex(s->p, s->g); s->kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT; s->kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY; } else { - ssh->pkt_ctx |= SSH2_PKTCTX_DHGROUP1; - ssh->kex_ctx = dh_setup_group1(); + ssh->pkt_ctx |= SSH2_PKTCTX_DHGROUP; + ssh->kex_ctx = dh_setup_group(ssh->kex); s->kex_init_value = SSH2_MSG_KEXDH_INIT; s->kex_reply_value = SSH2_MSG_KEXDH_REPLY; + logeventf(ssh, "Using Diffie-Hellman with standard group \"%s\"", + ssh->kex->groupname); } logevent("Doing Diffie-Hellman key exchange"); @@ -4732,7 +4772,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, /* * We've sent client NEWKEYS, so create and initialise - * client-to-servere session keys. + * client-to-server session keys. */ if (ssh->cs_cipher_ctx) ssh->cscipher->free_context(ssh->cs_cipher_ctx); @@ -7198,12 +7238,14 @@ static void ssh_free(void *handle) sfree(c); } freetree234(ssh->channels); + ssh->channels = NULL; } if (ssh->rportfwds) { while ((pf = delpos234(ssh->rportfwds, 0)) != NULL) sfree(pf); freetree234(ssh->rportfwds); + ssh->rportfwds = NULL; } sfree(ssh->deferred_send_data); if (ssh->x11auth) @@ -7219,9 +7261,9 @@ static void ssh_free(void *handle) if (ssh->s) ssh_do_close(ssh); expire_timer_context(ssh); - sfree(ssh); if (ssh->pinger) pinger_free(ssh->pinger); + sfree(ssh); random_unref(); }