CHAN_X11,
CHAN_AGENT,
CHAN_SOCKDATA,
- CHAN_SOCKDATA_DORMANT /* one the remote hasn't confirmed */
+ CHAN_SOCKDATA_DORMANT, /* one the remote hasn't confirmed */
+ /*
+ * CHAN_ZOMBIE is used to indicate a channel for which we've
+ * already destroyed the local data source: for instance, if a
+ * forwarded port experiences a socket error on the local side, we
+ * immediately destroy its local socket and turn the SSH channel
+ * into CHAN_ZOMBIE.
+ */
+ CHAN_ZOMBIE
};
/*
ret = loadrsakey(s->keyfile, &s->key, passphrase,
&error);
if (passphrase) {
- memset(passphrase, 0, strlen(passphrase));
+ smemclr(passphrase, strlen(passphrase));
sfree(passphrase);
}
if (ret == 1) {
ssh_channel_try_eof(c);
}
+void sshfwd_unclean_close(struct ssh_channel *c)
+{
+ Ssh ssh = c->ssh;
+ struct Packet *pktout;
+
+ if (ssh->state == SSH_STATE_CLOSED)
+ return;
+
+ if (!(c->closes & CLOSES_SENT_CLOSE)) {
+ pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
+ ssh2_pkt_adduint32(pktout, c->remoteid);
+ ssh2_pkt_send(ssh, pktout);
+ c->closes |= CLOSES_SENT_EOF | CLOSES_SENT_CLOSE;
+ }
+
+ switch (c->type) {
+ case CHAN_X11:
+ x11_close(c->u.x11.s);
+ break;
+ case CHAN_SOCKDATA:
+ case CHAN_SOCKDATA_DORMANT:
+ pfd_close(c->u.pfd.s);
+ break;
+ }
+ c->type = CHAN_ZOMBIE;
+
+ ssh2_channel_check_close(c);
+}
+
int sshfwd_write(struct ssh_channel *c, char *buf, int len)
{
Ssh ssh = c->ssh;
break;
}
}
+ if (!ssh->hostkey) {
+ bombout(("Couldn't agree a host key algorithm (available: %s)",
+ str ? str : "(null)"));
+ crStop(0);
+ }
+
s->guessok = s->guessok &&
first_in_commasep_string(hostkey_algs[0]->name, str, len);
ssh_pkt_getstring(pktin, &str, &len); /* client->server cipher */
assert(ssh->csmac->len <=
ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace);
- memset(keyspace, 0, sizeof(keyspace));
+ smemclr(keyspace, sizeof(keyspace));
}
logeventf(ssh, "Initialised %.200s client->server encryption",
assert(ssh->scmac->len <=
ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace);
- memset(keyspace, 0, sizeof(keyspace));
+ smemclr(keyspace, sizeof(keyspace));
}
logeventf(ssh, "Initialised %.200s server->client encryption",
ssh->sccipher->text_name);
*/
if ((ssh->remote_bugs & BUG_SSH2_MAXPKT) && newwin > OUR_V2_MAXPKT)
newwin = OUR_V2_MAXPKT;
-
/*
* Only send a WINDOW_ADJUST if there's significantly more window
/*
* Send outgoing EOF.
*/
- sshfwd_write_eof(ssh->mainchan);
+ sshfwd_write_eof(c);
}
/*
key = ssh2_load_userkey(s->keyfile, passphrase, &error);
if (passphrase) {
/* burn the evidence */
- memset(passphrase, 0, strlen(passphrase));
+ smemclr(passphrase, strlen(passphrase));
sfree(passphrase);
}
if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
*/
/* burn the evidence */
free_prompts(s->cur_prompt);
- memset(s->password, 0, strlen(s->password));
+ smemclr(s->password, strlen(s->password));
sfree(s->password);
ssh_disconnect(ssh, NULL, "Unable to authenticate",
SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
* re-enter it if they louse up the new password.)
*/
if (s->cur_prompt->prompts[0]->result[0]) {
- memset(s->password, 0, strlen(s->password));
+ smemclr(s->password, strlen(s->password));
/* burn the evidence */
sfree(s->password);
s->password =
* We don't need the old password any more, in any
* case. Burn the evidence.
*/
- memset(s->password, 0, strlen(s->password));
+ smemclr(s->password, strlen(s->password));
sfree(s->password);
} else {
}
}
}
+
+ /*
+ * Now process any SSH connection data that was stashed in our
+ * queue while we were frozen.
+ */
+ ssh_process_queued_incoming_data(ssh);
}
void ssh_send_port_open(void *channel, char *hostname, int port, char *org)