diff options
author | djm@openbsd.org <djm@openbsd.org> | 2016-02-08 10:57:07 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2016-02-08 21:58:32 +1100 |
commit | 19bcf2ea2d17413f2d9730dd2a19575ff86b9b6a (patch) | |
tree | a87286b290fcd540635890856fbcafef74341ec0 | |
parent | 603ba41179e4b53951c7b90ee95b6ef3faa3f15d (diff) |
upstream commit
refactor activation of rekeying
This makes automatic rekeying internal to the packet code (previously
the server and client loops needed to assist). In doing to it makes
application of rekey limits more accurate by accounting for packets
about to be sent as well as packets queued during rekeying events
themselves.
Based on a patch from dtucker@ which was in turn based on a patch
Aleksander Adamowski in bz#2521; ok markus@
Upstream-ID: a441227fd64f9739850ca97b4cf794202860fcd8
-rw-r--r-- | clientloop.c | 28 | ||||
-rw-r--r-- | kex.c | 21 | ||||
-rw-r--r-- | kex.h | 3 | ||||
-rw-r--r-- | opacket.h | 2 | ||||
-rw-r--r-- | packet.c | 154 | ||||
-rw-r--r-- | packet.h | 4 | ||||
-rw-r--r-- | serverloop.c | 20 |
7 files changed, 158 insertions, 74 deletions
diff --git a/clientloop.c b/clientloop.c index f0a08f234..9820455c4 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.283 2016/02/01 21:18:17 millert Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.284 2016/02/08 10:57:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1502,7 +1502,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1502 | { | 1502 | { |
1503 | fd_set *readset = NULL, *writeset = NULL; | 1503 | fd_set *readset = NULL, *writeset = NULL; |
1504 | double start_time, total_time; | 1504 | double start_time, total_time; |
1505 | int r, max_fd = 0, max_fd2 = 0, len, rekeying = 0; | 1505 | int r, max_fd = 0, max_fd2 = 0, len; |
1506 | u_int64_t ibytes, obytes; | 1506 | u_int64_t ibytes, obytes; |
1507 | u_int nalloc = 0; | 1507 | u_int nalloc = 0; |
1508 | char buf[100]; | 1508 | char buf[100]; |
@@ -1617,10 +1617,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1617 | if (compat20 && session_closed && !channel_still_open()) | 1617 | if (compat20 && session_closed && !channel_still_open()) |
1618 | break; | 1618 | break; |
1619 | 1619 | ||
1620 | rekeying = (active_state->kex != NULL && !active_state->kex->done); | 1620 | if (ssh_packet_is_rekeying(active_state)) { |
1621 | |||
1622 | if (rekeying) { | ||
1623 | debug("rekeying in progress"); | 1621 | debug("rekeying in progress"); |
1622 | } else if (need_rekeying) { | ||
1623 | /* manual rekey request */ | ||
1624 | debug("need rekeying"); | ||
1625 | if ((r = kex_start_rekex(active_state)) != 0) | ||
1626 | fatal("%s: kex_start_rekex: %s", __func__, | ||
1627 | ssh_err(r)); | ||
1628 | need_rekeying = 0; | ||
1624 | } else { | 1629 | } else { |
1625 | /* | 1630 | /* |
1626 | * Make packets of buffered stdin data, and buffer | 1631 | * Make packets of buffered stdin data, and buffer |
@@ -1651,23 +1656,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
1651 | */ | 1656 | */ |
1652 | max_fd2 = max_fd; | 1657 | max_fd2 = max_fd; |
1653 | client_wait_until_can_do_something(&readset, &writeset, | 1658 | client_wait_until_can_do_something(&readset, &writeset, |
1654 | &max_fd2, &nalloc, rekeying); | 1659 | &max_fd2, &nalloc, ssh_packet_is_rekeying(active_state)); |
1655 | 1660 | ||
1656 | if (quit_pending) | 1661 | if (quit_pending) |
1657 | break; | 1662 | break; |
1658 | 1663 | ||
1659 | /* Do channel operations unless rekeying in progress. */ | 1664 | /* Do channel operations unless rekeying in progress. */ |
1660 | if (!rekeying) { | 1665 | if (!ssh_packet_is_rekeying(active_state)) |
1661 | channel_after_select(readset, writeset); | 1666 | channel_after_select(readset, writeset); |
1662 | if (need_rekeying || packet_need_rekeying()) { | ||
1663 | debug("need rekeying"); | ||
1664 | active_state->kex->done = 0; | ||
1665 | if ((r = kex_send_kexinit(active_state)) != 0) | ||
1666 | fatal("%s: kex_send_kexinit: %s", | ||
1667 | __func__, ssh_err(r)); | ||
1668 | need_rekeying = 0; | ||
1669 | } | ||
1670 | } | ||
1671 | 1667 | ||
1672 | /* Buffer input from the connection. */ | 1668 | /* Buffer input from the connection. */ |
1673 | client_process_net_input(readset); | 1669 | client_process_net_input(readset); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.c,v 1.116 2016/01/14 16:17:39 markus Exp $ */ | 1 | /* $OpenBSD: kex.c,v 1.117 2016/02/08 10:57:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -606,6 +606,25 @@ kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) | |||
606 | return 0; | 606 | return 0; |
607 | } | 607 | } |
608 | 608 | ||
609 | /* | ||
610 | * Request key re-exchange, returns 0 on success or a ssherr.h error | ||
611 | * code otherwise. Must not be called if KEX is incomplete or in-progress. | ||
612 | */ | ||
613 | int | ||
614 | kex_start_rekex(struct ssh *ssh) | ||
615 | { | ||
616 | if (ssh->kex == NULL) { | ||
617 | error("%s: no kex", __func__); | ||
618 | return SSH_ERR_INTERNAL_ERROR; | ||
619 | } | ||
620 | if (ssh->kex->done == 0) { | ||
621 | error("%s: requested twice", __func__); | ||
622 | return SSH_ERR_INTERNAL_ERROR; | ||
623 | } | ||
624 | ssh->kex->done = 0; | ||
625 | return kex_send_kexinit(ssh); | ||
626 | } | ||
627 | |||
609 | static int | 628 | static int |
610 | choose_enc(struct sshenc *enc, char *client, char *server) | 629 | choose_enc(struct sshenc *enc, char *client, char *server) |
611 | { | 630 | { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.h,v 1.75 2016/01/14 16:17:39 markus Exp $ */ | 1 | /* $OpenBSD: kex.h,v 1.76 2016/02/08 10:57:07 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -179,6 +179,7 @@ int kex_input_ext_info(int, u_int32_t, void *); | |||
179 | int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); | 179 | int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); |
180 | int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *); | 180 | int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *); |
181 | int kex_send_newkeys(struct ssh *); | 181 | int kex_send_newkeys(struct ssh *); |
182 | int kex_start_rekex(struct ssh *); | ||
182 | 183 | ||
183 | int kexdh_client(struct ssh *); | 184 | int kexdh_client(struct ssh *); |
184 | int kexdh_server(struct ssh *); | 185 | int kexdh_server(struct ssh *); |
@@ -125,8 +125,6 @@ void packet_disconnect(const char *, ...) | |||
125 | sshpkt_add_padding(active_state, (pad)) | 125 | sshpkt_add_padding(active_state, (pad)) |
126 | #define packet_send_ignore(nbytes) \ | 126 | #define packet_send_ignore(nbytes) \ |
127 | ssh_packet_send_ignore(active_state, (nbytes)) | 127 | ssh_packet_send_ignore(active_state, (nbytes)) |
128 | #define packet_need_rekeying() \ | ||
129 | ssh_packet_need_rekeying(active_state) | ||
130 | #define packet_set_server() \ | 128 | #define packet_set_server() \ |
131 | ssh_packet_set_server(active_state) | 129 | ssh_packet_set_server(active_state) |
132 | #define packet_set_authenticated() \ | 130 | #define packet_set_authenticated() \ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.227 2016/02/04 23:43:48 djm Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.228 2016/02/08 10:57:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -259,6 +259,14 @@ ssh_alloc_session_state(void) | |||
259 | return NULL; | 259 | return NULL; |
260 | } | 260 | } |
261 | 261 | ||
262 | /* Returns nonzero if rekeying is in progress */ | ||
263 | int | ||
264 | ssh_packet_is_rekeying(struct ssh *ssh) | ||
265 | { | ||
266 | return ssh->state->rekeying || | ||
267 | (ssh->kex != NULL && ssh->kex->done == 0); | ||
268 | } | ||
269 | |||
262 | /* | 270 | /* |
263 | * Sets the descriptors used for communication. Disables encryption until | 271 | * Sets the descriptors used for communication. Disables encryption until |
264 | * packet_set_encryption_key is called. | 272 | * packet_set_encryption_key is called. |
@@ -1029,6 +1037,51 @@ ssh_set_newkeys(struct ssh *ssh, int mode) | |||
1029 | return 0; | 1037 | return 0; |
1030 | } | 1038 | } |
1031 | 1039 | ||
1040 | #define MAX_PACKETS (1U<<31) | ||
1041 | static int | ||
1042 | ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) | ||
1043 | { | ||
1044 | struct session_state *state = ssh->state; | ||
1045 | u_int32_t out_blocks; | ||
1046 | |||
1047 | /* XXX client can't cope with rekeying pre-auth */ | ||
1048 | if (!state->after_authentication) | ||
1049 | return 0; | ||
1050 | |||
1051 | /* Haven't keyed yet or KEX in progress. */ | ||
1052 | if (ssh->kex == NULL || ssh_packet_is_rekeying(ssh)) | ||
1053 | return 0; | ||
1054 | |||
1055 | /* Peer can't rekey */ | ||
1056 | if (ssh->compat & SSH_BUG_NOREKEY) | ||
1057 | return 0; | ||
1058 | |||
1059 | /* | ||
1060 | * Permit one packet in or out per rekey - this allows us to | ||
1061 | * make progress when rekey limits are very small. | ||
1062 | */ | ||
1063 | if (state->p_send.packets == 0 && state->p_read.packets == 0) | ||
1064 | return 0; | ||
1065 | |||
1066 | /* Time-based rekeying */ | ||
1067 | if (state->rekey_interval != 0 && | ||
1068 | state->rekey_time + state->rekey_interval <= monotime()) | ||
1069 | return 1; | ||
1070 | |||
1071 | /* Always rekey when MAX_PACKETS sent in either direction */ | ||
1072 | if (state->p_send.packets > MAX_PACKETS || | ||
1073 | state->p_read.packets > MAX_PACKETS) | ||
1074 | return 1; | ||
1075 | |||
1076 | /* Rekey after (cipher-specific) maxiumum blocks */ | ||
1077 | out_blocks = roundup(outbound_packet_len, | ||
1078 | state->newkeys[MODE_OUT]->enc.block_size); | ||
1079 | return (state->max_blocks_out && | ||
1080 | (state->p_send.blocks + out_blocks > state->max_blocks_out)) || | ||
1081 | (state->max_blocks_in && | ||
1082 | (state->p_read.blocks > state->max_blocks_in)); | ||
1083 | } | ||
1084 | |||
1032 | /* | 1085 | /* |
1033 | * Delayed compression for SSH2 is enabled after authentication: | 1086 | * Delayed compression for SSH2 is enabled after authentication: |
1034 | * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, | 1087 | * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, |
@@ -1232,35 +1285,58 @@ ssh_packet_send2_wrapped(struct ssh *ssh) | |||
1232 | return r; | 1285 | return r; |
1233 | } | 1286 | } |
1234 | 1287 | ||
1288 | /* returns non-zero if the specified packet type is usec by KEX */ | ||
1289 | static int | ||
1290 | ssh_packet_type_is_kex(u_char type) | ||
1291 | { | ||
1292 | return | ||
1293 | type >= SSH2_MSG_TRANSPORT_MIN && | ||
1294 | type <= SSH2_MSG_TRANSPORT_MAX && | ||
1295 | type != SSH2_MSG_SERVICE_REQUEST && | ||
1296 | type != SSH2_MSG_SERVICE_ACCEPT && | ||
1297 | type != SSH2_MSG_EXT_INFO; | ||
1298 | } | ||
1299 | |||
1235 | int | 1300 | int |
1236 | ssh_packet_send2(struct ssh *ssh) | 1301 | ssh_packet_send2(struct ssh *ssh) |
1237 | { | 1302 | { |
1238 | struct session_state *state = ssh->state; | 1303 | struct session_state *state = ssh->state; |
1239 | struct packet *p; | 1304 | struct packet *p; |
1240 | u_char type; | 1305 | u_char type; |
1241 | int r; | 1306 | int r, need_rekey; |
1242 | 1307 | ||
1308 | if (sshbuf_len(state->outgoing_packet) < 6) | ||
1309 | return SSH_ERR_INTERNAL_ERROR; | ||
1243 | type = sshbuf_ptr(state->outgoing_packet)[5]; | 1310 | type = sshbuf_ptr(state->outgoing_packet)[5]; |
1311 | need_rekey = !ssh_packet_type_is_kex(type) && | ||
1312 | ssh_packet_need_rekeying(ssh, sshbuf_len(state->outgoing_packet)); | ||
1244 | 1313 | ||
1245 | /* during rekeying we can only send key exchange messages */ | 1314 | /* |
1246 | if (state->rekeying) { | 1315 | * During rekeying we can only send key exchange messages. |
1247 | if ((type < SSH2_MSG_TRANSPORT_MIN) || | 1316 | * Queue everything else. |
1248 | (type > SSH2_MSG_TRANSPORT_MAX) || | 1317 | */ |
1249 | (type == SSH2_MSG_SERVICE_REQUEST) || | 1318 | if ((need_rekey || state->rekeying) && !ssh_packet_type_is_kex(type)) { |
1250 | (type == SSH2_MSG_SERVICE_ACCEPT) || | 1319 | if (need_rekey) |
1251 | (type == SSH2_MSG_EXT_INFO)) { | 1320 | debug3("%s: rekex triggered", __func__); |
1252 | debug("enqueue packet: %u", type); | 1321 | debug("enqueue packet: %u", type); |
1253 | p = calloc(1, sizeof(*p)); | 1322 | p = calloc(1, sizeof(*p)); |
1254 | if (p == NULL) | 1323 | if (p == NULL) |
1255 | return SSH_ERR_ALLOC_FAIL; | 1324 | return SSH_ERR_ALLOC_FAIL; |
1256 | p->type = type; | 1325 | p->type = type; |
1257 | p->payload = state->outgoing_packet; | 1326 | p->payload = state->outgoing_packet; |
1258 | TAILQ_INSERT_TAIL(&state->outgoing, p, next); | 1327 | TAILQ_INSERT_TAIL(&state->outgoing, p, next); |
1259 | state->outgoing_packet = sshbuf_new(); | 1328 | state->outgoing_packet = sshbuf_new(); |
1260 | if (state->outgoing_packet == NULL) | 1329 | if (state->outgoing_packet == NULL) |
1261 | return SSH_ERR_ALLOC_FAIL; | 1330 | return SSH_ERR_ALLOC_FAIL; |
1262 | return 0; | 1331 | if (need_rekey) { |
1332 | /* | ||
1333 | * This packet triggered a rekey, so send the | ||
1334 | * KEXINIT now. | ||
1335 | * NB. reenters this function via kex_start_rekex(). | ||
1336 | */ | ||
1337 | return kex_start_rekex(ssh); | ||
1263 | } | 1338 | } |
1339 | return 0; | ||
1264 | } | 1340 | } |
1265 | 1341 | ||
1266 | /* rekeying starts with sending KEXINIT */ | 1342 | /* rekeying starts with sending KEXINIT */ |
@@ -1276,10 +1352,22 @@ ssh_packet_send2(struct ssh *ssh) | |||
1276 | state->rekey_time = monotime(); | 1352 | state->rekey_time = monotime(); |
1277 | while ((p = TAILQ_FIRST(&state->outgoing))) { | 1353 | while ((p = TAILQ_FIRST(&state->outgoing))) { |
1278 | type = p->type; | 1354 | type = p->type; |
1355 | /* | ||
1356 | * If this packet triggers a rekex, then skip the | ||
1357 | * remaining packets in the queue for now. | ||
1358 | * NB. re-enters this function via kex_start_rekex. | ||
1359 | */ | ||
1360 | if (ssh_packet_need_rekeying(ssh, | ||
1361 | sshbuf_len(p->payload))) { | ||
1362 | debug3("%s: queued packet triggered rekex", | ||
1363 | __func__); | ||
1364 | return kex_start_rekex(ssh); | ||
1365 | } | ||
1279 | debug("dequeue packet: %u", type); | 1366 | debug("dequeue packet: %u", type); |
1280 | sshbuf_free(state->outgoing_packet); | 1367 | sshbuf_free(state->outgoing_packet); |
1281 | state->outgoing_packet = p->payload; | 1368 | state->outgoing_packet = p->payload; |
1282 | TAILQ_REMOVE(&state->outgoing, p, next); | 1369 | TAILQ_REMOVE(&state->outgoing, p, next); |
1370 | memset(p, 0, sizeof(*p)); | ||
1283 | free(p); | 1371 | free(p); |
1284 | if ((r = ssh_packet_send2_wrapped(ssh)) != 0) | 1372 | if ((r = ssh_packet_send2_wrapped(ssh)) != 0) |
1285 | return r; | 1373 | return r; |
@@ -1784,6 +1872,13 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1784 | #endif | 1872 | #endif |
1785 | /* reset for next packet */ | 1873 | /* reset for next packet */ |
1786 | state->packlen = 0; | 1874 | state->packlen = 0; |
1875 | |||
1876 | /* do we need to rekey? */ | ||
1877 | if (ssh_packet_need_rekeying(ssh, 0)) { | ||
1878 | debug3("%s: rekex triggered", __func__); | ||
1879 | if ((r = kex_start_rekex(ssh)) != 0) | ||
1880 | return r; | ||
1881 | } | ||
1787 | out: | 1882 | out: |
1788 | return r; | 1883 | return r; |
1789 | } | 1884 | } |
@@ -2268,25 +2363,6 @@ ssh_packet_send_ignore(struct ssh *ssh, int nbytes) | |||
2268 | } | 2363 | } |
2269 | } | 2364 | } |
2270 | 2365 | ||
2271 | #define MAX_PACKETS (1U<<31) | ||
2272 | int | ||
2273 | ssh_packet_need_rekeying(struct ssh *ssh) | ||
2274 | { | ||
2275 | struct session_state *state = ssh->state; | ||
2276 | |||
2277 | if (ssh->compat & SSH_BUG_NOREKEY) | ||
2278 | return 0; | ||
2279 | return | ||
2280 | (state->p_send.packets > MAX_PACKETS) || | ||
2281 | (state->p_read.packets > MAX_PACKETS) || | ||
2282 | (state->max_blocks_out && | ||
2283 | (state->p_send.blocks > state->max_blocks_out)) || | ||
2284 | (state->max_blocks_in && | ||
2285 | (state->p_read.blocks > state->max_blocks_in)) || | ||
2286 | (state->rekey_interval != 0 && state->rekey_time + | ||
2287 | state->rekey_interval <= monotime()); | ||
2288 | } | ||
2289 | |||
2290 | void | 2366 | void |
2291 | ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, time_t seconds) | 2367 | ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, time_t seconds) |
2292 | { | 2368 | { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.h,v 1.69 2016/01/29 02:54:45 dtucker Exp $ */ | 1 | /* $OpenBSD: packet.h,v 1.70 2016/02/08 10:57:07 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -86,6 +86,7 @@ int ssh_packet_get_connection_in(struct ssh *); | |||
86 | int ssh_packet_get_connection_out(struct ssh *); | 86 | int ssh_packet_get_connection_out(struct ssh *); |
87 | void ssh_packet_close(struct ssh *); | 87 | void ssh_packet_close(struct ssh *); |
88 | void ssh_packet_set_encryption_key(struct ssh *, const u_char *, u_int, int); | 88 | void ssh_packet_set_encryption_key(struct ssh *, const u_char *, u_int, int); |
89 | int ssh_packet_is_rekeying(struct ssh *); | ||
89 | void ssh_packet_set_protocol_flags(struct ssh *, u_int); | 90 | void ssh_packet_set_protocol_flags(struct ssh *, u_int); |
90 | u_int ssh_packet_get_protocol_flags(struct ssh *); | 91 | u_int ssh_packet_get_protocol_flags(struct ssh *); |
91 | int ssh_packet_start_compression(struct ssh *, int); | 92 | int ssh_packet_start_compression(struct ssh *, int); |
@@ -145,7 +146,6 @@ int ssh_packet_set_state(struct ssh *, struct sshbuf *); | |||
145 | const char *ssh_remote_ipaddr(struct ssh *); | 146 | const char *ssh_remote_ipaddr(struct ssh *); |
146 | int ssh_remote_port(struct ssh *); | 147 | int ssh_remote_port(struct ssh *); |
147 | 148 | ||
148 | int ssh_packet_need_rekeying(struct ssh *); | ||
149 | void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, time_t); | 149 | void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, time_t); |
150 | time_t ssh_packet_get_rekey_timeout(struct ssh *); | 150 | time_t ssh_packet_get_rekey_timeout(struct ssh *); |
151 | 151 | ||
diff --git a/serverloop.c b/serverloop.c index 47bc168b2..80d1db549 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: serverloop.c,v 1.181 2016/01/14 16:17:40 markus Exp $ */ | 1 | /* $OpenBSD: serverloop.c,v 1.182 2016/02/08 10:57:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -820,7 +820,7 @@ void | |||
820 | server_loop2(Authctxt *authctxt) | 820 | server_loop2(Authctxt *authctxt) |
821 | { | 821 | { |
822 | fd_set *readset = NULL, *writeset = NULL; | 822 | fd_set *readset = NULL, *writeset = NULL; |
823 | int rekeying = 0, max_fd; | 823 | int max_fd; |
824 | u_int nalloc = 0; | 824 | u_int nalloc = 0; |
825 | u_int64_t rekey_timeout_ms = 0; | 825 | u_int64_t rekey_timeout_ms = 0; |
826 | 826 | ||
@@ -847,11 +847,11 @@ server_loop2(Authctxt *authctxt) | |||
847 | for (;;) { | 847 | for (;;) { |
848 | process_buffered_input_packets(); | 848 | process_buffered_input_packets(); |
849 | 849 | ||
850 | rekeying = (active_state->kex != NULL && !active_state->kex->done); | 850 | if (!ssh_packet_is_rekeying(active_state) && |
851 | 851 | packet_not_very_much_data_to_write()) | |
852 | if (!rekeying && packet_not_very_much_data_to_write()) | ||
853 | channel_output_poll(); | 852 | channel_output_poll(); |
854 | if (options.rekey_interval > 0 && compat20 && !rekeying) | 853 | if (options.rekey_interval > 0 && compat20 && |
854 | !ssh_packet_is_rekeying(active_state)) | ||
855 | rekey_timeout_ms = packet_get_rekey_timeout() * 1000; | 855 | rekey_timeout_ms = packet_get_rekey_timeout() * 1000; |
856 | else | 856 | else |
857 | rekey_timeout_ms = 0; | 857 | rekey_timeout_ms = 0; |
@@ -866,14 +866,8 @@ server_loop2(Authctxt *authctxt) | |||
866 | } | 866 | } |
867 | 867 | ||
868 | collect_children(); | 868 | collect_children(); |
869 | if (!rekeying) { | 869 | if (!ssh_packet_is_rekeying(active_state)) |
870 | channel_after_select(readset, writeset); | 870 | channel_after_select(readset, writeset); |
871 | if (packet_need_rekeying()) { | ||
872 | debug("need rekeying"); | ||
873 | active_state->kex->done = 0; | ||
874 | kex_send_kexinit(active_state); | ||
875 | } | ||
876 | } | ||
877 | process_input(readset); | 871 | process_input(readset); |
878 | if (connection_closed) | 872 | if (connection_closed) |
879 | break; | 873 | break; |