Bugzilla – Attachment 1323 Details for
Bug 1338
Idletimeout for both client and server
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
IdleTimeout option for ssh & sshd
openssh-4.6p1-idletimeout.patch.txt (text/plain), 13.99 KB, created by
Wout Mertens
on 2007-07-11 03:09:35 AEST
(
hide
)
Description:
IdleTimeout option for ssh & sshd
Filename:
MIME Type:
Creator:
Wout Mertens
Created:
2007-07-11 03:09:35 AEST
Size:
13.99 KB
patch
obsolete
>diff -ru openssh-4.6p1-orig/clientloop.c openssh-4.6p1-idletimeout/clientloop.c >--- openssh-4.6p1-orig/clientloop.c 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/clientloop.c 2007-07-10 18:32:51.000000000 +0200 >@@ -482,7 +482,6 @@ > client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, > int *maxfdp, u_int *nallocp, int rekeying) > { >- struct timeval tv, *tvp; > int ret; > > /* Add any selections by the channel mechanism. */ >@@ -532,14 +531,8 @@ > * event pending. > */ > >- if (options.server_alive_interval == 0 || !compat20) >- tvp = NULL; >- else { >- tv.tv_sec = options.server_alive_interval; >- tv.tv_usec = 0; >- tvp = &tv; >- } >- ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); >+ ret = packet_select((*maxfdp)+1, *readsetp, *writesetp, NULL, >+ compat20 ? options.server_alive_interval : 0); > if (ret < 0) { > char buf[100]; > >diff -ru openssh-4.6p1-orig/packet.c openssh-4.6p1-idletimeout/packet.c >--- openssh-4.6p1-orig/packet.c 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/packet.c 2007-07-10 18:32:51.000000000 +0200 >@@ -161,6 +161,93 @@ > }; > TAILQ_HEAD(, packet) outgoing; > >+/* Idle timeout variables */ >+static time_t idletime_last=0; >+static int idletimeout=0; >+ >+ >+void >+packet_set_idletimeout(int max_idle_seconds) >+{ >+ idletimeout=max_idle_seconds; >+ if (max_idle_seconds>0) { >+ /* Initialize */ >+ time(&idletime_last); >+ } >+} >+ >+/* Called by whenever packets are sent or received. >+ * This function decides on which packets idletimeout should >+ * be reset */ >+void >+idletimeout_check(int type) >+{ >+ /* No-op, if idletimeouts are not configured */ >+ if (idletimeout==0) return; >+ >+ /* The following packets reset idletimeout on input or output. >+ * Note that only actual data resets idletimeout, control packets >+ * do not. */ >+ if (compat20) { >+ switch(type) { >+ case SSH2_MSG_CHANNEL_DATA: >+ case SSH2_MSG_CHANNEL_EXTENDED_DATA: >+ time(&idletime_last); >+ } >+ } else { >+ switch(type) { >+ case SSH_MSG_CHANNEL_DATA: >+ case SSH_CMSG_STDIN_DATA: >+ case SSH_SMSG_STDOUT_DATA: >+ case SSH_SMSG_STDERR_DATA: >+ time(&idletime_last); >+ } >+ } >+} >+ >+int >+packet_select(int maxfds, >+ fd_set *readset, fd_set *writeset, fd_set *exceptset, >+ int max_time_milliseconds) >+{ >+ struct timeval tv, *tvp=NULL; >+ int ret; >+ >+ if (idletimeout>0) { >+ /* Count the time to idletimeout */ >+ time_t diff=time(NULL)-idletime_last; >+ if (diff>=idletimeout) >+ tv.tv_sec=1; >+ else >+ tv.tv_sec=idletimeout-diff+1; >+ tv.tv_usec=0; >+ tvp = &tv; >+ debug("idletimeout after %ld seconds",tv.tv_sec); >+ } >+ /* If a timeout value was given and the timeout happens before >+ * idletimeout, use it */ >+ if (max_time_milliseconds>0 && >+ (tvp==NULL || max_time_milliseconds/1000<tv.tv_sec)) { >+ tv.tv_sec = max_time_milliseconds / 1000; >+ tv.tv_usec = 1000 * (max_time_milliseconds % 1000); >+ tvp = &tv; >+ debug("timeout after %d milliseconds",max_time_milliseconds); >+ } >+ if (tvp==NULL) debug("no timeout"); >+ >+ ret = select( maxfds, readset, writeset, exceptset, tvp ); >+ if (ret<0 && errno!=EAGAIN && errno!=EINTR) { >+ error("select: %.100s", strerror(errno)); >+ } >+ >+ /* Disconnect on idletimeout */ >+ if (idletimeout>0 && ret==0 && >+ time(NULL)-idletime_last>idletimeout) { >+ packet_disconnect("Idletimeout."); >+ idletimeout=0; >+ } >+ return ret; >+} > /* > * Sets the descriptors used for communication. Disables encryption until > * packet_set_encryption_key is called. >@@ -472,6 +559,9 @@ > int len; > > DBG(debug("packet_start[%d]", type)); >+ >+ idletimeout_check(type); >+ > len = compat20 ? 6 : 9; > memset(buf, 0, len - 1); > buf[len - 1] = type; >@@ -833,6 +923,8 @@ > cp = buffer_ptr(&outgoing_packet); > type = cp[5]; > >+ idletimeout_check(type); >+ > /* during rekeying we can only send key exchange messages */ > if (rekeying) { > if (!((type >= SSH2_MSG_TRANSPORT_MIN) && >@@ -912,20 +1004,21 @@ > /* If we got a packet, return it. */ > if (type != SSH_MSG_NONE) { > xfree(setp); >+ idletimeout_check(type); > return type; > } > /* > * Otherwise, wait for some data to arrive, add it to the > * buffer, and try again. > */ >- memset(setp, 0, howmany(connection_in + 1, NFDBITS) * >- sizeof(fd_mask)); >- FD_SET(connection_in, setp); >- >- /* Wait for some data to arrive. */ >- while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 && >- (errno == EAGAIN || errno == EINTR)) >- ; >+ do { >+ memset(setp, 0, howmany(connection_in + 1, NFDBITS) * >+ sizeof(fd_mask)); >+ FD_SET(connection_in, setp); >+ >+ /* Wait for some data to arrive. */ >+ } while (packet_select(connection_in + 1, >+ setp, NULL, NULL, 0) == -1); > > /* Read data from the socket. */ > len = read(connection_in, buf, sizeof(buf)); >@@ -1446,12 +1539,12 @@ > sizeof(fd_mask)); > packet_write_poll(); > while (packet_have_data_to_write()) { >- memset(setp, 0, howmany(connection_out + 1, NFDBITS) * >- sizeof(fd_mask)); >- FD_SET(connection_out, setp); >- while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 && >- (errno == EAGAIN || errno == EINTR)) >- ; >+ do { >+ memset(setp, 0, howmany(connection_out + 1, NFDBITS) * >+ sizeof(fd_mask)); >+ FD_SET(connection_out, setp); >+ } while (packet_select(connection_out + 1, >+ NULL, setp, NULL, 0) == -1); > packet_write_poll(); > } > xfree(setp); >diff -ru openssh-4.6p1-orig/packet.h openssh-4.6p1-idletimeout/packet.h >--- openssh-4.6p1-orig/packet.h 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/packet.h 2007-07-10 18:32:51.000000000 +0200 >@@ -103,4 +103,20 @@ > int packet_need_rekeying(void); > void packet_set_rekey_limit(u_int32_t); > >+/* This sets the maximum idle time before packet_select() automatically >+ * disconnects with packet_disconnect("Idletimeout"). >+ * Never autodisconnects if set to zero. zero is the default */ >+void packet_set_idletimeout(int max_idle_seconds); >+ >+/* This is an quite normal select, except that it implements idletimeouts >+ * set with packet_set_idletimeout(). >+ * It also returns exits, if select() returns any other error than AGAIN >+ * or EINTR. So if packet_select returns -1, you can safely reinit fd_sets >+ * and call packet_select again, without checking errno. >+ */ >+int packet_select(int maxfds, >+ fd_set *readset, fd_set *writeset, fd_set *exceptset, >+ int max_time_milliseconds); >+ >+ > #endif /* PACKET_H */ >diff -ru openssh-4.6p1-orig/readconf.c openssh-4.6p1-idletimeout/readconf.c >--- openssh-4.6p1-orig/readconf.c 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/readconf.c 2007-07-10 18:32:51.000000000 +0200 >@@ -130,7 +130,7 @@ > oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, > oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, > oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, >- oDeprecated, oUnsupported >+ oIdleTimeout, oDeprecated, oUnsupported > } OpCodes; > > /* Textual representations of the tokens. */ >@@ -226,6 +226,7 @@ > { "tunneldevice", oTunnelDevice }, > { "localcommand", oLocalCommand }, > { "permitlocalcommand", oPermitLocalCommand }, >+ { "idletimeout", oIdleTimeout }, > { NULL, oBadOption } > }; > >@@ -915,6 +916,28 @@ > intptr = &options->permit_local_command; > goto parse_flag; > >+ case oIdleTimeout: >+ arg = strdelim(&s); >+ if (!arg || *arg == '\0') >+ fatal("%s line %d: Missing IdleTimeout argument", >+ filename,linenum); >+ options->idletimeout=atoi(arg); >+ switch(arg[strlen(arg)-1]) { >+ case 'w': options->idletimeout*=7; >+ case 'd': options->idletimeout*=24; >+ case 'h': options->idletimeout*=60; >+ case 'm': options->idletimeout*=60; >+ case 's': >+ case '0': case '1': case '2': case '3': >+ case '4': case '5': case '6': case '7': >+ case '8': case '9': >+ break; >+ default: >+ fatal("%s line %d: Invalid IdleTimeout argument", >+ filename,linenum); >+ } >+ break; >+ > case oDeprecated: > debug("%s line %d: Deprecated option \"%s\"", > filename, linenum, keyword); >@@ -1065,6 +1088,7 @@ > options->tun_remote = -1; > options->local_command = NULL; > options->permit_local_command = -1; >+ options->idletimeout = -1; > } > > /* >@@ -1199,6 +1223,8 @@ > options->tun_remote = SSH_TUNID_ANY; > if (options->permit_local_command == -1) > options->permit_local_command = 0; >+ if (options->idletimeout == -1) >+ options->idletimeout = 0; > /* options->local_command should not be set by default */ > /* options->proxy_command should not be set by default */ > /* options->user will be set in the main program if appropriate */ >diff -ru openssh-4.6p1-orig/readconf.h openssh-4.6p1-idletimeout/readconf.h >--- openssh-4.6p1-orig/readconf.h 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/readconf.h 2007-07-10 18:32:51.000000000 +0200 >@@ -121,6 +121,12 @@ > char *local_command; > int permit_local_command; > >+ int idletimeout; /* >+ * If nonzero, the number of seconds >+ * after which idle connections >+ * will be terminated >+ */ >+ > } Options; > > #define SSHCTL_MASTER_NO 0 >diff -ru openssh-4.6p1-orig/servconf.c openssh-4.6p1-idletimeout/servconf.c >--- openssh-4.6p1-orig/servconf.c 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/servconf.c 2007-07-10 18:32:51.000000000 +0200 >@@ -122,6 +122,7 @@ > options->permit_tun = -1; > options->num_permitted_opens = -1; > options->adm_forced_command = NULL; >+ options->idletimeout = -1; > } > > void >@@ -262,6 +263,8 @@ > options->compression = 0; > } > #endif >+ if (options->idletimeout == -1) >+ options->idletimeout=0; > > } > >@@ -293,7 +296,7 @@ > sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, > sMatch, sPermitOpen, sForceCommand, > sUsePrivilegeSeparation, >- sDeprecated, sUnsupported >+ sIdleTimeout, sDeprecated, sUnsupported > } ServerOpCodes; > > #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ >@@ -403,6 +406,7 @@ > { "match", sMatch, SSHCFG_ALL }, > { "permitopen", sPermitOpen, SSHCFG_ALL }, > { "forcecommand", sForceCommand, SSHCFG_ALL }, >+ { "idletimeout", sIdleTimeout, SSHCFG_ALL }, > { NULL, sBadOption, 0 } > }; > >@@ -1268,6 +1272,28 @@ > arg = strdelim(&cp); > break; > >+ case sIdleTimeout: >+ arg = strdelim(&cp); >+ if (!arg || *arg == '\0') >+ fatal("%s line %d: Missing IdleTimeout argument", >+ filename,linenum); >+ options->idletimeout=atoi(arg); >+ switch(arg[strlen(arg)-1]) { >+ case 'w': options->idletimeout*=7; >+ case 'd': options->idletimeout*=24; >+ case 'h': options->idletimeout*=60; >+ case 'm': options->idletimeout*=60; >+ case 's': >+ case '0': case '1': case '2': case '3': >+ case '4': case '5': case '6': case '7': >+ case '8': case '9': >+ break; >+ default: >+ fatal("%s line %d: Invalid IdleTimeout argument", >+ filename,linenum); >+ } >+ break; >+ > default: > fatal("%s line %d: Missing handler for opcode %s (%d)", > filename, linenum, arg, opcode); >diff -ru openssh-4.6p1-orig/servconf.h openssh-4.6p1-idletimeout/servconf.h >--- openssh-4.6p1-orig/servconf.h 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/servconf.h 2007-07-10 18:32:51.000000000 +0200 >@@ -141,6 +141,11 @@ > int permit_tun; > > int num_permitted_opens; >+ int idletimeout; /* >+ * If nonzero, the number of second >+ * after which idle connections >+ * will be terminated >+ */ > } ServerOptions; > > void initialize_server_options(ServerOptions *); >diff -ru openssh-4.6p1-orig/serverloop.c openssh-4.6p1-idletimeout/serverloop.c >--- openssh-4.6p1-orig/serverloop.c 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/serverloop.c 2007-07-10 18:32:51.000000000 +0200 >@@ -277,7 +277,6 @@ > wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, > u_int *nallocp, u_int max_time_milliseconds) > { >- struct timeval tv, *tvp; > int ret; > int client_alive_scheduled = 0; > int program_alive_scheduled = 0; >@@ -348,22 +347,14 @@ > if (max_time_milliseconds == 0 || client_alive_scheduled) > max_time_milliseconds = 100; > >- if (max_time_milliseconds == 0) >- tvp = NULL; >- else { >- tv.tv_sec = max_time_milliseconds / 1000; >- tv.tv_usec = 1000 * (max_time_milliseconds % 1000); >- tvp = &tv; >- } >- >- /* Wait for something to happen, or the timeout to expire. */ >- ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); >+ /* Wait for something to happen, or the timeout to expire. >+ * packet select also implements server idletimeouts for us. */ >+ ret = packet_select((*maxfdp)+1, *readsetp, *writesetp, NULL, >+ max_time_milliseconds); > > if (ret == -1) { > memset(*readsetp, 0, *nallocp); > memset(*writesetp, 0, *nallocp); >- if (errno != EINTR) >- error("select: %.100s", strerror(errno)); > } else { > if (ret == 0 && client_alive_scheduled) > client_alive_check(); >diff -ru openssh-4.6p1-orig/session.c openssh-4.6p1-idletimeout/session.c >--- openssh-4.6p1-orig/session.c 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/session.c 2007-07-10 18:32:51.000000000 +0200 >@@ -238,6 +238,8 @@ > if (!no_port_forwarding_flag && options.allow_tcp_forwarding) > channel_permit_all_opens(); > >+ packet_set_idletimeout(options.idletimeout); >+ > if (compat20) > do_authenticated2(authctxt); > else >diff -ru openssh-4.6p1-orig/ssh.c openssh-4.6p1-idletimeout/ssh.c >--- openssh-4.6p1-orig/ssh.c 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/ssh.c 2007-07-10 18:32:51.000000000 +0200 >@@ -975,6 +975,9 @@ > /* Initiate port forwardings. */ > ssh_init_forwarding(); > >+ /* Start idletimeout timers before we daemonize */ >+ packet_set_idletimeout(options.idletimeout); >+ > /* If requested, let ssh continue in the background. */ > if (fork_after_authentication_flag) > if (daemon(1, 1) < 0) >diff -ru openssh-4.6p1-orig/sshconnect.c openssh-4.6p1-idletimeout/sshconnect.c >--- openssh-4.6p1-orig/sshconnect.c 2007-07-10 12:48:22.000000000 +0200 >+++ openssh-4.6p1-idletimeout/sshconnect.c 2007-07-10 18:32:51.000000000 +0200 >@@ -973,6 +973,7 @@ > ssh_userauth1(local_user, server_user, host, sensitive); > } > xfree(local_user); >+ packet_set_idletimeout(options.idletimeout); > } > > void
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1338
: 1323