Commit c53c2af1 authored by Darren Tucker's avatar Darren Tucker

- dtucker@cvs.openbsd.org 2013/05/16 02:00:34

     [ssh_config sshconnect2.c packet.c readconf.h readconf.c clientloop.c
     ssh_config.5 packet.h]
     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
parent 64c6fcee
......@@ -22,6 +22,12 @@
- dtucker@cvs.openbsd.org 2013/05/10 10:13:50
[ssh-pkcs11-helper.c]
remove unused extern optarg. ok markus@
- dtucker@cvs.openbsd.org 2013/05/16 02:00:34
[ssh_config sshconnect2.c packet.c readconf.h readconf.c clientloop.c
ssh_config.5 packet.h]
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
20130510
- (dtucker) [configure.ac] Enable -Wsizeof-pointer-memaccess if the compiler
......
/* $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
......@@ -583,7 +583,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. */
......@@ -632,12 +632,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;
}
......@@ -669,8 +673,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
......
/* $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
......@@ -58,6 +58,7 @@
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include "xmalloc.h"
#include "buffer.h"
......@@ -165,9 +166,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;
......@@ -1009,6 +1015,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);
......@@ -1933,13 +1940,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
......
/* $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>
......@@ -115,7 +115,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);
......
/* $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
......@@ -562,39 +562,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:
......@@ -1202,6 +1217,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;
......@@ -1337,6 +1353,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)
......
/* $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;
......
# $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
......@@ -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
......
/* $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.
......@@ -197,8 +197,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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment