From 46da7e6739aba106625d36376e9a8be29639f91c Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 10 Jan 2019 13:15:01 -0500 Subject: [PATCH 1/8] backports u3r_chubs from cc-release --- include/noun/retrieve.h | 10 ++++++++++ noun/retrieve.c | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/noun/retrieve.h b/include/noun/retrieve.h index b9a4de440..4a9398c0b 100644 --- a/include/noun/retrieve.h +++ b/include/noun/retrieve.h @@ -402,6 +402,16 @@ c3_w* c_w, u3_atom d); + /* u3r_chubs(): + ** + ** Copy double-words (a_w) through (a_w + b_w - 1) from (d) to (c). + */ + void + u3r_chubs(c3_w a_w, + c3_w b_w, + c3_d* c_d, + u3_atom d); + /* u3r_string(): `a`, a text atom, as malloced C string. */ c3_c* diff --git a/noun/retrieve.c b/noun/retrieve.c index b919ef47e..d106034e8 100644 --- a/noun/retrieve.c +++ b/noun/retrieve.c @@ -1352,6 +1352,21 @@ u3r_words(c3_w a_w, } } +/* u3r_chubs(): +** +** Copy double-words (a_w) through (a_w + b_w - 1) from (d) to (c). +*/ +void +u3r_chubs(c3_w a_w, + c3_w b_w, + c3_d* c_d, + u3_atom d) +{ + /* XX: assumes little-endian + */ + u3r_words(a_w * 2, b_w * 2, (c3_w *)c_d, d); +} + /* u3r_chop(): ** ** Into the bloq space of `met`, from position `fum` for a From 4c92b65d1f428b80852931c08a852a235e49fb50 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 10 Jan 2019 13:41:52 -0500 Subject: [PATCH 2/8] refactors u3_ward/u3_warc lifecycle, preventing potential leaks --- include/vere/vere.h | 4 +-- vere/http.c | 65 +++++++++++++++++++++------------------------ 2 files changed, 32 insertions(+), 37 deletions(-) diff --git a/include/vere/vere.h b/include/vere/vere.h index fe54c6f3a..d5f031cac 100644 --- a/include/vere/vere.h +++ b/include/vere/vere.h @@ -133,7 +133,7 @@ c3_w ipf_w; // ward ip c3_s por_s; // ward port c3_o sec; // secure connection - u3_atom sip; // ward ship + c3_d who_d[2]; // ward ship c3_c* hot_c; // ward hostname uv_buf_t non_u; // nonce struct _u3_http* htp_u; // local server backlink @@ -154,7 +154,7 @@ typedef struct _u3_ward { uv_tcp_t tcp_u; // listener handle uv_timer_t tim_u; // expiration timer - u3_atom sip; // reverse proxy for ship + c3_d who_d[2]; // reverse proxy for ship c3_s por_s; // listening on port uv_buf_t non_u; // nonce struct _u3_wcon* won_u; // candidate upstream connections diff --git a/vere/http.c b/vere/http.c index e0ee698ca..25e887f40 100644 --- a/vere/http.c +++ b/vere/http.c @@ -1652,22 +1652,32 @@ _proxy_warc_free(u3_warc* cli_u) /* _proxy_warc_new(): allocate ship-specific proxy client */ static u3_warc* -_proxy_warc_new(u3_http* htp_u, u3_atom sip, c3_s por_s, c3_o sec) +_proxy_warc_new(u3_http* htp_u, u3_atom sip, u3_atom non, c3_s por_s, c3_o sec) { - u3_warc* cli_u = c3_malloc(sizeof(*cli_u)); + u3_warc* cli_u = c3_calloc(sizeof(*cli_u)); cli_u->htp_u = htp_u; cli_u->por_s = por_s; - // XX set here instead of u3_http_ef_that() ? - cli_u->non_u = uv_buf_init(0, 0); - cli_u->sip = sip; cli_u->sec = sec; - // XX set here instead of _proxy_ward_resolve() ? - cli_u->hot_c = 0; - cli_u->nex_u = 0; - cli_u->pre_u = 0; + u3r_chubs(0, 2, cli_u->who_d, sip); _proxy_warc_link(cli_u); + { + c3_w len_w = u3r_met(3, non); + + c3_assert( 256 > len_w ); + + c3_y* non_y = c3_malloc(1 + len_w); + non_y[0] = (c3_y)len_w; + + u3r_bytes(0, len_w, non_y + 1, non); + + cli_u->non_u = uv_buf_init((c3_c*)non_y, 1 + len_w); + } + + u3z(non); + u3z(sip); + return cli_u; } @@ -2133,7 +2143,6 @@ _proxy_ward_free(uv_handle_t* han_u) { u3_ward* rev_u = han_u->data; - u3z(rev_u->sip); free(rev_u->non_u.base); free(rev_u); } @@ -2168,18 +2177,16 @@ _proxy_ward_close(u3_ward* rev_u) static u3_ward* _proxy_ward_new(u3_pcon* con_u, u3_atom sip) { - u3_ward* rev_u = c3_malloc(sizeof(*rev_u)); + u3_ward* rev_u = c3_calloc(sizeof(*rev_u)); rev_u->tcp_u.data = rev_u; rev_u->tim_u.data = rev_u; rev_u->con_u = con_u; - rev_u->sip = sip; - rev_u->por_s = 0; // set after opened - rev_u->won_u = 0; - rev_u->nex_u = 0; - rev_u->pre_u = 0; + u3r_chubs(0, 2, rev_u->who_d, sip); _proxy_ward_link(con_u, rev_u); + u3z(sip); + return rev_u; } @@ -2293,7 +2300,7 @@ _proxy_ward_plan(u3_ward* rev_u) u3_noun pax = u3nq(u3_blip, c3__http, c3__prox, u3nc(u3k(u3A->sen), u3_nul)); - u3_noun wis = u3nc(c3__wise, u3nq(u3k(rev_u->sip), + u3_noun wis = u3nc(c3__wise, u3nq(u3i_chubs(2, rev_u->who_d), rev_u->por_s, u3k(rev_u->con_u->sec), u3i_words(16, (c3_w*)rev_u->non_u.base))); @@ -2305,7 +2312,7 @@ _proxy_ward_plan(u3_ward* rev_u) static void _proxy_ward_start(u3_pcon* con_u, u3_noun sip) { - u3_ward* rev_u = _proxy_ward_new(con_u, sip); + u3_ward* rev_u = _proxy_ward_new(con_u, u3k(sip)); uv_tcp_init(u3L, &rev_u->tcp_u); @@ -2355,6 +2362,8 @@ _proxy_ward_start(u3_pcon* con_u, u3_noun sip) // XX u3_lo_shut(c3y); } + + u3z(sip); } /* _proxy_ward_connect_cb(): ward connection callback @@ -2455,7 +2464,7 @@ _proxy_ward_resolve(u3_warc* cli_u) // XX revisit c3_assert( 0 != u3_Host.sam_u.dns_c ); - u3_noun sip = u3dc("scot", 'p', u3k(cli_u->sip)); + u3_noun sip = u3dc("scot", 'p', u3i_chubs(2, cli_u->who_d)); c3_c* sip_c = u3r_string(sip); c3_w len_w = 1 + strlen(sip_c) + strlen(u3_Host.sam_u.dns_c); cli_u->hot_c = c3_malloc(len_w); @@ -2613,7 +2622,6 @@ _proxy_dest(u3_pcon* con_u, u3_noun sip) else { // XX check if (sein:title sip) == our // XX check will - // XX extract bytes from hip, this could leak _proxy_ward_start(con_u, u3k(hip)); } } @@ -2875,21 +2883,8 @@ u3_http_ef_that(u3_noun tat) return; } - // XX extract bytes from sip, this could leak - cli_u = _proxy_warc_new(htp_u, (u3_atom)sip, (c3_s)por, (c3_o)sec); - - // XX add to constructor - c3_w len_w = u3r_met(3, non); - - c3_assert( 256 > len_w ); - - c3_y* non_y = c3_malloc(1 + len_w); - non_y[0] = (c3_y)len_w; - - u3r_bytes(0, len_w, non_y + 1, non); - - cli_u->non_u = uv_buf_init((c3_c*)non_y, 1 + len_w); - + cli_u = _proxy_warc_new(htp_u, (u3_atom)u3k(sip), (u3_atom)u3k(non), + (c3_s)por, (c3_o)sec); if ( c3n == u3_Host.ops_u.net ) { cli_u->ipf_w = INADDR_LOOPBACK; From 9f6300b79bf196122bc4f5aabf373ecc913d1c9d Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 10 Jan 2019 14:16:26 -0500 Subject: [PATCH 3/8] refactors and comments u3_http_ef_that() --- vere/http.c | 54 +++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/vere/http.c b/vere/http.c index 25e887f40..b2e5b9cb3 100644 --- a/vere/http.c +++ b/vere/http.c @@ -2863,37 +2863,39 @@ u3_http_ef_that(u3_noun tat) !( c3y == sec || c3n == sec ) || ( c3n == u3ud(non) ) ) { uL(fprintf(uH, "http: that: invalid card\n")); - u3z(tat); - return; } + else { + u3_http* htp_u; + u3_warc* cli_u; - u3_http* htp_u; - u3_warc* cli_u; + for ( htp_u = u3_Host.htp_u; (0 != htp_u); htp_u = htp_u->nex_u ) { + if ( c3n == htp_u->lop && sec == htp_u->sec ) { + break; + } + } - for ( htp_u = u3_Host.htp_u; (0 != htp_u); htp_u = htp_u->nex_u ) { - if ( c3n == htp_u->lop && sec == htp_u->sec ) { - break; + // XX we should inform our sponsor if we aren't running a server + // so this situation can be avoided + // + if ( 0 == htp_u ) { + uL(fprintf(uH, "http: that: no %s server\n", (c3y == sec) ? + "secure" : "insecure")); + } + else { + cli_u = _proxy_warc_new(htp_u, (u3_atom)u3k(sip), (u3_atom)u3k(non), + (c3_s)por, (c3_o)sec); + + // resolve to loopback if networking is disabling + // + if ( c3n == u3_Host.ops_u.net ) { + cli_u->ipf_w = INADDR_LOOPBACK; + _proxy_ward_connect(cli_u); + } + else { + _proxy_ward_resolve(cli_u); + } } } - if ( 0 == htp_u ) { - uL(fprintf(uH, "http: that: no %s server\n", (c3y == sec) ? - "secure" : "insecure")); - u3z(tat); - return; - } - - cli_u = _proxy_warc_new(htp_u, (u3_atom)u3k(sip), (u3_atom)u3k(non), - (c3_s)por, (c3_o)sec); - - if ( c3n == u3_Host.ops_u.net ) { - cli_u->ipf_w = INADDR_LOOPBACK; - _proxy_ward_connect(cli_u); - u3z(tat); - return; - } - - _proxy_ward_resolve(cli_u); - u3z(tat); } From a20508b49d46f7307157af117549c1733e400321 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 10 Jan 2019 15:03:19 -0500 Subject: [PATCH 4/8] hardcodes tcp proxy domain --- vere/http.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/vere/http.c b/vere/http.c index b2e5b9cb3..94bd4bf6e 100644 --- a/vere/http.c +++ b/vere/http.c @@ -41,6 +41,10 @@ static void _http_form_free(void); static const c3_i TCP_BACKLOG = 16; +// XX temporary, add to u3_http_ef_form +// +#define PROXY_DOMAIN "arvo.network" + /* _http_vec_to_meth(): convert h2o_iovec_t to meth */ static u3_weak @@ -2460,16 +2464,15 @@ _proxy_ward_resolve(u3_warc* cli_u) hin_u.ai_socktype = SOCK_STREAM; hin_u.ai_protocol = IPPROTO_TCP; + // XX why the conditional? + // if ( 0 == cli_u->hot_c ) { - // XX revisit - c3_assert( 0 != u3_Host.sam_u.dns_c ); - u3_noun sip = u3dc("scot", 'p', u3i_chubs(2, cli_u->who_d)); c3_c* sip_c = u3r_string(sip); - c3_w len_w = 1 + strlen(sip_c) + strlen(u3_Host.sam_u.dns_c); + c3_w len_w = 1 + strlen(sip_c) + strlen(PROXY_DOMAIN); cli_u->hot_c = c3_malloc(len_w); // incremented to skip '~' - snprintf(cli_u->hot_c, len_w, "%s.%s", sip_c + 1, u3_Host.sam_u.dns_c); + snprintf(cli_u->hot_c, len_w, "%s.%s", sip_c + 1, PROXY_DOMAIN); free(sip_c); u3z(sip); From 280ff8725192a82cab864698e1d682aa0764cdf8 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 10 Jan 2019 13:42:30 -0500 Subject: [PATCH 5/8] refactors proxy domain parsing and validation --- vere/http.c | 68 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/vere/http.c b/vere/http.c index 94bd4bf6e..0e74174ed 100644 --- a/vere/http.c +++ b/vere/http.c @@ -2566,45 +2566,52 @@ _proxy_parse_sni(const uv_buf_t* buf_u, c3_c** hot_c) return u3_pars_good; } -/* _proxy_parse_ship(): determine destination for proxied request +/* _proxy_parse_ship(): determine destination (unit ship) for proxied request */ static u3_noun _proxy_parse_ship(c3_c* hot_c) { - u3_noun sip = u3_nul; - c3_c* dom_c; - if ( 0 == hot_c ) { - return sip; + return u3_nul; } + else { + c3_c* dom_c = strchr(hot_c, '.'); - dom_c = strchr(hot_c, '.'); + if ( 0 == dom_c ) { + return u3_nul; + } + else { + // length of the first subdomain + // + c3_w dif_w = dom_c - hot_c; + c3_w dns_w = strlen(PROXY_DOMAIN); - if ( 0 == dom_c ) { - return sip; - } + // validate that everything after the first subdomain + // matches the proxy domain + // (skipped if networking is disabled) + // + if ( (c3y == u3_Host.ops_u.net) && + ( (dns_w != strlen(hot_c) - (dif_w + 1)) || + (0 != strncmp(dom_c + 1, PROXY_DOMAIN, dns_w)) ) ) + { + return u3_nul; + } + else { + // attempt to parse the first subdomain as a @p + // + u3_noun sip; + c3_c* sip_c = c3_malloc(2 + dif_w); - // XX revisit - c3_assert( 0 != u3_Host.sam_u.dns_c ); + strncpy(sip_c + 1, hot_c, dif_w); + sip_c[0] = '~'; + sip_c[1 + dif_w] = 0; - c3_w dif_w = dom_c - hot_c; - c3_w dns_w = strlen(u3_Host.sam_u.dns_c); + sip = u3dc("slaw", 'p', u3i_string(sip_c)); + free(sip_c); - if ( (dns_w != strlen(hot_c) - (dif_w + 1)) || - (0 != strncmp(dom_c + 1, u3_Host.sam_u.dns_c, dns_w)) ) { - return sip; - } - - { - c3_c* sip_c = c3_malloc(2 + dif_w); - strncpy(sip_c + 1, hot_c, dif_w); - sip_c[0] = '~'; - sip_c[1 + dif_w] = 0; - - sip = u3dc("slaw", 'p', u3i_string(sip_c)); - free(sip_c); - - return sip; + return sip; + } + } } } @@ -2623,8 +2630,9 @@ _proxy_dest(u3_pcon* con_u, u3_noun sip) _proxy_loop_connect(con_u); } else { - // XX check if (sein:title sip) == our - // XX check will + // XX we should u3v_peek %j /=sein= to confirm + // that we're sponsoring this ship + // _proxy_ward_start(con_u, u3k(hip)); } } From 5c0a05011a99f5d7231be5c237282ac1eddcfe71 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 10 Jan 2019 20:20:42 -0500 Subject: [PATCH 6/8] disables proxy printf on u3_ward auth failure --- vere/http.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/vere/http.c b/vere/http.c index 0e74174ed..95783fa1e 100644 --- a/vere/http.c +++ b/vere/http.c @@ -2215,11 +2215,10 @@ _proxy_wcon_peek_read_cb(uv_stream_t* upt_u, c3_w len_w = rev_u->non_u.len; - // XX await further reads if siz_w < len_w ? if ( ((len_w + 1) != siz_w) || (len_w != buf_u->base[0]) || (0 != memcmp(rev_u->non_u.base, buf_u->base + 1, len_w)) ) { - uL(fprintf(uH, "proxy: ward auth fail\n")); + // uL(fprintf(uH, "proxy: ward auth fail\n")); _proxy_wcon_unlink(won_u); _proxy_wcon_close(won_u); } @@ -2344,6 +2343,16 @@ _proxy_ward_start(u3_pcon* con_u, u3_noun sip) rev_u->por_s = ntohs(add_u.sin_port); +#if 0 + { + u3_noun who = u3dc("scot", 'p', u3k(sip)); + c3_c* who_c = u3r_string(who); + fprintf(stderr, "\r\nward for %s started on %u\r\n", who_c, rev_u->por_s); + free(who_c); + u3z(who); + } +#endif + { c3_w* non_w = c3_malloc(64); From 71d27f99f05022f1efd0e4a8d3a53d31d786de1b Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 10 Jan 2019 20:51:14 -0500 Subject: [PATCH 7/8] refactors _proxy_ward_start() and _proxy_ward_plan() --- vere/http.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/vere/http.c b/vere/http.c index 95783fa1e..5bd47ef29 100644 --- a/vere/http.c +++ b/vere/http.c @@ -2299,6 +2299,23 @@ _proxy_ward_timer_cb(uv_timer_t* tim_u) static void _proxy_ward_plan(u3_ward* rev_u) { + u3_noun non; + + { + c3_w* non_w = c3_malloc(64); + c3_w len_w; + + c3_rand(non_w); + + non = u3i_words(16, non_w); + len_w = u3r_met(3, non); + + // the nonce is saved to authenticate u3_wcon + // and will be freed with u3_ward + // + rev_u->non_u = uv_buf_init((c3_c*)non_w, len_w); + } + // XX confirm duct u3_noun pax = u3nq(u3_blip, c3__http, c3__prox, u3nc(u3k(u3A->sen), u3_nul)); @@ -2306,7 +2323,7 @@ _proxy_ward_plan(u3_ward* rev_u) u3_noun wis = u3nc(c3__wise, u3nq(u3i_chubs(2, rev_u->who_d), rev_u->por_s, u3k(rev_u->con_u->sec), - u3i_words(16, (c3_w*)rev_u->non_u.base))); + non)); u3v_plan(pax, wis); } @@ -2353,24 +2370,11 @@ _proxy_ward_start(u3_pcon* con_u, u3_noun sip) } #endif - { - c3_w* non_w = c3_malloc(64); - - c3_rand(non_w); - - u3_noun non = u3i_words(16, non_w); - c3_w len_w = u3r_met(3, non); - - rev_u->non_u = uv_buf_init((c3_c*)non_w, len_w); - - u3z(non); - } - _proxy_ward_plan(rev_u); + // XX how long? + // uv_timer_init(u3L, &rev_u->tim_u); - - // XX how long? uv_timer_start(&rev_u->tim_u, _proxy_ward_timer_cb, 300 * 1000, 0); // XX u3_lo_shut(c3y); From 61afdf9309e0ae68bec9b02c59f578a75b5f3ee2 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Fri, 11 Jan 2019 11:06:20 -0500 Subject: [PATCH 8/8] fixes typos in http.c --- vere/http.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vere/http.c b/vere/http.c index 5bd47ef29..8baf7f729 100644 --- a/vere/http.c +++ b/vere/http.c @@ -2689,7 +2689,7 @@ _proxy_peek(u3_pcon* con_u) } } - if ( 0 != hot_c ) { + if ( 0 != hot_c ) { free(hot_c); } } @@ -2909,7 +2909,7 @@ u3_http_ef_that(u3_noun tat) cli_u = _proxy_warc_new(htp_u, (u3_atom)u3k(sip), (u3_atom)u3k(non), (c3_s)por, (c3_o)sec); - // resolve to loopback if networking is disabling + // resolve to loopback if networking is disabled // if ( c3n == u3_Host.ops_u.net ) { cli_u->ipf_w = INADDR_LOOPBACK;