Anti-idle in OpenSSH client?

Martin Johansson martin at fatbob.nu
Mon Apr 7 23:46:55 EST 2003


Hi!

On Fri, Apr 04, 2003 at 09:39:32AM -0600, mandar at webchat.chatsystems.com wrote:

>    Is this possible or planned with the OpenSSH client? Our draconian
> firewall admins have started timing out ssh sessions. Yes I'm aware I
> could hack up a port forwarding dumb traffic process, but was looking for
> a more elegant solution like the windows clients have. e.g. a command line
> option to ssh that lets you anti-idle..
> 
> 
>    Discussion on how to implement this in the code is also welcome ;)

I have a patch for this, posted quite some time ago to this list. It sends
SSH_MSH_IGNORE packets randomly within configurable upper and lower time
limits in seconds.

Set in ssh_config (or ~/.ssh/config):

BogusTrafficIntervalMin n
BogusTrafficIntervalMax n

/Martin

Here is the patch rediffed for 3.6.1p1:

diff -ur openssh-3.6.1p1/clientloop.c openssh-3.6.1p1.alive/clientloop.c
--- openssh-3.6.1p1/clientloop.c	Tue Apr  1 13:43:39 2003
+++ openssh-3.6.1p1.alive/clientloop.c	Mon Apr  7 14:48:13 2003
@@ -321,6 +321,9 @@
 client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
     int *maxfdp, int *nallocp, int rekeying)
 {
+	struct timeval tv, *tvp;
+	int ret;
+	
 	/* Add any selections by the channel mechanism. */
 	channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying);
 
@@ -362,13 +365,29 @@
 	/*
 	 * 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.
+	 * event pending.
+	 * Set a random timeout for the select, and send a random SSH_MSG_IGNORE
+	 * packet when the timeout expires to fool traffic analysis.
 	 */
-
-	if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) {
+	if (options.bogus_traffic_interval_max) {
+		u_int32_t rand = arc4random();
+		u_int64_t timeusec;
+		static u_int64_t timebase = 0;
+		
+		if (!timebase)
+			timebase = (options.bogus_traffic_interval_max -
+						options.bogus_traffic_interval_min) * 1000000;
+		timeusec = timebase * rand / 0xffffffffUL;
+		timeusec += options.bogus_traffic_interval_min * 1000000;
+		tv.tv_sec = timeusec / 1000000;
+		tv.tv_usec = timeusec % 1000000;
+		tvp = &tv;
+		debug2("Will send SSH_MSG_IGNORE in %lu.%lu s", tv.tv_sec, tv.tv_usec);
+	}
+	else tvp = NULL;
+			 
+	ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
+	if (ret < 0) {
 		char buf[100];
 
 		/*
@@ -386,6 +405,12 @@
 		buffer_append(&stderr_buffer, buf, strlen(buf));
 		quit_pending = 1;
 	}
+	else if (ret == 0) { /* timeout */
+		u_int32_t rand = arc4random();
+		packet_send_ignore((rand & 0x3f) + 1);
+		packet_send();
+		packet_write_wait();
+	}
 }
 
 static void
diff -ur openssh-3.6.1p1/readconf.c openssh-3.6.1p1.alive/readconf.c
--- openssh-3.6.1p1/readconf.c	Tue Apr  1 13:43:39 2003
+++ openssh-3.6.1p1.alive/readconf.c	Mon Apr  7 14:49:30 2003
@@ -114,7 +114,7 @@
 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
-	oEnableSSHKeysign,
+	oEnableSSHKeysign, oBogusTrafficIntervalMin, oBogusTrafficIntervalMax,
 	oDeprecated
 } OpCodes;
 
@@ -188,6 +188,8 @@
 	{ "clearallforwardings", oClearAllForwardings },
 	{ "enablesshkeysign", oEnableSSHKeysign },
 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
