diff --git a/src/comp.c b/src/comp.c index ed854fee..4593ce4f 100644 --- a/src/comp.c +++ b/src/comp.c @@ -96,6 +96,7 @@ comp_method_none_decomp(LIBSSH2_SESSION * session, static const LIBSSH2_COMP_METHOD comp_method_none = { "none", 0, /* not really compressing */ + 0, /* isn't used in userauth, go figure */ NULL, comp_method_none_comp, comp_method_none_decomp, @@ -330,6 +331,17 @@ comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract) static const LIBSSH2_COMP_METHOD comp_method_zlib = { "zlib", 1, /* yes, this compresses */ + 1, /* do compression during userauth */ + comp_method_zlib_init, + comp_method_zlib_comp, + comp_method_zlib_decomp, + comp_method_zlib_dtor, +}; + +static const LIBSSH2_COMP_METHOD comp_method_zlib_openssh = { + "zlib@openssh.com", + 1, /* yes, this compresses */ + 0, /* don't use compression during userauth */ comp_method_zlib_init, comp_method_zlib_comp, comp_method_zlib_decomp, @@ -342,6 +354,7 @@ static const LIBSSH2_COMP_METHOD comp_method_zlib = { static const LIBSSH2_COMP_METHOD *comp_methods[] = { #ifdef LIBSSH2_HAVE_ZLIB &comp_method_zlib, + &comp_method_zlib_openssh, #endif /* LIBSSH2_HAVE_ZLIB */ &comp_method_none, NULL diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h index 23545624..23fbc65c 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -892,6 +892,7 @@ struct _LIBSSH2_COMP_METHOD { const char *name; int compress; /* 1 if it does compress, 0 if it doesn't */ + int use_in_auth; /* 1 if compression should be used in userauth */ int (*init) (LIBSSH2_SESSION *session, int compress, void **abstract); int (*comp) (LIBSSH2_SESSION *session, unsigned char *dest, diff --git a/src/transport.c b/src/transport.c index 95b9a3ad..15425b92 100644 --- a/src/transport.c +++ b/src/transport.c @@ -167,6 +167,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ ) unsigned char macbuf[MAX_MACSIZE]; struct transportpacket *p = &session->packet; int rc; + int compressed; if (session->fullpacket_state == libssh2_NB_state_idle) { session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED; @@ -199,9 +200,13 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ ) session->fullpacket_payload_len -= p->padding_length; /* Check for and deal with decompression */ - if (session->remote.comp && - session->remote.comp->compress && - session->remote.comp_abstract) { + compressed = + session->local.comp != NULL && + session->local.comp->compress && + ((session->state & LIBSSH2_STATE_AUTHENTICATED) || + session->local.comp->use_in_auth); + + if (compressed && session->remote.comp_abstract) { /* * The buffer for the decompression (remote.comp_abstract) is * initialised in time when it is needed so as long it is NULL we @@ -682,6 +687,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session, #endif struct transportpacket *p = &session->packet; int encrypted; + int compressed; ssize_t ret; int rc; const unsigned char *orgdata = data; @@ -723,7 +729,13 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session, encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0; - if (encrypted && session->local.comp->compress) { + compressed = + session->local.comp != NULL && + session->local.comp->compress && + ((session->state & LIBSSH2_STATE_AUTHENTICATED) || + session->local.comp->use_in_auth); + + if (encrypted && compressed) { /* the idea here is that these function must fail if the output gets larger than what fits in the assigned buffer so thus they don't check the input size as we don't know how much it compresses */