- markus@cvs.openbsd.org 2004/01/19 09:24:21
     [channels.c]
     fake consumption for half closed channels since the peer is waiting for
     window adjust messages; bugzilla #790 Matthew Dillon; test + ok dtucker@
     reproduce with sh -c 'ulimit -f 10; ssh host -n od /bsd | cat > foo'
diff --git a/ChangeLog b/ChangeLog
index 48a4c2b..e88f86d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,11 @@
    - markus@cvs.openbsd.org 2004/01/13 19:45:15
      [compress.c]
      cast for portability; millert@
+   - markus@cvs.openbsd.org 2004/01/19 09:24:21
+     [channels.c]
+     fake consumption for half closed channels since the peer is waiting for
+     window adjust messages; bugzilla #790 Matthew Dillon; test + ok dtucker@
+     reproduce with sh -c 'ulimit -f 10; ssh host -n od /bsd | cat > foo'
 
 20040114
  - (dtucker) [auth-pam.c] Have monitor die if PAM authentication thread exits
@@ -1684,4 +1689,4 @@
  - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
    Report from murple@murple.net, diagnosis from dtucker@zip.com.au
 
-$Id: ChangeLog,v 1.3173 2004/01/21 00:01:23 djm Exp $
+$Id: ChangeLog,v 1.3174 2004/01/21 00:02:09 djm Exp $
diff --git a/channels.c b/channels.c
index 14405bd..e663c21 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.199 2003/12/02 17:01:14 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.200 2004/01/19 09:24:21 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -1817,13 +1817,25 @@
 	    c->type != SSH_CHANNEL_X11_OPEN)
 		return;
 
-	/* same for protocol 1.5 if output end is no longer open */
-	if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN)
-		return;
-
 	/* Get the data. */
 	data = packet_get_string(&data_len);
 
+	/*
+	 * Ignore data for protocol > 1.3 if output end is no longer open.
+	 * For protocol 2 the sending side is reducing its window as it sends
+	 * data, so we must 'fake' consumption of the data in order to ensure
+	 * that window updates are sent back.  Otherwise the connection might
+	 * deadlock.
+	 */
+	if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) {
+		if (compat20) {
+			c->local_window -= data_len;
+			c->local_consumed += data_len;
+		}
+		xfree(data);
+		return;
+	}
+
 	if (compat20) {
 		if (data_len > c->local_maxpacket) {
 			logit("channel %d: rcvd big packet %d, maxpack %d",