[clientloop.c clientloop.h readconf.c readconf.h scp.1 sftp.1 ssh.1]
     [ssh.c ssh_config.5]
     application layer keep alive (ServerAliveInterval ServerAliveCountMax)
     for ssh(1), similar to the sshd(8) option; ok beck@; with help from
     jmc and dtucker@
This commit is contained in:
Damien Miller 2003-12-17 16:33:10 +11:00
Родитель baafb981a4
Коммит 509b0107f0
10 изменённых файлов: 117 добавлений и 24 удалений

Просмотреть файл

@ -23,6 +23,12 @@
- markus@cvs.openbsd.org 2003/12/14 12:37:21
[ssh_config.5]
we don't support GSS KEX; from Simon Wilkinson
- markus@cvs.openbsd.org 2003/12/16 15:49:51
[clientloop.c clientloop.h readconf.c readconf.h scp.1 sftp.1 ssh.1]
[ssh.c ssh_config.5]
application layer keep alive (ServerAliveInterval ServerAliveCountMax)
for ssh(1), similar to the sshd(8) option; ok beck@; with help from
jmc and dtucker@
20031209
- (dtucker) OpenBSD CVS Sync
@ -1592,4 +1598,4 @@
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
$Id: ChangeLog,v 1.3145 2003/12/17 05:32:23 djm Exp $
$Id: ChangeLog,v 1.3146 2003/12/17 05:33:10 djm Exp $

Просмотреть файл

