[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 Add an optional second argument to RekeyLimit in the client to allow
rekeying based on elapsed time in addition to amount of traffic. rekeying based on elapsed time in addition to amount of traffic.
with djm@ jmc@, ok djm 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 20130510
- (dtucker) [configure.ac] Enable -Wsizeof-pointer-memaccess if the compiler - (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 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org> * Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -1810,6 +1810,10 @@ monitor_apply_keystate(struct monitor *pmonitor)
if (options.compression) if (options.compression)
mm_init_compression(pmonitor->m_zlib); 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 */ /* Network I/O buffers */
/* XXX inefficient for large buffers, need: buffer_init_from_string */ /* XXX inefficient for large buffers, need: buffer_init_from_string */
buffer_clear(packet_get_input()); 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> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * 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 - seconds = active_state->rekey_time + active_state->rekey_interval -
time(NULL); time(NULL);
return (seconds < 0 ? 0 : seconds); return (seconds <= 0 ? 1 : seconds);
} }
void 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 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -20,6 +20,7 @@
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <ctype.h>
#include <netdb.h> #include <netdb.h>
#include <pwd.h> #include <pwd.h>
#include <stdio.h> #include <stdio.h>
@ -110,6 +111,8 @@ initialize_server_options(ServerOptions *options)
options->permit_user_env = -1; options->permit_user_env = -1;
options->use_login = -1; options->use_login = -1;
options->compression = -1; options->compression = -1;
options->rekey_limit = -1;
options->rekey_interval = -1;
options->allow_tcp_forwarding = -1; options->allow_tcp_forwarding = -1;
options->allow_agent_forwarding = -1; options->allow_agent_forwarding = -1;
options->num_allow_users = 0; options->num_allow_users = 0;
@ -249,6 +252,10 @@ fill_default_server_options(ServerOptions *options)
options->use_login = 0; options->use_login = 0;
if (options->compression == -1) if (options->compression == -1)
options->compression = COMP_DELAYED; 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) if (options->allow_tcp_forwarding == -1)
options->allow_tcp_forwarding = FORWARD_ALLOW; options->allow_tcp_forwarding = FORWARD_ALLOW;
if (options->allow_agent_forwarding == -1) if (options->allow_agent_forwarding == -1)
@ -320,7 +327,7 @@ typedef enum {
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
sStrictModes, sEmptyPasswd, sTCPKeepAlive, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
sMaxStartups, sMaxAuthTries, sMaxSessions, sMaxStartups, sMaxAuthTries, sMaxSessions,
@ -422,6 +429,7 @@ static struct {
{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
{ "uselogin", sUseLogin, SSHCFG_GLOBAL }, { "uselogin", sUseLogin, SSHCFG_GLOBAL },
{ "compression", sCompression, SSHCFG_GLOBAL }, { "compression", sCompression, SSHCFG_GLOBAL },
{ "rekeylimit", sRekeyLimit, SSHCFG_ALL },
{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
@ -800,14 +808,14 @@ process_server_config_line(ServerOptions *options, char *line,
const char *filename, int linenum, int *activep, const char *filename, int linenum, int *activep,
struct connection_info *connectinfo) struct connection_info *connectinfo)
{ {
char *cp, **charptr, *arg, *p; char *cp, **charptr, *arg, *p, *endofnumber;
int cmdline = 0, *intptr, value, value2, n; int cmdline = 0, *intptr, value, value2, n, port, scale;
SyslogFacility *log_facility_ptr; SyslogFacility *log_facility_ptr;
LogLevel *log_level_ptr; LogLevel *log_level_ptr;
ServerOpCodes opcode; ServerOpCodes opcode;
int port;
u_int i, flags = 0; u_int i, flags = 0;
size_t len; size_t len;
long long orig, val64;
const struct multistate *multistate_ptr; const struct multistate *multistate_ptr;
cp = line; cp = line;
@ -1118,6 +1126,59 @@ process_server_config_line(ServerOptions *options, char *line,
multistate_ptr = multistate_compression; multistate_ptr = multistate_compression;
goto parse_multistate; 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: case sGatewayPorts:
intptr = &options->gateway_ports; intptr = &options->gateway_ports;
multistate_ptr = multistate_gatewayports; 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(max_authtries);
M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_interactive);
M_CP_INTOPT(ip_qos_bulk); M_CP_INTOPT(ip_qos_bulk);
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
/* See comment in servconf.h */ /* See comment in servconf.h */
COPY_MATCH_STRING_OPTS(); COPY_MATCH_STRING_OPTS();
@ -2006,5 +2069,7 @@ dump_config(ServerOptions *o)
printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
printf("%s\n", iptos2str(o->ip_qos_bulk)); printf("%s\n", iptos2str(o->ip_qos_bulk));
printf("rekeylimit %lld %d\n", o->rekey_limit, o->rekey_interval);
channel_print_adm_permitted_opens(); 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> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -176,6 +176,9 @@ typedef struct {
char *authorized_keys_command; char *authorized_keys_command;
char *authorized_keys_command_user; char *authorized_keys_command_user;
int64_t rekey_limit;
int rekey_interval;
char *version_addendum; /* Appended to SSH banner */ char *version_addendum; /* Appended to SSH banner */
u_int num_auth_methods; 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> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -277,7 +277,7 @@ client_alive_check(void)
*/ */
static void static void
wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, 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; struct timeval tv, *tvp;
int ret; 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(). */ int wait_status; /* Status returned by wait(). */
pid_t wait_pid; /* pid returned by wait(). */ pid_t wait_pid; /* pid returned by wait(). */
int waiting_termination = 0; /* Have displayed waiting close message. */ 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 previous_stdout_buffer_bytes;
u_int stdout_buffer_bytes; u_int stdout_buffer_bytes;
int type; int type;
@ -826,6 +826,7 @@ server_loop2(Authctxt *authctxt)
{ {
fd_set *readset = NULL, *writeset = NULL; fd_set *readset = NULL, *writeset = NULL;
int rekeying = 0, max_fd, nalloc = 0; int rekeying = 0, max_fd, nalloc = 0;
u_int64_t rekey_timeout_ms = 0;
debug("Entering interactive session for SSH2."); debug("Entering interactive session for SSH2.");
@ -854,8 +855,13 @@ server_loop2(Authctxt *authctxt)
if (!rekeying && packet_not_very_much_data_to_write()) if (!rekeying && packet_not_very_much_data_to_write())
channel_output_poll(); 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, wait_until_can_do_something(&readset, &writeset, &max_fd,
&nalloc, 0); &nalloc, rekey_timeout_ms);
if (received_sigterm) { if (received_sigterm) {
logit("Exiting on signal %d", (int)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> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -2364,6 +2364,10 @@ do_ssh2_kex(void)
if (options.kex_algorithms != NULL) if (options.kex_algorithms != NULL)
myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; 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(); myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
/* start key exchange */ /* 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 # This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information. # sshd_config(5) for more information.
@ -29,6 +29,9 @@
#KeyRegenerationInterval 1h #KeyRegenerationInterval 1h
#ServerKeyBits 1024 #ServerKeyBits 1024
# Ciphers and keying
#RekeyLimit default none
# Logging # Logging
# obsoletes QuietMode and FascistLogging # obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH #SyslogFacility AUTH

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" 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 $ .\" $OpenBSD: sshd_config.5,v 1.159 2013/05/16 04:09:14 dtucker Exp $
.Dd $Mdocdate: April 19 2013 $ .Dd $Mdocdate: May 16 2013 $
.Dt SSHD_CONFIG 5 .Dt SSHD_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -814,6 +814,7 @@ Available keywords are
.Cm PermitRootLogin , .Cm PermitRootLogin ,
.Cm PermitTunnel , .Cm PermitTunnel ,
.Cm PubkeyAuthentication , .Cm PubkeyAuthentication ,
.Cm RekeyLimit ,
.Cm RhostsRSAAuthentication , .Cm RhostsRSAAuthentication ,
.Cm RSAAuthentication , .Cm RSAAuthentication ,
.Cm X11DisplayOffset , .Cm X11DisplayOffset ,
@ -1008,6 +1009,33 @@ Specifies whether public key authentication is allowed.
The default is The default is
.Dq yes . .Dq yes .
Note that this option applies to protocol version 2 only. 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 .It Cm RevokedKeys
Specifies revoked public keys. Specifies revoked public keys.
Keys listed in this file will be refused for public key authentication. Keys listed in this file will be refused for public key authentication.