X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=command.c;h=8deb69ce2f233ee7d0c691a62cebd2d8ded43ce1;hb=9c2a265397821d91ec628f549516b25757f5c801;hp=9cf1967faa4bdb4a3f12d313e2a322881f787d1f;hpb=2830b9f881898aaec073d5ba19e33482e30190bd;p=paraslash.git diff --git a/command.c b/command.c index 9cf1967f..8deb69ce 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,15 +933,29 @@ __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; - /* recv challenge response */ - ret = recv_bin_buffer(fd, buf, HASH_SIZE); - if (ret < 0) - goto net_err; - numbytes = ret; - PARA_DEBUG_LOG("received %d bytes challenge response\n", ret); + if (cc->use_sideband) { + struct iovec iov; + ret = send_sb(&cc->scc, buf, numbytes, SBD_CHALLENGE, false); + buf = NULL; + if (ret < 0) + goto net_err; + ret = recv_sb(&cc->scc, SBD_CHALLENGE_RESPONSE, + HANDSHAKE_BUFSIZE, &iov); + if (ret < 0) + goto net_err; + buf = iov.iov_base; + numbytes = iov.iov_len; + } 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) + goto net_err; + numbytes = ret; + } + PARA_DEBUG_LOG("received %zu bytes challenge response\n", numbytes); ret = -E_BAD_USER; if (!cc->u) goto net_err; @@ -960,7 +975,10 @@ __noreturn void handle_connect(int fd, const char *peername) /* init stream cipher keys with the second part of the random buffer */ cc->scc.recv = sc_new(rand_buf + CHALLENGE_SIZE, SESSION_KEY_LEN); cc->scc.send = sc_new(rand_buf + CHALLENGE_SIZE + SESSION_KEY_LEN, SESSION_KEY_LEN); - ret = sc_send_buffer(&cc->scc, PROCEED_MSG); + if (cc->use_sideband) + ret = send_sb(&cc->scc, NULL, 0, SBD_PROCEED, false); + else + ret = sc_send_buffer(&cc->scc, PROCEED_MSG); if (ret < 0) goto net_err; ret = read_command(&cc->scc, &command); @@ -995,6 +1013,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);