diff common-kex.c @ 579:8c737cd7c1af

merge of '48fdaa8706d1acda35e9d564adc9a1fbc96c18c8' and '658fd03abd21e0da7c4c89b9fff9dc693c72daae'
author Matt Johnston <matt@ucc.asn.au>
date Sat, 27 Feb 2010 11:53:18 +0000
parents f9b5dc0cba61
children a98a2138364a
line wrap: on
line diff
--- a/common-kex.c	Wed Feb 24 16:13:15 2010 +0000
+++ b/common-kex.c	Sat Feb 27 11:53:18 2010 +0000
@@ -33,6 +33,7 @@
 #include "packet.h"
 #include "bignum.h"
 #include "random.h"
+#include "runopts.h"
 
 /* diffie-hellman-group1-sha1 value for p */
 static const unsigned char dh_p_val[] = {
@@ -91,10 +92,10 @@
 	buf_put_algolist(ses.writepayload, sshhashes);
 
 	/* compression_algorithms_client_to_server */
-	buf_put_algolist(ses.writepayload, sshcompress);
+	buf_put_algolist(ses.writepayload, ses.compress_algos);
 
 	/* compression_algorithms_server_to_client */
-	buf_put_algolist(ses.writepayload, sshcompress);
+	buf_put_algolist(ses.writepayload, ses.compress_algos);
 
 	/* languages_client_to_server */
 	buf_putstring(ses.writepayload, "", 0);
@@ -180,8 +181,16 @@
 
 /* Set up the kex for the first time */
 void kexfirstinitialise() {
+	ses.kexstate.donefirstkex = 0;
 
-	ses.kexstate.donefirstkex = 0;
+#ifndef DISABLE_ZLIB
+	if (opts.enable_compress) {
+		ses.compress_algos = ssh_compress;
+	} else
+#endif
+	{
+		ses.compress_algos = ssh_nocompress;
+	}
 	kexinitialise();
 }
 
@@ -272,8 +281,8 @@
 	    recv_IV		= S2C_IV;
 	    trans_key	= C2S_key;
 	    recv_key	= S2C_key;
-	    C2S_keysize = ses.newkeys->trans_algo_crypt->keysize;
-	    S2C_keysize = ses.newkeys->recv_algo_crypt->keysize;
+	    C2S_keysize = ses.newkeys->trans.algo_crypt->keysize;
+	    S2C_keysize = ses.newkeys->recv.algo_crypt->keysize;
 		mactransletter = 'E';
 		macrecvletter = 'F';
 	} else {
@@ -281,8 +290,8 @@
 	    recv_IV		= C2S_IV;
 	    trans_key	= S2C_key;
 	    recv_key	= C2S_key;
-	    C2S_keysize = ses.newkeys->recv_algo_crypt->keysize;
-	    S2C_keysize = ses.newkeys->trans_algo_crypt->keysize;
+	    C2S_keysize = ses.newkeys->recv.algo_crypt->keysize;
+	    S2C_keysize = ses.newkeys->trans.algo_crypt->keysize;
 		mactransletter = 'F';
 		macrecvletter = 'E';
 	}
@@ -292,31 +301,33 @@
 	hashkeys(C2S_key, C2S_keysize, &hs, 'C');
 	hashkeys(S2C_key, S2C_keysize, &hs, 'D');
 
-	recv_cipher = find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name);
+	recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
 	if (recv_cipher < 0)
 	    dropbear_exit("crypto error");
-	if (ses.newkeys->recv_crypt_mode->start(recv_cipher, 
+	if (ses.newkeys->recv.crypt_mode->start(recv_cipher, 
 			recv_IV, recv_key, 
-			ses.newkeys->recv_algo_crypt->keysize, 0, 
-			&ses.newkeys->recv_cipher_state) != CRYPT_OK) {
+			ses.newkeys->recv.algo_crypt->keysize, 0, 
+			&ses.newkeys->recv.cipher_state) != CRYPT_OK) {
 		dropbear_exit("crypto error");
 	}
 
-	trans_cipher = find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name);
+	trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name);
 	if (trans_cipher < 0)
 	    dropbear_exit("crypto error");
