1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 09:27:59 +00:00

Factor out ssh2_timer_update.

This is a preliminary refactoring for an upcoming change which will
need to affect every use of schedule_timer to wait for the next rekey:
those calls to schedule_timer are now centralised into a function that
does an organised piece of thinking about when the next timer should
be.

A side effect of this change is that the translation from
CONF_ssh_rekey_time to an actual tick count is now better proofed
against integer overflow (just in case the user entered a completely
silly value).
This commit is contained in:
Simon Tatham 2018-04-14 14:48:02 +01:00
parent a0b91e99b8
commit d50150c40f
2 changed files with 55 additions and 19 deletions

View File

@ -27,6 +27,13 @@ typedef struct terminal_tag Terminal;
#include "network.h"
#include "misc.h"
/*
* We express various time intervals in unsigned long minutes, but may need to
* clip some values so that the resulting number of ticks does not overflow an
* integer value.
*/
#define MAX_TICK_MINS (INT_MAX / (60 * TICKSPERSEC))
/*
* Fingerprints of the PGP master keys that can be used to establish a trust
* path between an executable and other files.

67
ssh.c
View File

@ -189,6 +189,14 @@ static unsigned int ssh_tty_parse_boolean(char *s)
return (atoi(s) != 0);
}
/* Safely convert rekey_time to unsigned long minutes */
static unsigned long rekey_mins(int rekey_time, unsigned long def)
{
if (rekey_time < 0 || rekey_time > MAX_TICK_MINS)
rekey_time = def;
return (unsigned long)rekey_time;
}
#define translate(x) if (type == x) return #x
#define translatek(x,ctx) if (type == x && (pkt_kctx == ctx)) return #x
#define translatea(x,ctx) if (type == x && (pkt_actx == ctx)) return #x
@ -722,6 +730,7 @@ static unsigned long ssh_pkt_getuint32(struct Packet *pkt);
static int ssh2_pkt_getbool(struct Packet *pkt);
static void ssh_pkt_getstring(struct Packet *pkt, char **p, int *length);
static void ssh2_timer(void *ctx, unsigned long now);
static int ssh2_timer_update(Ssh ssh, unsigned long rekey_time);
static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen,
struct Packet *pktin);
static void ssh2_msg_unexpected(Ssh ssh, struct Packet *pktin);
@ -7646,9 +7655,7 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen,
*/
ssh->kex_in_progress = FALSE;
ssh->last_rekey = GETTICKCOUNT();
if (conf_get_int(ssh->conf, CONF_ssh_rekey_time) != 0)
ssh->next_rekey = schedule_timer(conf_get_int(ssh->conf, CONF_ssh_rekey_time)*60*TICKSPERSEC,
ssh2_timer, ssh);
(void) ssh2_timer_update(ssh, 0);
/*
* Now we're encrypting. Begin returning 1 to the protocol main
@ -7722,11 +7729,7 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen,
* hit the event log _too_ often. */
ssh->outgoing_data_size = 0;
ssh->incoming_data_size = 0;
if (conf_get_int(ssh->conf, CONF_ssh_rekey_time) != 0) {
ssh->next_rekey =
schedule_timer(conf_get_int(ssh->conf, CONF_ssh_rekey_time)*60*TICKSPERSEC,
ssh2_timer, ssh);
}
(void) ssh2_timer_update(ssh, 0);
goto wait_for_rekey; /* this is still utterly horrid */
} else {
logeventf(ssh, "Initiating key re-exchange (%s)", (char *)in);
@ -11132,6 +11135,41 @@ static void ssh2_bare_connection_protocol_setup(Ssh ssh)
ssh->packet_dispatch[SSH2_MSG_DEBUG] = ssh2_msg_debug;
}
/*
* The rekey_time is zero except when re-configuring.
*
* We either schedule the next timer and return 0, or return 1 to run the
* callback now, which will call us again to re-schedule on completion.
*/
static int ssh2_timer_update(Ssh ssh, unsigned long rekey_time)
{
unsigned long mins;
unsigned long ticks;
mins = conf_get_int(ssh->conf, CONF_ssh_rekey_time);
mins = rekey_mins(mins, 60);
ticks = mins * 60 * TICKSPERSEC;
/* Handle change from previous setting */
if (rekey_time != 0 && rekey_time != mins) {
unsigned long next;
unsigned long now = GETTICKCOUNT();
mins = rekey_time;
ticks = mins * 60 * TICKSPERSEC;
next = ssh->last_rekey + ticks;
/* If overdue, caller will rekey synchronously now */
if (now - ssh->last_rekey > ticks)
return 1;
ticks = next - now;
}
/* Schedule the next timer */
ssh->next_rekey = schedule_timer(ticks, ssh2_timer, ssh);
return 0;
}
static void ssh2_timer(void *ctx, unsigned long now)
{
Ssh ssh = (Ssh)ctx;
@ -11466,17 +11504,8 @@ static void ssh_reconfig(void *handle, Conf *conf)
ssh_setup_portfwd(ssh, conf);
rekey_time = conf_get_int(conf, CONF_ssh_rekey_time);
if (conf_get_int(ssh->conf, CONF_ssh_rekey_time) != rekey_time &&
rekey_time != 0) {
unsigned long new_next = ssh->last_rekey + rekey_time*60*TICKSPERSEC;
unsigned long now = GETTICKCOUNT();
if (now - ssh->last_rekey > rekey_time*60*TICKSPERSEC) {
rekeying = "timeout shortened";
} else {
ssh->next_rekey = schedule_timer(new_next - now, ssh2_timer, ssh);
}
}
if (ssh2_timer_update(ssh, rekey_mins(rekey_time, 60)))
rekeying = "timeout shortened";
old_max_data_size = ssh->max_data_size;
ssh->max_data_size = parse_blocksize(conf_get_str(ssh->conf,