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. */