aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Timber <mieabby@gmail.com>2020-08-31 02:34:11 +0930
committerDavid Timber <mieabby@gmail.com>2020-08-31 02:34:11 +0930
commitff4d91db20381471493b4f485fa0f75390138e54 (patch)
treea6e4c85419e7e4400b9de44d593dff867e05d182
parentfbb4d5d648a8dc6dba9e33240bf66d82939e2880 (diff)
Impl run_bin
-rw-r--r--src/data/proto-test/runbin26
-rw-r--r--src/data/proto-test/runcmd_demux4
-rw-r--r--src/htbt.c356
-rw-r--r--src/htbt.h2
-rw-r--r--src/proone-htbthost.c58
-rw-r--r--src/protocol.c12
6 files changed, 392 insertions, 66 deletions
diff --git a/src/data/proto-test/runbin b/src/data/proto-test/runbin
new file mode 100644
index 0000000..099a1a6
--- /dev/null
+++ b/src/data/proto-test/runbin
@@ -0,0 +1,26 @@
+# msg id 0xA05, init
+8A05
+# PRNE_HTBT_OP_RUN_BIN
+07
+ # bin_len = 147
+ 000093
+ # detach = 0, args_len = 0
+ 0000
+ # #!/bin/bash
+ # outfile=$(mktemp /tmp/prne.XXXX)
+ # echo "$outfile"
+ # for (( i = 0; i < 10; i += 1 )); do
+ # echo "hello world?!" >> "$outfile"
+ # done
+ # sleep 10
+ 23212f62696e2f626173680a6f757466696c653d24286d6b74656d70202f
+ 746d702f70726e652e58585858290a6563686f2022246f757466696c6522
+ 0a666f722028282069203d20303b2069203c2031303b2069202b3d203120
+ 29293b20646f0a096563686f202268656c6c6f20776f726c643f2122203e
+ 3e2022246f757466696c65220a646f6e650a736c6565702031300a
+# msg id 0xA05, init
+8A05
+# PRNE_HTBT_OP_STDIO
+08
+ # stdio err = 0, fin = 1, len = 0
+ 4000
diff --git a/src/data/proto-test/runcmd_demux b/src/data/proto-test/runcmd_demux
index 01a9a2b..c0a630e 100644
--- a/src/data/proto-test/runcmd_demux
+++ b/src/data/proto-test/runcmd_demux
@@ -1,4 +1,4 @@
-# msg id 0xA03, init
+# msg id 0xA04, init
8A04
# PRNE_HTBT_OP_RUN_CMD
05
@@ -6,7 +6,7 @@
00 08
# "/bin/sh"
2f 62 69 6e 2f 73 68 00
-# msg id 0xA03, init
+# msg id 0xA04, init
8A04
# PRNE_HTBT_OP_STDIO
08
diff --git a/src/htbt.c b/src/htbt.c
index c2f765f..efc7b66 100644
--- a/src/htbt.c
+++ b/src/htbt.c
@@ -26,15 +26,21 @@
#define HTBT_LBD_BACKLOG 4
// LBD Socket Operation Timeout
static const struct timespec HTBT_LBD_SCK_OP_TIMEOUT = { 10, 0 }; // 10s
+// LBD Status Send Timeout
+static const struct timespec HTBT_LBD_STATUS_SND_TIMEOUT = { 5, 0 }; // 5s
// LBD Socket Bind Retry Interval
static const struct timespec HTBT_LBD_BIND_INT = { 5, 0 }; // 5s
// LBD TLS Close Timeout
static const struct timespec HTBT_LBD_CLOSE_TIMEOUT = { 3, 0 }; // 3s
-
+// Relay child Timeout
+static const struct timespec HTBT_RELAY_CHILD_TIMEOUT = { 60, 0 }; // 60s
+// Download tick timeout
+static const struct timespec HTBT_DL_TICK_TIMEOUT = { 30, 0 }; // 30s
typedef struct {
pth_t pth;
prne_htbt_t *parent;
+ size_t skip;
prne_iobuf_t iobuf[2];
int fd;
bool valid;
@@ -273,10 +279,12 @@ static void htbt_lbd_fab_frame (
const prne_htbt_msg_head_t *mh,
const void *body,
prne_htbt_ser_ft ser_f,
- pth_event_t root_ev)
+ pth_event_t ev)
{
size_t req, actual;
+ prne_assert(ev != NULL);
+
req = 0;
prne_htbt_ser_msg_head(NULL, 0, &actual, mh);
req += actual;
@@ -284,7 +292,7 @@ static void htbt_lbd_fab_frame (
req += actual;
prne_assert(req <= ctx->iobuf[1].size);
- htbt_lbd_consume_outbuf(ctx, req, root_ev);
+ htbt_lbd_consume_outbuf(ctx, req, ev);
if (!ctx->valid) {
return;
}
@@ -308,10 +316,19 @@ static void htbt_lbd_fab_status (
prne_htbt_status_code_t status,
int32_t err,
uint16_t corr_msgid,
- pth_event_t root_ev)
+ pth_event_t ev)
{
prne_htbt_msg_head_t mh;
prne_htbt_status_t s;
+ pth_event_t my_ev = NULL;
+
+ if (ev == NULL) {
+ my_ev = pth_event(
+ PTH_EVENT_TIME,
+ prne_pth_tstimeout(HTBT_LBD_STATUS_SND_TIMEOUT));
+ ev = my_ev;
+ }
+ prne_assert(ev != NULL);
prne_htbt_init_msg_head(&mh);
prne_htbt_init_status(&s);
@@ -326,45 +343,75 @@ static void htbt_lbd_fab_status (
&mh,
&s,
(prne_htbt_ser_ft)prne_htbt_ser_status,
- root_ev);
+ ev);
prne_htbt_free_msg_head(&mh);
prne_htbt_free_status(&s);
+ pth_event_free(my_ev, FALSE);
}
static void htbt_lbd_raise_protoerr (
htbt_lbd_client_t *ctx,
uint16_t corr_msgid,
- int32_t err,
- pth_event_t root_ev)
+ int32_t err)
{
+ pth_event_t ev = pth_event(
+ PTH_EVENT_TIME,
+ prne_pth_tstimeout(HTBT_LBD_STATUS_SND_TIMEOUT));
+
+ prne_assert(ev != NULL);
htbt_lbd_fab_status(
ctx,
PRNE_HTBT_STATUS_PROTO_ERR,
err,
corr_msgid,
- root_ev);
- htbt_lbd_consume_outbuf(ctx, ctx->iobuf[1].len, root_ev);
+ ev);
+ htbt_lbd_consume_outbuf(ctx, ctx->iobuf[1].len, ev);
ctx->valid = false;
+
+ pth_event_free(ev, FALSE);
}
-static void htbt_lbd_fab_unimpl (
+static void htbt_lbd_srv_stdio (
htbt_lbd_client_t *ctx,
- uint16_t corr_msgid,
- pth_event_t root_ev)
+ pth_event_t root_ev,
+ size_t off,
+ const prne_htbt_msg_head_t *mh)
{
- htbt_lbd_fab_status(
- ctx,
- PRNE_HTBT_STATUS_UNIMPL,
- 0,
- corr_msgid,
- root_ev);
+ prne_htbt_stdio_t sh;
+ size_t actual;
+ prne_htbt_ser_rc_t s_ret;
+
+ prne_htbt_init_stdio(&sh);
+
+ s_ret = prne_htbt_dser_stdio(
+ ctx->iobuf[0].m + off,
+ ctx->iobuf[0].len - off,
+ &actual,
+ &sh);
+ if (s_ret == PRNE_HTBT_SER_RC_MORE_BUF) {
+ goto END;
+ }
+ else {
+ prne_iobuf_shift(ctx->iobuf + 0, -(off + actual));
+ }
+ if (s_ret != PRNE_HTBT_SER_RC_OK) {
+ htbt_lbd_raise_protoerr(
+ ctx,
+ mh->id,
+ 0);
+ goto END;
+ }
+
+ ctx->skip = sh.len;
+END:
+ prne_htbt_free_stdio(&sh);
}
static void htbt_lbd_srv_hostinfo (
htbt_lbd_client_t *ctx,
pth_event_t root_ev,
- const size_t off,
+ size_t off,
const prne_htbt_msg_head_t *mh)
{
prne_htbt_host_info_t hi;
@@ -372,7 +419,12 @@ static void htbt_lbd_srv_hostinfo (
prne_iobuf_shift(ctx->iobuf + 0, -off);
if (ctx->parent->param.cb_f.hostinfo == NULL) {
- htbt_lbd_fab_unimpl(ctx, mh->id, root_ev);
+ htbt_lbd_fab_status(
+ ctx,
+ PRNE_HTBT_STATUS_UNIMPL,
+ 0,
+ mh->id,
+ root_ev);
return;
}
@@ -407,6 +459,7 @@ static bool htbt_relay_child (
int *c_out,
int *c_err)
{
+ bool conn_rd = true;
bool ret = true;
struct pollfd pfd[4];
prne_htbt_msg_head_t mh;
@@ -414,6 +467,7 @@ static bool htbt_relay_child (
int f_ret, pending, out_p = 0;
size_t actual;
ssize_t consume;
+ pth_event_t ev = NULL;
pfd[0].fd = conn;
pfd[1].fd = *c_in;
@@ -432,7 +486,7 @@ static bool htbt_relay_child (
if (iobuf[1].len > 0) {
pfd[0].events |= POLLOUT;
}
- if (iobuf[0].avail > 0 && !(sh[0].fin && sh[0].len == 0)) {
+ if (conn_rd && iobuf[0].avail > 0 && !(sh[0].fin && sh[0].len == 0)) {
pfd[0].events |= POLLIN;
}
@@ -452,12 +506,21 @@ static bool htbt_relay_child (
pfd[2 + out_p].events |= POLLIN;
}
- f_ret = pth_poll(pfd, 4, -1);
+ pth_event_free(ev, FALSE);
+ ev = pth_event(
+ PTH_EVENT_TIME,
+ prne_pth_tstimeout(HTBT_RELAY_CHILD_TIMEOUT));
+ prne_assert(ev != NULL);
+
+ f_ret = pth_poll_ev(pfd, 4, -1, ev);
if (f_ret < 0 && errno != EINTR) {
ret = false;
break;
}
- if (f_ret == 0 || (pfd[0].revents & (POLLNVAL | POLLHUP | POLLERR))) {
+ if (pth_event_status(ev) == PTH_STATUS_OCCURRED ||
+ f_ret == 0 ||
+ (pfd[0].revents & (POLLNVAL | POLLHUP | POLLERR)))
+ {
break;
}
@@ -497,7 +560,10 @@ static bool htbt_relay_child (
ssl,
iobuf[0].m + iobuf[0].len,
iobuf[0].avail);
- if (f_ret < 0) {
+ if (f_ret == 0) {
+ conn_rd = false;
+ }
+ else if (f_ret < 0) {
break;
}
else {
@@ -599,6 +665,7 @@ static bool htbt_relay_child (
prne_htbt_free_stdio(sh + 0);
prne_htbt_free_stdio(sh + 1);
prne_htbt_free_msg_head(&mh);
+ pth_event_free(ev, FALSE);
return ret;
}
@@ -623,20 +690,22 @@ static void htbt_do_cmd (
int errp[2] = { -1, -1 };
pid_t child = -1;
int f_ret, chld_status;
+ prne_htbt_status_code_t ret_status;
+ int32_t ret_err = 0;
if (pipe(errp) != 0 ||
fcntl(errp[0], F_SETFD, FD_CLOEXEC) != 0 ||
fcntl(errp[1], F_SETFD, FD_CLOEXEC) != 0)
{
- *out_status = PRNE_HTBT_STATUS_ERRNO;
- *out_err = errno;
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_err = errno;
goto END;
}
if (!detach &&
(pipe(cin) != 0 || pipe(cout) != 0 || pipe(cerr) != 0))
{
- *out_status = PRNE_HTBT_STATUS_ERRNO;
- *out_err = errno;
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_err = errno;
goto END;
}
@@ -677,13 +746,13 @@ static void htbt_do_cmd (
execv(args[0], args);
} while (false);
// CATCH
- *out_err = errno;
- write(errp[1], out_err, sizeof(int32_t));
+ ret_err = errno;
+ write(errp[1], &ret_err, sizeof(int32_t));
raise(SIGKILL);
}
else if (child < 0) {
- *out_status = PRNE_HTBT_STATUS_ERRNO;
- *out_err = errno;
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_err = errno;
goto END;
}
@@ -691,21 +760,21 @@ static void htbt_do_cmd (
close(errp[1]);
// This could block forever if the child gets stoppep
- f_ret = pth_read(errp[0], out_err, sizeof(int32_t));
+ f_ret = pth_read(errp[0], &ret_err, sizeof(int32_t));
if (f_ret == sizeof(int32_t)) {
- *out_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
goto END;
}
prne_close(errp[0]);
errp[0] = -1;
- *out_status = PRNE_HTBT_STATUS_OK;
+ ret_status = PRNE_HTBT_STATUS_OK;
if (detach) {
if (pth_waitpid(child, &chld_status, WUNTRACED) == child &&
!WIFSTOPPED(chld_status))
{
child = -1;
- *out_err = 0;
+ ret_err = 0;
}
}
else {
@@ -717,33 +786,33 @@ static void htbt_do_cmd (
!prne_sck_fcntl(cout[0]) ||
!prne_sck_fcntl(cerr[0]))
{
- *out_status = PRNE_HTBT_STATUS_ERRNO;
- *out_err = errno;
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_err = errno;
goto END;
}
if (htbt_relay_child(conn, ssl, iobuf, msg_id, &cin[1], &cout[0], &cerr[0])) {
if (pth_waitpid(child, &chld_status, WUNTRACED) < 0) {
- *out_status = PRNE_HTBT_STATUS_ERRNO;
- *out_err = errno;
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_err = errno;
goto END;
}
else if (WIFEXITED(chld_status)) {
- *out_err = WEXITSTATUS(chld_status);
+ ret_err = WEXITSTATUS(chld_status);
child = -1;
}
else if (WIFSIGNALED(chld_status)) {
- *out_err = 128 + WTERMSIG(chld_status);
+ ret_err = 128 + WTERMSIG(chld_status);
child = -1;
}
else {
// child has been stopped just right before exit
- *out_err = -1;
+ ret_err = -1;
}
}
else {
- *out_status = PRNE_HTBT_STATUS_ERRNO;
- *out_err = errno;
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_err = errno;
}
}
@@ -760,15 +829,21 @@ END:
kill(child, SIGKILL);
pth_waitpid(child, NULL, 0);
}
+
+ if (out_status != NULL) {
+ *out_status = ret_status;
+ }
+ if (out_err != NULL) {
+ *out_err = ret_err;
+ }
}
-static bool htbt_lbd_srv_run_cmd (
+static void htbt_lbd_srv_run_cmd (
htbt_lbd_client_t *ctx,
pth_event_t root_ev,
- const size_t off,
+ size_t off,
const prne_htbt_msg_head_t *mh)
{
- bool ret = false;
size_t actual;
prne_htbt_ser_rc_t s_ret;
prne_htbt_cmd_t cmd;
@@ -798,7 +873,7 @@ static bool htbt_lbd_srv_run_cmd (
goto END;
}
if (s_ret != PRNE_HTBT_SER_RC_OK) {
- htbt_lbd_raise_protoerr(ctx, mh->id, 0, root_ev);
+ htbt_lbd_raise_protoerr(ctx, mh->id, 0);
goto END;
}
@@ -813,12 +888,172 @@ static bool htbt_lbd_srv_run_cmd (
mh->id,
&status,
&err);
- htbt_lbd_fab_status(ctx, status, err, mh->id, root_ev);
- ret = true;
+ htbt_lbd_fab_status(ctx, status, err, mh->id, NULL);
}
+
END:
prne_htbt_free_cmd(&cmd);
- return ret;
+}
+
+static void htbt_lbd_srv_run_bin (
+ htbt_lbd_client_t *ctx,
+ pth_event_t root_ev,
+ size_t off,
+ const prne_htbt_msg_head_t *mh)
+{
+ prne_htbt_bin_meta_t bin_meta;
+ size_t actual;
+ prne_htbt_ser_rc_t s_ret;
+ char *add_args[1] = { NULL };
+ char **args = NULL;
+ int fd = -1, f_ret;
+ struct pollfd pfd;
+ pth_event_t ev = NULL;
+ prne_htbt_status_code_t ret_status = PRNE_HTBT_STATUS_OK;
+ int32_t ret_errno = 0;
+
+ prne_htbt_init_bin_meta(&bin_meta);
+
+ htbt_lbd_consume_outbuf(ctx, ctx->iobuf[1].len, root_ev);
+
+ s_ret = prne_htbt_dser_bin_meta(
+ ctx->iobuf[0].m + off,
+ ctx->iobuf[0].len - off,
+ &actual,
+ &bin_meta);
+ if (s_ret == PRNE_HTBT_SER_RC_MORE_BUF) {
+ goto END;
+ }
+ else {
+ off += actual;
+ prne_iobuf_shift(ctx->iobuf + 0, -off);
+ }
+ if (s_ret != PRNE_HTBT_SER_RC_OK) {
+ goto PROTO_ERR;
+ }
+
+ if (ctx->parent->param.cb_f.tmpfile == NULL) {
+ ret_status = PRNE_HTBT_STATUS_UNIMPL;
+ goto SND_STATUS;
+ }
+ errno = 0;
+ add_args[0] = ctx->parent->param.cb_f.tmpfile(bin_meta.bin_size, 0700);
+ if (add_args[0] == NULL) {
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_errno = errno;
+ goto SND_STATUS;
+ }
+ args = prne_htbt_parse_args(
+ bin_meta.cmd.mem,
+ bin_meta.cmd.mem_len,
+ 1,
+ add_args,
+ NULL,
+ SIZE_MAX);
+ if (args == NULL) {
+ goto END;
+ }
+
+ fd = open(add_args[0], O_WRONLY);
+ if (fd < 0) {
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_errno = errno;
+ goto SND_STATUS;
+ }
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+
+ pfd.fd = ctx->fd;
+ pfd.events = POLLIN;
+ while (bin_meta.bin_size > 0) {
+ pth_event_free(ev, FALSE);
+ ev = pth_event(
+ PTH_EVENT_TIME,
+ prne_pth_tstimeout(HTBT_DL_TICK_TIMEOUT));
+ prne_assert(ev != NULL);
+
+ if (ctx->iobuf[0].len == 0) {
+ f_ret = pth_poll_ev(&pfd, 1, -1, ev);
+ if (pth_event_status(ev) == PTH_STATUS_OCCURRED ||
+ f_ret == 0)
+ {
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_errno = ETIMEDOUT;
+ goto SND_STATUS;
+ }
+
+ if (pfd.revents & POLLIN) {
+ f_ret = mbedtls_ssl_read(
+ &ctx->ssl,
+ ctx->iobuf[0].m,
+ ctx->iobuf[0].avail);
+ if (f_ret <= 0) {
+ goto END;
+ }
+ prne_iobuf_shift(ctx->iobuf + 0, f_ret);
+ }
+ else if (pfd.revents) {
+ goto END;
+ }
+ }
+
+ actual = prne_op_min(bin_meta.bin_size, ctx->iobuf[0].len);
+ f_ret = pth_write(fd, ctx->iobuf[0].m, actual);
+ prne_iobuf_shift(ctx->iobuf + 0, -actual);
+ bin_meta.bin_size -= actual;
+ if (f_ret < 0) {
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_errno = errno;
+ goto SND_STATUS;
+ }
+ }
+ close(fd);
+ fd = -1;
+
+ htbt_do_cmd(
+ bin_meta.cmd.detach,
+ args,
+ ctx->fd,
+ &ctx->ssl,
+ ctx->iobuf,
+ mh->id,
+ &ret_status,
+ &ret_errno);
+ goto SND_STATUS;
+PROTO_ERR:
+ htbt_lbd_raise_protoerr(ctx, mh->id, 0);
+ goto END;
+SND_STATUS:
+ htbt_lbd_fab_status(
+ ctx,
+ ret_status,
+ ret_errno,
+ mh->id,
+ NULL);
+ goto END;
+END:
+ ctx->skip = bin_meta.bin_size;
+ prne_htbt_free_bin_meta(&bin_meta);
+ if (add_args[0] != NULL) {
+ unlink(add_args[0]);
+ prne_free(add_args[0]);
+ }
+ prne_free(args);
+ prne_close(fd);
+ pth_event_free(ev, FALSE);
+}
+
+static void htbt_lbd_skip_inbuf (htbt_lbd_client_t *ctx) {
+ size_t consume;
+
+ if (ctx->skip == 0) {
+ return;
+ }
+ consume = prne_op_min(ctx->iobuf[0].len, ctx->skip);
+
+ prne_iobuf_shift(
+ ctx->iobuf + 0,
+ -consume);
+ ctx->skip -= consume;
}
static bool htbt_lbd_consume_inbuf (
@@ -833,6 +1068,8 @@ static bool htbt_lbd_consume_inbuf (
prne_htbt_init_msg_head(&f_head);
while (ctx->valid) {
+ htbt_lbd_skip_inbuf(ctx);
+
prne_htbt_free_msg_head(&f_head);
prne_htbt_init_msg_head(&f_head);
@@ -848,7 +1085,7 @@ static bool htbt_lbd_consume_inbuf (
f_head.is_rsp ||
(f_head.op != PRNE_HTBT_OP_NOOP && f_head.id == 0))
{
- htbt_lbd_raise_protoerr(ctx, f_head.id, 0, root_ev);
+ htbt_lbd_raise_protoerr(ctx, f_head.id, 0);
goto END;
}
@@ -858,23 +1095,25 @@ static bool htbt_lbd_consume_inbuf (
case PRNE_HTBT_OP_NOOP:
prne_iobuf_shift(ctx->iobuf + 0, -actual);
break;
+ case PRNE_HTBT_OP_STDIO:
+ htbt_lbd_srv_stdio(ctx, root_ev, actual, &f_head);
+ break;
case PRNE_HTBT_OP_HOST_INFO:
htbt_lbd_srv_hostinfo(ctx, root_ev, actual, &f_head);
break;
case PRNE_HTBT_OP_RUN_CMD:
- if (!htbt_lbd_srv_run_cmd(ctx, root_ev, actual, &f_head)) {
- goto END;
- }
+ htbt_lbd_srv_run_cmd(ctx, root_ev, actual, &f_head);
break;
case PRNE_HTBT_OP_RUN_BIN:
+ htbt_lbd_srv_run_bin(ctx, root_ev, actual, &f_head);
+ break;
case PRNE_HTBT_OP_HOVER:
case PRNE_HTBT_OP_NY_BIN:
default:
htbt_lbd_raise_protoerr(
ctx,
f_head.id,
- PRNE_HTBT_STATUS_UNIMPL,
- root_ev);
+ PRNE_HTBT_STATUS_UNIMPL);
goto END;
}
}
@@ -975,6 +1214,7 @@ END:
static void htbt_init_lbd_client (htbt_lbd_client_t *c) {
c->pth = NULL;
c->parent = NULL;
+ c->skip = 0;
prne_init_iobuf(c->iobuf + 0);
prne_init_iobuf(c->iobuf + 1);
c->fd = -1;
diff --git a/src/htbt.h b/src/htbt.h
index b714b1e..2209fcf 100644
--- a/src/htbt.h
+++ b/src/htbt.h
@@ -11,7 +11,7 @@ typedef struct prne_htbt prne_htbt_t;
typedef struct prne_htbt_param prne_htbt_param_t;
typedef bool(*prne_htbt_cnc_txtrec_ft)(char *out);
typedef bool(*prne_htbt_hostinfo_ft)(prne_htbt_host_info_t *out);
-typedef char*(*prne_htbt_tmpfile_ft)(const size_t req_size);
+typedef char*(*prne_htbt_tmpfile_ft)(size_t req_size, const mode_t mode);
typedef bool(*prne_htbt_cmd_ft)(const prne_htbt_cmd_t *cmd);
typedef bool(*prne_htbt_bin_ft)(const char *path, const prne_htbt_cmd_t *cmd);
diff --git a/src/proone-htbthost.c b/src/proone-htbthost.c
index 4ba2f73..555b9d3 100644
--- a/src/proone-htbthost.c
+++ b/src/proone-htbthost.c
@@ -234,6 +234,63 @@ static bool parse_param (const char *arg) {
return true;
}
+static char *mktmpfile (size_t req_size, const mode_t mode) {
+ static int ctr = 0;
+ uint8_t *z = NULL;
+ size_t z_size;
+ ssize_t consume;
+ char *path = NULL, *ret = NULL;
+ int fd = -1, len;
+
+ z_size = prne_getpagesize();
+ z = prne_calloc(1, z_size);
+ if (z == NULL) {
+ z_size = 1;
+ z = prne_malloc(1, 1);
+ z[0] = 0;
+ }
+
+ len = snprintf(NULL, 0, "htbthost-tmp.%d", ctr);
+ if (len < 0) {
+ goto END;
+ }
+ path = prne_alloc_str(len);
+ if (path == NULL) {
+ goto END;
+ }
+ prne_memzero(path, len + 1);
+ if (len != snprintf(path, len + 1, "htbthost-tmp.%d", ctr)) {
+ goto END;
+ }
+
+ // TODO: Polyfill
+ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
+ if (fd < 0) {
+ goto END;
+ }
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+
+ while (req_size > 0) {
+ consume = prne_op_min(z_size, req_size);
+ if (pth_write(fd, z, consume) != (int)consume) {
+ goto END;
+ }
+ req_size -= consume;
+ }
+
+ ret = path;
+ path = NULL;
+ ctr += 1;
+END:
+ if (path != NULL && fd >= 0) {
+ unlink(path);
+ }
+ prne_free(path);
+ prne_close(fd);
+ prne_free(z);
+ return ret;
+}
+
int main (const int argc, const char **args) {
static mbedtls_entropy_context entropy;
@@ -378,6 +435,7 @@ int main (const int argc, const char **args) {
param.cncp_ssl_conf = &ssl.cncp.conf;
param.ctr_drbg = &rnd;
param.resolv = resolv;
+ param.cb_f.tmpfile = mktmpfile;
param.cb_f.cnc_txtrec = cb_txtrec;
param.cb_f.hostinfo = cb_hostinfo;
diff --git a/src/protocol.c b/src/protocol.c
index 301e884..5388f52 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -711,12 +711,14 @@ prne_htbt_ser_rc_t prne_htbt_dser_cmd (const uint8_t *data, const size_t len, si
return PRNE_HTBT_SER_RC_MORE_BUF;
}
- mem = (char*)prne_malloc(1, args_len);
- if (mem == NULL) {
- ret = PRNE_HTBT_SER_RC_ERRNO;
- goto END;
+ if (args_len > 0) {
+ mem = (char*)prne_malloc(1, args_len);
+ if (mem == NULL) {
+ ret = PRNE_HTBT_SER_RC_ERRNO;
+ goto END;
+ }
+ memcpy(mem, data + 2, args_len);
}
- memcpy(mem, data + 2, args_len);
saved_errno = errno;
errno = 0;