diff options
author | djm@openbsd.org <djm@openbsd.org> | 2023-09-04 00:01:46 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2023-09-04 10:09:53 +1000 |
commit | ccf7d913db34e49b7a6db1b8331bd402004c840d (patch) | |
tree | c3d9e34c513d590d7543de73cfa0289554d29b10 | |
parent | 43254b326ac6e2131dbd750f9464dc62c14bd5a7 (diff) |
upstream: make channel_output_poll() return a flag indicating
whether channel data was enqueued. Will be used to improve keystroke timing
obfuscation. Problem spotted by / tested by naddy@
OpenBSD-Commit-ID: f9776c7b0065ba7c3bbe50431fd3b629f44314d0
-rw-r--r-- | channels.c | 35 | ||||
-rw-r--r-- | channels.h | 4 |
2 files changed, 24 insertions, 15 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.432 2023/07/04 03:59:21 dlg Exp $ */ +/* $OpenBSD: channels.c,v 1.433 2023/09/04 00:01:46 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -2890,8 +2890,9 @@ channel_after_poll(struct ssh *ssh, struct pollfd *pfd, u_int npfd) /* * Enqueue data for channels with open or draining c->input. + * Returns non-zero if a packet was enqueued. */ -static void +static int channel_output_poll_input_open(struct ssh *ssh, Channel *c) { size_t len, plen; @@ -2914,7 +2915,7 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c) else chan_ibuf_empty(ssh, c); } - return; + return 0; } if (!c->have_remote_id) @@ -2931,7 +2932,7 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c) */ if (plen > c->remote_window || plen > c->remote_maxpacket) { debug("channel %d: datagram too big", c->self); - return; + return 0; } /* Enqueue it */ if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 || @@ -2940,7 +2941,7 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c) (r = sshpkt_send(ssh)) != 0) fatal_fr(r, "channel %i: send datagram", c->self); c->remote_window -= plen; - return; + return 1; } /* Enqueue packet for buffered data. */ @@ -2949,7 +2950,7 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c) if (len > c->remote_maxpacket) len = c->remote_maxpacket; if (len == 0) - return; + return 0; if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 || (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || (r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 || @@ -2958,19 +2959,21 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c) if ((r = sshbuf_consume(c->input, len)) != 0) fatal_fr(r, "channel %i: consume", c->self); c->remote_window -= len; + return 1; } /* * Enqueue data for channels with open c->extended in read mode. + * Returns non-zero if a packet was enqueued. */ -static void +static int channel_output_poll_extended_read(struct ssh *ssh, Channel *c) { size_t len; int r; if ((len = sshbuf_len(c->extended)) == 0) - return; + return 0; debug2("channel %d: rwin %u elen %zu euse %d", c->self, c->remote_window, sshbuf_len(c->extended), c->extended_usage); @@ -2979,7 +2982,7 @@ channel_output_poll_extended_read(struct ssh *ssh, Channel *c) if (len > c->remote_maxpacket) len = c->remote_maxpacket; if (len == 0) - return; + return 0; if (!c->have_remote_id) fatal_f("channel %d: no remote id", c->self); if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 || @@ -2992,15 +2995,20 @@ channel_output_poll_extended_read(struct ssh *ssh, Channel *c) fatal_fr(r, "channel %i: consume", c->self); c->remote_window -= len; debug2("channel %d: sent ext data %zu", c->self, len); + return 1; } -/* If there is data to send to the connection, enqueue some of it now. */ -void +/* + * If there is data to send to the connection, enqueue some of it now. + * Returns non-zero if data was enqueued. + */ +int channel_output_poll(struct ssh *ssh) { struct ssh_channels *sc = ssh->chanctxt; Channel *c; u_int i; + int ret = 0; for (i = 0; i < sc->channels_alloc; i++) { c = sc->channels[i]; @@ -3023,12 +3031,13 @@ channel_output_poll(struct ssh *ssh) /* Get the amount of buffered data for this channel. */ if (c->istate == CHAN_INPUT_OPEN || c->istate == CHAN_INPUT_WAIT_DRAIN) - channel_output_poll_input_open(ssh, c); + ret |= channel_output_poll_input_open(ssh, c); /* Send extended data, i.e. stderr */ if (!(c->flags & CHAN_EOF_SENT) && c->extended_usage == CHAN_EXTENDED_READ) - channel_output_poll_extended_read(ssh, c); + ret |= channel_output_poll_extended_read(ssh, c); } + return ret; } /* -- mux proxy support */ @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.151 2023/07/04 03:59:21 dlg Exp $ */ +/* $OpenBSD: channels.h,v 1.152 2023/09/04 00:01:46 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -335,7 +335,7 @@ struct timespec; void channel_prepare_poll(struct ssh *, struct pollfd **, u_int *, u_int *, u_int, struct timespec *); void channel_after_poll(struct ssh *, struct pollfd *, u_int); -void channel_output_poll(struct ssh *); +int channel_output_poll(struct ssh *); int channel_not_very_much_buffered_data(struct ssh *); void channel_close_all(struct ssh *); |