From 2d82f73484e588e9367657a25331afd4aa0bf976 Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Wed, 28 Jul 2004 16:44:16 +0000
Subject: [PATCH] Client mostly works up to password auth Need to rework
 algo-choosing etc, since server is now broken.

--HG--
extra : convert_revision : 458dc4eed0e885e7c91633d4781d3348213a0e19
---
 cli-auth.c       | 10 +++++-----
 cli-kex.c        | 10 ++++++++--
 cli-service.c    |  4 ++--
 cli-session.c    | 16 +++++++++++-----
 common-kex.c     |  8 ++++++++
 common-session.c |  1 +
 dss.c            |  4 ++++
 process-packet.c |  2 ++
 rsa.c            |  6 ++++++
 service.h        |  1 +
 session.h        |  2 ++
 signkey.c        |  7 +++++++
 12 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/cli-auth.c b/cli-auth.c
index 952546e1..d222d7e9 100644
--- a/cli-auth.c
+++ b/cli-auth.c
@@ -31,7 +31,7 @@ void cli_get_user() {
 
 		ses.authstate.username = m_strdup(pw->pw_name);
 	}
-	TRACE(("leave cli_get_user: %s", cli_ses.username));
+	TRACE(("leave cli_get_user: %s", ses.authstate.username));
 }
 
 /* Send a "none" auth request to get available methods */
@@ -90,7 +90,7 @@ void recv_msg_userauth_failure() {
 	tok = methods; /* tok stores the next method we'll compare */
 	for (i = 0; i <= methlen; i++) {
 		if (methods[i] == '\0') {
-			TRACE(("auth method '%s'\n", tok));
+			TRACE(("auth method '%s'", tok));
 #ifdef DROPBEAR_PUBKEY_AUTH
 			if (strncmp(AUTH_METHOD_PUBKEY, tok,
 				AUTH_METHOD_PUBKEY_LEN) == 0) {
@@ -103,9 +103,9 @@ void recv_msg_userauth_failure() {
 				ses.authstate.authtypes |= AUTH_TYPE_PASSWORD;
 			}
 #endif
-			tok = &methods[i]; /* Must make sure we don't use it after
-								  the last loop, since it'll point
-								  to something undefined */
+			tok = &methods[i+1]; /* Must make sure we don't use it after the
+									last loop, since it'll point to something
+									undefined */
 		}
 	}
 
diff --git a/cli-kex.c b/cli-kex.c
index 2577caff..d8824230 100644
--- a/cli-kex.c
+++ b/cli-kex.c
@@ -43,7 +43,7 @@ void send_msg_kexdh_init() {
 	cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int));
 	cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int));
 
-	m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x);
+	m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);
 	gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x);
 
 	CHECKCLEARTOWRITE();
@@ -58,17 +58,23 @@ void recv_msg_kexdh_reply() {
 
 	mp_int dh_f;
 	sign_key *hostkey = NULL;
-	int type;
+	int type, keylen;
 
+	TRACE(("enter recv_msg_kexdh_reply"));
 	type = ses.newkeys->algo_hostkey;
+	TRACE(("type is %d", type));
 
 	hostkey = new_sign_key();
+	keylen = buf_getint(ses.payload);
+
 	if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) {
+		TRACE(("failed getting pubkey"));
 		dropbear_exit("Bad KEX packet");
 	}
 
 	m_mp_init(&dh_f);
 	if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) {
+		TRACE(("failed getting mpint"));
 		dropbear_exit("Bad KEX packet");
 	}
 
