summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@cvs.openbsd.org>2008-06-12 20:38:29 +0000
committerDarren Tucker <dtucker@cvs.openbsd.org>2008-06-12 20:38:29 +0000
commit0370f48a8ef293881ca64834895064e53b53a18d (patch)
treeb815df70f2bab9cc86597d08e1335d64727e7bdf /usr.bin
parent14c885bd14c1b1d32b04af1ff86a395dc107a9bb (diff)
Make keepalive timeouts apply while waiting for a packet, particularly during
key renegotiation (bz #1363). With djm and Matt Day, ok djm@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/misc.c22
-rw-r--r--usr.bin/ssh/misc.h4
-rw-r--r--usr.bin/ssh/packet.c85
-rw-r--r--usr.bin/ssh/packet.h3
-rw-r--r--usr.bin/ssh/sshconnect.c23
-rw-r--r--usr.bin/ssh/sshd.c5
6 files changed, 111 insertions, 31 deletions
diff --git a/usr.bin/ssh/misc.c b/usr.bin/ssh/misc.c
index eacff32f24a..5997dc541f4 100644
--- a/usr.bin/ssh/misc.c
+++ b/usr.bin/ssh/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.67 2008/01/01 08:47:04 dtucker Exp $ */
+/* $OpenBSD: misc.c,v 1.68 2008/06/12 20:38:28 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -812,3 +812,23 @@ put_u16(void *vp, u_int16_t v)
p[0] = (u_char)(v >> 8) & 0xff;
p[1] = (u_char)v & 0xff;
}
+
+void
+ms_subtract_diff(struct timeval *start, int *ms)
+{
+ struct timeval diff, finish;
+
+ gettimeofday(&finish, NULL);
+ timersub(&finish, start, &diff);
+ *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
+}
+
+void
+ms_to_timeval(struct timeval *tv, int ms)
+{
+ if (ms < 0)
+ ms = 0;
+ tv->tv_sec = ms / 1000;
+ tv->tv_usec = (ms % 1000) * 1000;
+}
+
diff --git a/usr.bin/ssh/misc.h b/usr.bin/ssh/misc.h
index be05e806b16..5da170d2fd8 100644
--- a/usr.bin/ssh/misc.h
+++ b/usr.bin/ssh/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.37 2007/12/27 14:22:08 dtucker Exp $ */
+/* $OpenBSD: misc.h,v 1.38 2008/06/12 20:38:28 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -33,6 +33,8 @@ char *tilde_expand_filename(const char *, uid_t);
char *percent_expand(const char *, ...) __attribute__((__sentinel__));
char *tohex(const void *, size_t);
void sanitise_stdfd(void);
+void ms_subtract_diff(struct timeval *, int *);
+void ms_to_timeval(struct timeval *, int);
struct passwd *pwcopy(struct passwd *);
const char *ssh_gai_strerror(int);
diff --git a/usr.bin/ssh/packet.c b/usr.bin/ssh/packet.c
index b72e7a58d98..bc29fa46681 100644
--- a/usr.bin/ssh/packet.c
+++ b/usr.bin/ssh/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.153 2008/05/19 06:14:02 djm Exp $ */
+/* $OpenBSD: packet.c,v 1.154 2008/06/12 20:38:28 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -134,6 +134,9 @@ static int after_authentication = 0;
int keep_alive_timeouts = 0;
+/* Set to the maximum time that we will wait to send or receive a packet */
+static int packet_timeout_ms = -1;
+
/* Session key information for Encryption and MAC */
Newkeys *newkeys[MODE_MAX];
static struct packet_state {
@@ -187,6 +190,19 @@ packet_set_connection(int fd_in, int fd_out)
}
}
+void
+packet_set_timeout(int timeout, int count)
+{
+ if (timeout == 0 || count == 0) {
+ packet_timeout_ms = -1;
+ return;
+ }
+ if ((INT_MAX / 1000) / count < timeout)
+ packet_timeout_ms = INT_MAX;
+ else
+ packet_timeout_ms = timeout * count * 1000;
+}
+
/* Returns 1 if remote host is connected via socket, 0 if not. */
int
@@ -882,10 +898,11 @@ packet_send(void)
int
packet_read_seqnr(u_int32_t *seqnr_p)
{
- int type, len;
+ int type, len, ret, ms_remain;
fd_set *setp;
char buf[8192];
DBG(debug("packet_read()"));
+ struct timeval timeout, start, *timeoutp = NULL;
setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS),
sizeof(fd_mask));
@@ -916,11 +933,34 @@ packet_read_seqnr(u_int32_t *seqnr_p)
sizeof(fd_mask));
FD_SET(connection_in, setp);
+ if (packet_timeout_ms > 0) {
+ ms_remain = packet_timeout_ms;
+ timeoutp = &timeout;
+ }
/* Wait for some data to arrive. */
- while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 &&
- (errno == EAGAIN || errno == EINTR))
- ;
-
+ for (;;) {
+ if (packet_timeout_ms != -1) {
+ ms_to_timeval(&timeout, ms_remain);
+ gettimeofday(&start, NULL);
+ }
+ if ((ret = select(connection_in + 1, setp, NULL,
+ NULL, timeoutp)) >= 0)
+ break;
+ if (errno != EAGAIN && errno != EINTR)
+ break;
+ if (packet_timeout_ms == -1)
+ continue;
+ ms_subtract_diff(&start, &ms_remain);
+ if (ms_remain <= 0) {
+ ret = 0;
+ break;
+ }
+ }
+ if (ret == 0) {
+ logit("Connection to %.200s timed out while "
+ "waiting to read", get_remote_ipaddr());
+ cleanup_exit(255);
+ }
/* Read data from the socket. */
len = read(connection_in, buf, sizeof(buf));
if (len == 0) {
@@ -1443,6 +1483,8 @@ void
packet_write_wait(void)
{
fd_set *setp;
+ int ret, ms_remain;
+ struct timeval start, timeout, *timeoutp = NULL;
setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
sizeof(fd_mask));
@@ -1451,9 +1493,34 @@ packet_write_wait(void)
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))
- ;
+
+ if (packet_timeout_ms > 0) {
+ ms_remain = packet_timeout_ms;
+ timeoutp = &timeout;
+ }
+ for (;;) {
+ if (packet_timeout_ms != -1) {
+ ms_to_timeval(&timeout, ms_remain);
+ gettimeofday(&start, NULL);
+ }
+ if ((ret = select(connection_out + 1, NULL, setp,
+ NULL, timeoutp)) >= 0)
+ break;
+ if (errno != EAGAIN && errno != EINTR)
+ break;
+ if (packet_timeout_ms == -1)
+ continue;
+ ms_subtract_diff(&start, &ms_remain);
+ if (ms_remain <= 0) {
+ ret = 0;
+ break;
+ }
+ }
+ if (ret == 0) {
+ logit("Connection to %.200s timed out while "
+ "waiting to write", get_remote_ipaddr());
+ cleanup_exit(255);
+ }
packet_write_poll();
}
xfree(setp);
diff --git a/usr.bin/ssh/packet.h b/usr.bin/ssh/packet.h
index 927e0831ce2..fd4e1ac7a72 100644
--- a/usr.bin/ssh/packet.h
+++ b/usr.bin/ssh/packet.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.47 2008/05/08 06:59:01 markus Exp $ */
+/* $OpenBSD: packet.h,v 1.48 2008/06/12 20:38:28 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -21,6 +21,7 @@
#include <openssl/bn.h>
void packet_set_connection(int, int);
+void packet_set_timeout(int, int);
void packet_set_nonblocking(void);
int packet_get_connection_in(void);
int packet_get_connection_out(void);
diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c
index 0328634dd0d..56a3c83d951 100644
--- a/usr.bin/ssh/sshconnect.c
+++ b/usr.bin/ssh/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.206 2008/06/12 00:13:55 grunk Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.207 2008/06/12 20:38:28 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -64,23 +64,6 @@ extern pid_t proxy_command_pid;
static int show_other_keys(const char *, Key *);
static void warn_changed_key(Key *);
-static void
-ms_subtract_diff(struct timeval *start, int *ms)
-{
- struct timeval diff, finish;
-
- gettimeofday(&finish, NULL);
- timersub(&finish, start, &diff);
- *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
-}
-
-static void
-ms_to_timeval(struct timeval *tv, int ms)
-{
- tv->tv_sec = ms / 1000;
- tv->tv_usec = (ms % 1000) * 1000;
-}
-
/*
* Connect to the given ssh server using a proxy command.
*/
@@ -165,6 +148,8 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
/* Set the connection file descriptors. */
packet_set_connection(pout[0], pin[1]);
+ packet_set_timeout(options.server_alive_interval,
+ options.server_alive_count_max);
/* Indicate OK return */
return 0;
@@ -409,6 +394,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
/* Set the connection. */
packet_set_connection(sock, sock);
+ packet_set_timeout(options.server_alive_interval,
+ options.server_alive_count_max);
return 0;
}
diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c
index 6f9fa702a90..18dac283595 100644
--- a/usr.bin/ssh/sshd.c
+++ b/usr.bin/ssh/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.359 2008/06/10 08:17:40 jmc Exp $ */
+/* $OpenBSD: sshd.c,v 1.360 2008/06/12 20:38:28 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1765,6 +1765,9 @@ main(int ac, char **av)
destroy_sensitive_data();
}
+ packet_set_timeout(options.client_alive_interval,
+ options.client_alive_count_max);
+
/* Start session. */
do_authenticated(authctxt);