diff options
-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; |