- 1.47 Thu Feb 8 23:11:42 GMT 2001 by dugsong
     [serverloop.c sshconnect1.c]
     mitigate SSH1 traffic analysis - from Solar Designer
     <solar@openwall.com>, ok provos@
diff --git a/ChangeLog b/ChangeLog
index fe271d6..d4fb242 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -92,6 +92,10 @@
    - itojun@cvs.openbsd.org 2001/02/07 18:04:50
      [xmalloc.c]
      fix size_t -> int cast (use u_long).  markus ok
+   - 1.47 Thu Feb 8 23:11:42 GMT 2001 by dugsong
+     [serverloop.c sshconnect1.c]
+     mitigate SSH1 traffic analysis - from Solar Designer 
+     <solar@openwall.com>, ok provos@
  - (bal) fixed sftp-client.c.  Return 'status' instead of '0'  
    (from the OpenBSD tree)
  - (bal) Synced ssh.1, ssh-add.1 and sshd.8 w/ OpenBSD
@@ -3880,4 +3884,4 @@
  - Wrote replacements for strlcpy and mkdtemp
  - Released 1.0pre1
 
-$Id: ChangeLog,v 1.736 2001/02/10 23:34:54 mouring Exp $
+$Id: ChangeLog,v 1.737 2001/02/10 23:44:47 mouring Exp $
diff --git a/serverloop.c b/serverloop.c
index c8187ab..8fc94db 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.46 2001/02/08 19:30:52 itojun Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.47 2001/02/08 23:11:42 dugsong Exp $");
 
 #include "xmalloc.h"
 #include "packet.h"
@@ -317,6 +317,7 @@
 void
 process_output(fd_set * writeset)
 {
+	struct termios tio;
 	int len;
 
 	/* Write buffered data to program stdin. */
@@ -336,7 +337,16 @@
 #endif
 			fdin = -1;
 		} else {
-			/* Successful write.  Consume the data from the buffer. */
+			/* Successful write. */
+			if (tcgetattr(fdin, &tio) == 0 &&
+			    !(tio.c_lflag & ECHO)) {
+				/* Simulate echo to reduce the impact of traffic analysis. */
+				packet_start(SSH_MSG_IGNORE);
+				memset(buffer_ptr(&stdin_buffer), 0, len);
+				packet_put_string(buffer_ptr(&stdin_buffer), len);
+				packet_send();
+			}
+			/* Consume the data from the buffer. */
 			buffer_consume(&stdin_buffer, len);
 			/* Update the count of bytes written to the program. */
 			stdin_bytes += len;
diff --git a/sshconnect1.c b/sshconnect1.c
index c33ac50..a71d28c 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -13,7 +13,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect1.c,v 1.24 2001/02/08 19:30:52 itojun Exp $");
+RCSID("$OpenBSD: sshconnect1.c,v 1.25 2001/02/08 23:11:43 dugsong Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/evp.h>
@@ -51,6 +51,20 @@
 extern Options options;
 extern char *__progname;
 
+void
+ssh1_put_password(char *password)
+{
+	int size;
+	char *padded;
+
+	size = roundup(strlen(password), 32);
+	padded = xmalloc(size);
+	strlcpy(padded, password, size);
+	packet_put_string(padded, size);
+	memset(padded, 0, size);
+	xfree(padded);
+}
+
 /*
  * Checks if the user has an authentication agent, and if so, tries to
  * authenticate using the agent.
@@ -658,7 +672,7 @@
 			break;
 		}
 		packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
-		packet_put_string(response, strlen(response));
+		ssh1_put_password(response);
 		memset(response, 0, strlen(response));
 		xfree(response);
 		packet_send();
@@ -691,7 +705,7 @@
 			error("Permission denied, please try again.");
 		password = read_passphrase(prompt, 0);
 		packet_start(SSH_CMSG_AUTH_PASSWORD);
-		packet_put_string(password, strlen(password));
+		ssh1_put_password(password);
 		memset(password, 0, strlen(password));
 		xfree(password);
 		packet_send();