From 98b81ebcadac060eb234c4d062ba6ffe58d4d666 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 19 Dec 2022 15:15:08 +0100 Subject: [PATCH] wrapper: Correctly handle rekey with delayed compression Signed-off-by: Jakub Jelen Reviewed-by: Norbert Pocs --- src/wrapper.c | 66 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/src/wrapper.c b/src/wrapper.c index 49f13b73..836c7cdd 100644 --- a/src/wrapper.c +++ b/src/wrapper.c @@ -242,9 +242,32 @@ void crypto_free(struct ssh_crypto_struct *crypto) SAFE_FREE(crypto); } +static void +compression_enable(ssh_session session, + enum ssh_crypto_direction_e direction, + bool delayed) +{ + /* The delayed compression is turned on AFTER authentication. This means + * that we need to turn it on immediately in case of rekeying */ + if (delayed && !(session->flags & SSH_SESSION_FLAG_AUTHENTICATED)) { + if (direction == SSH_DIRECTION_IN) { + session->next_crypto->delayed_compress_in = 1; + } else { /* SSH_DIRECTION_OUT */ + session->next_crypto->delayed_compress_out = 1; + } + } else { + if (direction == SSH_DIRECTION_IN) { + session->next_crypto->do_compress_in = 1; + } else { /* SSH_DIRECTION_OUT */ + session->next_crypto->do_compress_out = 1; + } + } +} + static int crypt_set_algorithms2(ssh_session session) { const char *wanted = NULL; + const char *method = NULL; struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab(); struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab(); uint8_t i = 0; @@ -367,22 +390,29 @@ static int crypt_set_algorithms2(ssh_session session) session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type; session->next_crypto->in_hmac_etm = ssh_hmactab[i].etm; - /* compression */ - cmp = strcmp(session->next_crypto->kex_methods[SSH_COMP_C_S], "zlib"); + /* compression: client */ + method = session->next_crypto->kex_methods[SSH_COMP_C_S]; + cmp = strcmp(method, "zlib"); if (cmp == 0) { - session->next_crypto->do_compress_out = 1; + SSH_LOG(SSH_LOG_PACKET, "enabling C->S compression"); + compression_enable(session, SSH_DIRECTION_OUT, false); } - cmp = strcmp(session->next_crypto->kex_methods[SSH_COMP_S_C], "zlib"); + cmp = strcmp(method, "zlib@openssh.com"); if (cmp == 0) { - session->next_crypto->do_compress_in = 1; + SSH_LOG(SSH_LOG_PACKET, "enabling C->S delayed compression"); + compression_enable(session, SSH_DIRECTION_OUT, true); } - cmp = strcmp(session->next_crypto->kex_methods[SSH_COMP_C_S], "zlib@openssh.com"); + + method = session->next_crypto->kex_methods[SSH_COMP_S_C]; + cmp = strcmp(method, "zlib"); if (cmp == 0) { - session->next_crypto->delayed_compress_out = 1; + SSH_LOG(SSH_LOG_PACKET, "enabling S->C compression"); + compression_enable(session, SSH_DIRECTION_IN, false); } - cmp = strcmp(session->next_crypto->kex_methods[SSH_COMP_S_C], "zlib@openssh.com"); + cmp = strcmp(method, "zlib@openssh.com"); if (cmp == 0) { - session->next_crypto->delayed_compress_in = 1; + SSH_LOG(SSH_LOG_PACKET, "enabling S->C delayed compression"); + compression_enable(session, SSH_DIRECTION_IN, true); } return SSH_OK; @@ -522,34 +552,24 @@ int crypt_set_algorithms_server(ssh_session session){ cmp = strcmp(method, "zlib"); if (cmp == 0) { SSH_LOG(SSH_LOG_PACKET, "enabling C->S compression"); - session->next_crypto->do_compress_in = 1; + compression_enable(session, SSH_DIRECTION_IN, false); } cmp = strcmp(method, "zlib@openssh.com"); if (cmp == 0) { SSH_LOG(SSH_LOG_PACKET, "enabling C->S delayed compression"); - - if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) { - session->next_crypto->do_compress_in = 1; - } else { - session->next_crypto->delayed_compress_in = 1; - } + compression_enable(session, SSH_DIRECTION_IN, true); } method = session->next_crypto->kex_methods[SSH_COMP_S_C]; cmp = strcmp(method, "zlib"); if (cmp == 0) { SSH_LOG(SSH_LOG_PACKET, "enabling S->C compression"); - session->next_crypto->do_compress_out = 1; + compression_enable(session, SSH_DIRECTION_OUT, false); } cmp = strcmp(method, "zlib@openssh.com"); if (cmp == 0) { SSH_LOG(SSH_LOG_PACKET, "enabling S->C delayed compression"); - - if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) { - session->next_crypto->do_compress_out = 1; - } else { - session->next_crypto->delayed_compress_out = 1; - } + compression_enable(session, SSH_DIRECTION_OUT, true); } method = session->next_crypto->kex_methods[SSH_HOSTKEYS];