return msg;
}
-static char *get_status(struct misc_meta_data *nmmd, int parser_friendly)
+static unsigned get_status(struct misc_meta_data *nmmd, int parser_friendly,
+ char **result)
{
char mtime[30] = "";
char *status, *flags; /* vss status info */
free(flags);
free(status);
free(ut);
- return b.buf;
+ *result = b.buf;
+ return b.offset;
}
static int check_sender_args(int argc, char * const * argv, struct sender_command_data *scd)
return -E_COMMAND_SYNTAX;
for (;;) {
mmd_dup(nmmd);
- s = get_status(nmmd, parser_friendly);
- ret = sc_send_buffer(&cc->scc, s);
+ ret = get_status(nmmd, parser_friendly, &s);
+ ret = sc_send_bin_buffer(&cc->scc, s, ret);
free(s);
if (ret < 0)
goto out;
#define HANDSHAKE_BUFSIZE 4096
+static int parse_sb_command(struct command_context *cc, struct iovec *iov)
+{
+ int ret, i;
+ char *p, *end;
+
+ ret = -E_BAD_CMD;
+ if (iov->iov_base == NULL || iov->iov_len == 0)
+ goto out;
+ p = iov->iov_base;
+ p[iov->iov_len - 1] = '\0'; /* just to be sure */
+ cc->cmd = get_cmd_ptr(p, NULL);
+ if (!cc->cmd)
+ goto out;
+ ret = check_perms(cc->u->perms, cc->cmd);
+ if (ret < 0)
+ goto out;
+ end = iov->iov_base + iov->iov_len;
+ for (i = 0, p = iov->iov_base; p < end; i++)
+ p += strlen(p) + 1;
+ cc->argc = i;
+ cc->argv = para_malloc((cc->argc + 1) * sizeof(char *));
+ for (i = 0, p = iov->iov_base; p < end; i++) {
+ cc->argv[i] = para_strdup(p);
+ p += strlen(p) + 1;
+ }
+ cc->argv[cc->argc] = NULL;
+ ret = cc->argc;
+out:
+ free(iov->iov_base);
+ return ret;
+}
+
/**
* Perform user authentication and execute a command.
*
PARA_DEBUG_LOG("sending %u byte challenge + rc4 keys (%zu bytes)\n",
CHALLENGE_SIZE, numbytes);
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;
- buf = para_malloc(HANDSHAKE_BUFSIZE);
+ 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;
}
- /* 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);
+ PARA_DEBUG_LOG("received %zu bytes challenge response\n", numbytes);
ret = -E_BAD_USER;
if (!cc->u)
goto net_err;
/* 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 (ret < 0)
- goto net_err;
- ret = read_command(&cc->scc, &command);
- if (ret == -E_COMMAND_SYNTAX)
- goto err_out;
+ 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 = -E_BAD_CMD;
- cc->cmd = parse_cmd(command);
- if (!cc->cmd)
- goto err_out;
- /* valid command, check permissions */
- ret = check_perms(cc->u->perms, cc->cmd);
- if (ret < 0)
- goto err_out;
- /* valid command and sufficient perms */
- ret = create_argv(command, "\n", &cc->argv);
- if (ret < 0)
- goto err_out;
- cc->argc = ret;
+ if (cc->use_sideband) {
+ struct iovec iov;
+ ret = recv_sb(&cc->scc, SBD_COMMAND, MAX_COMMAND_LEN, &iov);
+ if (ret < 0)
+ goto net_err;
+ ret = parse_sb_command(cc, &iov);
+ if (ret < 0)
+ goto err_out;
+ cc->argc = ret;
+ } else {
+ ret = read_command(&cc->scc, &command);
+ if (ret == -E_COMMAND_SYNTAX)
+ goto err_out;
+ if (ret < 0)
+ goto net_err;
+ ret = -E_BAD_CMD;
+ cc->cmd = parse_cmd(command);
+ if (!cc->cmd)
+ goto err_out;
+ /* valid command, check permissions */
+ ret = check_perms(cc->u->perms, cc->cmd);
+ if (ret < 0)
+ goto err_out;
+ /* valid command and sufficient perms */
+ ret = create_argv(command, "\n", &cc->argv);
+ if (ret < 0)
+ goto err_out;
+ cc->argc = ret;
+ }
PARA_NOTICE_LOG("calling com_%s() for %s@%s\n", cc->cmd->name,
cc->u->name, peername);
ret = cc->cmd->handler(cc);