+	{ "BogusTrafficIntervalMax", oBogusTrafficIntervalMax },
+	{ "BogusTrafficIntervalMin", oBogusTrafficIntervalMin },
 	{ NULL, oBadOption }
 };
 
@@ -415,6 +417,42 @@
 		intptr = &options->no_host_authentication_for_localhost;
 		goto parse_flag;
 
+	case oBogusTrafficIntervalMax:
+		arg = strdelim(&s);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing argument.", filename, linenum);
+		if (arg[0] < '0' || arg[0] > '9')
+			fatal("%.200s line %d: Bad number.", filename, linenum);
+
+		/* Octal, decimal, or hex format? */
+		value = strtol(arg, &endofnumber, 0);
+		if (arg == endofnumber)
+			fatal("%.200s line %d: Bad number.", filename, linenum);
+		if (*activep && options->bogus_traffic_interval_max == -1)
+			options->bogus_traffic_interval_max = value;
+		if (options->bogus_traffic_interval_min != -1 &&
+			options->bogus_traffic_interval_min >= value)
+			fatal("%.200s line %d: Bad value.", filename, linenum);
+		break;
+		
+	case oBogusTrafficIntervalMin:
+		arg = strdelim(&s);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing argument.", filename, linenum);
+		if (arg[0] < '0' || arg[0] > '9')
+			fatal("%.200s line %d: Bad number.", filename, linenum);
+
+		/* Octal, decimal, or hex format? */
+		value = strtol(arg, &endofnumber, 0);
+		if (arg == endofnumber)
+			fatal("%.200s line %d: Bad number.", filename, linenum);
+		if (*activep && options->bogus_traffic_interval_min == -1)
+			options->bogus_traffic_interval_min = value;
+		if (options->bogus_traffic_interval_max != -1 &&
+			options->bogus_traffic_interval_max  <= value)
+			fatal("%.200s line %d: Bad value.", filename, linenum);
+		break;
+		
 	case oNumberOfPasswordPrompts:
 		intptr = &options->number_of_password_prompts;
 		goto parse_int;
@@ -795,6 +833,8 @@
 	options->smartcard_device = NULL;
 	options->enable_ssh_keysign = - 1;
 	options->no_host_authentication_for_localhost = - 1;
+	options->bogus_traffic_interval_max = -1;
+	options->bogus_traffic_interval_min = -1;
 }
 
 /*
@@ -855,6 +895,10 @@
 		options->compression = 0;
 	if (options->keepalives == -1)
 		options->keepalives = 1;
+	if (options->bogus_traffic_interval_max == -1)
+		options->bogus_traffic_interval_max = 0;
+	if (options->bogus_traffic_interval_min == -1)
+		options->bogus_traffic_interval_min = 0;
 	if (options->compression_level == -1)
 		options->compression_level = 6;
 	if (options->port == -1)
Only in openssh-3.6.1p1.alive/: readconf.c.orig
Only in openssh-3.6.1p1.alive/: readconf.c.rej
diff -ur openssh-3.6.1p1/readconf.h openssh-3.6.1p1.alive/readconf.h
--- openssh-3.6.1p1/readconf.h	Tue Apr  1 13:43:40 2003
+++ openssh-3.6.1p1.alive/readconf.h	Mon Apr  7 14:48:13 2003
@@ -61,6 +61,16 @@
 	int     compression_level;	/* Compression level 1 (fast) to 9
 					 * (best). */
 	int     keepalives;	/* Set SO_KEEPALIVE. */
+	int	    bogus_traffic_interval_max;	/*
+					 * max time value of SSH_MSG_IGNORE 
+					 * interval 
+					 */
+	int	    bogus_traffic_interval_min;	/*
+					 * min time value of SSH_MSG_IGNORE
+					 * interval
+					 */
+	int	pam_authentication_via_kbd_int;
+
 	LogLevel log_level;	/* Level for logging. */
 
 	int     port;		/* Port to connect. */




More information about the openssh-unix-dev mailing list