free(ct->config_file);
free(ct->key_file);
client_cmdline_parser_free(&ct->conf);
+ free(ct->challenge_hash);
+ sb_free(ct->sbc);
free(ct);
}
case CL_RECEIVED_WELCOME:
case CL_RECEIVED_PROCEED:
+ case CL_RECEIVED_CHALLENGE:
para_fd_set(ct->scc.fd, &s->wfds, &s->max_fileno);
return;
return find_arg(feature, ct->features) >= 0? true : false;
}
+static int send_sb_command(struct client_task *ct)
+{
+ int i;
+ char *command, *p;
+ size_t len = 0;
+
+ if (ct->sbc)
+ return send_sb(ct, NULL, 0, 0, false);
+
+ for (i = 0; i < ct->conf.inputs_num; i++)
+ len += strlen(ct->conf.inputs[i]) + 1;
+ p = command = para_malloc(len);
+ for (i = 0; i < ct->conf.inputs_num; i++) {
+ strcpy(p, ct->conf.inputs[i]);
+ p += strlen(ct->conf.inputs[i]) + 1;
+ }
+ PARA_DEBUG_LOG("--> %s\n", command);
+ return send_sb(ct, command, len, SBD_COMMAND, false);
+}
+
/**
* The post select hook for client commands.
*
/* decrypted challenge/session key buffer */
unsigned char crypt_buf[1024];
/* the SHA1 of the decrypted challenge */
- unsigned char challenge_hash[HASH_SIZE];
if (ct->use_sideband) {
struct sb_buffer sbb;
if (ret < 0)
goto out;
}
- hash_function((char *)crypt_buf, CHALLENGE_SIZE, challenge_hash);
+ ct->challenge_hash = para_malloc(HASH_SIZE);
+ hash_function((char *)crypt_buf, CHALLENGE_SIZE, ct->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,
SESSION_KEY_LEN);
- hash_to_asc(challenge_hash, buf);
+ hash_to_asc(ct->challenge_hash, buf);
PARA_INFO_LOG("--> %s\n", buf);
- ret = write_all(ct->scc.fd, (char *)challenge_hash, HASH_SIZE);
- if (ret < 0)
- goto out;
- ct->status = CL_SENT_CH_RESPONSE;
+ ct->status = CL_RECEIVED_CHALLENGE;
return;
}
+ case CL_RECEIVED_CHALLENGE:
+ if (ct->use_sideband) {
+ ret = send_sb(ct, ct->challenge_hash, HASH_SIZE,
+ SBD_CHALLENGE_RESPONSE, false);
+ if (ret != 0)
+ ct->challenge_hash = NULL;
+ if (ret <= 0)
+ goto out;
+ } else {
+ ret = write_all(ct->scc.fd, (char *)ct->challenge_hash, HASH_SIZE);
+ if (ret < 0)
+ goto out;
+ }
+ ct->status = CL_SENT_CH_RESPONSE;
+ goto out;
case CL_SENT_CH_RESPONSE: /* read server response */
{
+ if (ct->use_sideband) {
+ struct sb_buffer sbb;
+ ret = recv_sb(ct, &s->rfds, &sbb);
+ if (ret <= 0)
+ goto out;
+ free(sbb.iov.iov_base);
+ if (sbb.band != SBD_PROCEED)
+ ret = -E_BAD_BAND;
+ else
+ ct->status = CL_RECEIVED_PROCEED;
+ goto out;
+ }
ret = client_recv_buffer(ct, &s->rfds, buf, sizeof(buf), &n);
if (ret < 0 || n == 0)
goto out;
char *command = NULL;
if (!FD_ISSET(ct->scc.fd, &s->wfds))
return;
+ if (ct->use_sideband) {
+ ret = send_sb_command(ct);
+ if (ret <= 0)
+ goto out;
+ ct->status = CL_SENT_COMMAND;
+ return;
+ }
for (i = 0; i < ct->conf.inputs_num; i++) {
char *tmp = command;
command = make_message("%s\n%s", command?