@ -59,7 +59,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: clientloop.c,v 1.116 2003/12/09 23:45:32 dtucker Exp $");
RCSID("$OpenBSD: clientloop.c,v 1.117 2003/12/16 15:49:51 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@ -127,6 +127,7 @@ static int connection_in; /* Connection to server (input). */
static int connection_out; /* Connection to server (output). */
static int need_rekeying; /* Set to non-zero if rekeying is requested. */
static int session_closed = 0; /* In SSH2: login session closed. */
static int server_alive_timeouts = 0;
static void client_init_dispatch(void);
int session_ident = -1;
@ -313,6 +314,24 @@ client_check_window_change(void)
}
}
static void
client_global_request_reply(int type, u_int32_t seq, void *ctxt)
{
server_alive_timeouts = 0;
client_global_request_reply_fwd(type, seq, ctxt);
}
static void
server_alive_check(void)
{
if (++server_alive_timeouts > options.server_alive_count_max)
packet_disconnect("Timeout, server not responding.");
packet_start(SSH2_MSG_GLOBAL_REQUEST);
packet_put_cstring("keepalive@openssh.com");
packet_put_char(1); /* boolean: want reply */
packet_send();
}
/*
* Waits until the client can do something (some data becomes available on
* one of the file descriptors).
@ -322,6 +341,9 @@ static void
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);
@ -363,13 +385,18 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
/*
* 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.
*/
if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) {
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);
if (ret < 0) {
char buf[100];
/*
@ -386,7 +413,8 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
buffer_append(&stderr_buffer, buf, strlen(buf));
quit_pending = 1;
}
} else if (ret == 0)
server_alive_check();
}
static void
@ -1365,7 +1393,8 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt)
rtype = packet_get_string(NULL);
want_reply = packet_get_char();
debug("client_input_global_request: rtype %s want_reply %d", rtype, want_reply);
debug("client_input_global_request: rtype %s want_reply %d",
rtype, want_reply);
if (want_reply) {
packet_start(success ?
SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);

Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.h,v 1.7 2002/04/22 21:04:52 markus Exp $ */
/* $OpenBSD: clientloop.h,v 1.8 2003/12/16 15:49:51 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -37,4 +37,4 @@
/* Client side main loop for the interactive session. */
int client_loop(int, int, int);
void client_global_request_reply(int type, u_int32_t seq, void *ctxt);
void client_global_request_reply_fwd(int, u_int32_t, void *);

Просмотреть файл

@ -12,7 +12,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: readconf.c,v 1.126 2003/12/09 21:53:36 markus Exp $");
RCSID("$OpenBSD: readconf.c,v 1.127 2003/12/16 15:49:51 markus Exp $");
#include "ssh.h"
#include "xmalloc.h"
@ -105,6 +105,7 @@ typedef enum {
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
oServerAliveInterval, oServerAliveCountMax,
oDeprecated, oUnsupported
} OpCodes;
@ -189,6 +190,8 @@ static struct {
{ "rekeylimit", oRekeyLimit },
{ "connecttimeout", oConnectTimeout },
{ "addressfamily", oAddressFamily },
{ "serveraliveinterval", oServerAliveInterval },
{ "serveralivecountmax", oServerAliveCountMax },
{ NULL, oBadOption }
};
@ -307,7 +310,7 @@ process_config_line(Options *options, const char *host,
/* NOTREACHED */
case oConnectTimeout:
intptr = &options->connection_timeout;
/* parse_time: */
parse_time:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%s line %d: missing time value.",
@ -733,6 +736,14 @@ parse_int:
intptr = &options->enable_ssh_keysign;
goto parse_flag;
case oServerAliveInterval:
intptr = &options->server_alive_interval;
goto parse_time;
case oServerAliveCountMax:
intptr = &options->server_alive_count_max;
goto parse_int;
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
@ -860,6 +871,8 @@ initialize_options(Options * options)
options->no_host_authentication_for_localhost = - 1;
options->rekey_limit = - 1;
options->verify_host_key_dns = -1;
options->server_alive_interval = -1;
options->server_alive_count_max = -1;
}
/*
@ -974,6 +987,10 @@ fill_default_options(Options * options)
options->rekey_limit = 0;
if (options->verify_host_key_dns == -1)
options->verify_host_key_dns = 0;
if (options->server_alive_interval == -1)
options->server_alive_interval = 0;
if (options->server_alive_count_max == -1)
options->server_alive_count_max = 3;
/* options->proxy_command should not be set by default */
/* options->user will be set in the main program if appropriate */
/* options->hostname will be set in the main program if appropriate */

Просмотреть файл

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.h,v 1.58 2003/12/09 21:53:36 markus Exp $ */
/* $OpenBSD: readconf.h,v 1.59 2003/12/16 15:49:51 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -100,6 +100,8 @@ typedef struct {
int enable_ssh_keysign;
int rekey_limit;
int no_host_authentication_for_localhost;
int server_alive_interval;
int server_alive_count_max;
} Options;

4
scp.1
Просмотреть файл

@ -9,7 +9,7 @@
.\"
.\" Created: Sun May 7 00:14:37 1995 ylo
.\"
.\" $OpenBSD: scp.1,v 1.31 2003/12/09 21:53:36 markus Exp $
.\" $OpenBSD: scp.1,v 1.32 2003/12/16 15:49:51 markus Exp $
.\"
.Dd September 25, 1999
.Dt SCP 1
@ -149,6 +149,8 @@ For full details of the options listed below, and their possible values, see
.It PubkeyAuthentication
.It RhostsRSAAuthentication
.It RSAAuthentication
.It ServerAliveInterval
.It ServerAliveCountMax
.It SmartcardDevice
.It StrictHostKeyChecking
.It TCPKeepAlive

4
sftp.1
Просмотреть файл

@ -1,4 +1,4 @@
.\" $OpenBSD: sftp.1,v 1.48 2003/12/09 21:53:37 markus Exp $
.\" $OpenBSD: sftp.1,v 1.49 2003/12/16 15:49:51 markus Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@ -170,6 +170,8 @@ For full details of the options listed below, and their possible values, see
.It PubkeyAuthentication
.It RhostsRSAAuthentication
.It RSAAuthentication
.It ServerAliveInterval
.It ServerAliveCountMax
.It SmartcardDevice
.It StrictHostKeyChecking
.It TCPKeepAlive

4
ssh.1
Просмотреть файл

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh.1,v 1.180 2003/12/09 21:53:37 markus Exp $
.\" $OpenBSD: ssh.1,v 1.181 2003/12/16 15:49:51 markus Exp $
.Dd September 25, 1999
.Dt SSH 1
.Os
@ -648,6 +648,8 @@ For full details of the options listed below, and their possible values, see
.It RemoteForward
.It RhostsRSAAuthentication
.It RSAAuthentication
.It ServerAliveInterval
.It ServerAliveCountMax
.It SmartcardDevice
.It StrictHostKeyChecking
.It TCPKeepAlive

9
ssh.c
Просмотреть файл

@ -40,7 +40,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh.c,v 1.205 2003/12/09 17:30:05 markus Exp $");
RCSID("$OpenBSD: ssh.c,v 1.206 2003/12/16 15:49:51 markus Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@ -1029,16 +1029,13 @@ client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
}
void
client_global_request_reply(int type, u_int32_t seq, void *ctxt)
client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
{
int i;
i = client_global_request_id++;
if (i >= options.num_remote_forwards) {
debug("client_global_request_reply: too many replies %d > %d",
i, options.num_remote_forwards);
if (i >= options.num_remote_forwards)
return;
}
debug("remote forward %s for: listen %d, connect %s:%d",
type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
options.remote_forwards[i].port,

Просмотреть файл

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh_config.5,v 1.27 2003/12/14 12:37:21 markus Exp $
.\" $OpenBSD: ssh_config.5,v 1.28 2003/12/16 15:49:51 markus Exp $
.Dd September 25, 1999
.Dt SSH_CONFIG 5
.Os
@ -552,6 +552,42 @@ running.
The default is
.Dq yes .
Note that this option applies to protocol version 1 only.
.It Cm ServerAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the server,
.Nm ssh
will send a message through the encrypted
channel to request a response from the server.
The default
is 0, indicating that these messages will not be sent to the server.
This option applies to protocol version 2 only.
.It Cm ServerAliveCountMax
Sets the number of server alive messages (see above) which may be
sent without
.Nm ssh
receiving any messages back from the server.
If this threshold is reached while server alive messages are being sent,
.Nm ssh
will disconnect from the server, terminating the session.
It is important to note that the use of server alive messages is very
different from
.Cm TCPKeepAlive
(below).
The server alive messages are sent through the encrypted channel
and therefore will not be spoofable.
The TCP keepalive option enabled by
.Cm TCPKeepAlive
is spoofable.
The server alive mechanism is valuable when the client or
server depend on knowing when a connection has become inactive.
.Pp
The default value is 3.
If, for example,
.Cm ServerAliveInterval
(above) is set to 15, and
.Cm ServerAliveCountMax
is left at the default, if the server becomes unresponsive ssh
will disconnect after approximately 45 seconds.
.It Cm SmartcardDevice
Specifies which smartcard device to use.
The argument to this keyword is the device