diff options
-rw-r--r-- | cli-auth.c | 2 | ||||
-rw-r--r-- | common-algo.c | 1 | ||||
-rw-r--r-- | common-kex.c | 23 | ||||
-rw-r--r-- | dbclient.1 | 1 | ||||
-rw-r--r-- | kex.h | 5 | ||||
-rw-r--r-- | packet.c | 13 | ||||
-rw-r--r-- | session.h | 2 | ||||
-rw-r--r-- | svr-auth.c | 2 | ||||
-rw-r--r-- | sysoptions.h | 1 |
9 files changed, 40 insertions, 10 deletions
@@ -229,6 +229,8 @@ void recv_msg_userauth_failure() { void recv_msg_userauth_success() { TRACE(("received msg_userauth_success")) + /* Note: in delayed-zlib mode, setting authdone here + * will enable compression in the transport layer */ ses.authstate.authdone = 1; cli_ses.state = USERAUTH_SUCCESS_RCVD; cli_ses.lastauthtype = AUTH_TYPE_NONE; diff --git a/common-algo.c b/common-algo.c index 21ac96a..d38c5e5 100644 --- a/common-algo.c +++ b/common-algo.c @@ -124,6 +124,7 @@ algo_type sshhashes[] = { algo_type sshcompress[] = { #ifndef DISABLE_ZLIB {"zlib", DROPBEAR_COMP_ZLIB, NULL, 1}, + {"zlib@openssh.com", DROPBEAR_COMP_ZLIB_DELAY, NULL, 1}, #endif {"none", DROPBEAR_COMP_NONE, NULL, 1}, {NULL, 0, NULL, 0} diff --git a/common-kex.c b/common-kex.c index e9c655d..80eb2a1 100644 --- a/common-kex.c +++ b/common-kex.c @@ -331,12 +331,26 @@ void gen_new_keys() { } #ifndef DISABLE_ZLIB + +int is_compress_trans() { + return ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB + || (ses.authstate.authdone + && ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB_DELAY); +} + +int is_compress_recv() { + return ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB + || (ses.authstate.authdone + && ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB_DELAY); +} + /* Set up new zlib compression streams, close the old ones. Only * called from gen_new_keys() */ static void gen_new_zstreams() { /* create new zstreams */ - if (ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB) { + if (ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB + || ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB_DELAY) { ses.newkeys->recv_zstream = (z_streamp)m_malloc(sizeof(z_stream)); ses.newkeys->recv_zstream->zalloc = Z_NULL; ses.newkeys->recv_zstream->zfree = Z_NULL; @@ -348,7 +362,8 @@ static void gen_new_zstreams() { ses.newkeys->recv_zstream = NULL; } - if (ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB) { + if (ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB + || ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB_DELAY) { ses.newkeys->trans_zstream = (z_streamp)m_malloc(sizeof(z_stream)); ses.newkeys->trans_zstream->zalloc = Z_NULL; ses.newkeys->trans_zstream->zfree = Z_NULL; @@ -360,7 +375,7 @@ static void gen_new_zstreams() { } else { ses.newkeys->trans_zstream = NULL; } - + /* clean up old keys */ if (ses.keys->recv_zstream != NULL) { if (inflateEnd(ses.keys->recv_zstream) == Z_STREAM_ERROR) { @@ -377,7 +392,7 @@ static void gen_new_zstreams() { m_free(ses.keys->trans_zstream); } } -#endif +#endif /* DISABLE_ZLIB */ /* Executed upon receiving a kexinit message from the client to initiate @@ -10,6 +10,7 @@ dbclient \- lightweight SSH2 client .I l\fR:\fIh\fR:\fIr\fR] [\-l .IR user ] .I host +.RI [ command ] .SH DESCRIPTION .B dbclient is a SSH 2 client designed to be small enough to be used in small memory @@ -37,6 +37,11 @@ void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv); void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, sign_key *hostkey); +#ifndef DISABLE_ZLIB +int is_compress_trans(); +int is_compress_recv(); +#endif + void recv_msg_kexdh_init(); /* server */ void send_msg_kexdh_init(); /* client */ @@ -290,10 +290,9 @@ void decrypt_packet() { buf_setpos(ses.decryptreadbuf, PACKET_PAYLOAD_OFF); #ifndef DISABLE_ZLIB - if (ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB) { + if (is_compress_recv()) { /* decompress */ ses.payload = buf_decompress(ses.decryptreadbuf, len); - } else #endif { @@ -469,6 +468,7 @@ void encrypt_packet() { buffer * writebuf; /* the packet which will go on the wire */ buffer * clearwritebuf; /* unencrypted, possibly compressed */ unsigned char type; + unsigned int clear_len; type = ses.writepayload->data[0]; TRACE(("enter encrypt_packet()")) @@ -488,11 +488,12 @@ void encrypt_packet() { /* Encrypted packet len is payload+5, then worst case is if we are 3 away * from a blocksize multiple. In which case we need to pad to the * multiple, then add another blocksize (or MIN_PACKET_LEN) */ - clearwritebuf = buf_new((ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3 + clear_len = (ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3; + #ifndef DISABLE_ZLIB - + ZLIB_COMPRESS_INCR /* bit of a kludge, but we can't know len*/ + clear_len += ZLIB_COMPRESS_INCR; /* bit of a kludge, but we can't know len*/ #endif - ); + clearwritebuf = buf_new(clear_len); buf_setlen(clearwritebuf, PACKET_PAYLOAD_OFF); buf_setpos(clearwritebuf, PACKET_PAYLOAD_OFF); @@ -500,7 +501,7 @@ void encrypt_packet() { #ifndef DISABLE_ZLIB /* compression */ - if (ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB) { + if (is_compress_trans()) { buf_compress(clearwritebuf, ses.writepayload, ses.writepayload->len); } else #endif @@ -71,6 +71,8 @@ struct key_context { char recv_algo_comp; /* compression */ char trans_algo_comp; + int allow_compress; /* whether compression has started (useful in + zlib@openssh.com delayed compression case) */ #ifndef DISABLE_ZLIB z_streamp recv_zstream; z_streamp trans_zstream; @@ -368,6 +368,8 @@ void send_msg_userauth_success() { buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_SUCCESS); encrypt_packet(); + /* authdone must be set after encrypt_packet() for + * delayed-zlib mode */ ses.authstate.authdone = 1; ses.connect_time = 0; diff --git a/sysoptions.h b/sysoptions.h index 6b17151..4899e42 100644 --- a/sysoptions.h +++ b/sysoptions.h @@ -68,6 +68,7 @@ #define DROPBEAR_COMP_NONE 0 #define DROPBEAR_COMP_ZLIB 1 +#define DROPBEAR_COMP_ZLIB_DELAY 2 /* Required for pubkey auth */ #if defined(ENABLE_SVR_PUBKEY_AUTH) || defined(DROPBEAR_CLIENT) |