diff --git a/cli-service.c b/cli-service.c
index c8739194..8ba06c62 100644
--- a/cli-service.c
+++ b/cli-service.c
@@ -12,8 +12,8 @@ void send_msg_service_request(char* servicename) {
 
 	CHECKCLEARTOWRITE();
 
-	buf_putbyte(ses.payload, SSH_MSG_SERVICE_REQUEST);
-	buf_putstring(ses.payload, servicename, strlen(servicename));
+	buf_putbyte(ses.writepayload, SSH_MSG_SERVICE_REQUEST);
+	buf_putstring(ses.writepayload, servicename, strlen(servicename));
 
 	encrypt_packet();
 	TRACE(("leave send_msg_service_request"));
diff --git a/cli-session.c b/cli-session.c
index 9f80bd11..2ae27196 100644
--- a/cli-session.c
+++ b/cli-session.c
@@ -21,6 +21,7 @@ static const packettype cli_packettypes[] = {
 	{SSH_MSG_KEXINIT, recv_msg_kexinit},
 	{SSH_MSG_KEXDH_REPLY, recv_msg_kexdh_reply}, // client
 	{SSH_MSG_NEWKEYS, recv_msg_newkeys},
+	{SSH_MSG_SERVICE_ACCEPT, recv_msg_service_accept}, // client
 	{SSH_MSG_CHANNEL_DATA, recv_msg_channel_data},
 	{SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust},
 	{SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_remotetcp},
@@ -30,8 +31,8 @@ static const packettype cli_packettypes[] = {
 	{SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close},
 	{SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation},
 	{SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure},
-	{SSH_MSG_USERAUTH_FAILURE, recv_msg_userauth_failure},
-	{SSH_MSG_USERAUTH_SUCCESS, recv_msg_userauth_success},
+	{SSH_MSG_USERAUTH_FAILURE, recv_msg_userauth_failure}, // client
+	{SSH_MSG_USERAUTH_SUCCESS, recv_msg_userauth_success}, // client
 	{0, 0} /* End */
 };
 
@@ -90,11 +91,11 @@ static void cli_sessionloop() {
 
 	TRACE(("enter cli_sessionloop"));
 
-	if (cli_ses.kex_state == KEX_NOTHING && ses.kexstate.recvkexinit) {
-		cli_ses.state = KEXINIT_RCVD;
+	if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) {
+		cli_ses.kex_state = KEXINIT_RCVD;
 	}
 
-	if (cli_ses.state == KEXINIT_RCVD) {
+	if (cli_ses.kex_state == KEXINIT_RCVD) {
 
 		/* We initiate the KEXDH. If DH wasn't the correct type, the KEXINIT
 		 * negotiation would have failed. */
@@ -120,6 +121,7 @@ static void cli_sessionloop() {
 	 * in normal operation */
 	if (ses.kexstate.donefirstkex == 0) {
 		TRACE(("XXX XXX might be bad! leave cli_sessionloop: haven't donefirstkex"));
+		return;
 	}
 
 	switch (cli_ses.state) {
@@ -129,6 +131,7 @@ static void cli_sessionloop() {
 			 * userauth */
 			send_msg_service_request(SSH_SERVICE_USERAUTH);
 			cli_ses.state = SERVICE_AUTH_REQ_SENT;
+			TRACE(("leave cli_sessionloop: sent userauth service req"));
 			return;
 
 		/* userauth code */
@@ -136,10 +139,12 @@ static void cli_sessionloop() {
 			cli_get_user();
 			cli_auth_getmethods();
 			cli_ses.state = USERAUTH_METHODS_SENT;
+			TRACE(("leave cli_sessionloop: sent userauth methods req"));
 			return;
 			
 		case USERAUTH_FAIL_RCVD:
 			cli_auth_try();
+			TRACE(("leave cli_sessionloop: cli_auth_try"));
 			return;
 
 		/* XXX more here needed */
@@ -149,6 +154,7 @@ static void cli_sessionloop() {
 		break;
 	}
 
+	TRACE(("leave cli_sessionloop: fell out"));
 
 }
 
diff --git a/common-kex.c b/common-kex.c
index 9847a48e..07b221be 100644
--- a/common-kex.c
+++ b/common-kex.c
@@ -613,6 +613,7 @@ static void read_kex_algos() {
 		erralgo = "kex";
 		goto error;
 	}
+	TRACE(("kex algo %s", algo->name));
 	ses.newkeys->algo_kex = algo->val;
 
 	/* server_host_key_algorithms */
@@ -622,6 +623,7 @@ static void read_kex_algos() {
 		erralgo = "hostkey";
 		goto error;
 	}
+	TRACE(("hostkey algo %s", algo->name));
 	ses.newkeys->algo_hostkey = algo->val;
 
 	/* encryption_algorithms_client_to_server */
@@ -631,6 +633,7 @@ static void read_kex_algos() {
 		goto error;
 	}
 	ses.newkeys->recv_algo_crypt = (struct dropbear_cipher*)algo->data;
+	TRACE(("enc algo recv %s", algo->name));
 
 	/* encryption_algorithms_server_to_client */
 	algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess);
@@ -639,6 +642,7 @@ static void read_kex_algos() {
 		goto error;
 	}
 	ses.newkeys->trans_algo_crypt = (struct dropbear_cipher*)algo->data;
+	TRACE(("enc algo trans %s", algo->name));
 
 	/* mac_algorithms_client_to_server */
 	algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess);
@@ -647,6 +651,7 @@ static void read_kex_algos() {
 		goto error;
 	}
 	ses.newkeys->recv_algo_mac = (struct dropbear_hash*)algo->data;
+	TRACE(("mac algo recv %s", algo->name));
 
 	/* mac_algorithms_server_to_client */
 	algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess);
@@ -655,6 +660,7 @@ static void read_kex_algos() {
 		goto error;
 	}
 	ses.newkeys->trans_algo_mac = (struct dropbear_hash*)algo->data;
+	TRACE(("mac algo trans %s", algo->name));
 
 	/* compression_algorithms_client_to_server */
 	algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
@@ -663,6 +669,7 @@ static void read_kex_algos() {
 		goto error;
 	}
 	ses.newkeys->recv_algo_comp = algo->val;
+	TRACE(("comp algo recv %s", algo->name));
 
 	/* compression_algorithms_server_to_client */
 	algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
@@ -671,6 +678,7 @@ static void read_kex_algos() {
 		goto error;
 	}
 	ses.newkeys->trans_algo_comp = algo->val;
+	TRACE(("comp algo trans %s", algo->name));
 
 	/* languages_client_to_server */
 	buf_eatstring(ses.payload);
diff --git a/common-session.c b/common-session.c
index 93e7c744..79166f49 100644
--- a/common-session.c
+++ b/common-session.c
@@ -75,6 +75,7 @@ void common_session_init(int sock, char* remotehost) {
 	ses.requirenext = SSH_MSG_KEXINIT;
 	ses.dataallowed = 0; /* don't send data yet, we'll wait until after kex */
 	ses.ignorenext = 0;
+	ses.lastpacket = 0;
 
 	/* set all the algos to none */
 	ses.keys = (struct key_context*)m_malloc(sizeof(struct key_context));
diff --git a/dss.c b/dss.c
index ebe80c6e..74b92c70 100644
--- a/dss.c
+++ b/dss.c
@@ -45,6 +45,7 @@
  * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
 int buf_get_dss_pub_key(buffer* buf, dss_key *key) {
 
+	TRACE(("enter buf_get_dss_pub_key"));
 	assert(key != NULL);
 	key->p = m_malloc(sizeof(mp_int));
 	key->q = m_malloc(sizeof(mp_int));
@@ -58,14 +59,17 @@ int buf_get_dss_pub_key(buffer* buf, dss_key *key) {
 	 || buf_getmpint(buf, key->q) == DROPBEAR_FAILURE
 	 || buf_getmpint(buf, key->g) == DROPBEAR_FAILURE
 	 || buf_getmpint(buf, key->y) == DROPBEAR_FAILURE) {
+		TRACE(("leave buf_get_dss_pub_key: failed reading mpints"));
 		return DROPBEAR_FAILURE;
 	}
 
 	if (mp_count_bits(key->p) < MIN_DSS_KEYLEN) {
 		dropbear_log(LOG_WARNING, "DSS key too short");
+		TRACE(("leave buf_get_dss_pub_key: short key"));
 		return DROPBEAR_FAILURE;
 	}
 
+	TRACE(("leave buf_get_dss_pub_key: success"));
 	return DROPBEAR_SUCCESS;
 }
 
diff --git a/process-packet.c b/process-packet.c
index f9f6dee3..3e6b79cb 100644
--- a/process-packet.c
+++ b/process-packet.c
@@ -50,6 +50,8 @@ void process_packet() {
 	type = buf_getbyte(ses.payload);
 	TRACE(("process_packet: packet type = %d", type));
 
+	ses.lastpacket = type;
+
 	/* These packets we can receive at any time */
 	switch(type) {
 
diff --git a/rsa.c b/rsa.c
index 936b2c80..2d63c023 100644
--- a/rsa.c
+++ b/rsa.c
@@ -205,6 +205,8 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data,
 	mp_int *rsa_em = NULL;
 	int ret = DROPBEAR_FAILURE;
 
+	TRACE(("enter buf_rsa_verify"));
+
 	assert(key != NULL);
 
 	m_mp_init_multi(&rsa_mdash, &rsa_s, NULL);
@@ -217,6 +219,7 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data,
 
 	if (mp_read_unsigned_bin(&rsa_s, buf_getptr(buf, buf->len - buf->pos),
 				buf->len - buf->pos) != MP_OKAY) {
+		TRACE(("failed reading rsa_s"));
 		goto out;
 	}
 
@@ -230,17 +233,20 @@ int buf_rsa_verify(buffer * buf, rsa_key *key, const unsigned char* data,
 	rsa_em = rsa_pad_em(key, data, len);
 
 	if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) {
+		TRACE(("failed exptmod rsa_s"));
 		goto out;
 	}
 
 	if (mp_cmp(rsa_em, &rsa_mdash) == MP_EQ) {
 		/* signature is valid */
+		TRACE(("success!"));
 		ret = DROPBEAR_SUCCESS;
 	}
 
 out:
 	mp_clear_multi(rsa_em, &rsa_mdash, &rsa_s, NULL);
 	m_free(rsa_em);
+	TRACE(("leave buf_rsa_verify: ret %d", ret));
 	return ret;
 
 }
diff --git a/service.h b/service.h
index 5f503479..197d8d1d 100644
--- a/service.h
+++ b/service.h
@@ -27,5 +27,6 @@
 
 void recv_msg_service_request(); /* Server */
 void send_msg_service_request(); /* Client */
+void recv_msg_service_accept(); /* Client */
 
 #endif /* _SERVICE_H_ */
diff --git a/session.h b/session.h
index 4a7e0ac7..bf6adb3e 100644
--- a/session.h
+++ b/session.h
@@ -119,6 +119,8 @@ struct sshsession {
 
 	unsigned char ignorenext; /* whether to ignore the next packet,
 								 used for kex_follows stuff */
+
+	unsigned char lastpacket; /* What the last received packet type was */
 	
 
 
diff --git a/signkey.c b/signkey.c
index 5fcdbbf8..faf37398 100644
--- a/signkey.c
+++ b/signkey.c
@@ -52,8 +52,12 @@ int buf_get_pub_key(buffer *buf, sign_key *key, int *type) {
 	unsigned char* ident;
 	unsigned int len;
 
+	TRACE(("enter buf_get_pub_key"));
+	printhex(buf_getptr(buf, 0x99), 0x99);
+
 	ident = buf_getstring(buf, &len);
 
+
 #ifdef DROPBEAR_DSS
 	if (memcmp(ident, SSH_SIGNKEY_DSS, len) == 0
 			&& (*type == DROPBEAR_SIGNKEY_ANY 
@@ -78,6 +82,7 @@ int buf_get_pub_key(buffer *buf, sign_key *key, int *type) {
 		return buf_get_rsa_pub_key(buf, key->rsakey);
 	}
 #endif
+	TRACE(("leave buf_get_pub_key: didn't match the type we want (%d versus '%s'len %d)", *type, ident, len));
 
 	m_free(ident);
 
@@ -352,6 +357,8 @@ int buf_verify(buffer * buf, sign_key *key, const unsigned char *data,
 	unsigned char * ident = NULL;
 	unsigned int identlen = 0;
 
+	TRACE(("enter buf_verify"));
+
 	bloblen = buf_getint(buf);
 	ident = buf_getstring(buf, &identlen);
 
-- 
GitLab