-	if (ses.newkeys->trans_crypt_mode->start(trans_cipher, 
+	if (ses.newkeys->trans.crypt_mode->start(trans_cipher, 
 			trans_IV, trans_key, 
-			ses.newkeys->trans_algo_crypt->keysize, 0, 
-			&ses.newkeys->trans_cipher_state) != CRYPT_OK) {
+			ses.newkeys->trans.algo_crypt->keysize, 0, 
+			&ses.newkeys->trans.cipher_state) != CRYPT_OK) {
 		dropbear_exit("crypto error");
 	}
 	
 	/* MAC keys */
-	hashkeys(ses.newkeys->transmackey, 
-			ses.newkeys->trans_algo_mac->keysize, &hs, mactransletter);
-	hashkeys(ses.newkeys->recvmackey, 
-			ses.newkeys->recv_algo_mac->keysize, &hs, macrecvletter);
+	hashkeys(ses.newkeys->trans.mackey, 
+			ses.newkeys->trans.algo_mac->keysize, &hs, mactransletter);
+	hashkeys(ses.newkeys->recv.mackey, 
+			ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter);
+	ses.newkeys->trans.hash_index = find_hash(ses.newkeys->trans.algo_mac->hashdesc->name),
+	ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hashdesc->name),
 
 #ifndef DISABLE_ZLIB
 	gen_new_zstreams();
