From 5bc6db4b9651424600834503e0986e8943f6b9f9 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 17 Feb 2019 19:06:03 +0000 Subject: [PATCH] Call ssh_check_frozen when BPP consumes input. In commit 0f405ae8a, I arranged to stop reading from the SSH connection if the in_raw bufchain got too big. But in at least some tools (this bit me just now with PSCP), nothing actually calls ssh_check_frozen again when the bufchain clears, so it stays frozen. Now ssh_check_frozen is non-static, and all the BPP implementations call it whenever they consume data from ssh->in_raw. --- ssh.c | 2 +- ssh.h | 1 + ssh1bpp.c | 1 + ssh2bpp-bare.c | 1 + ssh2bpp.c | 1 + sshserver.c | 1 + sshverstring.c | 4 ++++ 7 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ssh.c b/ssh.c index 24e870b6..73aa3557 100644 --- a/ssh.c +++ b/ssh.c @@ -317,7 +317,7 @@ static void ssh_got_ssh_version(struct ssh_version_receiver *rcv, ssh_bpp_free(old_bpp); } -static void ssh_check_frozen(Ssh *ssh) +void ssh_check_frozen(Ssh *ssh) { if (!ssh->s) return; diff --git a/ssh.h b/ssh.h index 82539d5d..2fcef6fa 100644 --- a/ssh.h +++ b/ssh.h @@ -380,6 +380,7 @@ void ssh_got_fallback_cmd(Ssh *ssh); /* Communications back to ssh.c from the BPP */ void ssh_conn_processed_data(Ssh *ssh); +void ssh_check_frozen(Ssh *ssh); /* Functions to abort the connection, for various reasons. */ void ssh_remote_error(Ssh *ssh, const char *fmt, ...); diff --git a/ssh1bpp.c b/ssh1bpp.c index 733c77f9..77cec35f 100644 --- a/ssh1bpp.c +++ b/ssh1bpp.c @@ -124,6 +124,7 @@ void ssh1_bpp_start_compression(BinaryPacketProtocol *bpp) s->bpp.input_eof); \ if (!success) \ goto eof; \ + ssh_check_frozen(s->bpp.ssh); \ } while (0) static void ssh1_bpp_handle_input(BinaryPacketProtocol *bpp) diff --git a/ssh2bpp-bare.c b/ssh2bpp-bare.c index 292803f8..44bb3332 100644 --- a/ssh2bpp-bare.c +++ b/ssh2bpp-bare.c @@ -59,6 +59,7 @@ static void ssh2_bare_bpp_free(BinaryPacketProtocol *bpp) s->bpp.input_eof); \ if (!success) \ goto eof; \ + ssh_check_frozen(s->bpp.ssh); \ } while (0) static void ssh2_bare_bpp_handle_input(BinaryPacketProtocol *bpp) diff --git a/ssh2bpp.c b/ssh2bpp.c index 68368f24..befcfdf7 100644 --- a/ssh2bpp.c +++ b/ssh2bpp.c @@ -269,6 +269,7 @@ static void ssh2_bpp_enable_pending_compression(struct ssh2_bpp_state *s) s->bpp.input_eof); \ if (!success) \ goto eof; \ + ssh_check_frozen(s->bpp.ssh); \ } while (0) #define userauth_range(pkttype) ((unsigned)((pkttype) - 50) < 20) diff --git a/sshserver.c b/sshserver.c index c07779ff..d1b877b5 100644 --- a/sshserver.c +++ b/sshserver.c @@ -76,6 +76,7 @@ void share_setup_x11_channel(ssh_sharing_connstate *cs, share_channel *chan, Channel *agentf_new(SshChannel *c) { return NULL; } bool agent_exists(void) { return false; } void ssh_got_exitcode(Ssh *ssh, int exitcode) {} +void ssh_check_frozen(Ssh *ssh) {} mainchan *mainchan_new( PacketProtocolLayer *ppl, ConnectionLayer *cl, Conf *conf, diff --git a/sshverstring.c b/sshverstring.c index 55e0fdc1..23085cd3 100644 --- a/sshverstring.c +++ b/sshverstring.c @@ -242,6 +242,7 @@ void ssh_verstring_handle_input(BinaryPacketProtocol *bpp) bufchain_fetch(s->bpp.in_raw, s->prefix, s->prefix_wanted.len); if (!memcmp(s->prefix, s->prefix_wanted.ptr, s->prefix_wanted.len)) { bufchain_consume(s->bpp.in_raw, s->prefix_wanted.len); + ssh_check_frozen(s->bpp.ssh); break; } @@ -258,9 +259,11 @@ void ssh_verstring_handle_input(BinaryPacketProtocol *bpp) data = bufchain_prefix(s->bpp.in_raw); if ((nl = memchr(data.ptr, '\012', data.len)) != NULL) { bufchain_consume(s->bpp.in_raw, nl - (char *)data.ptr + 1); + ssh_check_frozen(s->bpp.ssh); break; } else { bufchain_consume(s->bpp.in_raw, data.len); + ssh_check_frozen(s->bpp.ssh); } } } @@ -298,6 +301,7 @@ void ssh_verstring_handle_input(BinaryPacketProtocol *bpp) memcpy(s->vstring + s->vslen, data.ptr, data.len); s->vslen += data.len; bufchain_consume(s->bpp.in_raw, data.len); + ssh_check_frozen(s->bpp.ssh); } while (s->vstring[s->vslen-1] != '\012');