diff --git a/docs/changes.txt b/docs/changes.txt index d26d99a..64f76ea 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -152,7 +152,7 @@ v0.8.1 * zapret-antidpi: http_unixeol * blockcheck2: http_unixeol test -0.8.2 +v0.8.2 * nfqws2: do not start if NFQWS2_COMPAT_VER unexpected * nfqws2: cache dns response IP addresses if --ipcache-hostname enabled @@ -163,14 +163,14 @@ v0.8.1 * winws2: --wf-filter-loopback * blockcheck2: NOTEST_MISC_HTTP[S], NOTEST_SYNDATA_HTTP[S] -0.8.3 +v0.8.3 * nfqws2, zapret-lib: gzip compression and decompression * nfqws2: ignore trailing spaces and tabs in hostlists and ipsets. "host.com " or "1.2.3.4 " are ok now * init.d: 99-lan-filter custom script * mdig: --eagain, --eagain-delay -0.8.4 +v0.8.4 * winws2: fix loopback large packets processing (up to 64K) * zapret-lib, zapret-antidpi: use numeric indexes in http dissects @@ -180,7 +180,7 @@ v0.8.1 * nfqws2: gracefully shutdown on SIGINT and SIGTERM * nfqws2: harden wireguard detection. do not detect if reserved bytes 1..3 != 0 -0.8.5 +v0.8.5 * nfqws2: do not require / in the beginning of URI in http * zapret-lib: rawsend_dissect_segmented support URG @@ -190,13 +190,13 @@ v0.8.1 * zapret-lib: tcp_nop_del * blockcheck2: tcp_nop_del in SYN packets with md5 in openbsd -0.8.6 +v0.8.6 * winws2, blockcheck2: allow multiple instances in windows, linux, freebsd (not openbsd) * nfqws2: fix critical bug - wrong ipv6 dissection * zapret-auto: fix standard_failure_detector http redirect regression -0.9.0 +v0.9.0 * nfqws2: removed hard check for host: presence in http_req * nfqws2: file open test before destroying in-memory content of ipset/hostlist @@ -215,21 +215,21 @@ v0.8.1 * winws2: use windivert bulk mode * nfqws2: template free import -0.9.1 +v0.9.1 * nfqws2: 'stat', 'clock_getfloattime' luacalls * nfqws2: bcryptorandom normalize behavior when system entropy is low. prevent blocks * nfqws2: --new[=name] * winws2: fix not setting signal handlers -0.9.2 +v0.9.2 * nfqws2: bt and utp_bt protocol detectors * nfqws2: localtime,gmtime,timelocal,timegm luacalls * winws2: load wlanapi.dll dynamically only if needed * winws2: fixed lost windivert deinit on logical network disappear -0.9.3 +v0.9.3 * nfqws2: handling of incoming fragmented packets (no reconstruct, raw ip payload) * zapret-auto: per_instance_condition orchestrator @@ -240,3 +240,8 @@ v0.8.1 * github: reduce executables files size * install_bin: added linux-riscv64 scan dir * github actions: added linux-riscv64 arch + +v0.9.4 + +* github actions: update upx to 5.1.0. use upx for linux-riscv5 +* github actions: stronger zip and gz compression diff --git a/lua/zapret-lib.lua b/lua/zapret-lib.lua index 5a15b64..4548755 100644 --- a/lua/zapret-lib.lua +++ b/lua/zapret-lib.lua @@ -2125,7 +2125,7 @@ function is_tls_record(tls, offset, ctype, partialOK) if not tls then return false end if not offset then offset=1 end - if (#tls-offset+1)<6 or (ctype and ctype~=tls_record_type(tls, offset)) then return false end + if (#tls-offset+1)<5 or (ctype and ctype~=tls_record_type(tls, offset)) then return false end local f2 = u16(tls, offset+1) return f2>=TLS_VER_SSL30 and f2<=TLS_VER_TLS12 and (partialOK or tls_record_full(tls, offset)) @@ -2164,12 +2164,12 @@ function is_tls_handshake(tls, offset, htype, partialOK) if not TLS_HANDSHAKE_TYPE_NAMES[typ] then return false end if typ==TLS_HANDSHAKE_TYPE_CLIENT or typ==TLS_HANDSHAKE_TYPE_SERVER then -- valid tls versions + if (#tls-offset+1)<6 then return false end local f2 = u16(tls,offset+4) if f2TLS_VER_TLS12 then return false end end -- length fits to data buffer return partialOK or tls_handshake_full(tls, offset) - end function is_tls_hello(tls, offset, partialOK) return is_tls_handshake(tls, offset, TLS_HANDSHAKE_TYPE_CLIENT, partialOK) or is_tls_handshake(tls, offset, TLS_HANDSHAKE_TYPE_SERVER, partialOK) @@ -2448,6 +2448,11 @@ function tls_dissect(tls, offset, partialOK) if typ==TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC then encrypted = true elseif typ==TLS_RECORD_TYPE_HANDSHAKE and not encrypted then + -- need 4 bytes for handshake type and 24-bit length + if (#tls-offset+1)<9 then + if not partialOK then return end + break + end local htyp = tls_handshake_type(tls, off + 5) tdis.rec[#tdis.rec].htype = htyp if not tdis.handshake then tdis.handshake = {} end @@ -2477,10 +2482,10 @@ function tls_dissect(tls, offset, partialOK) if tdis.handshake then for htyp, handshake in pairs(tdis.handshake) do if (handshake.type == TLS_HANDSHAKE_TYPE_CLIENT or handshake.type == TLS_HANDSHAKE_TYPE_SERVER) then - tls_dissect_handshake(handshake, 1, partialOK) + tls_dissect_handshake(handshake, partialOK) end end - elseif is_tls_handshake(tls, offset, nil, partialOK) then + elseif not tdis.rec and is_tls_handshake(tls, offset, nil, partialOK) then local htyp = tls_handshake_type(tls, offset) tdis.handshake = { [htyp] = { type = htyp, name = TLS_HANDSHAKE_TYPE_NAMES[htyp], data = string.sub(tls, offset, #tls) } } tls_dissect_handshake(tdis.handshake[htyp], partialOK) diff --git a/nfq2/hostlist.c b/nfq2/hostlist.c index e07b92a..8f5aaf6 100644 --- a/nfq2/hostlist.c +++ b/nfq2/hostlist.c @@ -97,6 +97,12 @@ bool AppendHostList(hostlist_pool **hostlist, const char *filename) return false; } } + if (ferror(F)) + { + DLOG_PERROR("AppendHostList"); + fclose(F); + return false; + } fclose(F); } diff --git a/nfq2/ipset.c b/nfq2/ipset.c index 55add05..ba1f23e 100644 --- a/nfq2/ipset.c +++ b/nfq2/ipset.c @@ -114,6 +114,12 @@ static bool AppendIpset(ipset *ips, const char *filename) return false; } } + if (ferror(F)) + { + DLOG_PERROR("AppendIpset"); + fclose(F); + return false; + } fclose(F); } diff --git a/nfq2/lua.c b/nfq2/lua.c index d21b112..5388dd8 100644 --- a/nfq2/lua.c +++ b/nfq2/lua.c @@ -2539,7 +2539,7 @@ bool lua_reconstruct_dissect(lua_State *L, int idx, uint8_t *buf, size_t *len, b } else if (udp) { - sz = (uint16_t)(lpayload+sizeof(struct udphdr)); + sz = lpayload+sizeof(struct udphdr); if (sz>0xFFFF) { DLOG_ERR("reconstruct_dissect: invalid payload length\n"); diff --git a/nfq2/nfqws.c b/nfq2/nfqws.c index 8cd8909..e7acfd4 100644 --- a/nfq2/nfqws.c +++ b/nfq2/nfqws.c @@ -71,13 +71,13 @@ static void ReloadCheck() if (!LoadAllHostLists()) { DLOG_ERR("hostlists load failed. this is fatal.\n"); - exit(1); + exit(200); } ResetAllIpsetModTime(); if (!LoadAllIpsets()) { DLOG_ERR("ipset load failed. this is fatal.\n"); - exit(1); + exit(200); } bReload = false; } @@ -317,24 +317,15 @@ static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, uint8_t *m goto exiterr; } - DLOG_CONDUP("unbinding existing nf_queue handler for AF_INET (if any)\n"); - if (nfq_unbind_pf(*h, AF_INET) < 0) { - DLOG_PERROR("nfq_unbind_pf()"); - goto exiterr; - } + // linux kernels pass both ipv4 and ipv6 even if only AF_INET is boumd + // linux 3.8 - bind calls are NOOP. linux 3.8- - secondary bind to AF_INET6 will fail DLOG_CONDUP("binding nfnetlink_queue as nf_queue handler for AF_INET\n"); if (nfq_bind_pf(*h, AF_INET) < 0) { - DLOG_PERROR("nfq_bind_pf()"); + DLOG_PERROR("nfq_bind_pf(AF_INET)"); goto exiterr; } - DLOG_CONDUP("binding nfnetlink_queue as nf_queue handler for AF_INET6\n"); - if (nfq_bind_pf(*h, AF_INET6) < 0) { - DLOG_PERROR("nfq_bind_pf()"); - // do not fail - kernel may not support ipv6 - } - DLOG_CONDUP("binding this socket to queue '%u'\n", params.qnum); *qh = nfq_create_queue(*h, params.qnum, &nfq_cb, mod_buffer); if (!*qh) { @@ -355,7 +346,7 @@ static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, uint8_t *m if (nfq_set_queue_flags(*qh, NFQA_CFG_F_FAIL_OPEN, NFQA_CFG_F_FAIL_OPEN)) { DLOG_ERR("can't set queue flags. its OK on linux <3.6\n"); - // dot not fail. not supported on old linuxes <3.6 + // dot not fail. not supported in old linuxes <3.6 } int yes = 1, fd = nfq_fd(*h); diff --git a/nfq2/protocol.c b/nfq2/protocol.c index 41e141e..e5389ea 100644 --- a/nfq2/protocol.c +++ b/nfq2/protocol.c @@ -551,10 +551,14 @@ bool TLSFindExtLenOffsetInHandshake(const uint8_t *data, size_t len, size_t *off l += data[l] + 1; // CipherSuitesLength if (len < (l + 2)) return false; - l += (data[0]==0x02 ? 0 : pntoh16(data + l)) + 2; + if (data[0]==0x01) // client hello ? + l += pntoh16(data + l); + l+=2; // CompressionMethodsLength if (len < (l + 1)) return false; - l += data[l] + 1; + if (data[0]==0x01) // client hello ? + l += data[l]; + l++; // ExtensionsLength if (len < (l + 2)) return false; *off = l;