[sshd_config.5 servconf.c servconf.h packet.c serverloop.c monitor.c sshd_config
     sshd.c] Add RekeyLimit to sshd with the same syntax as the client allowing
     rekeying based on traffic volume or time.  ok djm@, help & ok jmc@ for the man
     page.
This commit is contained in:
Darren Tucker 2013-05-16 20:29:28 +10:00
parent c53c2af173
commit 5f96f3b4be
9 changed files with 135 additions and 17 deletions

View File

@ -28,6 +28,11 @@
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
- dtucker@cvs.openbsd.org 2013/05/16 04:09:14
[sshd_config.5 servconf.c servconf.h packet.c serverloop.c monitor.c sshd_config
sshd.c] Add RekeyLimit to sshd with the same syntax as the client allowing
rekeying based on traffic volume or time. ok djm@, help & ok jmc@ for the man
page.
20130510
- (dtucker) [configure.ac] Enable -Wsizeof-pointer-memaccess if the compiler

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.122 2013/03/07 19:27:25 markus Exp $ */
/* $OpenBSD: monitor.c,v 1.123 2013/05/16 04:09:13 dtucker Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -1810,6 +1810,10 @@ monitor_apply_keystate(struct monitor *pmonitor)
if (options.compression)
mm_init_compression(pmonitor->m_zlib);
if (options.rekey_limit || options.rekey_interval)
packet_set_rekey_limits((u_int32_t)options.rekey_limit,
(time_t)options.rekey_interval);
/* Network I/O buffers */
/* XXX inefficient for large buffers, need: buffer_init_from_string */
buffer_clear(packet_get_input());

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.184 2013/05/16 02:00:34 dtucker Exp $ */
/* $OpenBSD: packet.c,v 1.185 2013/05/16 04:09:13 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1966,7 +1966,7 @@ packet_get_rekey_timeout(void)
seconds = active_state->rekey_time + active_state->rekey_interval -
time(NULL);
return (seconds < 0 ? 0 : seconds);
return (seconds <= 0 ? 1 : seconds);
}
void

View File

@ -1,5 +1,5 @@
/* $OpenBSD: servconf.c,v 1.234 2013/02/06 00:20:42 dtucker Exp $ */
/* $OpenBSD: servconf.c,v 1.235 2013/05/16 04:09:14 dtucker Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -20,6 +20,7 @@
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <ctype.h>
#include <netdb.h>
#include <pwd.h>
#include <stdio.h>
@ -110,6 +111,8 @@ initialize_server_options(ServerOptions *options)
options->permit_user_env = -1;
options->use_login = -1;
options->compression = -1;
options->rekey_limit = -1;
options->rekey_interval = -1;
options->allow_tcp_forwarding = -1;
options->allow_agent_forwarding = -1;
options->num_allow_users = 0;
@ -249,6 +252,10 @@ fill_default_server_options(ServerOptions *options)
options->use_login = 0;
if (options->compression == -1)
options->compression = COMP_DELAYED;
if (options->rekey_limit == -1)
options->rekey_limit = 0;
if (options->rekey_interval == -1)
options->rekey_interval = 0;
if (options->allow_tcp_forwarding == -1)
options->allow_tcp_forwarding = FORWARD_ALLOW;
if (options->allow_agent_forwarding == -1)
@ -320,7 +327,7 @@ typedef enum {
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
sStrictModes, sEmptyPasswd, sTCPKeepAlive,
sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
sMaxStartups, sMaxAuthTries, sMaxSessions,
@ -422,6 +429,7 @@ static struct {
{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
{ "compression", sCompression, SSHCFG_GLOBAL },
{ "rekeylimit", sRekeyLimit, SSHCFG_ALL },
{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
@ -800,14 +808,14 @@ process_server_config_line(ServerOptions *options, char *line,
const char *filename, int linenum, int *activep,
struct connection_info *connectinfo)
{
char *cp, **charptr, *arg, *p;
int cmdline = 0, *intptr, value, value2, n;
char *cp, **charptr, *arg, *p, *endofnumber;
int cmdline = 0, *intptr, value, value2, n, port, scale;
SyslogFacility *log_facility_ptr;
LogLevel *log_level_ptr;
ServerOpCodes opcode;
int port;
u_int i, flags = 0;
size_t len;
long long orig, val64;
const struct multistate *multistate_ptr;
cp = line;
@ -1118,6 +1126,59 @@ process_server_config_line(ServerOptions *options, char *line,
multistate_ptr = multistate_compression;
goto parse_multistate;
case sRekeyLimit:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
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);
}
if (*activep && options->rekey_limit == -1)
options->rekey_limit = (u_int32_t)val64;
if (cp != NULL) { /* optional rekey interval present */
if (strcmp(cp, "none") == 0) {
(void)strdelim(&cp); /* discard */
break;
}
intptr = &options->rekey_interval;
goto parse_time;
}
break;
case sGatewayPorts:
intptr = &options->gateway_ports;
multistate_ptr = multistate_gatewayports;
@ -1718,6 +1779,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
M_CP_INTOPT(max_authtries);
M_CP_INTOPT(ip_qos_interactive);
M_CP_INTOPT(ip_qos_bulk);
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
@ -2006,5 +2069,7 @@ dump_config(ServerOptions *o)
printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
printf("%s\n", iptos2str(o->ip_qos_bulk));
printf("rekeylimit %lld %d\n", o->rekey_limit, o->rekey_interval);
channel_print_adm_permitted_opens();
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.107 2013/01/03 05:49:36 djm Exp $ */
/* $OpenBSD: servconf.h,v 1.108 2013/05/16 04:09:14 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -176,6 +176,9 @@ typedef struct {
char *authorized_keys_command;
char *authorized_keys_command_user;
int64_t rekey_limit;
int rekey_interval;
char *version_addendum; /* Appended to SSH banner */
u_int num_auth_methods;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: serverloop.c,v 1.164 2012/12/07 01:51:35 dtucker Exp $ */
/* $OpenBSD: serverloop.c,v 1.165 2013/05/16 04:09:14 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -277,7 +277,7 @@ client_alive_check(void)
*/
static void
wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
u_int *nallocp, u_int max_time_milliseconds)
u_int *nallocp, u_int64_t max_time_milliseconds)
{
struct timeval tv, *tvp;
int ret;
@ -563,7 +563,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
int wait_status; /* Status returned by wait(). */
pid_t wait_pid; /* pid returned by wait(). */
int waiting_termination = 0; /* Have displayed waiting close message. */
u_int max_time_milliseconds;
u_int64_t max_time_milliseconds;
u_int previous_stdout_buffer_bytes;
u_int stdout_buffer_bytes;
int type;
@ -826,6 +826,7 @@ server_loop2(Authctxt *authctxt)
{
fd_set *readset = NULL, *writeset = NULL;
int rekeying = 0, max_fd, nalloc = 0;
u_int64_t rekey_timeout_ms = 0;
debug("Entering interactive session for SSH2.");
@ -854,8 +855,13 @@ server_loop2(Authctxt *authctxt)
if (!rekeying && packet_not_very_much_data_to_write())
channel_output_poll();
if (options.rekey_interval > 0 && compat20 && !rekeying)
rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
else
rekey_timeout_ms = 0;
wait_until_can_do_something(&readset, &writeset, &max_fd,
&nalloc, 0);
&nalloc, rekey_timeout_ms);
if (received_sigterm) {
logit("Exiting on signal %d", (int)received_sigterm);

6
sshd.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.399 2013/04/07 02:10:33 dtucker Exp $ */
/* $OpenBSD: sshd.c,v 1.400 2013/05/16 04:09:14 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -2364,6 +2364,10 @@ do_ssh2_kex(void)
if (options.kex_algorithms != NULL)
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
if (options.rekey_limit || options.rekey_interval)
packet_set_rekey_limits((u_int32_t)options.rekey_limit,
(time_t)options.rekey_interval);
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
/* start key exchange */

View File

@ -1,4 +1,4 @@
# $OpenBSD: sshd_config,v 1.89 2013/02/06 00:20:42 dtucker Exp $
# $OpenBSD: sshd_config,v 1.90 2013/05/16 04:09:14 dtucker Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
@ -29,6 +29,9 @@
#KeyRegenerationInterval 1h
#ServerKeyBits 1024
# Ciphers and keying
#RekeyLimit default none
# Logging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH

View File

@ -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: sshd_config.5,v 1.158 2013/04/19 01:00:10 djm Exp $
.Dd $Mdocdate: April 19 2013 $
.\" $OpenBSD: sshd_config.5,v 1.159 2013/05/16 04:09:14 dtucker Exp $
.Dd $Mdocdate: May 16 2013 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@ -814,6 +814,7 @@ Available keywords are
.Cm PermitRootLogin ,
.Cm PermitTunnel ,
.Cm PubkeyAuthentication ,
.Cm RekeyLimit ,
.Cm RhostsRSAAuthentication ,
.Cm RSAAuthentication ,
.Cm X11DisplayOffset ,
@ -1008,6 +1009,33 @@ Specifies whether public key authentication is allowed.
The default is
.Dq yes .
Note that 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, 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
.Sq G
to indicate Kilobytes, Megabytes, or Gigabytes, respectively.
The default is between
.Sq 1G
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 RevokedKeys
Specifies revoked public keys.
Keys listed in this file will be refused for public key authentication.