summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@cvs.openbsd.org>2013-05-16 02:00:35 +0000
committerDarren Tucker <dtucker@cvs.openbsd.org>2013-05-16 02:00:35 +0000
commit722d0265fc441f3b3c72fe882be8d4daf4b76180 (patch)
tree804ae16b71f4df528f2cb6e90fd2ff0e57519822 /usr.bin
parentcfd6bfe7193d6d95e8ce3e2a98ca29537a900422 (diff)
Add an optional second argument to RekeyLimit in the client to allow
rekeying based on elapsed time in addition to amount of traffic. with djm@ jmc@, ok djm
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/clientloop.c23
-rw-r--r--usr.bin/ssh/packet.c33
-rw-r--r--usr.bin/ssh/packet.h5
-rw-r--r--usr.bin/ssh/readconf.c80
-rw-r--r--usr.bin/ssh/readconf.h3
-rw-r--r--usr.bin/ssh/ssh_config3
-rw-r--r--usr.bin/ssh/ssh_config.520
-rw-r--r--usr.bin/ssh/sshconnect2.c7
8 files changed, 123 insertions, 51 deletions
diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c
index 48da1e9b601..f26302226f9 100644
--- a/usr.bin/ssh/clientloop.c
+++ b/usr.bin/ssh/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.248 2013/01/02 00:32:07 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.249 2013/05/16 02:00:34 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -575,7 +575,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
{
struct timeval tv, *tvp;
int timeout_secs;
- time_t minwait_secs = 0;
+ time_t minwait_secs = 0, server_alive_time = 0, now = time(NULL);
int ret;
/* Add any selections by the channel mechanism. */
@@ -624,12 +624,16 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
*/
timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */
- if (options.server_alive_interval > 0 && compat20)
+ if (options.server_alive_interval > 0 && compat20) {
timeout_secs = options.server_alive_interval;
+ server_alive_time = now + options.server_alive_interval;
+ }
+ if (options.rekey_interval > 0 && compat20 && !rekeying)
+ timeout_secs = MIN(timeout_secs, packet_get_rekey_timeout());
set_control_persist_exit_time();
if (control_persist_exit_time > 0) {
timeout_secs = MIN(timeout_secs,
- control_persist_exit_time - time(NULL));
+ control_persist_exit_time - now);
if (timeout_secs < 0)
timeout_secs = 0;
}
@@ -661,8 +665,15 @@ 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();
+ } else if (ret == 0) {
+ /*
+ * Timeout. Could have been either keepalive or rekeying.
+ * Keepalive we check here, rekeying is checked in clientloop.
+ */
+ if (server_alive_time != 0 && server_alive_time <= time(NULL))
+ server_alive_check();
+ }
+
}
static void
diff --git a/usr.bin/ssh/packet.c b/usr.bin/ssh/packet.c
index b8fb80ba5d2..4291bc8c1f9 100644
--- a/usr.bin/ssh/packet.c
+++ b/usr.bin/ssh/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.183 2013/04/19 01:06:50 djm Exp $ */
+/* $OpenBSD: packet.c,v 1.184 2013/05/16 02:00:34 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -54,6 +54,7 @@
#include <string.h>
#include <unistd.h>
#include <signal.h>
+#include <time.h>
#include "xmalloc.h"
#include "buffer.h"
@@ -161,9 +162,14 @@ struct session_state {
Newkeys *newkeys[MODE_MAX];
struct packet_state p_read, p_send;
+ /* Volume-based rekeying */
u_int64_t max_blocks_in, max_blocks_out;
u_int32_t rekey_limit;
+ /* Time-based rekeying */
+ time_t rekey_interval; /* how often in seconds */
+ time_t rekey_time; /* time of last rekeying */
+
/* Session key for protocol v1 */
u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
u_int ssh1_keylen;
@@ -998,6 +1004,7 @@ packet_send2(void)
/* after a NEWKEYS message we can send the complete queue */
if (type == SSH2_MSG_NEWKEYS) {
active_state->rekeying = 0;
+ active_state->rekey_time = time(NULL);
while ((p = TAILQ_FIRST(&active_state->outgoing))) {
type = p->type;
debug("dequeue packet: %u", type);
@@ -1911,13 +1918,33 @@ packet_need_rekeying(void)
(active_state->max_blocks_out &&
(active_state->p_send.blocks > active_state->max_blocks_out)) ||
(active_state->max_blocks_in &&
- (active_state->p_read.blocks > active_state->max_blocks_in));
+ (active_state->p_read.blocks > active_state->max_blocks_in)) ||
+ (active_state->rekey_interval != 0 && active_state->rekey_time +
+ active_state->rekey_interval <= time(NULL));
}
void
-packet_set_rekey_limit(u_int32_t bytes)
+packet_set_rekey_limits(u_int32_t bytes, time_t seconds)
{
+ debug3("rekey after %lld bytes, %d seconds", (long long)bytes,
+ (int)seconds);
active_state->rekey_limit = bytes;
+ active_state->rekey_interval = seconds;
+ /*
+ * We set the time here so that in post-auth privsep slave we count
+ * from the completion of the authentication.
+ */
+ active_state->rekey_time = time(NULL);
+}
+
+time_t
+packet_get_rekey_timeout(void)
+{
+ time_t seconds;
+
+ seconds = active_state->rekey_time + active_state->rekey_interval -
+ time(NULL);
+ return (seconds < 0 ? 0 : seconds);
}
void
diff --git a/usr.bin/ssh/packet.h b/usr.bin/ssh/packet.h
index f2f009ef9ab..0941b5d54ab 100644
--- a/usr.bin/ssh/packet.h
+++ b/usr.bin/ssh/packet.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.57 2012/01/25 19:40:09 markus Exp $ */
+/* $OpenBSD: packet.h,v 1.58 2013/05/16 02:00:34 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -109,7 +109,8 @@ do { \
} while (0)
int packet_need_rekeying(void);
-void packet_set_rekey_limit(u_int32_t);
+void packet_set_rekey_limits(u_int32_t, time_t);
+time_t packet_get_rekey_timeout(void);
void packet_backup_state(void);
void packet_restore_state(void);
diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c
index 519e308e2a0..b7e85de6056 100644
--- a/usr.bin/ssh/readconf.c
+++ b/usr.bin/ssh/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.197 2013/03/06 23:36:53 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.198 2013/05/16 02:00:34 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -558,39 +558,54 @@ parse_yesnoask:
case oRekeyLimit:
arg = strdelim(&s);
if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing argument.", filename, linenum);
- if (arg[0] < '0' || arg[0] > '9')
- fatal("%.200s line %d: Bad number.", filename, linenum);
- orig = val64 = strtoll(arg, &endofnumber, 10);
- if (arg == endofnumber)
- fatal("%.200s line %d: Bad number.", filename, linenum);
- switch (toupper(*endofnumber)) {
- case '\0':
- scale = 1;
- break;
- case 'K':
- scale = 1<<10;
- break;
- case 'M':
- scale = 1<<20;
- break;
- case 'G':
- scale = 1<<30;
- break;
- default:
- fatal("%.200s line %d: Invalid RekeyLimit suffix",
- filename, linenum);
+ fatal("%.200s line %d: Missing argument.", filename,
+ linenum);
+ if (strcmp(arg, "default") == 0) {
+ val64 = 0;
+ } else {
+ if (arg[0] < '0' || arg[0] > '9')
+ fatal("%.200s line %d: Bad number.", filename,
+ linenum);
+ orig = val64 = strtoll(arg, &endofnumber, 10);
+ if (arg == endofnumber)
+ fatal("%.200s line %d: Bad number.", filename,
+ linenum);
+ switch (toupper(*endofnumber)) {
+ case '\0':
+ scale = 1;
+ break;
+ case 'K':
+ scale = 1<<10;
+ break;
+ case 'M':
+ scale = 1<<20;
+ break;
+ case 'G':
+ scale = 1<<30;
+ break;
+ default:
+ fatal("%.200s line %d: Invalid RekeyLimit "
+ "suffix", filename, linenum);
+ }
+ val64 *= scale;
+ /* detect integer wrap and too-large limits */
+ if ((val64 / scale) != orig || val64 > UINT_MAX)
+ fatal("%.200s line %d: RekeyLimit too large",
+ filename, linenum);
+ if (val64 != 0 && val64 < 16)
+ fatal("%.200s line %d: RekeyLimit too small",
+ filename, linenum);
}
- val64 *= scale;
- /* detect integer wrap and too-large limits */
- if ((val64 / scale) != orig || val64 > UINT_MAX)
- fatal("%.200s line %d: RekeyLimit too large",
- filename, linenum);
- if (val64 < 16)
- fatal("%.200s line %d: RekeyLimit too small",
- filename, linenum);
if (*activep && options->rekey_limit == -1)
options->rekey_limit = (u_int32_t)val64;
+ if (s != NULL) { /* optional rekey interval present */
+ if (strcmp(s, "none") == 0) {
+ (void)strdelim(&s); /* discard */
+ break;
+ }
+ intptr = &options->rekey_interval;
+ goto parse_time;
+ }
break;
case oIdentityFile:
@@ -1198,6 +1213,7 @@ initialize_options(Options * options)
options->no_host_authentication_for_localhost = - 1;
options->identities_only = - 1;
options->rekey_limit = - 1;
+ options->rekey_interval = -1;
options->verify_host_key_dns = -1;
options->server_alive_interval = -1;
options->server_alive_count_max = -1;
@@ -1331,6 +1347,8 @@ fill_default_options(Options * options)
options->enable_ssh_keysign = 0;
if (options->rekey_limit == -1)
options->rekey_limit = 0;
+ if (options->rekey_interval == -1)
+ options->rekey_interval = 0;
if (options->verify_host_key_dns == -1)
options->verify_host_key_dns = 0;
if (options->server_alive_interval == -1)
diff --git a/usr.bin/ssh/readconf.h b/usr.bin/ssh/readconf.h
index 841648906c8..e20573090a3 100644
--- a/usr.bin/ssh/readconf.h
+++ b/usr.bin/ssh/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.93 2013/02/22 04:45:09 dtucker Exp $ */
+/* $OpenBSD: readconf.h,v 1.94 2013/05/16 02:00:34 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -110,6 +110,7 @@ typedef struct {
int enable_ssh_keysign;
int64_t rekey_limit;
+ int rekey_interval;
int no_host_authentication_for_localhost;
int identities_only;
int server_alive_interval;
diff --git a/usr.bin/ssh/ssh_config b/usr.bin/ssh/ssh_config
index 18936740f6e..bb408193633 100644
--- a/usr.bin/ssh/ssh_config
+++ b/usr.bin/ssh/ssh_config
@@ -1,4 +1,4 @@
-# $OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $
+# $OpenBSD: ssh_config,v 1.27 2013/05/16 02:00:34 dtucker Exp $
# This is the ssh client system-wide configuration file. See
# ssh_config(5) for more information. This file provides defaults for
@@ -45,3 +45,4 @@
# PermitLocalCommand no
# VisualHostKey no
# ProxyCommand ssh -q -W %h:%p gateway.example.com
+# RekeyLimit 1G 1h
diff --git a/usr.bin/ssh/ssh_config.5 b/usr.bin/ssh/ssh_config.5
index 269529c0082..97897e00e70 100644
--- a/usr.bin/ssh/ssh_config.5
+++ b/usr.bin/ssh/ssh_config.5
@@ -33,8 +33,8 @@
.\" (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.161 2013/01/08 18:49:04 markus Exp $
-.Dd $Mdocdate: January 8 2013 $
+.\" $OpenBSD: ssh_config.5,v 1.162 2013/05/16 02:00:34 dtucker Exp $
+.Dd $Mdocdate: May 16 2013 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@@ -931,8 +931,9 @@ The default is
This option applies to protocol version 2 only.
.It Cm RekeyLimit
Specifies the maximum amount of data that may be transmitted before the
-session key is renegotiated.
-The argument is the number of bytes, with an optional suffix of
+session key is renegotiated, optionally followed a maximum amount of
+time that may pass before the session key is renegotiated.
+The first argument is specified in bytes and may have a suffix of
.Sq K ,
.Sq M ,
or
@@ -943,6 +944,17 @@ The default is between
and
.Sq 4G ,
depending on the cipher.
+The optional second value is specified in seconds and may use any of the
+units documented in the
+.Sx TIME FORMATS
+section of
+.Xr sshd_config 5 .
+The default value for
+.Cm RekeyLimit
+is
+.Dq default none ,
+which means that rekeying is performed after the cipher's default amount
+of data has been sent or received and no time based rekeying is done.
This option applies to protocol version 2 only.
.It Cm RemoteForward
Specifies that a TCP port on the remote machine be forwarded over
diff --git a/usr.bin/ssh/sshconnect2.c b/usr.bin/ssh/sshconnect2.c
index 805348233cc..43716f35315 100644
--- a/usr.bin/ssh/sshconnect2.c
+++ b/usr.bin/ssh/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.195 2013/05/10 03:40:07 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.196 2013/05/16 02:00:34 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -191,8 +191,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
if (options.kex_algorithms != NULL)
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
- if (options.rekey_limit)
- packet_set_rekey_limit((u_int32_t)options.rekey_limit);
+ if (options.rekey_limit || options.rekey_interval)
+ packet_set_rekey_limits((u_int32_t)options.rekey_limit,
+ (time_t)options.rekey_interval);
/* start key exchange */
kex = kex_setup(myproposal);