summaryrefslogtreecommitdiffstats
path: root/channels.c
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2002-03-26 03:26:24 +0000
committerBen Lindstrom <mouring@eviladmin.org>2002-03-26 03:26:24 +0000
commitcf15944c2355f61116d7fb5e793c097dd347284f (patch)
tree15203eed8ed647b7f11f7e5347e8a9bc0f18f2b5 /channels.c
parent4f054607f05f18a705579a2475f490ed47e31028 (diff)
- markus@cvs.openbsd.org 2002/03/25 21:13:51
[channels.c channels.h compat.c compat.h nchan.c] don't send stderr data after EOF, accept this from older known (broken) sshd servers only, fixes http://bugzilla.mindrot.org/show_bug.cgi?id=179
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/channels.c b/channels.c
index 2b1f33f3..95817624 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.171 2002/03/04 19:37:58 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.172 2002/03/25 21:13:51 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -706,7 +706,11 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
if (buffer_len(&c->output) > 0) {
FD_SET(c->wfd, writeset);
} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
- chan_obuf_empty(c);
+ if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
+ debug2("channel %d: obuf_empty delayed efd %d/(%d)",
+ c->self, c->efd, buffer_len(&c->extended));
+ else
+ chan_obuf_empty(c);
}
}
/** XXX check close conditions, too */
@@ -714,7 +718,8 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
if (c->extended_usage == CHAN_EXTENDED_WRITE &&
buffer_len(&c->extended) > 0)
FD_SET(c->efd, writeset);
- else if (c->extended_usage == CHAN_EXTENDED_READ &&
+ else if (!(c->flags & CHAN_EOF_SENT) &&
+ c->extended_usage == CHAN_EXTENDED_READ &&
buffer_len(&c->extended) < c->remote_window)
FD_SET(c->efd, readset);
}
@@ -1632,12 +1637,18 @@ channel_output_poll(void)
fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
/*
* input-buffer is empty and read-socket shutdown:
- * tell peer, that we will not send more data: send IEOF
+ * tell peer, that we will not send more data: send IEOF.
+ * hack for extended data: delay EOF if EFD still in use.
*/
- chan_ibuf_empty(c);
+ if (CHANNEL_EFD_INPUT_ACTIVE(c))
+ debug2("channel %d: ibuf_empty delayed efd %d/(%d)",
+ c->self, c->efd, buffer_len(&c->extended));
+ else
+ chan_ibuf_empty(c);
}
/* Send extended data, i.e. stderr */
if (compat20 &&
+ !(c->flags & CHAN_EOF_SENT) &&
c->remote_window > 0 &&
(len = buffer_len(&c->extended)) > 0 &&
c->extended_usage == CHAN_EXTENDED_READ) {
@@ -1726,6 +1737,13 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
log("channel %d: ext data for non open", id);
return;
}
+ if (c->flags & CHAN_EOF_RCVD) {
+ if (datafellows & SSH_BUG_EXTEOF)
+ debug("channel %d: accepting ext data after eof", id);
+ else
+ packet_disconnect("Received extended_data after EOF "
+ "on channel %d.", id);
+ }
tcode = packet_get_int();
if (c->efd == -1 ||
c->extended_usage != CHAN_EXTENDED_WRITE ||