diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/proone-print-all-data.c | 2 | ||||
-rw-r--r-- | src/proone.c | 77 | ||||
-rw-r--r-- | src/proone.h | 2 | ||||
-rw-r--r-- | src/proone_dvault.c | 22 | ||||
-rw-r--r-- | src/proone_dvault.h | 2 | ||||
-rw-r--r-- | src/proone_heartbeat-worker.c | 2 | ||||
-rw-r--r-- | src/proone_pack.c | 67 | ||||
-rw-r--r-- | src/proone_util.c | 154 | ||||
-rw-r--r-- | src/proone_util.h | 6 |
9 files changed, 283 insertions, 51 deletions
diff --git a/src/proone-print-all-data.c b/src/proone-print-all-data.c index 0c89cba..adf5ee9 100644 --- a/src/proone-print-all-data.c +++ b/src/proone-print-all-data.c @@ -15,7 +15,7 @@ int main (void) { switch (type) { case PROONE_DATA_TYPE_CSTR: - printf("%10lld: %s\n", (long long)i, proone_dvault_unmask_entry_cstr(i)); + printf("%10lld: %s\n", (long long)i, proone_dvault_unmask_entry_cstr(i, NULL)); break; default: fprintf(stderr, "Error: unhandled data type (%d)'%s'\n", (int)type, proone_data_type2str(type)); diff --git a/src/proone.c b/src/proone.c index 5e2d672..7ddaa8b 100644 --- a/src/proone.c +++ b/src/proone.c @@ -45,7 +45,7 @@ static bool ensure_single_instance (void) { int fd; fd = shm_open( - proone_dvault_unmask_entry_cstr(PROONE_DATA_KEY_PROC_LIM_SHM), + proone_dvault_unmask_entry_cstr(PROONE_DATA_KEY_PROC_LIM_SHM, NULL), O_RDWR | O_CREAT | O_TRUNC, 0666); proone_dvault_reset_dict(); @@ -151,6 +151,54 @@ static void proc_fin_call (void) { } } +static void print_ready_signature (void) { + size_t len; + uint8_t *sig_data; + char *plain_str, *sig_str; + + plain_str = proone_dvault_unmask_entry_cstr(PROONE_DATA_KEY_SIGN_INIT_OK, &len); + + sig_data = (uint8_t*)malloc(len + 1); + sig_data[0] = (uint8_t)(proone_rnd_gen_int(pne_global.rnd) % 256); + memcpy(sig_data + 1, plain_str, len); + proone_dvault_reset_dict(); + proone_dvault_invert_mem(len, sig_data + 1, sig_data[0]); + + sig_str = proone_enc_base64_mem(sig_data, len); + if (sig_str == NULL) { + abort(); + } + + puts(sig_str); + + free(sig_str); + free(sig_data); +} + +static void read_host_credential (void) { + static const size_t buf_size = (1 + 2 + 255 * 2) * 4 / 3; + char *buf = (char*)malloc(buf_size); + size_t i; + bool found = false; + + for (i = 0; i < buf_size; i += 1) { + if (read(STDIN_FILENO, &buf[i], 1) != 1) { + goto END; + } + + if (buf[i] == '\n') { + found = true; + break; + } + } + if (found) { + proone_dec_base64_mem(buf, i, &pne_global.host_cred_data, &pne_global.host_cred_size); + } + +END: + free(buf); +} + int main (const int argc, char **args) { int exit_code = 0; @@ -158,6 +206,8 @@ int main (const int argc, char **args) { worker_tuple_t *wt; proone_worker_sched_info_t sched_info; + pne_global.host_cred_data = NULL; + pne_global.host_cred_size = 0; pne_global.has_proc_lim_lock = false; pne_global.bin_ready = false; pne_global.caught_signal = 0; @@ -173,9 +223,9 @@ int main (const int argc, char **args) { #endif init_rnd_engine(); + print_ready_signature(); + read_host_credential(); // get fed with the bin archive - puts(proone_dvault_unmask_entry_cstr(PROONE_DATA_KEY_SIGN_INIT_OK)); - proone_dvault_reset_dict(); pne_global.bin_pack = proone_unpack_bin_archive(STDIN_FILENO); if (pne_global.bin_pack.result == PROONE_UNPACK_BIN_ARCHIVE_OK) { pne_global.bin_ready = proone_index_bin_archive(&pne_global.bin_pack, &pne_global.bin_archive) == PROONE_INDEX_BIN_ARCHIVE_OK; @@ -185,12 +235,12 @@ int main (const int argc, char **args) { close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); - errno = 0; // install signal handlers // try to exit gracefully upon reception of these signals signal(SIGINT, handle_interrupt); signal(SIGTERM, handle_interrupt); + signal(SIGCHLD, SIG_IGN); #ifndef DEBUG signal(SIGPIPE, SIG_IGN); #endif @@ -271,6 +321,9 @@ int main (const int argc, char **args) { 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 = realloc(pollfd_pool.arr, total_pollfd_size * sizeof(struct pollfd)); if (ny_mem != NULL) { pollfd_pool.arr = (struct pollfd*)ny_mem; @@ -279,6 +332,11 @@ int main (const int argc, char **args) { 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 & PROONE_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)); @@ -299,6 +357,11 @@ int main (const int argc, char **args) { 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 & PROONE_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); @@ -326,8 +389,12 @@ END: wt->sched_req.mem_func.free(&wt->sched_req); } + free(pne_global.host_cred_data); + pne_global.host_cred_data = NULL; + pne_global.host_cred_size = 0; + if (pne_global.has_proc_lim_lock) { - shm_unlink(proone_dvault_unmask_entry_cstr(PROONE_DATA_KEY_PROC_LIM_SHM)); + shm_unlink(proone_dvault_unmask_entry_cstr(PROONE_DATA_KEY_PROC_LIM_SHM, NULL)); proone_dvault_reset_dict(); pne_global.has_proc_lim_lock = false; } diff --git a/src/proone.h b/src/proone.h index c40a1b1..49e9d9c 100644 --- a/src/proone.h +++ b/src/proone.h @@ -6,6 +6,8 @@ struct proone_global { + uint8_t *host_cred_data; + size_t host_cred_size; bool has_proc_lim_lock; bool bin_ready; int caught_signal; diff --git a/src/proone_dvault.c b/src/proone_dvault.c index 0347871..1da09cc 100644 --- a/src/proone_dvault.c +++ b/src/proone_dvault.c @@ -40,9 +40,12 @@ static uint8_t *unmasked_buf = NULL; static size_t unmasked_buf_size = 0; -static void pne_dvault_invert_entry (const proone_data_key_t key) { +static void pne_dvault_invert_entry (const proone_data_key_t key, size_t *len) { const size_t entry_size = proone_dvault_get_entry_size(key); + if (len != NULL) { + *len = entry_size; + } memcpy(unmasked_buf, PROONE_DATA_DICT[key] + 4, entry_size); proone_dvault_invert_mem(entry_size, unmasked_buf, proone_dvault_get_entry_salt(key)); } @@ -134,12 +137,21 @@ void proone_init_dvault (void) { for (i = PROONE_DATA_KEY_NONE + 1; i < NB_PROONE_DATA_KEY; i += 1) { entry_size = proone_dvault_get_entry_size(i); + switch (proone_dvault_get_entry_data_type(i)) { + case PROONE_DATA_TYPE_CSTR: + entry_size += 1; + break; + } + if (entry_size > max_size) { max_size = entry_size; } } - unmasked_buf = malloc(max_size); + if (max_size == 0) { + abort(); + } + unmasked_buf = calloc(max_size, 1); unmasked_buf_size = max_size; if (unmasked_buf == NULL) { abort(); @@ -163,11 +175,11 @@ uint8_t proone_dvault_get_entry_salt (const proone_data_key_t key) { return PROONE_DATA_DICT[key][1]; } -const char *proone_dvault_unmask_entry_cstr (const proone_data_key_t key) { +char *proone_dvault_unmask_entry_cstr (const proone_data_key_t key, size_t *len) { proone_dvault_reset_dict(); pne_dvault_entry_check(key, PROONE_DATA_TYPE_CSTR); - pne_dvault_invert_entry(key); - return (const char*)unmasked_buf; + pne_dvault_invert_entry(key, len); + return (char*)unmasked_buf; } void proone_dvault_reset_dict (void) { diff --git a/src/proone_dvault.h b/src/proone_dvault.h index 0884c98..8dedee6 100644 --- a/src/proone_dvault.h +++ b/src/proone_dvault.h @@ -43,5 +43,5 @@ void proone_deinit_dvault (void); proone_data_type_t proone_dvault_get_entry_data_type (const proone_data_key_t key); size_t proone_dvault_get_entry_size (const proone_data_key_t key); uint8_t proone_dvault_get_entry_salt (const proone_data_key_t key); -const char *proone_dvault_unmask_entry_cstr (const proone_data_key_t key); +char *proone_dvault_unmask_entry_cstr (const proone_data_key_t key, size_t *len); void proone_dvault_reset_dict (void); diff --git a/src/proone_heartbeat-worker.c b/src/proone_heartbeat-worker.c index b0d4be2..817021e 100644 --- a/src/proone_heartbeat-worker.c +++ b/src/proone_heartbeat-worker.c @@ -47,6 +47,8 @@ static void heartbeat_worker_work (void *in_ctx, const proone_worker_sched_info_ } if (revents & POLLIN) { socklen_t addr_len; + + // TODO if (ctx->domain == AF_INET) { struct sockaddr_in remote_addr; diff --git a/src/proone_pack.c b/src/proone_pack.c index f9d8c3b..dec602e 100644 --- a/src/proone_pack.c +++ b/src/proone_pack.c @@ -1,10 +1,10 @@ #include "proone_pack.h" +#include "proone_util.h" #include <stdint.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> -#include <ctype.h> #include <fcntl.h> #include <unistd.h> @@ -37,27 +37,32 @@ proone_unpack_bin_archive_result_t proone_unpack_bin_archive (const int fd) { proone_unpack_bin_archive_result_t ret; BIO *b64_bio = NULL, *mem_bio = NULL; - uint8_t fd_buf[fd_buf_size], bio_buf[bio_buf_size], z_buf[z_buf_size]; + uint8_t *mem = NULL, *fd_buf = NULL, *bio_buf = NULL, *z_buf = NULL; int fd_read_size, fd_data_size, bio_write_size, bio_read_size; int z_func_ret; z_stream stream; size_t z_out_size; void *ny_buf; bool stream_end; - size_t i; proone_init_unpack_bin_archive_result(&ret); + memset(&stream, 0, sizeof(z_stream)); + + mem = (uint8_t*)malloc(fd_buf_size + bio_buf_size + z_buf_size); + if (mem == NULL) { + ret.result = PROONE_UNPACK_BIN_ARCHIVE_MEM_ERR; + ret.err = errno; + goto END; + } + fd_buf = mem; + bio_buf = mem + fd_buf_size; + z_buf = mem + fd_buf_size + bio_buf_size; - stream.zalloc = NULL; - stream.zfree = NULL; - stream.opaque = NULL; - stream.avail_in = 0; - stream.next_in = Z_NULL; z_func_ret = inflateInit(&stream); if (z_func_ret != Z_OK) { ret.result = PROONE_UNPACK_BIN_ARCHIVE_Z_ERR; ret.err = z_func_ret; - return ret; + goto END; } if ((mem_bio = BIO_new(BIO_s_mem())) == NULL || (b64_bio = BIO_new(BIO_f_base64())) == NULL) { @@ -81,21 +86,7 @@ proone_unpack_bin_archive_result_t proone_unpack_bin_archive (const int fd) { } // remove white spaces - fd_data_size = fd_read_size; - for (i = 0; i < (size_t)fd_data_size; ) { - if (isspace(fd_buf[i])) { - if (i + 1 >= (size_t)fd_data_size) { - // last trailing whitespace - fd_data_size -= 1; - break; - } - memmove(fd_buf + i, fd_buf + i + 1, fd_data_size - i - 1); - fd_data_size -= 1; - } - else { - i += 1; - } - } + fd_data_size = proone_str_shift_spaces((char*)fd_buf, (size_t)fd_read_size); if (fd_data_size > 0) { BIO_reset(mem_bio); @@ -133,31 +124,33 @@ proone_unpack_bin_archive_result_t proone_unpack_bin_archive (const int fd) { } z_out_size = z_buf_size - stream.avail_out; - ny_buf = realloc(ret.data, ret.data_size + z_out_size); - if (ny_buf == NULL) { - ret.result = PROONE_UNPACK_BIN_ARCHIVE_MEM_ERR; - ret.err = errno; - break; + if (z_out_size > 0) { + ny_buf = realloc(ret.data, ret.data_size + z_out_size); + if (ny_buf == NULL) { + ret.result = PROONE_UNPACK_BIN_ARCHIVE_MEM_ERR; + ret.err = errno; + break; + } + ret.data = (uint8_t*)ny_buf; + + memcpy(ret.data + ret.data_size, z_buf, z_out_size); + ret.data_size += z_out_size; } - ret.data = (uint8_t*)ny_buf; - - memcpy(ret.data + ret.data_size, z_buf, z_out_size); - ret.data_size += z_out_size; } while (stream.avail_out == 0); } } } while (!stream_end); END: - inflateEnd(&stream); - BIO_free(b64_bio); - BIO_free(mem_bio); - + free(mem); if (ret.result != PROONE_UNPACK_BIN_ARCHIVE_OK) { free(ret.data); ret.data = NULL; ret.data_size = 0; } + inflateEnd(&stream); + BIO_free(b64_bio); + BIO_free(mem_bio); return ret; } diff --git a/src/proone_util.c b/src/proone_util.c index dc9e498..6017e54 100644 --- a/src/proone_util.c +++ b/src/proone_util.c @@ -1,6 +1,13 @@ #include "proone_util.h" #include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include <errno.h> + +#include <openssl/bio.h> +#include <openssl/evp.h> void proone_succeed_or_die (const int ret) { @@ -9,6 +16,8 @@ void proone_succeed_or_die (const int ret) { } } +void proone_empty_func () {} + void proone_rnd_alphanumeric_str (proone_rnd_engine_t *rnd_engine, char *str, const size_t len) { static const char SET[] = "qwertyuiopasdfghjklzxcvbnm0123456789"; size_t i = 0; @@ -31,7 +40,27 @@ void proone_rnd_alphanumeric_str (proone_rnd_engine_t *rnd_engine, char *str, co } } -void proone_empty_func () {} +size_t proone_str_shift_spaces (char *str, const size_t len) { + size_t i, ret = len; + + for (i = 0; i < ret; ) { + if (isspace(str[i])) { + if (i + 1 >= ret) { + // last trailing whitespace + ret -= 1; + break; + } + memmove(str + i, str + i + 1, ret - i - 1); + ret -= 1; + } + else { + i += 1; + } + } + + return ret; +} + struct timespec proone_sub_timespec (const struct timespec *a, const struct timespec *b) { struct timespec ret; @@ -62,3 +91,126 @@ int proone_cmp_timespec (const struct timespec *a, const struct timespec *b) { return a->tv_nsec < b->tv_nsec ? -1 : a->tv_nsec > b->tv_nsec ? 1 : 0; } + +char *proone_enc_base64_mem (const uint8_t *data, const size_t size) { + char *ret = NULL, *p = NULL; + BIO *b64_bio = NULL, *mem_bio = NULL; + bool ok = true; + int out_len; + + if (size > INT32_MAX || size == 0) { + return NULL; + } + + b64_bio = BIO_new(BIO_f_base64()); + mem_bio = BIO_new(BIO_s_mem()); + if (b64_bio == NULL || mem_bio == NULL) { + ok = false; + goto END; + } + BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); + BIO_push(b64_bio, mem_bio); + + if (BIO_write(b64_bio, data, size) != (int)size) { + ok = false; + goto END; + } + + out_len = BIO_get_mem_data(mem_bio, &p); + if (out_len < 0) { + ok = false; + goto END; + } + if (out_len > 0) { + ret = (char*)malloc(out_len + 1); + if (ret == NULL) { + ok = false; + goto END; + } + memcpy(ret, p, out_len); + ret[out_len] = 0; + } + +END: + BIO_free(b64_bio); + BIO_free(mem_bio); + if (!ok) { + free(ret); + ret = NULL; + } + + return ret; +} + +bool proone_dec_base64_mem (const char *str, const size_t str_len, uint8_t **data, size_t *size) { + char *in_mem = NULL; + size_t in_mem_len, out_len; + uint8_t *out_mem = NULL; + BIO *b64_bio = NULL, *mem_bio = NULL; + bool ret = true; + int read_size = 0; + + if (str_len > INT32_MAX) { + errno = EINVAL; + return false; + } + if (str_len == 0) { + ret = true; + goto END; + } + + in_mem = (char*)malloc(str_len); + if (in_mem == NULL) { + ret = false; + goto END; + } + memcpy(in_mem, str, str_len); + in_mem_len = proone_str_shift_spaces(in_mem, str_len); + if (in_mem_len == 0) { + ret = true; + goto END; + } + + b64_bio = BIO_new(BIO_f_base64()); + mem_bio = BIO_new_mem_buf(in_mem, in_mem_len); + if (b64_bio == NULL || mem_bio == NULL) { + ret = false; + goto END; + } + BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); + BIO_push(b64_bio, mem_bio); + + out_len = in_mem_len * 3 / 4; + out_mem = (uint8_t*)malloc((size_t)out_len); + if (out_mem == NULL) { + ret = false; + goto END; + } + + read_size = BIO_read(b64_bio, out_mem, out_len); + if (read_size < 0) { + ret = false; + goto END; + } + +END: + BIO_free(b64_bio); + BIO_free(mem_bio); + free(in_mem); + if (ret) { + if (read_size > 0) { + *data = out_mem; + *size = (size_t)read_size; + } + else { + free(out_mem); + *data = NULL; + *size = 0; + } + } + else { + free(out_mem); + } + + return ret; +} diff --git a/src/proone_util.h b/src/proone_util.h index 730ed3c..605f2a8 100644 --- a/src/proone_util.h +++ b/src/proone_util.h @@ -21,10 +21,14 @@ bool proone_strendsw (const char *str, const char *w) { #endif void proone_succeed_or_die (const int ret); +void proone_empty_func (); void proone_rnd_alphanumeric_str (proone_rnd_engine_t *rnd_engine, char *str, const size_t len); -void proone_empty_func (); +size_t proone_str_shift_spaces (char *str, const size_t len); struct timespec proone_sub_timespec (const struct timespec *a, const struct timespec *b); double proone_real_timespec (const struct timespec *ts); int proone_cmp_timespec (const struct timespec *a, const struct timespec *b); + +char *proone_enc_base64_mem (const uint8_t *data, const size_t size); +bool proone_dec_base64_mem (const char *str, const size_t str_len, uint8_t **data, size_t *size); |