diff options
author | djm@openbsd.org <djm@openbsd.org> | 2023-01-17 09:44:48 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2023-01-17 20:50:41 +1100 |
commit | 0293c19807f83141cdf33b443154459f9ee471f6 (patch) | |
tree | b24a66100ba0d93f33bd420e40cb2fb8b30477a5 /serverloop.c | |
parent | 8ec2e3123802d2beeca06c1644b0b647f6d36dab (diff) | |
download | openssh-git-0293c19807f83141cdf33b443154459f9ee471f6.tar.gz |
upstream: Add a sshd_config UnusedConnectionTimeout option to terminate
client connections that have no open channels for some length of time. This
complements the recently-added ChannelTimeout option that terminates inactive
channels after a timeout.
ok markus@
OpenBSD-Commit-ID: ca983be74c0350364c11f8ba3bd692f6f24f5da9
Diffstat (limited to 'serverloop.c')
-rw-r--r-- | serverloop.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/serverloop.c b/serverloop.c index 2d46feb9..6db0916d 100644 --- a/serverloop.c +++ b/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.233 2023/01/06 02:38:23 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.234 2023/01/17 09:44:48 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -172,17 +172,19 @@ wait_until_can_do_something(struct ssh *ssh, int *conn_in_readyp, int *conn_out_readyp) { struct timespec timeout; + char remote_id[512]; int ret; int client_alive_scheduled = 0; u_int p; - /* time we last heard from the client OR sent a keepalive */ - static time_t last_client_time; + time_t now; + static time_t last_client_time, unused_connection_expiry; *conn_in_readyp = *conn_out_readyp = 0; /* Prepare channel poll. First two pollfd entries are reserved */ ptimeout_init(&timeout); channel_prepare_poll(ssh, pfdp, npfd_allocp, npfd_activep, 2, &timeout); + now = monotime(); if (*npfd_activep < 2) fatal_f("bad npfd %u", *npfd_activep); /* shouldn't happen */ if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh)) { @@ -191,6 +193,18 @@ wait_until_can_do_something(struct ssh *ssh, } /* + * If no channels are open and UnusedConnectionTimeout is set, then + * start the clock to terminate the connection. + */ + if (options.unused_connection_timeout != 0) { + if (channel_still_open(ssh) || unused_connection_expiry == 0) { + unused_connection_expiry = now + + options.unused_connection_timeout; + } + ptimeout_deadline_monotime(&timeout, unused_connection_expiry); + } + + /* * if using client_alive, set the max timeout accordingly, * and indicate that this particular timeout was for client * alive by setting the client_alive_scheduled flag. @@ -199,8 +213,9 @@ wait_until_can_do_something(struct ssh *ssh, * analysis more difficult, but we're not doing it yet. */ if (options.client_alive_interval) { + /* Time we last heard from the client OR sent a keepalive */ if (last_client_time == 0) - last_client_time = monotime(); + last_client_time = now; ptimeout_deadline_sec(&timeout, options.client_alive_interval); /* XXX ? deadline_monotime(last_client_time + alive_interval) */ client_alive_scheduled = 1; @@ -237,9 +252,9 @@ wait_until_can_do_something(struct ssh *ssh, *conn_in_readyp = (*pfdp)[0].revents != 0; *conn_out_readyp = (*pfdp)[1].revents != 0; + now = monotime(); /* need to reset after ppoll() */ /* ClientAliveInterval probing */ if (client_alive_scheduled) { - time_t now = monotime(); if (ret == 0 && now > last_client_time + options.client_alive_interval) { /* ppoll timed out and we're due to probe */ @@ -250,6 +265,14 @@ wait_until_can_do_something(struct ssh *ssh, last_client_time = now; } } + + /* UnusedConnectionTimeout handling */ + if (unused_connection_expiry != 0 && + now > unused_connection_expiry && !channel_still_open(ssh)) { + sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); + logit("terminating inactive connection from %s", remote_id); + cleanup_exit(255); + } } /* |