unsigned long incoming_data_size, outgoing_data_size, deferred_data_size;
unsigned long max_data_size;
int kex_in_progress;
- long next_rekey;
+ long next_rekey, last_rekey;
};
#define logevent(s) logevent(ssh->frontend, s)
/* Data sent down one of our channels. */
int i = ssh_pkt_getuint32(pktin);
char *p;
- int len;
+ unsigned int len;
struct ssh_channel *c;
ssh_pkt_getstring(pktin, &p, &len);
/* Data for an agent message. Buffer it. */
while (len > 0) {
if (c->u.a.lensofar < 4) {
- int l = min(4 - c->u.a.lensofar, len);
+ unsigned int l = min(4 - c->u.a.lensofar, len);
memcpy(c->u.a.msglen + c->u.a.lensofar, p,
l);
p += l;
memcpy(c->u.a.message, c->u.a.msglen, 4);
}
if (c->u.a.lensofar >= 4 && len > 0) {
- int l =
+ unsigned int l =
min(c->u.a.totallen - c->u.a.lensofar,
len);
memcpy(c->u.a.message + c->u.a.lensofar, p,
* Key exchange is over. Schedule a timer for our next rekey.
*/
ssh->kex_in_progress = FALSE;
+ ssh->last_rekey = GETTICKCOUNT();
if (ssh->cfg.ssh_rekey_time != 0)
ssh->next_rekey = schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
ssh2_timer, ssh);
static void ssh2_msg_channel_data(Ssh ssh, struct Packet *pktin)
{
char *data;
- int length;
+ unsigned int length;
unsigned i = ssh_pkt_getuint32(pktin);
struct ssh_channel *c;
c = find234(ssh->channels, &i, ssh_channelfind);
case CHAN_AGENT:
while (length > 0) {
if (c->u.a.lensofar < 4) {
- int l = min(4 - c->u.a.lensofar, length);
+ unsigned int l = min(4 - c->u.a.lensofar, length);
memcpy(c->u.a.msglen + c->u.a.lensofar,
data, l);
data += l;
memcpy(c->u.a.message, c->u.a.msglen, 4);
}
if (c->u.a.lensofar >= 4 && length > 0) {
- int l =
+ unsigned int l =
min(c->u.a.totallen - c->u.a.lensofar,
length);
memcpy(c->u.a.message + c->u.a.lensofar,
{
Ssh ssh = (Ssh)ctx;
- if (!ssh->kex_in_progress &&
+ if (!ssh->kex_in_progress && ssh->cfg.ssh_rekey_time != 0 &&
now - ssh->next_rekey >= 0) {
do_ssh2_transport(ssh, "Initiating key re-exchange (timeout)",
-1, NULL);
ssh->channels = NULL;
ssh->rportfwds = NULL;
+ ssh->portfwds = NULL;
ssh->send_ok = 0;
ssh->editing = 0;
static void ssh_reconfig(void *handle, Config *cfg)
{
Ssh ssh = (Ssh) handle;
+ char *rekeying = NULL;
+ unsigned long old_max_data_size;
+
pinger_reconfig(ssh->pinger, &ssh->cfg, cfg);
ssh_setup_portfwd(ssh, cfg);
+
+ if (ssh->cfg.ssh_rekey_time != cfg->ssh_rekey_time &&
+ cfg->ssh_rekey_time != 0) {
+ long new_next = ssh->last_rekey + cfg->ssh_rekey_time*60*TICKSPERSEC;
+ long now = GETTICKCOUNT();
+
+ if (new_next - now < 0) {
+ rekeying = "Initiating key re-exchange (timeout shortened)";
+ } else {
+ ssh->next_rekey = schedule_timer(new_next - now, ssh2_timer, ssh);
+ }
+ }
+
+ old_max_data_size = ssh->max_data_size;
+ ssh->max_data_size = parse_blocksize(cfg->ssh_rekey_data);
+ if (old_max_data_size != ssh->max_data_size &&
+ ssh->max_data_size != 0) {
+ if (ssh->outgoing_data_size > ssh->max_data_size ||
+ ssh->incoming_data_size > ssh->max_data_size)
+ rekeying = "Initiating key re-exchange (data limit lowered)";
+ }
+
+ if (rekeying && !ssh->kex_in_progress) {
+ do_ssh2_transport(ssh, rekeying, -1, NULL);
+ }
+
ssh->cfg = *cfg; /* STRUCTURE COPY */
}
PKT_INT, c->localid,
PKT_STR, hostname,
PKT_INT, port,
- //PKT_STR, <org:orgport>,
+ /* PKT_STR, <org:orgport>, */
PKT_END);
} else {
pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
}
/*
+ * cfg_info for SSH is the currently running version of the
+ * protocol. (1 for 1; 2 for 2; 0 for not-decided-yet.)
+ */
+static int ssh_cfg_info(void *handle)
+{
+ Ssh ssh = (Ssh) handle;
+ return ssh->version;
+}
+
+/*
* Gross hack: pscp will try to start SFTP but fall back to scp1 if
* that fails. This variable is the means by which scp.c can reach
* into the SSH code and find out which one it got.
ssh_provide_ldisc,
ssh_provide_logctx,
ssh_unthrottle,
+ ssh_cfg_info,
22
};