summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--clientloop.c45
-rw-r--r--clientloop.h4
-rw-r--r--readconf.c21
-rw-r--r--readconf.h4
-rw-r--r--scp.14
-rw-r--r--sftp.14
-rw-r--r--ssh.14
-rw-r--r--ssh.c9
-rw-r--r--ssh_config.538
10 files changed, 117 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 39e8042da..3593792c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -23,6 +23,12 @@
23 - markus@cvs.openbsd.org 2003/12/14 12:37:21 23 - markus@cvs.openbsd.org 2003/12/14 12:37:21
24 [ssh_config.5] 24 [ssh_config.5]
25 we don't support GSS KEX; from Simon Wilkinson 25 we don't support GSS KEX; from Simon Wilkinson
26 - markus@cvs.openbsd.org 2003/12/16 15:49:51
27 [clientloop.c clientloop.h readconf.c readconf.h scp.1 sftp.1 ssh.1]
28 [ssh.c ssh_config.5]
29 application layer keep alive (ServerAliveInterval ServerAliveCountMax)
30 for ssh(1), similar to the sshd(8) option; ok beck@; with help from
31 jmc and dtucker@
26 32
2720031209 3320031209
28 - (dtucker) OpenBSD CVS Sync 34 - (dtucker) OpenBSD CVS Sync
@@ -1592,4 +1598,4 @@
1592 - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. 1598 - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
1593 Report from murple@murple.net, diagnosis from dtucker@zip.com.au 1599 Report from murple@murple.net, diagnosis from dtucker@zip.com.au
1594 1600
1595$Id: ChangeLog,v 1.3145 2003/12/17 05:32:23 djm Exp $ 1601$Id: ChangeLog,v 1.3146 2003/12/17 05:33:10 djm Exp $
diff --git a/clientloop.c b/clientloop.c
index 67b9dfcea..626b29a5a 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
59 */ 59 */
60 60
61#include "includes.h" 61#include "includes.h"
62RCSID("$OpenBSD: clientloop.c,v 1.116 2003/12/09 23:45:32 dtucker Exp $"); 62RCSID("$OpenBSD: clientloop.c,v 1.117 2003/12/16 15:49:51 markus Exp $");
63 63
64#include "ssh.h" 64#include "ssh.h"
65#include "ssh1.h" 65#include "ssh1.h"
@@ -127,6 +127,7 @@ static int connection_in; /* Connection to server (input). */
127static int connection_out; /* Connection to server (output). */ 127static int connection_out; /* Connection to server (output). */
128static int need_rekeying; /* Set to non-zero if rekeying is requested. */ 128static int need_rekeying; /* Set to non-zero if rekeying is requested. */
129static int session_closed = 0; /* In SSH2: login session closed. */ 129static int session_closed = 0; /* In SSH2: login session closed. */
130static int server_alive_timeouts = 0;
130 131
131static void client_init_dispatch(void); 132static void client_init_dispatch(void);
132int session_ident = -1; 133int session_ident = -1;
@@ -313,6 +314,24 @@ client_check_window_change(void)
313 } 314 }
314} 315}
315 316
317static void
318client_global_request_reply(int type, u_int32_t seq, void *ctxt)
319{
320 server_alive_timeouts = 0;
321 client_global_request_reply_fwd(type, seq, ctxt);
322}
323
324static void
325server_alive_check(void)
326{
327 if (++server_alive_timeouts > options.server_alive_count_max)
328 packet_disconnect("Timeout, server not responding.");
329 packet_start(SSH2_MSG_GLOBAL_REQUEST);
330 packet_put_cstring("keepalive@openssh.com");
331 packet_put_char(1); /* boolean: want reply */
332 packet_send();
333}
334
316/* 335/*
317 * Waits until the client can do something (some data becomes available on 336 * Waits until the client can do something (some data becomes available on
318 * one of the file descriptors). 337 * one of the file descriptors).
@@ -322,6 +341,9 @@ static void
322client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, 341client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
323 int *maxfdp, int *nallocp, int rekeying) 342 int *maxfdp, int *nallocp, int rekeying)
324{ 343{
344 struct timeval tv, *tvp;
345 int ret;
346
325 /* Add any selections by the channel mechanism. */ 347 /* Add any selections by the channel mechanism. */
326 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); 348 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying);
327 349
@@ -363,13 +385,18 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
363 /* 385 /*
364 * Wait for something to happen. This will suspend the process until 386 * Wait for something to happen. This will suspend the process until
365 * some selected descriptor can be read, written, or has some other 387 * some selected descriptor can be read, written, or has some other
366 * event pending. Note: if you want to implement SSH_MSG_IGNORE 388 * event pending.
367 * messages to fool traffic analysis, this might be the place to do
368 * it: just have a random timeout for the select, and send a random
369 * SSH_MSG_IGNORE packet when the timeout expires.
370 */ 389 */
371 390
372 if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) { 391 if (options.server_alive_interval == 0 || !compat20)
392 tvp = NULL;
393 else {
394 tv.tv_sec = options.server_alive_interval;
395 tv.tv_usec = 0;
396 tvp = &tv;
397 }
398 ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
399 if (ret < 0) {
373 char buf[100]; 400 char buf[100];
374 401
375 /* 402 /*
@@ -386,7 +413,8 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
386 snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); 413 snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
387 buffer_append(&stderr_buffer, buf, strlen(buf)); 414 buffer_append(&stderr_buffer, buf, strlen(buf));
388 quit_pending = 1; 415 quit_pending = 1;
389 } 416 } else if (ret == 0)
417 server_alive_check();
390} 418}
391 419
392static void 420static void
@@ -1365,7 +1393,8 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt)
1365 1393
1366 rtype = packet_get_string(NULL); 1394 rtype = packet_get_string(NULL);
1367 want_reply = packet_get_char(); 1395 want_reply = packet_get_char();
1368 debug("client_input_global_request: rtype %s want_reply %d", rtype, want_reply); 1396 debug("client_input_global_request: rtype %s want_reply %d",
1397 rtype, want_reply);
1369 if (want_reply) { 1398 if (want_reply) {
1370 packet_start(success ? 1399 packet_start(success ?
1371 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 1400 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
diff --git a/clientloop.h b/clientloop.h
index 8056a40c3..56af06bc1 100644
--- a/clientloop.h
+++ b/clientloop.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.h,v 1.7 2002/04/22 21:04:52 markus Exp $ */ 1/* $OpenBSD: clientloop.h,v 1.8 2003/12/16 15:49:51 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -37,4 +37,4 @@
37 37
38/* Client side main loop for the interactive session. */ 38/* Client side main loop for the interactive session. */
39int client_loop(int, int, int); 39int client_loop(int, int, int);
40void client_global_request_reply(int type, u_int32_t seq, void *ctxt); 40void client_global_request_reply_fwd(int, u_int32_t, void *);
diff --git a/readconf.c b/readconf.c
index cd2c81443..2591e0dba 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.126 2003/12/09 21:53:36 markus Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.127 2003/12/16 15:49:51 markus Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -105,6 +105,7 @@ typedef enum {
105 oClearAllForwardings, oNoHostAuthenticationForLocalhost, 105 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
106 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 106 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
107 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 107 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
108 oServerAliveInterval, oServerAliveCountMax,
108 oDeprecated, oUnsupported 109 oDeprecated, oUnsupported
109} OpCodes; 110} OpCodes;
110 111
@@ -189,6 +190,8 @@ static struct {
189 { "rekeylimit", oRekeyLimit }, 190 { "rekeylimit", oRekeyLimit },
190 { "connecttimeout", oConnectTimeout }, 191 { "connecttimeout", oConnectTimeout },
191 { "addressfamily", oAddressFamily }, 192 { "addressfamily", oAddressFamily },
193 { "serveraliveinterval", oServerAliveInterval },
194 { "serveralivecountmax", oServerAliveCountMax },
192 { NULL, oBadOption } 195 { NULL, oBadOption }
193}; 196};
194 197
@@ -307,7 +310,7 @@ process_config_line(Options *options, const char *host,
307 /* NOTREACHED */ 310 /* NOTREACHED */
308 case oConnectTimeout: 311 case oConnectTimeout:
309 intptr = &options->connection_timeout; 312 intptr = &options->connection_timeout;
310/* parse_time: */ 313parse_time:
311 arg = strdelim(&s); 314 arg = strdelim(&s);
312 if (!arg || *arg == '\0') 315 if (!arg || *arg == '\0')
313 fatal("%s line %d: missing time value.", 316 fatal("%s line %d: missing time value.",
@@ -733,6 +736,14 @@ parse_int:
733 intptr = &options->enable_ssh_keysign; 736 intptr = &options->enable_ssh_keysign;
734 goto parse_flag; 737 goto parse_flag;
735 738
739 case oServerAliveInterval:
740 intptr = &options->server_alive_interval;
741 goto parse_time;
742
743 case oServerAliveCountMax:
744 intptr = &options->server_alive_count_max;
745 goto parse_int;
746
736 case oDeprecated: 747 case oDeprecated:
737 debug("%s line %d: Deprecated option \"%s\"", 748 debug("%s line %d: Deprecated option \"%s\"",
738 filename, linenum, keyword); 749 filename, linenum, keyword);
@@ -860,6 +871,8 @@ initialize_options(Options * options)
860 options->no_host_authentication_for_localhost = - 1; 871 options->no_host_authentication_for_localhost = - 1;
861 options->rekey_limit = - 1; 872 options->rekey_limit = - 1;
862 options->verify_host_key_dns = -1; 873 options->verify_host_key_dns = -1;
874 options->server_alive_interval = -1;
875 options->server_alive_count_max = -1;
863} 876}
864 877
865/* 878/*
@@ -974,6 +987,10 @@ fill_default_options(Options * options)
974 options->rekey_limit = 0; 987 options->rekey_limit = 0;
975 if (options->verify_host_key_dns == -1) 988 if (options->verify_host_key_dns == -1)
976 options->verify_host_key_dns = 0; 989 options->verify_host_key_dns = 0;
990 if (options->server_alive_interval == -1)
991 options->server_alive_interval = 0;
992 if (options->server_alive_count_max == -1)
993 options->server_alive_count_max = 3;
977 /* options->proxy_command should not be set by default */ 994 /* options->proxy_command should not be set by default */
978 /* options->user will be set in the main program if appropriate */ 995 /* options->user will be set in the main program if appropriate */
979 /* options->hostname will be set in the main program if appropriate */ 996 /* options->hostname will be set in the main program if appropriate */
diff --git a/readconf.h b/readconf.h
index f2a859fbe..3f27af961 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.58 2003/12/09 21:53:36 markus Exp $ */ 1/* $OpenBSD: readconf.h,v 1.59 2003/12/16 15:49:51 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -100,6 +100,8 @@ typedef struct {
100 int enable_ssh_keysign; 100 int enable_ssh_keysign;
101 int rekey_limit; 101 int rekey_limit;
102 int no_host_authentication_for_localhost; 102 int no_host_authentication_for_localhost;
103 int server_alive_interval;
104 int server_alive_count_max;
103} Options; 105} Options;
104 106
105 107
diff --git a/scp.1 b/scp.1
index cbebb949a..f5ca1e45a 100644
--- a/scp.1
+++ b/scp.1
@@ -9,7 +9,7 @@
9.\" 9.\"
10.\" Created: Sun May 7 00:14:37 1995 ylo 10.\" Created: Sun May 7 00:14:37 1995 ylo
11.\" 11.\"
12.\" $OpenBSD: scp.1,v 1.31 2003/12/09 21:53:36 markus Exp $ 12.\" $OpenBSD: scp.1,v 1.32 2003/12/16 15:49:51 markus Exp $
13.\" 13.\"
14.Dd September 25, 1999 14.Dd September 25, 1999
15.Dt SCP 1 15.Dt SCP 1
@@ -149,6 +149,8 @@ For full details of the options listed below, and their possible values, see
149.It PubkeyAuthentication 149.It PubkeyAuthentication
150.It RhostsRSAAuthentication 150.It RhostsRSAAuthentication
151.It RSAAuthentication 151.It RSAAuthentication
152.It ServerAliveInterval
153.It ServerAliveCountMax
152.It SmartcardDevice 154.It SmartcardDevice
153.It StrictHostKeyChecking 155.It StrictHostKeyChecking
154.It TCPKeepAlive 156.It TCPKeepAlive
diff --git a/sftp.1 b/sftp.1
index 91a288dfc..8563e2bdd 100644
--- a/sftp.1
+++ b/sftp.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: sftp.1,v 1.48 2003/12/09 21:53:37 markus Exp $ 1.\" $OpenBSD: sftp.1,v 1.49 2003/12/16 15:49:51 markus Exp $
2.\" 2.\"
3.\" Copyright (c) 2001 Damien Miller. All rights reserved. 3.\" Copyright (c) 2001 Damien Miller. All rights reserved.
4.\" 4.\"
@@ -170,6 +170,8 @@ For full details of the options listed below, and their possible values, see
170.It PubkeyAuthentication 170.It PubkeyAuthentication
171.It RhostsRSAAuthentication 171.It RhostsRSAAuthentication
172.It RSAAuthentication 172.It RSAAuthentication
173.It ServerAliveInterval
174.It ServerAliveCountMax
173.It SmartcardDevice 175.It SmartcardDevice
174.It StrictHostKeyChecking 176.It StrictHostKeyChecking
175.It TCPKeepAlive 177.It TCPKeepAlive
diff --git a/ssh.1 b/ssh.1
index 33521268b..e2cd5d343 100644
--- a/ssh.1
+++ b/ssh.1
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh.1,v 1.180 2003/12/09 21:53:37 markus Exp $ 37.\" $OpenBSD: ssh.1,v 1.181 2003/12/16 15:49:51 markus Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH 1 39.Dt SSH 1
40.Os 40.Os
@@ -648,6 +648,8 @@ For full details of the options listed below, and their possible values, see
648.It RemoteForward 648.It RemoteForward
649.It RhostsRSAAuthentication 649.It RhostsRSAAuthentication
650.It RSAAuthentication 650.It RSAAuthentication
651.It ServerAliveInterval
652.It ServerAliveCountMax
651.It SmartcardDevice 653.It SmartcardDevice
652.It StrictHostKeyChecking 654.It StrictHostKeyChecking
653.It TCPKeepAlive 655.It TCPKeepAlive
diff --git a/ssh.c b/ssh.c
index 222aaab7f..da390c12d 100644
--- a/ssh.c
+++ b/ssh.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: ssh.c,v 1.205 2003/12/09 17:30:05 markus Exp $"); 43RCSID("$OpenBSD: ssh.c,v 1.206 2003/12/16 15:49:51 markus Exp $");
44 44
45#include <openssl/evp.h> 45#include <openssl/evp.h>
46#include <openssl/err.h> 46#include <openssl/err.h>
@@ -1029,16 +1029,13 @@ client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
1029} 1029}
1030 1030
1031void 1031void
1032client_global_request_reply(int type, u_int32_t seq, void *ctxt) 1032client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
1033{ 1033{
1034 int i; 1034 int i;
1035 1035
1036 i = client_global_request_id++; 1036 i = client_global_request_id++;
1037 if (i >= options.num_remote_forwards) { 1037 if (i >= options.num_remote_forwards)
1038 debug("client_global_request_reply: too many replies %d > %d",
1039 i, options.num_remote_forwards);
1040 return; 1038 return;
1041 }
1042 debug("remote forward %s for: listen %d, connect %s:%d", 1039 debug("remote forward %s for: listen %d, connect %s:%d",
1043 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", 1040 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
1044 options.remote_forwards[i].port, 1041 options.remote_forwards[i].port,
diff --git a/ssh_config.5 b/ssh_config.5
index cb26eab69..210da059b 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh_config.5,v 1.27 2003/12/14 12:37:21 markus Exp $ 37.\" $OpenBSD: ssh_config.5,v 1.28 2003/12/16 15:49:51 markus Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH_CONFIG 5 39.Dt SSH_CONFIG 5
40.Os 40.Os
@@ -552,6 +552,42 @@ running.
552The default is 552The default is
553.Dq yes . 553.Dq yes .
554Note that this option applies to protocol version 1 only. 554Note that this option applies to protocol version 1 only.
555.It Cm ServerAliveInterval
556Sets a timeout interval in seconds after which if no data has been received
557from the server,
558.Nm ssh
559will send a message through the encrypted
560channel to request a response from the server.
561The default
562is 0, indicating that these messages will not be sent to the server.
563This option applies to protocol version 2 only.
564.It Cm ServerAliveCountMax
565Sets the number of server alive messages (see above) which may be
566sent without
567.Nm ssh
568receiving any messages back from the server.
569If this threshold is reached while server alive messages are being sent,
570.Nm ssh
571will disconnect from the server, terminating the session.
572It is important to note that the use of server alive messages is very
573different from
574.Cm TCPKeepAlive
575(below).
576The server alive messages are sent through the encrypted channel
577and therefore will not be spoofable.
578The TCP keepalive option enabled by
579.Cm TCPKeepAlive
580is spoofable.
581The server alive mechanism is valuable when the client or
582server depend on knowing when a connection has become inactive.
583.Pp
584The default value is 3.
585If, for example,
586.Cm ServerAliveInterval
587(above) is set to 15, and
588.Cm ServerAliveCountMax
589is left at the default, if the server becomes unresponsive ssh
590will disconnect after approximately 45 seconds.
555.It Cm SmartcardDevice 591.It Cm SmartcardDevice
556Specifies which smartcard device to use. 592Specifies which smartcard device to use.
557The argument to this keyword is the device 593The argument to this keyword is the device