[PATCH] Add a Maximum Idle Time (1.2.2)

Jacob Luna Lundberg jacob at velius.chaos2.org
Tue Mar 7 21:54:37 EST 2000


Sean Aaron Lisse <nebulous at owlnet.rice.edu> wrote:
>   I recommend sending some random characters instead of a constant string
> like "bla".

     Done.  I used random strings with a maximum length of 256 chars.
Sound good to everybody?  And the patch is also at:
http://www.chaos2.org/~jacob/code/patch-openssh-1.2.2-trans_inter-r2

-Jacob

-- 

"Heh.  You mean this is Stef's source code?"
  -User Friendly
-------------- next part --------------
diff -ur openssh-1.2.2/bsd-misc.c openssh-1.2.2-trans_inter-r2/bsd-misc.c
--- openssh-1.2.2/bsd-misc.c	Sat Jan 22 15:32:03 2000
+++ openssh-1.2.2-trans_inter-r2/bsd-misc.c	Tue Mar  7 02:25:48 2000
@@ -68,7 +68,6 @@
 	int j;
 } rc4_t;
 
-void get_random_bytes(unsigned char *buf, int len);
 void rc4_key(rc4_t *r, unsigned char *key, int len);
 void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len);
 
diff -ur openssh-1.2.2/bsd-misc.h openssh-1.2.2-trans_inter-r2/bsd-misc.h
--- openssh-1.2.2/bsd-misc.h	Thu Jan  6 01:28:41 2000
+++ openssh-1.2.2-trans_inter-r2/bsd-misc.h	Tue Mar  7 02:25:49 2000
@@ -42,6 +42,7 @@
 #ifndef HAVE_ARC4RANDOM
 unsigned int arc4random(void);
 void arc4random_stir(void);
+void get_random_bytes(unsigned char *buf, int len);
 #endif /* !HAVE_ARC4RANDOM */
 
 #ifndef HAVE_SETPROCTITLE
diff -ur openssh-1.2.2/clientloop.c openssh-1.2.2-trans_inter-r2/clientloop.c
--- openssh-1.2.2/clientloop.c	Mon Dec  6 20:38:32 1999
+++ openssh-1.2.2-trans_inter-r2/clientloop.c	Tue Mar  7 02:28:31 2000
@@ -396,8 +396,10 @@
  */
 
 void 
