From: djm Date: Fri, 16 Jul 2021 09:00:23 +0000 (+0000) Subject: Explicitly check for and start time-based rekeying in the client X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=76eecf5e6b7acc2802512acf4a91b8f20e4a49c6;p=openbsd Explicitly check for and start time-based rekeying in the client and server mainloops. Previously the rekey timeout could expire but rekeying would not start until a packet was sent or received. This could cause us to spin in select() on the rekey timeout if the connection was quiet. ok markus@ --- diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index 83efcef25d1..b84c986bd35 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.366 2021/07/13 23:48:36 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.367 2021/07/16 09:00:23 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1350,6 +1350,10 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, if (quit_pending) break; + /* A timeout may have triggered rekeying */ + if ((r = ssh_packet_check_rekey(ssh)) != 0) + fatal_fr(r, "cannot start rekeying"); + /* * Send as much buffered packet data as possible to the * sender. diff --git a/usr.bin/ssh/packet.c b/usr.bin/ssh/packet.c index 3156eedb0c5..240186162bb 100644 --- a/usr.bin/ssh/packet.c +++ b/usr.bin/ssh/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.300 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.301 2021/07/16 09:00:23 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -982,6 +982,15 @@ ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) (state->p_read.blocks > state->max_blocks_in)); } +int +ssh_packet_check_rekey(struct ssh *ssh) +{ + if (!ssh_packet_need_rekeying(ssh, 0)) + return 0; + debug3_f("rekex triggered"); + return kex_start_rekex(ssh); +} + /* * Delayed compression for SSH2 is enabled after authentication: * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, @@ -1674,12 +1683,8 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) /* reset for next packet */ state->packlen = 0; - /* do we need to rekey? */ - if (ssh_packet_need_rekeying(ssh, 0)) { - debug3_f("rekex triggered"); - if ((r = kex_start_rekex(ssh)) != 0) - return r; - } + if ((r = ssh_packet_check_rekey(ssh)) != 0) + return r; out: return r; } diff --git a/usr.bin/ssh/packet.h b/usr.bin/ssh/packet.h index 2fc6c5b7191..ac03c27aa21 100644 --- a/usr.bin/ssh/packet.h +++ b/usr.bin/ssh/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.92 2020/03/06 18:11:10 markus Exp $ */ +/* $OpenBSD: packet.h,v 1.93 2021/07/16 09:00:23 djm Exp $ */ /* * Author: Tatu Ylonen @@ -99,6 +99,7 @@ void ssh_packet_clear_keys(struct ssh *); void ssh_clear_newkeys(struct ssh *, int); int ssh_packet_is_rekeying(struct ssh *); +int ssh_packet_check_rekey(struct ssh *); void ssh_packet_set_protocol_flags(struct ssh *, u_int); u_int ssh_packet_get_protocol_flags(struct ssh *); void ssh_packet_set_tos(struct ssh *, int); diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c index dd13b792029..ab2af547f2a 100644 --- a/usr.bin/ssh/serverloop.c +++ b/usr.bin/ssh/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.227 2021/06/25 03:38:17 dtucker Exp $ */ +/* $OpenBSD: serverloop.c,v 1.228 2021/07/16 09:00:23 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -329,7 +329,7 @@ void server_loop2(struct ssh *ssh, Authctxt *authctxt) { fd_set *readset = NULL, *writeset = NULL; - int max_fd; + int r, max_fd; u_int nalloc = 0, connection_in, connection_out; u_int64_t rekey_timeout_ms = 0; sigset_t bsigset, osigset; @@ -391,6 +391,9 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) channel_after_select(ssh, readset, writeset); if (process_input(ssh, readset, connection_in) < 0) break; + /* A timeout may have triggered rekeying */ + if ((r = ssh_packet_check_rekey(ssh)) != 0) + fatal_fr(r, "cannot start rekeying"); process_output(ssh, writeset, connection_out); } collect_children(ssh);