- (djm) OpenBSD CVS:
   - markus@cvs.openbsd.org  2001/02/15 16:19:59
     [channels.c channels.h serverloop.c sshconnect.c sshconnect.h]
     [sshconnect1.c sshconnect2.c]
     genericize password padding function for SSH1 and SSH2.
     add stylized echo to 2, too.
 - (djm) Add roundup() macro to defines.h
diff --git a/channels.c b/channels.c
index a079fc2..b728694 100644
--- a/channels.c
+++ b/channels.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.90 2001/02/08 21:58:28 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.91 2001/02/15 23:19:59 markus Exp $");
 
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
@@ -193,6 +193,18 @@
 	c->efd = efd;
 	c->extended_usage = extusage;
 
+	/* XXX ugly hack: nonblock is only set by the server */
+	if (nonblock && isatty(c->rfd)) {
+		debug("channel: %d: rfd %d isatty", c->self, c->rfd);
+		c->isatty = 1;
+		if (!isatty(c->wfd)) {
+			error("channel: %d: wfd %d is not a tty?",
+			    c->self, c->wfd);
+		}
+	} else {
+		c->isatty = 0;
+	}
+
 	/* enable nonblocking mode */
 	if (nonblock) {
 		if (rfd != -1)
@@ -776,6 +788,21 @@
 			}
 			return -1;
 		}
+		if (compat20 && c->isatty) {
+			struct termios tio;
+			if (tcgetattr(c->wfd, &tio) == 0 &&
+			    !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
+				/*
+				 * Simulate echo to reduce the impact of
+				 * traffic analysis.
+				 */
+				packet_start(SSH2_MSG_IGNORE);
+				memset(buffer_ptr(&c->output), 0, len);
+				packet_put_string(buffer_ptr(&c->output), len);
+				packet_send();
+				debug("channel: %d simulate echo (%d)", c->self, len);
+			}
+		}
 		buffer_consume(&c->output, len);
 		if (compat20 && len > 0) {
 			c->local_consumed += len;