summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@cvs.openbsd.org>2013-05-16 04:09:15 +0000
committerDarren Tucker <dtucker@cvs.openbsd.org>2013-05-16 04:09:15 +0000
commit0d2048efbe7fea0ca06397d8fe2f6c9a7598a649 (patch)
treefbce25e37ec06be3f66703a4ce164bf10818fba3
parent292160a7eab4b5751de8106302c891412f956e7a (diff)
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.
-rw-r--r--usr.bin/ssh/monitor.c6
-rw-r--r--usr.bin/ssh/packet.c4
-rw-r--r--usr.bin/ssh/servconf.c75
-rw-r--r--usr.bin/ssh/servconf.h5
-rw-r--r--usr.bin/ssh/serverloop.c14
-rw-r--r--usr.bin/ssh/sshd.c6
-rw-r--r--usr.bin/ssh/sshd_config5
-rw-r--r--usr.bin/ssh/sshd_config.532
8 files changed, 130 insertions, 17 deletions
diff --git a/usr.bin/ssh/monitor.c b/usr.bin/ssh/monitor.c
index 737c3c1abab..e537d9d5abf 100644
--- a/usr.bin/ssh/monitor.c
+++ b/usr.bin/ssh/monitor.c
@@ -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>
@@ -1477,6 +1477,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());
diff --git a/usr.bin/ssh/packet.c b/usr.bin/ssh/packet.c
index 4291bc8c1f9..aa852389d85 100644
--- a/usr.bin/ssh/packet.c
+++ b/usr.bin/ssh/packet.c
@@ -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
@@ -1944,7 +1944,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
diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c
index ca55775cfdc..640eaf06606 100644
--- a/usr.bin/ssh/servconf.c
+++ b/usr.bin/ssh/servconf.c
@@ -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
@@ -19,6 +19,7 @@
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#include <ctype.h>
#include <netdb.h>
#include <pwd.h>
#include <stdio.h>
@@ -103,6 +104,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;
@@ -235,6 +238,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)
@@ -293,7 +300,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,
@@ -383,6 +390,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 },
@@ -761,14 +769,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;
@@ -1073,6 +1081,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;
@@ -1673,6 +1734,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();
@@ -1956,5 +2019,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();
}
diff --git a/usr.bin/ssh/servconf.h b/usr.bin/ssh/servconf.h
index 059259ac062..d32f2a141fe 100644
--- a/usr.bin/ssh/servconf.h
+++ b/usr.bin/ssh/servconf.h
@@ -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>
@@ -174,6 +174,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;
diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c
index 802d11f8a91..da4a2804d2a 100644
--- a/usr.bin/ssh/serverloop.c
+++ b/usr.bin/ssh/serverloop.c
@@ -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
@@ -271,7 +271,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;
@@ -531,7 +531,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;
@@ -794,6 +794,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.");
@@ -822,8 +823,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);
diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c
index 16e24ed623c..69f09c4764b 100644
--- a/usr.bin/ssh/sshd.c
+++ b/usr.bin/ssh/sshd.c
@@ -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
@@ -2222,6 +2222,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 */
diff --git a/usr.bin/ssh/sshd_config b/usr.bin/ssh/sshd_config
index 89a26490ac5..13e1cd3b0f7 100644
--- a/usr.bin/ssh/sshd_config
+++ b/usr.bin/ssh/sshd_config
@@ -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.
@@ -27,6 +27,9 @@
#KeyRegenerationInterval 1h
#ServerKeyBits 1024
+# Ciphers and keying
+#RekeyLimit default none
+
# Logging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH
diff --git a/usr.bin/ssh/sshd_config.5 b/usr.bin/ssh/sshd_config.5
index b82fdf9f3a8..cdfcc52440a 100644
--- a/usr.bin/ssh/sshd_config.5
+++ b/usr.bin/ssh/sshd_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: 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
@@ -815,6 +815,7 @@ Available keywords are
.Cm PermitRootLogin ,
.Cm PermitTunnel ,
.Cm PubkeyAuthentication ,
+.Cm RekeyLimit ,
.Cm RhostsRSAAuthentication ,
.Cm RSAAuthentication ,
.Cm X11DisplayOffset ,
@@ -1009,6 +1010,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.