From fa9e0ecb219000e07eaf694f50679a8edfb5dc9e Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Wed, 4 Jan 2012 21:46:11 +0100 Subject: [PATCH] Send and receive challenge via sideband. If both server and client support sideband connections, the challenge is now sent as a sideband packet using the dedicated SBD_CHALLENGE designator. --- client_common.c | 37 ++++++++++++++++++++++++++++--------- command.c | 22 ++++++++++++++++------ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/client_common.c b/client_common.c index ba4c2699..f3cea05d 100644 --- a/client_common.c +++ b/client_common.c @@ -299,14 +299,33 @@ static void client_post_select(struct sched *s, struct task *t) /* the SHA1 of the decrypted challenge */ unsigned char challenge_hash[HASH_SIZE]; - ret = client_recv_buffer(ct, &s->rfds, buf, sizeof(buf), &n); - if (ret < 0 || n == 0) - goto out; - PARA_INFO_LOG("<-- [challenge] (%zu bytes)\n", n); - ret = priv_decrypt(ct->key_file, crypt_buf, - (unsigned char *)buf, n); - if (ret < 0) - goto out; + if (ct->use_sideband) { + struct sb_buffer sbb; + ret = recv_sb(ct, &s->rfds, &sbb); + if (ret <= 0) + goto out; + if (sbb.band != SBD_CHALLENGE) { + ret = -E_BAD_BAND; + free(sbb.iov.iov_base); + goto out; + } + n = sbb.iov.iov_len; + PARA_INFO_LOG("<-- [challenge] (%zu bytes)\n", n); + ret = priv_decrypt(ct->key_file, crypt_buf, + sbb.iov.iov_base, n); + free(sbb.iov.iov_base); + if (ret < 0) + goto out; + } else { + ret = client_recv_buffer(ct, &s->rfds, buf, sizeof(buf), &n); + if (ret < 0 || n == 0) + goto out; + PARA_INFO_LOG("<-- [challenge] (%zu bytes)\n", n); + ret = priv_decrypt(ct->key_file, crypt_buf, + (unsigned char *)buf, n); + if (ret < 0) + goto out; + } hash_function((char *)crypt_buf, CHALLENGE_SIZE, challenge_hash); ct->scc.send = sc_new(crypt_buf + CHALLENGE_SIZE, SESSION_KEY_LEN); ct->scc.recv = sc_new(crypt_buf + CHALLENGE_SIZE + SESSION_KEY_LEN, @@ -417,7 +436,7 @@ static void client_post_select(struct sched *s, struct task *t) out: t->error = ret; if (ret < 0) { - if (ret != -E_SERVER_EOF && ret != -E_BTR_EOF) + if (ret != -E_SERVER_EOF && ret != -E_BTR_EOF && ret != -E_EOF) PARA_ERROR_LOG("%s\n", para_strerror(-t->error)); btr_remove_node(btrn); } diff --git a/command.c b/command.c index 9cf1967f..5790f11d 100644 --- a/command.c +++ b/command.c @@ -854,6 +854,8 @@ out: return ret; } +#define HANDSHAKE_BUFSIZE 4096 + /** * Perform user authentication and execute a command. * @@ -884,10 +886,9 @@ out: __noreturn void handle_connect(int fd, const char *peername) { int ret; - char buf[4096]; unsigned char rand_buf[CHALLENGE_SIZE + 2 * SESSION_KEY_LEN]; unsigned char challenge_hash[HASH_SIZE]; - char *p, *command = NULL; + char *p, *command = NULL, *buf = para_malloc(HANDSHAKE_BUFSIZE) /* must be on the heap */; size_t numbytes; struct command_context cc_struct = {.peer = peername}, *cc = &cc_struct; @@ -905,7 +906,7 @@ __noreturn void handle_connect(int fd, const char *peername) if (ret < 0) goto net_err; /* recv auth request line */ - ret = recv_buffer(fd, buf, sizeof(buf)); + ret = recv_buffer(fd, buf, HANDSHAKE_BUFSIZE); if (ret < 0) goto net_err; ret = parse_auth_request(buf, ret, &cc->u, &cc->use_sideband); @@ -932,9 +933,17 @@ __noreturn void handle_connect(int fd, const char *peername) } PARA_DEBUG_LOG("sending %u byte challenge + rc4 keys (%zu bytes)\n", CHALLENGE_SIZE, numbytes); - ret = write_all(fd, buf, numbytes); - if (ret < 0) - goto net_err; + if (cc->use_sideband) { + ret = send_sb(&cc->scc, buf, numbytes, SBD_CHALLENGE, false); + buf = NULL; + if (ret < 0) + goto net_err; + buf = para_malloc(HANDSHAKE_BUFSIZE); + } else { + ret = write_all(fd, buf, numbytes); + if (ret < 0) + goto net_err; + } /* recv challenge response */ ret = recv_bin_buffer(fd, buf, HASH_SIZE); if (ret < 0) @@ -995,6 +1004,7 @@ err_out: net_err: PARA_NOTICE_LOG("%s\n", para_strerror(-ret)); out: + free(buf); free(command); sc_free(cc->scc.recv); sc_free(cc->scc.send); -- 2.39.5