@@ -334,15 +345,15 @@
 #ifndef DISABLE_ZLIB
 
 int is_compress_trans() {
-	return ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB
+	return ses.keys->trans.algo_comp == DROPBEAR_COMP_ZLIB
 		|| (ses.authstate.authdone
-			&& ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
+			&& ses.keys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
 }
 
 int is_compress_recv() {
-	return ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB
+	return ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB
 		|| (ses.authstate.authdone
-			&& ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
+			&& ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
 }
 
 /* Set up new zlib compression streams, close the old ones. Only
@@ -350,47 +361,49 @@
 static void gen_new_zstreams() {
 
 	/* create new zstreams */
-	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;
+	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;
 		
-		if (inflateInit(ses.newkeys->recv_zstream) != Z_OK) {
+		if (inflateInit(ses.newkeys->recv.zstream) != Z_OK) {
 			dropbear_exit("zlib error");
 		}
 	} else {
-		ses.newkeys->recv_zstream = NULL;
+		ses.newkeys->recv.zstream = NULL;
 	}
 
-	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;
+	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;
 	
-		if (deflateInit(ses.newkeys->trans_zstream, Z_DEFAULT_COMPRESSION) 
+		if (deflateInit2(ses.newkeys->trans.zstream, Z_DEFAULT_COMPRESSION,
+					Z_DEFLATED, DROPBEAR_ZLIB_WINDOW_BITS, 
+					DROPBEAR_ZLIB_MEM_LEVEL, Z_DEFAULT_STRATEGY)
 				!= Z_OK) {
 			dropbear_exit("zlib error");
 		}
 	} else {
-		ses.newkeys->trans_zstream = NULL;
+		ses.newkeys->trans.zstream = NULL;
 	}
 
 	/* clean up old keys */
-	if (ses.keys->recv_zstream != NULL) {
-		if (inflateEnd(ses.keys->recv_zstream) == Z_STREAM_ERROR) {
+	if (ses.keys->recv.zstream != NULL) {
+		if (inflateEnd(ses.keys->recv.zstream) == Z_STREAM_ERROR) {
 			/* Z_DATA_ERROR is ok, just means that stream isn't ended */
 			dropbear_exit("crypto error");
 		}
-		m_free(ses.keys->recv_zstream);
+		m_free(ses.keys->recv.zstream);
 	}
-	if (ses.keys->trans_zstream != NULL) {
-		if (deflateEnd(ses.keys->trans_zstream) == Z_STREAM_ERROR) {
+	if (ses.keys->trans.zstream != NULL) {
+		if (deflateEnd(ses.keys->trans.zstream) == Z_STREAM_ERROR) {
 			/* Z_DATA_ERROR is ok, just means that stream isn't ended */
 			dropbear_exit("crypto error");
 		}
-		m_free(ses.keys->trans_zstream);
+		m_free(ses.keys->trans.zstream);
 	}
 }
 #endif /* DISABLE_ZLIB */
@@ -666,7 +679,7 @@
 	TRACE(("hash s2c is  %s", s2c_hash_algo->name))
 
 	/* compression_algorithms_client_to_server */
-	c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
+	c2s_comp_algo = ses.buf_match_algo(ses.payload, ses.compress_algos, &goodguess);
 	if (c2s_comp_algo == NULL) {
 		erralgo = "comp c->s";
 		goto error;
@@ -674,7 +687,7 @@
 	TRACE(("hash c2s is  %s", c2s_comp_algo->name))
 
 	/* compression_algorithms_server_to_client */
-	s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
+	s2c_comp_algo = ses.buf_match_algo(ses.payload, ses.compress_algos, &goodguess);
 	if (s2c_comp_algo == NULL) {
 		erralgo = "comp s->c";
 		goto error;
@@ -698,36 +711,36 @@
 
 	/* Handle the asymmetry */
 	if (IS_DROPBEAR_CLIENT) {
-		ses.newkeys->recv_algo_crypt = 
+		ses.newkeys->recv.algo_crypt = 
 			(struct dropbear_cipher*)s2c_cipher_algo->data;
-		ses.newkeys->trans_algo_crypt = 
+		ses.newkeys->trans.algo_crypt = 
 			(struct dropbear_cipher*)c2s_cipher_algo->data;
-		ses.newkeys->recv_crypt_mode = 
+		ses.newkeys->recv.crypt_mode = 
 			(struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
-		ses.newkeys->trans_crypt_mode =
+		ses.newkeys->trans.crypt_mode =
 			(struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
-		ses.newkeys->recv_algo_mac = 
+		ses.newkeys->recv.algo_mac = 
 			(struct dropbear_hash*)s2c_hash_algo->data;
-		ses.newkeys->trans_algo_mac = 
+		ses.newkeys->trans.algo_mac = 
 			(struct dropbear_hash*)c2s_hash_algo->data;
-		ses.newkeys->recv_algo_comp = s2c_comp_algo->val;
-		ses.newkeys->trans_algo_comp = c2s_comp_algo->val;
+		ses.newkeys->recv.algo_comp = s2c_comp_algo->val;
+		ses.newkeys->trans.algo_comp = c2s_comp_algo->val;
 	} else {
 		/* SERVER */
-		ses.newkeys->recv_algo_crypt = 
+		ses.newkeys->recv.algo_crypt = 
 			(struct dropbear_cipher*)c2s_cipher_algo->data;
-		ses.newkeys->trans_algo_crypt = 
+		ses.newkeys->trans.algo_crypt = 
 			(struct dropbear_cipher*)s2c_cipher_algo->data;
-		ses.newkeys->recv_crypt_mode =
+		ses.newkeys->recv.crypt_mode =
 			(struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
-		ses.newkeys->trans_crypt_mode =
+		ses.newkeys->trans.crypt_mode =
 			(struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
-		ses.newkeys->recv_algo_mac = 
+		ses.newkeys->recv.algo_mac = 
 			(struct dropbear_hash*)c2s_hash_algo->data;
-		ses.newkeys->trans_algo_mac = 
+		ses.newkeys->trans.algo_mac = 
 			(struct dropbear_hash*)s2c_hash_algo->data;
-		ses.newkeys->recv_algo_comp = c2s_comp_algo->val;
-		ses.newkeys->trans_algo_comp = s2c_comp_algo->val;
+		ses.newkeys->recv.algo_comp = c2s_comp_algo->val;
+		ses.newkeys->trans.algo_comp = s2c_comp_algo->val;
 	}
 
 	/* reserved for future extensions */