diff options
author | Darren Tucker <dtucker@cvs.openbsd.org> | 2013-05-16 04:09:15 +0000 |
---|---|---|
committer | Darren Tucker <dtucker@cvs.openbsd.org> | 2013-05-16 04:09:15 +0000 |
commit | 0d2048efbe7fea0ca06397d8fe2f6c9a7598a649 (patch) | |
tree | fbce25e37ec06be3f66703a4ce164bf10818fba3 | |
parent | 292160a7eab4b5751de8106302c891412f956e7a (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.c | 6 | ||||
-rw-r--r-- | usr.bin/ssh/packet.c | 4 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.c | 75 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.h | 5 | ||||
-rw-r--r-- | usr.bin/ssh/serverloop.c | 14 | ||||
-rw-r--r-- | usr.bin/ssh/sshd.c | 6 | ||||
-rw-r--r-- | usr.bin/ssh/sshd_config | 5 | ||||
-rw-r--r-- | usr.bin/ssh/sshd_config.5 | 32 |
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. |