if (ssh->v1_compressing) {
unsigned char *decompblk;
int decomplen;
- zlib_decompress_block(ssh->sc_comp_ctx,
- ssh->pktin.body - 1, ssh->pktin.length + 1,
- &decompblk, &decomplen);
+ if (!zlib_decompress_block(ssh->sc_comp_ctx,
+ ssh->pktin.body - 1, ssh->pktin.length + 1,
+ &decompblk, &decomplen)) {
+ bombout(("Zlib decompression encountered invalid data"));
+ crStop(0);
+ }
if (ssh->pktin.maxlen < st->pad + decomplen) {
ssh->pktin.maxlen = st->pad + decomplen;
(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
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
if (ssh->cfg.sshbug_hmac2 == FORCE_ON ||
(ssh->cfg.sshbug_hmac2 == AUTO &&
+ !wc_match("* VShell", imp) &&
(wc_match("2.1.0*", imp) || wc_match("2.0.*", imp) ||
wc_match("2.2.0*", imp) || wc_match("2.3.0*", imp) ||
wc_match("2.1 *", imp)))) {
if (ssh->cfg.sshbug_derivekey2 == FORCE_ON ||
(ssh->cfg.sshbug_derivekey2 == AUTO &&
+ !wc_match("* VShell", imp) &&
(wc_match("2.0.0*", imp) || wc_match("2.0.10*", imp) ))) {
/*
* These versions have the key-derivation bug (failing to
*/
logeventf(ssh, "Looking up host \"%s\"", host);
addr = name_lookup(host, port, realhost, &ssh->cfg);
- if ((err = sk_addr_error(addr)) != NULL)
+ if ((err = sk_addr_error(addr)) != NULL) {
+ sk_addr_free(addr);
return err;
+ }
/*
* Open socket.
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) {
/* 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;
if (s->authed)
break;
}
+ sfree(s->response);
}
if (s->authed)
break;
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) {
}
logevent("Sending password with camouflage packets");
ssh_pkt_defersend(ssh);
+ sfree(randomstr);
}
else if (!(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
/*
} 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;
}
if (!ssh->cfg.nopty) {
+ /* Unpick the terminal-speed string. */
+ /* XXX perhaps we should allow no speeds to be sent. */
+ int ospeed = 38400, ispeed = 38400; /* last-resort defaults */
+ sscanf(ssh->cfg.termspeed, "%d,%d", &ospeed, &ispeed);
+ /* Send the pty request. */
send_packet(ssh, SSH1_CMSG_REQUEST_PTY,
PKT_STR, ssh->cfg.termtype,
PKT_INT, ssh->term_height,
PKT_INT, ssh->term_width,
- PKT_INT, 0, PKT_INT, 0, PKT_CHAR, 0, PKT_END);
+ PKT_INT, 0, PKT_INT, 0, /* width,height in pixels */
+ PKT_CHAR, 192, PKT_INT, ispeed, /* TTY_OP_ISPEED */
+ PKT_CHAR, 193, PKT_INT, ospeed, /* TTY_OP_OSPEED */
+ PKT_CHAR, 0, PKT_END);
ssh->state = SSH_STATE_INTERMED;
do {
crReturnV;
c_write_str(ssh, "Server refused to allocate pty\r\n");
ssh->editing = ssh->echoing = 1;
}
- logevent("Allocated pty");
+ logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
+ ospeed, ispeed);
} else {
ssh->editing = ssh->echoing = 1;
}
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
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)",
s->method = 0;
ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
+ s->need_pw = FALSE;
/*
* Most password/passphrase prompts will be
if (s->authed)
continue;
}
+ sfree(s->response);
}
if (!s->method && s->can_pubkey && s->publickey_blob
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);
* 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. */
ssh2_pkt_send(ssh);
s->type = AUTH_TYPE_PUBLICKEY;
+ key->alg->freekey(key->data);
}
} else if (s->method == AUTH_PASSWORD) {
/*
} 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;
* Now allocate a pty for the session.
*/
if (!ssh->cfg.nopty) {
+ /* Unpick the terminal-speed string. */
+ /* XXX perhaps we should allow no speeds to be sent. */
+ int ospeed = 38400, ispeed = 38400; /* last-resort defaults */
+ sscanf(ssh->cfg.termspeed, "%d,%d", &ospeed, &ispeed);
+ /* Build the pty request. */
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid); /* recipient channel */
ssh2_pkt_addstring(ssh, "pty-req");
ssh2_pkt_adduint32(ssh, 0); /* pixel width */
ssh2_pkt_adduint32(ssh, 0); /* pixel height */
ssh2_pkt_addstring_start(ssh);
- ssh2_pkt_addstring_data(ssh, "\0", 1); /* TTY_OP_END, no special options */
+ ssh2_pkt_addbyte(ssh, 128); /* TTY_OP_ISPEED */
+ ssh2_pkt_adduint32(ssh, ispeed);
+ ssh2_pkt_addbyte(ssh, 129); /* TTY_OP_OSPEED */
+ ssh2_pkt_adduint32(ssh, ospeed);
+ ssh2_pkt_addstring_data(ssh, "\0", 1); /* TTY_OP_END */
ssh2_pkt_send(ssh);
ssh->state = SSH_STATE_INTERMED;
c_write_str(ssh, "Server refused to allocate pty\r\n");
ssh->editing = ssh->echoing = 1;
} else {
- logevent("Allocated pty");
+ logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
+ ospeed, ispeed);
}
} else {
ssh->editing = ssh->echoing = 1;
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);
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);