mirror of git://anongit.mindrot.org/openssh.git
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
This commit is contained in:
parent
43254b326a
commit
ccf7d913db
35
channels.c
35
channels.c
|
@ -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>
|
* 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
|
||||||
|
@ -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.
|
* 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)
|
channel_output_poll_input_open(struct ssh *ssh, Channel *c)
|
||||||
{
|
{
|
||||||
size_t len, plen;
|
size_t len, plen;
|
||||||
|
@ -2914,7 +2915,7 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
|
||||||
else
|
else
|
||||||
chan_ibuf_empty(ssh, c);
|
chan_ibuf_empty(ssh, c);
|
||||||
}
|
}
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!c->have_remote_id)
|
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) {
|
if (plen > c->remote_window || plen > c->remote_maxpacket) {
|
||||||
debug("channel %d: datagram too big", c->self);
|
debug("channel %d: datagram too big", c->self);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Enqueue it */
|
/* Enqueue it */
|
||||||
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
|
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)
|
(r = sshpkt_send(ssh)) != 0)
|
||||||
fatal_fr(r, "channel %i: send datagram", c->self);
|
fatal_fr(r, "channel %i: send datagram", c->self);
|
||||||
c->remote_window -= plen;
|
c->remote_window -= plen;
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enqueue packet for buffered data. */
|
/* Enqueue packet for buffered data. */
|
||||||
|
@ -2949,7 +2950,7 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
|
||||||
if (len > c->remote_maxpacket)
|
if (len > c->remote_maxpacket)
|
||||||
len = c->remote_maxpacket;
|
len = c->remote_maxpacket;
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return;
|
return 0;
|
||||||
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
|
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
|
||||||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
|
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
|
||||||
(r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 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)
|
if ((r = sshbuf_consume(c->input, len)) != 0)
|
||||||
fatal_fr(r, "channel %i: consume", c->self);
|
fatal_fr(r, "channel %i: consume", c->self);
|
||||||
c->remote_window -= len;
|
c->remote_window -= len;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enqueue data for channels with open c->extended in read mode.
|
* 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)
|
channel_output_poll_extended_read(struct ssh *ssh, Channel *c)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if ((len = sshbuf_len(c->extended)) == 0)
|
if ((len = sshbuf_len(c->extended)) == 0)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
debug2("channel %d: rwin %u elen %zu euse %d", c->self,
|
debug2("channel %d: rwin %u elen %zu euse %d", c->self,
|
||||||
c->remote_window, sshbuf_len(c->extended), c->extended_usage);
|
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)
|
if (len > c->remote_maxpacket)
|
||||||
len = c->remote_maxpacket;
|
len = c->remote_maxpacket;
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return;
|
return 0;
|
||||||
if (!c->have_remote_id)
|
if (!c->have_remote_id)
|
||||||
fatal_f("channel %d: no remote id", c->self);
|
fatal_f("channel %d: no remote id", c->self);
|
||||||
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 ||
|
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);
|
fatal_fr(r, "channel %i: consume", c->self);
|
||||||
c->remote_window -= len;
|
c->remote_window -= len;
|
||||||
debug2("channel %d: sent ext data %zu", c->self, 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)
|
channel_output_poll(struct ssh *ssh)
|
||||||
{
|
{
|
||||||
struct ssh_channels *sc = ssh->chanctxt;
|
struct ssh_channels *sc = ssh->chanctxt;
|
||||||
Channel *c;
|
Channel *c;
|
||||||
u_int i;
|
u_int i;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
for (i = 0; i < sc->channels_alloc; i++) {
|
for (i = 0; i < sc->channels_alloc; i++) {
|
||||||
c = sc->channels[i];
|
c = sc->channels[i];
|
||||||
|
@ -3023,12 +3031,13 @@ channel_output_poll(struct ssh *ssh)
|
||||||
/* Get the amount of buffered data for this channel. */
|
/* Get the amount of buffered data for this channel. */
|
||||||
if (c->istate == CHAN_INPUT_OPEN ||
|
if (c->istate == CHAN_INPUT_OPEN ||
|
||||||
c->istate == CHAN_INPUT_WAIT_DRAIN)
|
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 */
|
/* Send extended data, i.e. stderr */
|
||||||
if (!(c->flags & CHAN_EOF_SENT) &&
|
if (!(c->flags & CHAN_EOF_SENT) &&
|
||||||
c->extended_usage == CHAN_EXTENDED_READ)
|
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 */
|
/* -- 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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
|
@ -335,7 +335,7 @@ struct timespec;
|
||||||
void channel_prepare_poll(struct ssh *, struct pollfd **,
|
void channel_prepare_poll(struct ssh *, struct pollfd **,
|
||||||
u_int *, u_int *, u_int, struct timespec *);
|
u_int *, u_int *, u_int, struct timespec *);
|
||||||
void channel_after_poll(struct ssh *, struct pollfd *, u_int);
|
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 *);
|
int channel_not_very_much_buffered_data(struct ssh *);
|
||||||
void channel_close_all(struct ssh *);
|
void channel_close_all(struct ssh *);
|
||||||
|
|
Loading…
Reference in New Issue