-client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
+client_wait_until_can_do_something(fd_set * readset, fd_set * writeset, int trans_inter)
 {
+	int select_return;
+
 	/* Initialize select masks. */
 	FD_ZERO(readset);
 
@@ -436,15 +438,35 @@
 		max_fd = channel_max_fd();
 
 	/*
-	 * Wait for something to happen.  This will suspend the process until
-	 * some selected descriptor can be read, written, or has some other
-	 * event pending. Note: if you want to implement SSH_MSG_IGNORE
-	 * messages to fool traffic analysis, this might be the place to do
-	 * it: just have a random timeout for the select, and send a random
-	 * SSH_MSG_IGNORE packet when the timeout expires.
+	 *	Wait for something to happen.  This will suspend the process
+	 * until some selected descriptor can be read, written, or has some
+	 * other event pending.
+	 *	Implemented timeout SSH_MSG_IGNORE packets to keep a minimum
+	 * frequency of traffic present on a connection.  This can be used to
+	 * prevent a firewall (ip_masq f.e.) from timing out and causing a new
+	 * port to be allocated which effectively kills the connection.
+	 *	To fool traffic analysis, set the timeout on the SSH_MSG_IGNORE
+	 * packets randomly instead of periodically.
 	 */
 
-	if (select(max_fd + 1, readset, writeset, NULL, NULL) < 0) {
+	if( trans_inter > 0 ) {
+		struct timeval timeout;
+		timeout.tv_sec = trans_inter;
+		timeout.tv_usec = 0;
+		select_return = select(max_fd + 1, readset, writeset, NULL, &timeout);
+		if(select_return == 0) {
+			int random_length = arc4random() & 0xff;
+			char *random_string = (char *)xmalloc(random_length);
+			get_random_bytes(random_string, random_length);
+			packet_start(SSH_MSG_IGNORE);
+			packet_put_string(random_string, random_length);
+			packet_send();
+			xfree(random_string);
+		}
+	} else
+		select_return = select(max_fd + 1, readset, writeset, NULL, NULL);
+
+	if( select_return < 0 ) {
 		char buf[100];
 		/* Some systems fail to clear these automatically. */
 		FD_ZERO(readset);
@@ -863,7 +885,7 @@
 		 * Wait until we have something to do (something becomes
 		 * available on one of the descriptors).
 		 */
-		client_wait_until_can_do_something(&readset, &writeset);
+		client_wait_until_can_do_something(&readset, &writeset, options.trans_inter);
 
 		if (quit_pending)
 			break;
diff -ur openssh-1.2.2/readconf.c openssh-1.2.2-trans_inter-r2/readconf.c
--- openssh-1.2.2/readconf.c	Sun Dec  5 16:47:29 1999
+++ openssh-1.2.2-trans_inter-r2/readconf.c	Tue Mar  7 02:25:23 2000
@@ -78,6 +78,7 @@
      UseRsh no
      StrictHostKeyChecking yes
      KeepAlives no
+     TransmitInterlude 0
      IdentityFile ~/.ssh/identity
      Port 22
      EscapeChar ~
@@ -101,8 +102,8 @@
 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
-	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
-	oUsePrivilegedPort, oLogLevel
+	oCompressionLevel, oKeepAlives, oTransmitInterlude, oNumberOfPasswordPrompts,
+	oTISAuthentication, oUsePrivilegedPort, oLogLevel
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -148,6 +149,7 @@
 	{ "compression", oCompression },
 	{ "compressionlevel", oCompressionLevel },
 	{ "keepalive", oKeepAlives },
+	{ "transmitinterlude", oTransmitInterlude },
 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
 	{ "tisauthentication", oTISAuthentication },
 	{ "loglevel", oLogLevel },
@@ -355,6 +357,10 @@
 		intptr = &options->keepalives;
 		goto parse_flag;
 
+	case oTransmitInterlude:
+		intptr = &options->trans_inter;
+		goto parse_int;
+
 	case oNumberOfPasswordPrompts:
 		intptr = &options->number_of_password_prompts;
 		goto parse_int;
@@ -610,6 +616,7 @@
 	options->strict_host_key_checking = -1;
 	options->compression = -1;
 	options->keepalives = -1;
+	options->trans_inter = -1;
 	options->compression_level = -1;
 	options->port = -1;
 	options->connection_attempts = -1;
@@ -677,6 +684,8 @@
 		options->compression = 0;
 	if (options->keepalives == -1)
 		options->keepalives = 1;
+	if (options->trans_inter == -1)
+		options->trans_inter = 0;
 	if (options->compression_level == -1)
 		options->compression_level = 6;
 	if (options->port == -1)
diff -ur openssh-1.2.2/readconf.h openssh-1.2.2-trans_inter-r2/readconf.h
--- openssh-1.2.2/readconf.h	Sun Dec  5 16:47:29 1999
+++ openssh-1.2.2-trans_inter-r2/readconf.h	Tue Mar  7 02:25:23 2000
@@ -56,6 +56,7 @@
 	int     compression_level;	/* Compression level 1 (fast) to 9
 					 * (best). */
 	int     keepalives;	/* Set SO_KEEPALIVE. */
+	int     trans_inter;	/* Guarantee transmit every n seconds. */
 	LogLevel log_level;	/* Level for logging. */
 
 	int     port;		/* Port to connect. */
diff -ur openssh-1.2.2/ssh.0 openssh-1.2.2-trans_inter-r2/ssh.0
--- openssh-1.2.2/ssh.0	Wed Jan 26 19:17:09 2000
+++ openssh-1.2.2-trans_inter-r2/ssh.0	Tue Mar  7 02:25:23 2000
@@ -486,6 +486,21 @@
              be verified automatically in either case.  The argument must be
              ``yes'' or ``no''.
 
+     TransmitInterlude
+             Specifies a maximum time to allow between transmitting packets,
+             in seconds.  If this amount of time passes and the client has no
+             data to send, it will send an ignore packet to the server.  One
+             example where this is useful is when using ssh from behind a Lin-
+             ux ip_masquerade firewall.  If packets aren't sent through such a
+             firewall periodically, the firewall may forget about the connec-
+             tion.  Then when a packet finally is sent, the firewall will as-
+             sign a new port, which will cause the remote server to disconnect
+             the session.  This option defaults to ``0'', which means not
+             sending periodic packets.  A setting of a few hundred seconds
+             should be about right if this is needed.  You should probably try
+             setting KeepAlive to ``yes'' in your conf files on both the serv-
+             er and the client first.
+
      UsePrivilegedPort
              Specifies whether to use a privileged port for outgoing connec-
              tions.  The argument must be ``yes'' or ``no''. The default is
diff -ur openssh-1.2.2/ssh.1 openssh-1.2.2-trans_inter-r2/ssh.1
--- openssh-1.2.2/ssh.1	Sat Jan 22 00:57:40 2000
+++ openssh-1.2.2-trans_inter-r2/ssh.1	Tue Mar  7 02:25:23 2000
@@ -720,6 +720,22 @@
 .Dq yes
 or
 .Dq no .
+.It Cm TransmitInterlude
+Specifies a maximum time to allow between transmitting packets,
+in seconds.  If this amount of time passes and the client has
+no data to send, it will send an ignore packet to the server.
+One example where this is useful is when using ssh from behind
+a Linux ip_masquerade firewall.  If packets aren't sent through
+such a firewall periodically, the firewall may forget about the
+connection.  Then when a packet finally is sent, the firewall
+will assign a new port, which will cause the remote server to
+disconnect the session.  This option defaults to
+.Dq 0 ,
+which means not sending periodic packets.  A setting of a few
+hundred seconds should be about right if this is needed.  You
+should probably try setting KeepAlive to
+.Dq yes
+in your conf files on both the server and the client first.
 .It Cm UsePrivilegedPort
 Specifies whether to use a privileged port for outgoing connections.
 The argument must be


More information about the openssh-unix-dev mailing list