X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/36b8d9bb9274b5ca088063a83d255121691a579f..954a954017ef83065bfb605b0bd99d8856071892:/ssh.c diff --git a/ssh.c b/ssh.c index f06b2df2..6c1aeb75 100644 --- a/ssh.c +++ b/ssh.c @@ -1780,7 +1780,8 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring) (ssh->cfg.sshbug_ignore1 == AUTO && (!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") || !strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") || - !strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25")))) { + !strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25") || + !strcmp(imp, "OSU_1.4alpha3")))) { /* * These versions don't support SSH1_MSG_IGNORE, so we have * to use a different defence against password length @@ -1792,7 +1793,7 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring) if (ssh->cfg.sshbug_plainpw1 == FORCE_ON || (ssh->cfg.sshbug_plainpw1 == AUTO && - (!strcmp(imp, "Cisco-1.25")))) { + (!strcmp(imp, "Cisco-1.25") || !strcmp(imp, "OSU_1.4alpha3")))) { /* * These versions need a plain password sent; they can't * handle having a null and a random length of data after @@ -2168,7 +2169,6 @@ static const char *connect_to_host(Ssh ssh, char *host, int port, ssh->fn = &fn_table; ssh->s = new_connection(addr, *realhost, port, 0, 1, nodelay, (Plug) ssh, &ssh->cfg); - sk_addr_free(addr); if ((err = sk_socket_error(ssh->s)) != NULL) { ssh->s = NULL; return err; @@ -2535,6 +2535,22 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) ssh->crcda_ctx = crcda_make_context(); logevent("Installing CRC compensation attack detector"); + if (servkey.modulus) { + sfree(servkey.modulus); + servkey.modulus = NULL; + } + if (servkey.exponent) { + sfree(servkey.exponent); + servkey.exponent = NULL; + } + if (hostkey.modulus) { + sfree(hostkey.modulus); + hostkey.modulus = NULL; + } + if (hostkey.exponent) { + sfree(hostkey.exponent); + hostkey.exponent = NULL; + } crWaitUntil(ispkt); if (ssh->pktin.type != SSH1_SMSG_SUCCESS) { @@ -2602,7 +2618,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) /* Load the public half of ssh->cfg.keyfile so we notice if it's in Pageant */ if (!filename_is_null(ssh->cfg.keyfile)) { if (!rsakey_pubblob(&ssh->cfg.keyfile, - &s->publickey_blob, &s->publickey_bloblen)) + &s->publickey_blob, &s->publickey_bloblen, NULL)) s->publickey_blob = NULL; } else s->publickey_blob = NULL; @@ -2751,6 +2767,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (s->authed) break; } + sfree(s->response); } if (s->authed) break; @@ -2888,11 +2905,15 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) s->tried_publickey = 1; { - int ret = loadrsakey(&ssh->cfg.keyfile, &s->key, s->password); + const char *error = NULL; + int ret = loadrsakey(&ssh->cfg.keyfile, &s->key, s->password, + &error); if (ret == 0) { c_write_str(ssh, "Couldn't load private key from "); c_write_str(ssh, filename_to_str(&ssh->cfg.keyfile)); - c_write_str(ssh, ".\r\n"); + c_write_str(ssh, " ("); + c_write_str(ssh, error); + c_write_str(ssh, ").\r\n"); continue; /* go and try password */ } if (ret == -1) { @@ -3033,6 +3054,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) } logevent("Sending password with camouflage packets"); ssh_pkt_defersend(ssh); + sfree(randomstr); } else if (!(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) { /* @@ -3298,6 +3320,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt) } else { while (*ssh->portfwd_strptr) ssh->portfwd_strptr++; dport = dserv = -1; + ssh->portfwd_strptr++; /* eat the NUL and move to next one */ } sport = atoi(sports); sserv = 0; @@ -4333,6 +4356,12 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (ssh->sccomp->text_name) logeventf(ssh, "Initialised %s decompression", ssh->sccomp->text_name); + freebn(s->f); + freebn(s->K); + if (ssh->kex == &ssh_diffiehellman_gex) { + freebn(s->g); + freebn(s->p); + } /* * If this is the first key exchange phase, we must pass the @@ -4586,7 +4615,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (keytype == SSH_KEYTYPE_SSH2) { s->publickey_blob = ssh2_userkey_loadpub(&ssh->cfg.keyfile, NULL, - &s->publickey_bloblen); + &s->publickey_bloblen, NULL); } else { char *msgbuf; logeventf(ssh, "Unable to use this key file (%s)", @@ -4715,6 +4744,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) s->method = 0; ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK; + s->need_pw = FALSE; /* * Most password/passphrase prompts will be @@ -4894,6 +4924,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (s->authed) continue; } + sfree(s->response); } if (!s->method && s->can_pubkey && s->publickey_blob @@ -4916,7 +4947,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) pub_blob = (unsigned char *)ssh2_userkey_loadpub(&ssh->cfg.keyfile, &algorithm, - &pub_blob_len); + &pub_blob_len, + NULL); if (pub_blob) { ssh2_pkt_init(ssh, SSH2_MSG_USERAUTH_REQUEST); ssh2_pkt_addstring(ssh, s->username); @@ -5093,14 +5125,18 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) * We have our passphrase. Now try the actual authentication. */ struct ssh2_userkey *key; + const char *error = NULL; - key = ssh2_load_userkey(&ssh->cfg.keyfile, s->password); + key = ssh2_load_userkey(&ssh->cfg.keyfile, s->password, + &error); if (key == SSH2_WRONG_PASSPHRASE || key == NULL) { if (key == SSH2_WRONG_PASSPHRASE) { c_write_str(ssh, "Wrong passphrase\r\n"); s->tried_pubkey_config = FALSE; } else { - c_write_str(ssh, "Unable to load private key\r\n"); + c_write_str(ssh, "Unable to load private key ("); + c_write_str(ssh, error); + c_write_str(ssh, ")\r\n"); s->tried_pubkey_config = TRUE; } /* Send a spurious AUTH_NONE to return to the top. */ @@ -5409,6 +5445,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) } else { while (*ssh->portfwd_strptr) ssh->portfwd_strptr++; dport = dserv = -1; + ssh->portfwd_strptr++; /* eat the NUL and move to next one */ } sport = atoi(sports); sserv = 0; @@ -6230,10 +6267,18 @@ static void ssh_free(void *handle) ssh->csmac->free_context(ssh->cs_mac_ctx); if (ssh->sc_mac_ctx) ssh->scmac->free_context(ssh->sc_mac_ctx); - if (ssh->cs_comp_ctx) - ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx); - if (ssh->sc_comp_ctx) - ssh->sccomp->compress_cleanup(ssh->sc_comp_ctx); + if (ssh->cs_comp_ctx) { + if (ssh->cscomp) + ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx); + else + zlib_compress_cleanup(ssh->cs_comp_ctx); + } + if (ssh->sc_comp_ctx) { + if (ssh->sccomp) + ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx); + else + zlib_decompress_cleanup(ssh->sc_comp_ctx); + } if (ssh->kex_ctx) dh_cleanup(ssh->kex_ctx); sfree(ssh->savedhost); @@ -6267,7 +6312,22 @@ static void ssh_free(void *handle) sfree(ssh->do_ssh1_login_state); sfree(ssh->do_ssh2_transport_state); sfree(ssh->do_ssh2_authconn_state); - + if (ssh->pktout.data) { + sfree(ssh->pktout.data); + ssh->pktout.data = NULL; + } + if (ssh->pktin.data) { + sfree(ssh->pktin.data); + ssh->pktin.data = NULL; + } + if (ssh->crcda_ctx) { + crcda_free_context(ssh->crcda_ctx); + ssh->crcda_ctx = NULL; + } + if (ssh->logctx) { + log_free(ssh->logctx); + ssh->logctx = NULL; + } if (ssh->s) ssh_do_close(ssh); sfree(ssh);