From 8ab0d98297cb18d5bb12b71648bb34310141ef1c Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 19 Jul 2009 03:10:34 +0200 Subject: [PATCH] client_post_select(): Defer decrypting of server challenge. The old code worked only by pure luck: We allocated the crypt buffer on the stack as an ordinary automatic variable. This buffer was filled right after we received the challenge from the server, but it was used in a _subsequent_ call to client_post_select(). There's no guarantee that the content of the crypt buffer stays the same between these two calls. So defer the decryption until the client status is CL_RECEIVED_CHALLENGE, i.e. until the socket file descriptor is known to be ready for sending back the SHA1 of the decrypted challenge. --- client_common.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/client_common.c b/client_common.c index eb053581..108867bd 100644 --- a/client_common.c +++ b/client_common.c @@ -141,7 +141,6 @@ static ssize_t client_recv_buffer(struct client_task *ct) static void client_post_select(struct sched *s, struct task *t) { struct client_task *ct = container_of(t, struct client_task, task); - unsigned char crypt_buf[1024]; t->error = 0; if (ct->rc4c.fd < 0) @@ -172,23 +171,26 @@ static void client_post_select(struct sched *s, struct task *t) t->error = client_recv_buffer(ct); if (t->error < 0) goto err; - PARA_INFO_LOG("<-- [challenge] (%d bytes)\n", t->error); - /* decrypt challenge/rc4 buffer */ + ct->loaded = t->error; + PARA_INFO_LOG("<-- [challenge] (%d bytes)\n", ct->loaded); + ct->status = CL_RECEIVED_CHALLENGE; + return; + case CL_RECEIVED_CHALLENGE: + { + /* decrypted challenge/rc4 buffer */ + unsigned char crypt_buf[1024]; + /* the SHA1 of the decrypted challenge */ + unsigned char challenge_sha1[HASH_SIZE]; + t->error = para_decrypt_buffer(ct->key_file, crypt_buf, - (unsigned char *)ct->buf, t->error); + (unsigned char *)ct->buf, ct->loaded); if (t->error < 0) goto err; - ct->status = CL_RECEIVED_CHALLENGE; + sha1_hash((char *)crypt_buf, CHALLENGE_SIZE, challenge_sha1); RC4_set_key(&ct->rc4c.send_key, RC4_KEY_LEN, crypt_buf + CHALLENGE_SIZE); RC4_set_key(&ct->rc4c.recv_key, RC4_KEY_LEN, crypt_buf + CHALLENGE_SIZE + RC4_KEY_LEN); - return; - case CL_RECEIVED_CHALLENGE: - { - unsigned char challenge_sha1[HASH_SIZE]; - /* send sha1 of decrypted challenge */ - sha1_hash((char *)crypt_buf, CHALLENGE_SIZE, challenge_sha1); hash_to_asc(challenge_sha1, ct->buf); PARA_INFO_LOG("--> %s\n", ct->buf); t->error = send_bin_buffer(ct->rc4c.fd, (char *)challenge_sha1, -- 2.39.5