From 98ce42f5adbcee6b678d354b4d6b84300f740432 Mon Sep 17 00:00:00 2001 From: yosoyubik Date: Thu, 26 Oct 2023 14:15:00 +0200 Subject: [PATCH] stun: add sanity checks on response --- pkg/vere/io/ames.c | 61 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/pkg/vere/io/ames.c b/pkg/vere/io/ames.c index 7e75afac81..8f1c449f29 100644 --- a/pkg/vere/io/ames.c +++ b/pkg/vere/io/ames.c @@ -1272,10 +1272,9 @@ static void _stun_on_request(u3_ames *sam_u, c3_y buf_r[20], buf_y[cur_w] = 0x00; buf_y[cur_w + 1] = 0x01; // STUN attribute type 0x0001 buf_y[cur_w + 2] = 0x00; buf_y[cur_w + 3] = 0x08; // STUN attribute length // extra reserved 0x0 byte - // XX use memcpy instead? - _ames_etch_short(buf_y + cur_w+ 5, 0x01); // family 0x01:IPv4 - _ames_etch_short(buf_y + cur_w+ 6, add_u->sin_port); // Port - _ames_etch_word(buf_y + cur_w+ 8, htonl(add_u->sin_addr.s_addr)); // IP Addres + buf_y[cur_w + 5] = 0x01; // family 0x01:IPv4 + memcpy(buf_y + cur_w + 6, &add_u->sin_port, 2); // Port + memcpy(buf_y + cur_w + 8, &add_u->sin_addr.s_addr, 4); // IP Addres uv_buf_t buf_u = uv_buf_init((c3_c*)buf_y, 32); u3l_log("hear request on %u", add_u->sin_addr.s_addr); @@ -1307,11 +1306,7 @@ _stun_on_response(u3_ames* sam_u) // TODO read arg uv_timer_stop(&sam_u->sun_u.tim_u); sam_u->sun_u.tim_u.data = sam_u; uv_timer_start(&sam_u->sun_u.tim_u, _stun_timer_cb, 25*1000, 0); - // inject %stun task into arvo - u3_noun wir = u3nc(c3__ames, u3_nul); - u3_noun cad = u3nc(c3__stun, c3n); - u3_ovum *ovo_u = u3_ovum_init(0, c3__ames, wir, cad); - u3_auto_plan(&sam_u->car_u, ovo_u); + } break; default: assert("programmer error"); } @@ -1500,6 +1495,18 @@ _stun_start(u3_ames* sam_u, u3_noun dad) _stun_czar(sam_u); } +static c3_o +_stun_is_our_response(c3_y buf_y[32], c3_y tid_y[12], c3_w buf_len) +{ + c3_w cookie = htonl(0x2112A442); + + return !(buf_len == 32 && + buf_y[0] == 0x01 && buf_y[1] == 0x01 && + memcmp(&cookie, buf_y + 4, 4) == 0 && + memcmp(tid_y, buf_y + 8, 12) == 0 + ); +} + static c3_o _ames_is_czar(u3_noun who) { @@ -2391,6 +2398,8 @@ _ames_recv_cb(uv_udp_t* wax_u, const struct sockaddr* adr_u, unsigned flg_i) { + u3_ames* sam_u = wax_u->data; + if ( 0 > nrd_i ) { if ( u3C.wag_w & u3o_verbose ) { u3l_log("ames: recv: fail: %s", uv_strerror(nrd_i)); @@ -2406,25 +2415,41 @@ _ames_recv_cb(uv_udp_t* wax_u, } c3_free(buf_u->base); } - // STUN resquest/response - // TODO sanity checks - // TODO check STUN cookie else if (buf_u->base[0] == 0x0 && buf_u->base[1] == 0x01) { // STUN request + // TODO more sanity checks on proper STUN requests? u3_ames* sam_u = wax_u->data; _stun_on_request(sam_u, (c3_y *)buf_u->base, adr_u); - } else if ((buf_u->base[0] == 0x01 && buf_u->base[1] == 0x01)) { + } else if (_stun_is_our_response(buf_u->base, sam_u->sun_u.tid_y, nrd_i) + == c3y) { // STUN response - u3_ames* sam_u = wax_u->data; - c3_w ip_addr = _ames_sift_word(buf_u->base + 28); c3_s port = _ames_sift_short(buf_u->base + 26); u3l_log("ip: %u", ntohl(ip_addr)); u3l_log("port: %u", ntohs(port)); - // Cache lane - sam_u->sun_u.sef_u.por_s = ntohs(port); - sam_u->sun_u.sef_u.pip_w = ntohs(ip_addr); + // New lane + u3_lane lan_u; + lan_u.por_s = ntohs(port); + lan_u.pip_w = ntohs(ip_addr); + + u3_noun wir = u3nc(c3__ames, u3_nul); + if (sam_u->sun_u.sef_u.por_s == 0 && sam_u->sun_u.sef_u.pip_w == 0) { + // inject %stun task into arvo + u3l_log("First STUN response"); + u3_noun cad = u3nc(c3__stun, c3n); + u3_ovum *ovo_u = u3_ovum_init(0, c3__ames, wir, cad); + u3_auto_plan(&sam_u->car_u, ovo_u); + } + else if (sam_u->sun_u.sef_u.por_s != lan_u.por_s || + sam_u->sun_u.sef_u.pip_w != lan_u.pip_w) { + // inject %once task into arvo + u3l_log("IP port changed"); + u3_noun cad = u3nc(c3__once, u3_nul); + u3_ovum *ovo_u = u3_ovum_init(0, c3__ames, wir, cad); + u3_auto_plan(&sam_u->car_u, ovo_u); + } + sam_u->sun_u.sef_u = lan_u; _stun_on_response(sam_u); } else { u3_ames* sam_u = wax_u->data;