upstream: trigger keystroke timing obfucation only if the channels
layer enqueud some data in the last poll() cycle; this avoids triggering the obfuscatior for non-channels data like ClientAlive probes and also fixes a related problem were the obfucations would be triggered on fully quiescent connections. Based on / tested by naddy@ OpenBSD-Commit-ID: d98f32dc62d7663ff4660e4556e184032a0db123
This commit is contained in:
parent
b5fd97896b
commit
694150ad92
24
clientloop.c
24
clientloop.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: clientloop.c,v 1.395 2023/09/04 00:04:02 djm Exp $ */
|
/* $OpenBSD: clientloop.c,v 1.396 2023/09/04 00:08:14 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -533,7 +533,8 @@ send_chaff(struct ssh *ssh)
|
||||||
* output fd should be polled.
|
* output fd should be polled.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout)
|
obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout,
|
||||||
|
int channel_did_enqueue)
|
||||||
{
|
{
|
||||||
static int active;
|
static int active;
|
||||||
static struct timespec next_interval, chaff_until;
|
static struct timespec next_interval, chaff_until;
|
||||||
|
@ -558,7 +559,8 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout)
|
||||||
ssh_packet_have_data_to_write(ssh)) {
|
ssh_packet_have_data_to_write(ssh)) {
|
||||||
/* Stop if the output buffer has more than a few keystrokes */
|
/* Stop if the output buffer has more than a few keystrokes */
|
||||||
stop_reason = "output buffer filling";
|
stop_reason = "output buffer filling";
|
||||||
} else if (active && ssh_packet_have_data_to_write(ssh)) {
|
} else if (active && channel_did_enqueue &&
|
||||||
|
ssh_packet_have_data_to_write(ssh)) {
|
||||||
/* Still in active mode and have a keystroke queued. */
|
/* Still in active mode and have a keystroke queued. */
|
||||||
had_keystroke = 1;
|
had_keystroke = 1;
|
||||||
} else if (active) {
|
} else if (active) {
|
||||||
|
@ -587,7 +589,8 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout)
|
||||||
* interactively. In this case, start quantising outbound packets to
|
* interactively. In this case, start quantising outbound packets to
|
||||||
* fixed time intervals to hide inter-keystroke timing.
|
* fixed time intervals to hide inter-keystroke timing.
|
||||||
*/
|
*/
|
||||||
if (!active && ssh_packet_interactive_data_to_write(ssh)) {
|
if (!active && ssh_packet_interactive_data_to_write(ssh) &&
|
||||||
|
channel_did_enqueue && ssh_packet_have_data_to_write(ssh)) {
|
||||||
debug3_f("starting: interval %d",
|
debug3_f("starting: interval %d",
|
||||||
options.obscure_keystroke_timing_interval);
|
options.obscure_keystroke_timing_interval);
|
||||||
just_started = had_keystroke = active = 1;
|
just_started = had_keystroke = active = 1;
|
||||||
|
@ -637,7 +640,7 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
client_wait_until_can_do_something(struct ssh *ssh, struct pollfd **pfdp,
|
client_wait_until_can_do_something(struct ssh *ssh, struct pollfd **pfdp,
|
||||||
u_int *npfd_allocp, u_int *npfd_activep, int rekeying,
|
u_int *npfd_allocp, u_int *npfd_activep, int channel_did_enqueue,
|
||||||
int *conn_in_readyp, int *conn_out_readyp)
|
int *conn_in_readyp, int *conn_out_readyp)
|
||||||
{
|
{
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
|
@ -661,7 +664,7 @@ client_wait_until_can_do_something(struct ssh *ssh, struct pollfd **pfdp,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
oready = obfuscate_keystroke_timing(ssh, &timeout);
|
oready = obfuscate_keystroke_timing(ssh, &timeout, channel_did_enqueue);
|
||||||
|
|
||||||
/* Monitor server connection on reserved pollfd entries */
|
/* Monitor server connection on reserved pollfd entries */
|
||||||
(*pfdp)[0].fd = connection_in;
|
(*pfdp)[0].fd = connection_in;
|
||||||
|
@ -680,7 +683,7 @@ client_wait_until_can_do_something(struct ssh *ssh, struct pollfd **pfdp,
|
||||||
ptimeout_deadline_monotime(&timeout, control_persist_exit_time);
|
ptimeout_deadline_monotime(&timeout, control_persist_exit_time);
|
||||||
if (options.server_alive_interval > 0)
|
if (options.server_alive_interval > 0)
|
||||||
ptimeout_deadline_monotime(&timeout, server_alive_time);
|
ptimeout_deadline_monotime(&timeout, server_alive_time);
|
||||||
if (options.rekey_interval > 0 && !rekeying) {
|
if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh)) {
|
||||||
ptimeout_deadline_sec(&timeout,
|
ptimeout_deadline_sec(&timeout,
|
||||||
ssh_packet_get_rekey_timeout(ssh));
|
ssh_packet_get_rekey_timeout(ssh));
|
||||||
}
|
}
|
||||||
|
@ -1402,7 +1405,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
|
||||||
struct pollfd *pfd = NULL;
|
struct pollfd *pfd = NULL;
|
||||||
u_int npfd_alloc = 0, npfd_active = 0;
|
u_int npfd_alloc = 0, npfd_active = 0;
|
||||||
double start_time, total_time;
|
double start_time, total_time;
|
||||||
int r, len;
|
int channel_did_enqueue = 0, r, len;
|
||||||
u_int64_t ibytes, obytes;
|
u_int64_t ibytes, obytes;
|
||||||
int conn_in_ready, conn_out_ready;
|
int conn_in_ready, conn_out_ready;
|
||||||
|
|
||||||
|
@ -1492,6 +1495,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
|
||||||
|
|
||||||
/* Main loop of the client for the interactive session mode. */
|
/* Main loop of the client for the interactive session mode. */
|
||||||
while (!quit_pending) {
|
while (!quit_pending) {
|
||||||
|
channel_did_enqueue = 0;
|
||||||
|
|
||||||
/* Process buffered packets sent by the server. */
|
/* Process buffered packets sent by the server. */
|
||||||
client_process_buffered_input_packets(ssh);
|
client_process_buffered_input_packets(ssh);
|
||||||
|
@ -1513,7 +1517,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
|
||||||
* enqueue them for sending to the server.
|
* enqueue them for sending to the server.
|
||||||
*/
|
*/
|
||||||
if (ssh_packet_not_very_much_data_to_write(ssh))
|
if (ssh_packet_not_very_much_data_to_write(ssh))
|
||||||
channel_output_poll(ssh);
|
channel_did_enqueue = channel_output_poll(ssh);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the window size has changed, and buffer a
|
* Check if the window size has changed, and buffer a
|
||||||
|
@ -1529,7 +1533,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
|
||||||
* available on one of the descriptors).
|
* available on one of the descriptors).
|
||||||
*/
|
*/
|
||||||
client_wait_until_can_do_something(ssh, &pfd, &npfd_alloc,
|
client_wait_until_can_do_something(ssh, &pfd, &npfd_alloc,
|
||||||
&npfd_active, ssh_packet_is_rekeying(ssh),
|
&npfd_active, channel_did_enqueue,
|
||||||
&conn_in_ready, &conn_out_ready);
|
&conn_in_ready, &conn_out_ready);
|
||||||
|
|
||||||
if (quit_pending)
|
if (quit_pending)
|
||||||
|
|
Loading…
Reference in New Issue