mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-14 06:13:09 +00:00
Compare commits
32 Commits
827ab7cdcc
...
v0.9.4.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
847e689bfb | ||
|
|
287527092a | ||
|
|
a9514f39f5 | ||
|
|
4b7ff505e4 | ||
|
|
2120264e0b | ||
|
|
178bced5f3 | ||
|
|
ff78968807 | ||
|
|
e4535d2646 | ||
|
|
7c60ad3a7a | ||
|
|
a621edf898 | ||
|
|
2809f8d7e4 | ||
|
|
97819327cd | ||
|
|
eb9a1e9f6b | ||
|
|
6f6850707a | ||
|
|
f702865311 | ||
|
|
6447081a01 | ||
|
|
e4e513ec66 | ||
|
|
47630450bd | ||
|
|
e4129fec63 | ||
|
|
f71ba91e7c | ||
|
|
59e6603b83 | ||
|
|
14a061859f | ||
|
|
9aaa419f68 | ||
|
|
d5231bc4fc | ||
|
|
35cebfba73 | ||
|
|
811d16054b | ||
|
|
a9ee072a14 | ||
|
|
1dbf5ecfe6 | ||
|
|
b210db168f | ||
|
|
5306a043d0 | ||
|
|
b375a94036 | ||
|
|
8b2bff4187 |
64
.github/workflows/build.yml
vendored
64
.github/workflows/build.yml
vendored
@@ -26,32 +26,20 @@ jobs:
|
||||
tool: aarch64-unknown-linux-musl
|
||||
- arch: arm
|
||||
tool: arm-unknown-linux-musleabi
|
||||
# - arch: armhf
|
||||
# tool: arm-unknown-linux-musleabihf
|
||||
# - arch: armv7
|
||||
# tool: armv7-unknown-linux-musleabi
|
||||
# - arch: armv7hf
|
||||
# tool: armv7-unknown-linux-musleabihf
|
||||
# - arch: mips64el
|
||||
# tool: mips64el-unknown-linux-musl
|
||||
- arch: mips64
|
||||
tool: mips64-unknown-linux-musl
|
||||
# - arch: mipsel
|
||||
# tool: mipsel-unknown-linux-musl
|
||||
- arch: mipselsf
|
||||
tool: mipsel-unknown-linux-muslsf
|
||||
# - arch: mips
|
||||
# tool: mips-unknown-linux-musl
|
||||
- arch: mipssf
|
||||
tool: mips-unknown-linux-muslsf
|
||||
# - arch: ppc64
|
||||
# tool: powerpc64-unknown-linux-musl
|
||||
- arch: ppc
|
||||
tool: powerpc-unknown-linux-musl
|
||||
- arch: x86
|
||||
tool: i586-unknown-linux-musl
|
||||
- arch: x86_64
|
||||
tool: x86_64-unknown-linux-musl
|
||||
- arch: riscv64
|
||||
tool: riscv64-unknown-linux-musl
|
||||
- arch: lexra
|
||||
tool: mips-linux
|
||||
dir: rsdk-4.6.4-5281-EB-3.10-0.9.33-m32ub-20141001
|
||||
@@ -69,7 +57,7 @@ jobs:
|
||||
env:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
TOOL: ${{ matrix.tool }}
|
||||
REPO: ${{ matrix.arch == 'lexra' && matrix.repo || 'spvkgn/musl-cross' }}
|
||||
REPO: ${{ matrix.arch == 'lexra' && matrix.repo || 'bol-van/musl-cross' }}
|
||||
DIR: ${{ matrix.arch == 'lexra' && matrix.dir || matrix.tool }}
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
@@ -98,6 +86,8 @@ jobs:
|
||||
LUAJIT_VER: 2.1
|
||||
LUAJIT_RELEASE: 2.1-20250826
|
||||
LUAJIT_LUAVER: 5.1
|
||||
MINSIZE: -flto=auto -ffunction-sections -fdata-sections
|
||||
LDMINSIZE: -Wl,--gc-sections -flto=auto
|
||||
run: |
|
||||
DEPS_DIR=$GITHUB_WORKSPACE/deps
|
||||
export CC="$TARGET-gcc"
|
||||
@@ -107,13 +97,19 @@ jobs:
|
||||
export STRIP=$TARGET-strip
|
||||
export PKG_CONFIG_PATH=$DEPS_DIR/lib/pkgconfig
|
||||
export STAGING_DIR=$RUNNER_TEMP
|
||||
if [ "$ARCH" = lexra ]; then
|
||||
OPTIMIZE=-Os
|
||||
else
|
||||
OPTIMIZE=-Oz
|
||||
fi
|
||||
MINSIZE="$OPTIMIZE $MINSIZE"
|
||||
|
||||
if [[ "$ARCH" == lexra ]] || [[ "$ARCH" == ppc ]] || [[ "$ARCH" == x86 ]] ; then
|
||||
if [[ "$ARCH" == lexra ]] || [[ "$ARCH" == ppc ]] || [[ "$ARCH" == riscv64 ]] || [[ "$ARCH" == x86 ]] ; then
|
||||
# use classic lua
|
||||
wget -qO- https://www.lua.org/ftp/lua-${LUA_RELEASE}.tar.gz | tar -xz
|
||||
(
|
||||
cd lua-${LUA_RELEASE}
|
||||
make CC=$CC CFLAGS="-Os -flto=auto $CFLAGS" linux -j$(nproc)
|
||||
make CC=$CC AR="$AR rc" CFLAGS="$MINSIZE $CFLAGS" LDFLAGS="$LDMINSIZE $LDFLAGS" linux -j$(nproc)
|
||||
make install INSTALL_TOP=$DEPS_DIR INSTALL_BIN=$DEPS_DIR/bin INSTALL_INC=$DEPS_DIR/include/lua${LUA_VER} INSTALL_LIB=$DEPS_DIR/lib
|
||||
)
|
||||
LJIT=0
|
||||
@@ -131,7 +127,7 @@ jobs:
|
||||
esac
|
||||
(
|
||||
cd luajit2-*
|
||||
make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC="$HOSTCC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP CFLAGS="-Os -s -flto=auto $CFLAGS" -j$(nproc)
|
||||
make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC="$HOSTCC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP TARGET_CFLAGS="$MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" -j$(nproc)
|
||||
make install PREFIX= DESTDIR=$DEPS_DIR
|
||||
)
|
||||
LJIT=1
|
||||
@@ -147,7 +143,8 @@ jobs:
|
||||
for i in libmnl libnfnetlink libnetfilter_queue ; do
|
||||
(
|
||||
cd $i-*
|
||||
CFLAGS="-Os -flto=auto $CFLAGS" \
|
||||
CFLAGS="$MINSIZE $CFLAGS" \
|
||||
LDFLAGS="$LDMINSIZE $LDFLAGS" \
|
||||
./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking
|
||||
make install -j$(nproc) DESTDIR=$DEPS_DIR
|
||||
)
|
||||
@@ -159,7 +156,7 @@ jobs:
|
||||
xargs -I{} wget -qO- https://github.com/madler/zlib/archive/refs/tags/{}.tar.gz | tar -xz
|
||||
(
|
||||
cd zlib-*
|
||||
CFLAGS="-Os -flto=auto $CFLAGS" \
|
||||
CFLAGS="$MINSIZE $CFLAGS" \
|
||||
./configure --prefix= --static
|
||||
make install -j$(nproc) DESTDIR=$DEPS_DIR
|
||||
)
|
||||
@@ -170,6 +167,7 @@ jobs:
|
||||
install -Dm644 -t $DEPS_DIR/include/sys /usr/include/x86_64-linux-gnu/sys/queue.h /usr/include/sys/capability.h
|
||||
|
||||
# zapret2
|
||||
OPTIMIZE=$OPTIMIZE \
|
||||
CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -static-libgcc -static -I$DEPS_DIR/include $CFLAGS" \
|
||||
LDFLAGS="-L$DEPS_DIR/lib $LDFLAGS" \
|
||||
make -C zapret2 LUA_JIT=$LJIT LUA_CFLAGS="$LCFLAGS" LUA_LIB="$LLIB" -j$(nproc)
|
||||
@@ -220,6 +218,8 @@ jobs:
|
||||
LUAJIT_VER: 2.1
|
||||
LUAJIT_RELEASE: 2.1-20250826
|
||||
LUAJIT_LUAVER: 5.1
|
||||
MINSIZE: -Oz -flto=auto -ffunction-sections -fdata-sections
|
||||
LDMINSIZE: -Wl,--gc-sections -flto=auto
|
||||
run: |
|
||||
DEPS_DIR=$GITHUB_WORKSPACE/deps
|
||||
export TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64
|
||||
@@ -242,7 +242,7 @@ jobs:
|
||||
esac
|
||||
(
|
||||
cd luajit2-*
|
||||
make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC="$HOSTCC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP CFLAGS="-Os -flto=auto $CFLAGS" -j$(nproc)
|
||||
make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC="$HOSTCC" CROSS= CC="$CC" TARGET_AR="$AR rcus" TARGET_STRIP=$STRIP TARGET_CFLAGS="$MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" -j$(nproc)
|
||||
make install PREFIX= DESTDIR=$DEPS_DIR
|
||||
)
|
||||
LJIT=1
|
||||
@@ -258,7 +258,8 @@ jobs:
|
||||
for i in libmnl libnfnetlink libnetfilter_queue ; do
|
||||
(
|
||||
cd $i-*
|
||||
CFLAGS="-Os -flto=auto -Wno-implicit-function-declaration" \
|
||||
CFLAGS="$MINSIZE -Wno-implicit-function-declaration $CFLAGS" \
|
||||
LDFLAGS="$LDMINSIZE $LDFLAGS" \
|
||||
./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking
|
||||
make install -j$(nproc) DESTDIR=$DEPS_DIR
|
||||
)
|
||||
@@ -314,12 +315,14 @@ jobs:
|
||||
TARGET: ${{ matrix.target }}
|
||||
ARCH: ${{ matrix.arch }}
|
||||
CC: ${{ matrix.target }}-freebsd11-clang
|
||||
MINSIZE: -Oz -flto=auto -ffunction-sections -fdata-sections
|
||||
LDMINSIZE: -Wl,--gc-sections -flto=auto
|
||||
run: |
|
||||
|
||||
wget -qO- https://github.com/openresty/luajit2/archive/refs/tags/v${LUAJIT_RELEASE}.tar.gz | tar -xz
|
||||
(
|
||||
cd luajit2-*
|
||||
make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC=gcc CC=$CC CFLAGS="-Os -flto=auto $CFLAGS"
|
||||
make BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI HOST_CC=gcc CC=$CC TARGET_CFLAGS="$MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS"
|
||||
make install PREFIX= DESTDIR=$DEPS_DIR
|
||||
)
|
||||
|
||||
@@ -390,7 +393,7 @@ jobs:
|
||||
uses: cygwin/cygwin-install-action@v4
|
||||
with:
|
||||
platform: ${{ matrix.arch }}
|
||||
site: ${{ matrix.arch == 'x86_64' && 'http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215' || null }}
|
||||
site: ${{ matrix.arch == 'x86_64' && 'http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215' || 'http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/2022/11/23/063457' }}
|
||||
check-sig: 'false'
|
||||
packages: >-
|
||||
gcc-core
|
||||
@@ -424,13 +427,15 @@ jobs:
|
||||
- name: Build luajit
|
||||
env:
|
||||
LUAJIT_RELEASE: 2.1-20250826
|
||||
MINSIZE: -Os -flto=auto -ffunction-sections -fdata-sections
|
||||
LDMINSIZE: -Wl,--gc-sections -flto=auto
|
||||
shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}'
|
||||
run: >-
|
||||
export MAKEFLAGS=-j$(nproc) &&
|
||||
wget -q https://github.com/openresty/luajit2/archive/refs/tags/v${LUAJIT_RELEASE}.tar.gz &&
|
||||
tar -xzf v${LUAJIT_RELEASE}.tar.gz &&
|
||||
rm -f v${LUAJIT_RELEASE}.tar.gz &&
|
||||
make -C luajit2-${LUAJIT_RELEASE} BUILDMODE=static XCFLAGS=-DLUAJIT_DISABLE_FFI CFLAGS="-Os -s" &&
|
||||
make -C luajit2-${LUAJIT_RELEASE} BUILDMODE=static XCFLAGS="-DLUAJIT_DISABLE_FFI -ffat-lto-objects" TARGET_CFLAGS="$MINSIZE $CFLAGS" TARGET_LDFLAGS="$LDMINSIZE $LDFLAGS" &&
|
||||
make -C luajit2-${LUAJIT_RELEASE} install
|
||||
|
||||
- name: Build winws
|
||||
@@ -488,7 +493,7 @@ jobs:
|
||||
uses: crazy-max/ghaction-upx@v3
|
||||
with:
|
||||
install-only: true
|
||||
version: v4.2.4
|
||||
version: v5.1.0
|
||||
|
||||
- name: Prepare binaries
|
||||
shell: bash
|
||||
@@ -532,6 +537,7 @@ jobs:
|
||||
*-linux-mipselsf ) run_dir linux-mipsel ;;
|
||||
*-linux-mipssf ) run_dir linux-mips ;;
|
||||
*-linux-ppc ) run_dir linux-ppc ;;
|
||||
*-linux-riscv64 ) run_dir linux-riscv64 ;;
|
||||
*-linux-x86 ) run_dir linux-x86 ;;
|
||||
*-linux-x86_64 ) run_dir linux-x86_64 ;;
|
||||
*-linux-lexra ) run_dir linux-lexra ;;
|
||||
@@ -546,8 +552,8 @@ jobs:
|
||||
run: |
|
||||
rm -rf ${{ env.repo_dir }}/.git*
|
||||
find ${{ env.repo_dir }}/binaries -type f -exec sha256sum {} \; >sha256sum.txt
|
||||
tar --owner=0 --group=0 -czf ${{ env.repo_dir }}.tar.gz ${{ env.repo_dir }}
|
||||
zip -qr ${{ env.repo_dir }}.zip ${{ env.repo_dir }}
|
||||
tar --owner=0 --group=0 -c ${{ env.repo_dir }} | pigz -11 >${{ env.repo_dir }}.tar.gz
|
||||
zip -9qr ${{ env.repo_dir }}.zip ${{ env.repo_dir }}
|
||||
(
|
||||
cd ${{ env.repo_dir }}
|
||||
rm -rf binaries/{android*,freebsd*,win*} \
|
||||
@@ -555,7 +561,7 @@ jobs:
|
||||
nfq2 ip2net mdig docs Makefile
|
||||
pigz -11 lua/*.lua
|
||||
)
|
||||
tar --owner=0 --group=0 -czf ${{ env.repo_dir }}-openwrt-embedded.tar.gz ${{ env.repo_dir }}
|
||||
tar --owner=0 --group=0 -c ${{ env.repo_dir }} | pigz -11 >${{ env.repo_dir }}-openwrt-embedded.tar.gz
|
||||
|
||||
- name: Upload release assets
|
||||
uses: softprops/action-gh-release@v2
|
||||
|
||||
@@ -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,25 +215,36 @@ 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
|
||||
* 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
|
||||
zapret-auto: "instances" argument in condition orchestrator
|
||||
zapret-auto: cond_tcp_has_ts, cond_lua iff functions
|
||||
zapret-lib: replay_execution_plan and plan_clear max parameter
|
||||
init.d: use bitmap:port ipset for standard dports
|
||||
* nfqws2: handling of incoming fragmented packets (no reconstruct, raw ip payload)
|
||||
* zapret-auto: per_instance_condition orchestrator
|
||||
* zapret-auto: "instances" argument in condition orchestrator
|
||||
* zapret-auto: cond_tcp_has_ts, cond_lua iff functions
|
||||
* zapret-lib: replay_execution_plan and plan_clear max parameter
|
||||
* init.d: use bitmap:port ipset for standard dports
|
||||
* 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
|
||||
* nfqws2: --chdir
|
||||
* nfqws2: fixed wrong scale factor application to winsize
|
||||
* nfqws2: very old kernels compat
|
||||
|
||||
@@ -11,9 +11,9 @@ setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouc
|
||||
|
||||
4) install and compile luajit from here : https://github.com/openresty/luajit2
|
||||
|
||||
download latest releast, unpack, cd to it's directory
|
||||
download latest release, unpack, cd to it's directory
|
||||
|
||||
make BUILDMODE=static CFLAGS="-Os"
|
||||
make BUILDMODE=static CFLAGS="-Os -DLUAJIT_DISABLE_FFI -ffat-lto-objects -flto=auto -ffunction-sections -fdata-sections -fvisibility=hidden"
|
||||
make install
|
||||
|
||||
5) cd to %ZAPRET_BASE%/nfq2
|
||||
@@ -32,5 +32,5 @@ Choose version 2.2.2 for Windows 10 and 2.2.0 for Windows 7.
|
||||
8) Copy cygwin1.dll, winws2.exe, windivert.dll and windivert64.sys to one folder.
|
||||
|
||||
9) Run winws2.exe from cmd.exe running as administrator.
|
||||
winws will not run from cygwin shell with cygwin1.dll copy in it's folder.
|
||||
winws will not run without cygwin1.dll outside of cygwin shell.
|
||||
winws2 will not run from cygwin shell with cygwin1.dll copy in it's folder.
|
||||
winws2 will not run without cygwin1.dll outside of cygwin shell.
|
||||
|
||||
@@ -637,6 +637,7 @@ General parameters for all versions - nfqws2, dvtws2, winws2.
|
||||
--comment=any_text ; any text. ignored
|
||||
--intercept=0|1 ; allow interception. 0 - no, 1 - yes. If 0 lua-init scripts are executed then process exits. NFQUEUE is not initialized.
|
||||
--daemon ; detach from the console (daemonize)
|
||||
--chdir[=path] ; change current directory. if no path specified use the executable file directory - EXEDIR
|
||||
--pidfile=<filename> ; write PID to a file
|
||||
--ctrack-timeouts=S:E:F[:U] ; conntrack timeouts for tcp stages (SYN, ESTABLISHED, FIN) and for udp
|
||||
--ctrack-disable=[0|1] ; 1 disables conntrack
|
||||
|
||||
@@ -696,6 +696,7 @@ nfqws2 использует стандартный парсер getopt_long_only
|
||||
--comment=any_text ; любой текст. игнорируется
|
||||
--intercept=0|1 ; разрешить перехват. 0 - нет, 1 - да. при 0 выполняются lua-init скрипты и процесс завершается, перехват не включается, очередь NFQUEUE не инициализируется
|
||||
--daemon ; отключиться от консоли (демонизироваться)
|
||||
--chdir[=path] ; сменить текущую директорию. если нет path, выбирается путь исполняемого файла - EXEDIR
|
||||
--pidfile=<filename> ; запись PID в файл
|
||||
--ctrack-timeouts=S:E:F[:U] ; таймауты conntrack для стадий tcp SYN, ESTABLISHED, FIN и для udp
|
||||
--ctrack-disable=[0|1] ; 1 отключает conntrack
|
||||
|
||||
@@ -48,7 +48,7 @@ zapret2 является дальнейшим развитием проекта
|
||||
|
||||
Lua код получает от C кода структурированное представление приходящих пакетов в виде дерева (диссекты), подобного тем, что вы видите в wireshark.
|
||||
Туда же приходят результаты сборки или дешифровки частей некоторых протоколов (tls, quic).
|
||||
С код предоставляет функции-хелперы, позволяющие отсылать пакеты, работать с двоичными данными, разбирать TLS, искать маркер-позции и т.д.
|
||||
С код предоставляет функции-хелперы, позволяющие отсылать пакеты, работать с двоичными данными, разбирать TLS, искать маркер-позиции и т.д.
|
||||
Имеется библиотека хелперов, написанных на Lua, а так же готовая библиотека программ атаки на DPI (стратегий), реализующая функции *nfqws1* в расширенном варианте
|
||||
и с большей гибкостью.
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ fi
|
||||
unset PKTWS
|
||||
case $UNAME in
|
||||
Linux)
|
||||
ARCHLIST="my linux-x86_64 linux-x86 linux-arm64 linux-arm linux-mips64 linux-mipsel linux-mips linux-lexra linux-ppc"
|
||||
ARCHLIST="my linux-x86_64 linux-x86 linux-arm64 linux-arm linux-mips64 linux-mipsel linux-mips linux-lexra linux-ppc linux-riscv64"
|
||||
PKTWS=nfqws2
|
||||
;;
|
||||
FreeBSD)
|
||||
|
||||
@@ -477,7 +477,7 @@ function per_instance_condition(ctx, desync)
|
||||
if not instance then break end
|
||||
if instance.arg.cond then
|
||||
if type(_G[instance.arg.cond])~="function" then
|
||||
error(name..": invalid 'iff' function '"..instance.arg.cond.."'")
|
||||
error("per_instance_condition: invalid 'iff' function '"..instance.arg.cond.."'")
|
||||
end
|
||||
if logical_xor(_G[instance.arg.cond](desync), instance.arg.cond_neg) then
|
||||
verdict = plan_instance_execute(desync, verdict, instance)
|
||||
|
||||
@@ -434,7 +434,7 @@ function string2hex(s)
|
||||
return ss
|
||||
end
|
||||
function has_nonprintable(s)
|
||||
return s:match("[^ -\\r\\n\\t]")
|
||||
return s:match("[^ -\r\n\t]")
|
||||
end
|
||||
function make_readable(v)
|
||||
if type(v)=="string" then
|
||||
@@ -805,9 +805,9 @@ function autottl(incoming_ttl, attl)
|
||||
|
||||
if incoming_ttl>223 then
|
||||
orig=255
|
||||
elseif incoming_ttl<128 and incoming_ttl>96 then
|
||||
elseif incoming_ttl<=128 and incoming_ttl>96 then
|
||||
orig=128
|
||||
elseif incoming_ttl<64 and incoming_ttl>32 then
|
||||
elseif incoming_ttl<=64 and incoming_ttl>32 then
|
||||
orig=64
|
||||
else
|
||||
return nil
|
||||
@@ -1161,16 +1161,15 @@ function rawsend_dissect_segmented(desync, dis, mss, options)
|
||||
local pos=1
|
||||
local len
|
||||
local payload=discopy.payload
|
||||
|
||||
while pos <= #payload do
|
||||
len = #payload - pos + 1
|
||||
if len > max_data then len = max_data end
|
||||
if oob then
|
||||
if urp>=pos and urp<(pos+len)then
|
||||
discopy.tcp.th_flags = bitor(dis.tcp.th_flags, TH_URG)
|
||||
discopy.tcp.th_flags = bitor(discopy.tcp.th_flags, TH_URG)
|
||||
discopy.tcp.th_urp = urp-pos+1
|
||||
else
|
||||
discopy.tcp.th_flags = bitand(dis.tcp.th_flags, bitnot(TH_URG))
|
||||
discopy.tcp.th_flags = bitand(discopy.tcp.th_flags, bitnot(TH_URG))
|
||||
discopy.tcp.th_urp = 0
|
||||
end
|
||||
end
|
||||
@@ -2125,7 +2124,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 +2163,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 f2<TLS_VER_SSL30 or f2>TLS_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 +2447,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-off+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
|
||||
@@ -2463,7 +2467,7 @@ function tls_dissect(tls, offset, partialOK)
|
||||
-- next record
|
||||
if not is_tls_record(tls, off + 5 + len, nil, partialOK) or tls_record_type(tls, off + 5 + len) ~= typ then
|
||||
if not partialOK then return end
|
||||
break
|
||||
goto endrec
|
||||
end
|
||||
off = off + 5 + len
|
||||
len = tls_record_data_len(tls, off)
|
||||
@@ -2473,14 +2477,15 @@ function tls_dissect(tls, offset, partialOK)
|
||||
-- next record
|
||||
off = off + 5 + len
|
||||
end
|
||||
::endrec::
|
||||
|
||||
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)
|
||||
|
||||
@@ -90,10 +90,9 @@ function test_hkdf()
|
||||
local ikm = brandom(math.random(5,10))
|
||||
for ninfo=1,nblob do
|
||||
local info = brandom(math.random(5,10))
|
||||
local okm_prev
|
||||
for k,sha in pairs({"sha256","sha224"}) do
|
||||
for k,okml in pairs({8, 16, 50}) do
|
||||
local okm_prev
|
||||
for k,okml in pairs({8, 16, 50}) do
|
||||
local okm
|
||||
print("* hkdf "..sha)
|
||||
print("salt: "..string2hex(salt))
|
||||
@@ -107,7 +106,6 @@ function test_hkdf()
|
||||
print("duplicate okm !")
|
||||
end
|
||||
okms[okm] = true
|
||||
|
||||
test_assert(not okm_prev or okm_prev==string.sub(okm, 1, #okm_prev))
|
||||
okm_prev = okm
|
||||
end
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
CC ?= cc
|
||||
PKG_CONFIG ?= pkg-config
|
||||
OPTIMIZE ?= -Os
|
||||
CFLAGS += -std=gnu99 -s $(OPTIMIZE) -flto=auto -Wno-address-of-packed-member
|
||||
OPTIMIZE ?= -Oz
|
||||
MINSIZE ?= -flto=auto -ffunction-sections -fdata-sections
|
||||
CFLAGS += -std=gnu99 -s $(OPTIMIZE) $(MINSIZE) -Wno-address-of-packed-member
|
||||
LDFLAGS += -flto=auto -Wl,--gc-sections
|
||||
LIBS = -lz -lm
|
||||
SRC_FILES = *.c crypto/*.c
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
CC ?= cc
|
||||
PKG_CONFIG ?= pkg-config
|
||||
OPTIMIZE ?= -Os
|
||||
CFLAGS += -std=gnu99 $(OPTIMIZE) -flto=auto
|
||||
MINSIZE ?= -flto=auto -ffunction-sections -fdata-sections
|
||||
CFLAGS += -std=gnu99 $(OPTIMIZE) $(MINSIZE)
|
||||
CFLAGS_LINUX = -Wno-alloc-size-larger-than
|
||||
CFLAGS_SYSTEMD = -DUSE_SYSTEMD
|
||||
CFLAGS_BSD = -Wno-address-of-packed-member
|
||||
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static
|
||||
CFLAGS_CYGWIN32 =
|
||||
CFLAGS_UBSAN = -fsanitize=undefined,alignment -fno-sanitize-recover=undefined,alignment
|
||||
LDFLAGS += -flto=auto -Wl,--gc-sections
|
||||
LDFLAGS_ANDROID = -llog
|
||||
LIBS =
|
||||
LIBS_LINUX = -lz -lnetfilter_queue -lnfnetlink -lmnl -lm
|
||||
@@ -27,6 +30,7 @@ ifeq ($(LUA_JIT),1)
|
||||
LUAJIT_VER?=2.1
|
||||
LUAJIT_LUA_VER?=5.1
|
||||
LUA_PKG:=luajit
|
||||
CFLAGS_CYGWIN32 = -msse2 -mfpmath=sse
|
||||
|
||||
$(info trying luajit $(LUAJIT_VER) lua $(LUAJIT_LUA_VER))
|
||||
|
||||
@@ -149,9 +153,9 @@ bsd: $(SRC_FILES)
|
||||
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_BSD) -o dvtws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_BSD) $(LDFLAGS)
|
||||
|
||||
cygwin64:
|
||||
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_CYGWIN) -o winws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_CYGWIN) $(LIBS_CYGWIN64) $(RES_CYGWIN64) $(LDFLAGS)
|
||||
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_CYGWIN) -o winws2 $(SRC_FILES) $(RES_CYGWIN64) $(LIBS) $(LUA_LIB) $(LIBS_CYGWIN) $(LIBS_CYGWIN64) $(LDFLAGS)
|
||||
cygwin32:
|
||||
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_CYGWIN) -o winws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_CYGWIN) $(LIBS_CYGWIN32) $(RES_CYGWIN32) $(LDFLAGS)
|
||||
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_CYGWIN) $(CFLAGS_CYGWIN32) -o winws2 $(SRC_FILES) $(RES_CYGWIN32) $(LIBS) $(LUA_LIB) $(LIBS_CYGWIN) $(LIBS_CYGWIN32) $(LDFLAGS)
|
||||
cygwin: cygwin64
|
||||
|
||||
clean:
|
||||
|
||||
@@ -140,8 +140,17 @@ static void ConntrackApplyPos(t_ctrack *t, bool bReverse, const struct dissect *
|
||||
|
||||
if (dis->ip6) direct->ip6flow = ntohl(dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_flow);
|
||||
|
||||
scale = tcp_find_scale_factor(dis->tcp);
|
||||
mss = tcp_find_mss(dis->tcp);
|
||||
direct->winsize_calc = direct->winsize = ntohs(dis->tcp->th_win);
|
||||
if (t->pos.state == SYN)
|
||||
{
|
||||
// scale and mss only valid in syn packets
|
||||
scale = tcp_find_scale_factor(dis->tcp);
|
||||
if (scale != SCALE_NONE) direct->scale = scale;
|
||||
direct->mss = tcp_find_mss(dis->tcp);
|
||||
}
|
||||
else if (direct->scale != SCALE_NONE)
|
||||
// apply scale only outside of the SYN stage
|
||||
direct->winsize_calc <<= direct->scale;
|
||||
|
||||
direct->seq_last = ntohl(dis->tcp->th_seq);
|
||||
direct->pos = direct->seq_last + dis->len_payload;
|
||||
@@ -154,10 +163,6 @@ static void ConntrackApplyPos(t_ctrack *t, bool bReverse, const struct dissect *
|
||||
if (!((direct->pos - direct->uppos) & 0x80000000))
|
||||
direct->uppos = direct->pos;
|
||||
}
|
||||
direct->winsize_calc = direct->winsize = ntohs(dis->tcp->th_win);
|
||||
if (scale != SCALE_NONE) direct->scale = scale;
|
||||
if (direct->scale != SCALE_NONE) direct->winsize_calc <<= direct->scale;
|
||||
if (mss && !direct->mss) direct->mss = mss;
|
||||
|
||||
if (!direct->rseq_over_2G && ((direct->seq_last - direct->seq0) & 0x80000000))
|
||||
direct->rseq_over_2G = true;
|
||||
@@ -347,7 +352,7 @@ void ConntrackPoolDump(const t_conntrack *p)
|
||||
{
|
||||
t_conntrack_pool *t, *tmp;
|
||||
time_t tnow;
|
||||
char sa1[40], sa2[40];
|
||||
char sa1[INET6_ADDRSTRLEN], sa2[INET6_ADDRSTRLEN];
|
||||
|
||||
if (!(tnow=boottime())) return;
|
||||
HASH_ITER(hh, p->pool, t, tmp) {
|
||||
|
||||
@@ -258,8 +258,6 @@ int gcm_start(gcm_context *ctx, // pointer to user-provided GCM context
|
||||
size_t use_len; // byte count to process, up to 16 bytes
|
||||
size_t i; // local loop iterator
|
||||
|
||||
if (iv_len!=12) return -1;
|
||||
|
||||
// since the context might be reused under the same key
|
||||
// we zero the working buffers for this next new process
|
||||
memset(ctx->y, 0x00, sizeof(ctx->y));
|
||||
@@ -447,7 +445,7 @@ int gcm_crypt_and_tag(
|
||||
prepare the gcm context with the keying material, we simply
|
||||
invoke each of the three GCM sub-functions in turn...
|
||||
*/
|
||||
if (iv_len!=12 || tag_len>16) return -1;
|
||||
if (tag_len>16) return -1;
|
||||
|
||||
int ret;
|
||||
if ((ret=gcm_start(ctx, mode, iv, iv_len, add, add_len))) return ret;
|
||||
@@ -483,26 +481,28 @@ int gcm_auth_decrypt(
|
||||
uchar check_tag[16]; // the tag generated and returned by decryption
|
||||
int diff; // an ORed flag to detect authentication errors
|
||||
size_t i; // our local iterator
|
||||
int ret;
|
||||
|
||||
if (iv_len!=12 || tag_len>16) return -1;
|
||||
if (tag_len>16) return -1;
|
||||
|
||||
/*
|
||||
we use GCM_DECRYPT_AND_TAG (above) to perform our decryption
|
||||
(which is an identical XORing to reverse the previous one)
|
||||
and also to re-generate the matching authentication tag
|
||||
*/
|
||||
gcm_crypt_and_tag(ctx, AES_DECRYPT, iv, iv_len, add, add_len,
|
||||
input, output, length, check_tag, tag_len);
|
||||
if ((ret = gcm_crypt_and_tag(ctx, AES_DECRYPT, iv, iv_len, add, add_len, input, output, length, check_tag, tag_len))) return ret;
|
||||
|
||||
// now we verify the authentication tag in 'constant time'
|
||||
for (diff = 0, i = 0; i < tag_len; i++)
|
||||
diff |= tag[i] ^ check_tag[i];
|
||||
|
||||
if (diff != 0) { // see whether any bits differed?
|
||||
if (diff)
|
||||
{
|
||||
// see whether any bits differed?
|
||||
memset(output, 0, length); // if so... wipe the output data
|
||||
return(GCM_AUTH_FAILURE); // return GCM_AUTH_FAILURE
|
||||
}
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
@@ -60,9 +60,9 @@ int hkdf(SHAversion whichSha,
|
||||
uint8_t okm[], size_t okm_len)
|
||||
{
|
||||
uint8_t prk[USHAMaxHashSize];
|
||||
return hkdfExtract(whichSha, salt, salt_len, ikm, ikm_len, prk) ||
|
||||
hkdfExpand(whichSha, prk, USHAHashSize(whichSha), info,
|
||||
info_len, okm, okm_len);
|
||||
int ret;
|
||||
if ((ret=hkdfExtract(whichSha, salt, salt_len, ikm, ikm_len, prk))) return ret;
|
||||
return hkdfExpand(whichSha, prk, USHAHashSize(whichSha), info, info_len, okm, okm_len);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -146,6 +146,7 @@ int hkdfExpand(SHAversion whichSha, const uint8_t prk[], size_t prk_len,
|
||||
size_t hash_len, N;
|
||||
unsigned char T[USHAMaxHashSize];
|
||||
size_t Tlen, where, i;
|
||||
int ret;
|
||||
|
||||
if (info == 0) {
|
||||
info = (const unsigned char *)"";
|
||||
@@ -164,12 +165,11 @@ int hkdfExpand(SHAversion whichSha, const uint8_t prk[], size_t prk_len,
|
||||
for (i = 1; i <= N; i++) {
|
||||
HMACContext context;
|
||||
unsigned char c = i;
|
||||
int ret = hmacReset(&context, whichSha, prk, prk_len) ||
|
||||
hmacInput(&context, T, Tlen) ||
|
||||
hmacInput(&context, info, info_len) ||
|
||||
hmacInput(&context, &c, 1) ||
|
||||
hmacResult(&context, T);
|
||||
if (ret != shaSuccess) return ret;
|
||||
if ((ret=hmacReset(&context, whichSha, prk, prk_len))) return ret;
|
||||
if ((ret=hmacInput(&context, T, Tlen))) return ret;
|
||||
if ((ret=hmacInput(&context, info, info_len))) return ret;
|
||||
if ((ret=hmacInput(&context, &c, 1))) return ret;
|
||||
if ((ret=hmacResult(&context, T))) return ret;
|
||||
memcpy(okm + where, T,
|
||||
(i != N) ? hash_len : (okm_len - where));
|
||||
where += hash_len;
|
||||
@@ -321,9 +321,8 @@ int hkdfResult(HKDFContext *context,
|
||||
if (!okm) return context->Corrupted = shaBadParam;
|
||||
if (!prk) prk = prkbuf;
|
||||
|
||||
ret = hmacResult(&context->hmacContext, prk) ||
|
||||
hkdfExpand(context->whichSha, prk, context->hashSize, info,
|
||||
info_len, okm, okm_len);
|
||||
if (!(ret = hmacResult(&context->hmacContext, prk)))
|
||||
ret = hkdfExpand(context->whichSha, prk, context->hashSize, info, info_len, okm, okm_len);
|
||||
context->Computed = 1;
|
||||
return context->Corrupted = ret;
|
||||
}
|
||||
|
||||
@@ -49,9 +49,10 @@ int hmac(SHAversion whichSha,
|
||||
uint8_t digest[USHAMaxHashSize])
|
||||
{
|
||||
HMACContext context;
|
||||
return hmacReset(&context, whichSha, key, key_len) ||
|
||||
hmacInput(&context, message_array, length) ||
|
||||
hmacResult(&context, digest);
|
||||
int ret;
|
||||
if ((ret=hmacReset(&context, whichSha, key, key_len))) return ret;
|
||||
if ((ret=hmacInput(&context, message_array, length))) return ret;
|
||||
return hmacResult(&context, digest);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -101,10 +102,8 @@ int hmacReset(HMACContext *context, enum SHAversion whichSha,
|
||||
*/
|
||||
if (key_len > blocksize) {
|
||||
USHAContext tcontext;
|
||||
int err = USHAReset(&tcontext, whichSha) ||
|
||||
USHAInput(&tcontext, key, key_len) ||
|
||||
USHAResult(&tcontext, tempkey);
|
||||
if (err != shaSuccess) return err;
|
||||
if ((ret=USHAReset(&tcontext, whichSha)) || (ret=USHAInput(&tcontext, key, key_len)) || (ret=USHAResult(&tcontext, tempkey)))
|
||||
return ret;
|
||||
|
||||
key = tempkey;
|
||||
key_len = hashsize;
|
||||
@@ -134,9 +133,9 @@ int hmacReset(HMACContext *context, enum SHAversion whichSha,
|
||||
|
||||
/* perform inner hash */
|
||||
/* init context for 1st pass */
|
||||
ret = USHAReset(&context->shaContext, whichSha) ||
|
||||
if (!(ret = USHAReset(&context->shaContext, whichSha)))
|
||||
/* and start with inner pad */
|
||||
USHAInput(&context->shaContext, k_ipad, blocksize);
|
||||
ret = USHAInput(&context->shaContext, k_ipad, blocksize);
|
||||
return context->Corrupted = ret;
|
||||
}
|
||||
|
||||
@@ -197,8 +196,7 @@ int hmacFinalBits(HMACContext *context,
|
||||
if (context->Corrupted) return context->Corrupted;
|
||||
if (context->Computed) return context->Corrupted = shaStateError;
|
||||
/* then final bits of datagram */
|
||||
return context->Corrupted =
|
||||
USHAFinalBits(&context->shaContext, bits, bit_count);
|
||||
return context->Corrupted = USHAFinalBits(&context->shaContext, bits, bit_count);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -229,21 +227,16 @@ int hmacResult(HMACContext *context, uint8_t *digest)
|
||||
|
||||
/* finish up 1st pass */
|
||||
/* (Use digest here as a temporary buffer.) */
|
||||
ret =
|
||||
USHAResult(&context->shaContext, digest) ||
|
||||
|
||||
if (!(ret=USHAResult(&context->shaContext, digest)) &&
|
||||
/* perform outer SHA */
|
||||
/* init context for 2nd pass */
|
||||
USHAReset(&context->shaContext, context->whichSha) ||
|
||||
|
||||
!(ret=USHAReset(&context->shaContext, context->whichSha)) &&
|
||||
/* start with outer pad */
|
||||
USHAInput(&context->shaContext, context->k_opad,
|
||||
context->blockSize) ||
|
||||
|
||||
!(ret=USHAInput(&context->shaContext, context->k_opad, context->blockSize)) &&
|
||||
/* then results of 1st hash */
|
||||
USHAInput(&context->shaContext, digest, context->hashSize) ||
|
||||
!(ret=USHAInput(&context->shaContext, digest, context->hashSize)))
|
||||
/* finish up 2nd pass */
|
||||
USHAResult(&context->shaContext, digest);
|
||||
ret=USHAResult(&context->shaContext, digest);
|
||||
|
||||
context->Computed = 1;
|
||||
return context->Corrupted = ret;
|
||||
|
||||
118
nfq2/darkmagic.c
118
nfq2/darkmagic.c
@@ -285,7 +285,7 @@ void str_icmp_type_name(char *s, size_t s_len, bool v6, uint8_t type)
|
||||
|
||||
static void str_srcdst_ip(char *s, size_t s_len, const void *saddr,const void *daddr)
|
||||
{
|
||||
char s_ip[16],d_ip[16];
|
||||
char s_ip[INET_ADDRSTRLEN],d_ip[INET_ADDRSTRLEN];
|
||||
*s_ip=*d_ip=0;
|
||||
inet_ntop(AF_INET, saddr, s_ip, sizeof(s_ip));
|
||||
inet_ntop(AF_INET, daddr, d_ip, sizeof(d_ip));
|
||||
@@ -306,7 +306,7 @@ void print_ip(const struct ip *ip)
|
||||
}
|
||||
void str_srcdst_ip6(char *s, size_t s_len, const void *saddr,const void *daddr)
|
||||
{
|
||||
char s_ip[40],d_ip[40];
|
||||
char s_ip[INET6_ADDRSTRLEN],d_ip[INET6_ADDRSTRLEN];
|
||||
*s_ip=*d_ip=0;
|
||||
inet_ntop(AF_INET6, saddr, s_ip, sizeof(s_ip));
|
||||
inet_ntop(AF_INET6, daddr, d_ip, sizeof(d_ip));
|
||||
@@ -314,14 +314,14 @@ void str_srcdst_ip6(char *s, size_t s_len, const void *saddr,const void *daddr)
|
||||
}
|
||||
void str_ip6hdr(char *s, size_t s_len, const struct ip6_hdr *ip6hdr, uint8_t proto)
|
||||
{
|
||||
char ss[83],s_proto[16];
|
||||
char ss[100],s_proto[16];
|
||||
str_srcdst_ip6(ss,sizeof(ss),&ip6hdr->ip6_src,&ip6hdr->ip6_dst);
|
||||
str_proto_name(s_proto,sizeof(s_proto),proto);
|
||||
snprintf(s,s_len,"%s proto=%s ttl=%u",ss,s_proto,ip6hdr->ip6_hlim);
|
||||
}
|
||||
void print_ip6hdr(const struct ip6_hdr *ip6hdr, uint8_t proto)
|
||||
{
|
||||
char s[128];
|
||||
char s[132];
|
||||
str_ip6hdr(s,sizeof(s),ip6hdr,proto);
|
||||
printf("%s",s);
|
||||
}
|
||||
@@ -504,7 +504,7 @@ uint8_t *proto_find_ip6_exthdr(struct ip6_hdr *ip6, size_t len, uint8_t proto)
|
||||
bool fr=false;
|
||||
uint16_t fr_off=0;
|
||||
|
||||
if (len<sizeof(struct ip6_hdr)) return false;
|
||||
if (len<sizeof(struct ip6_hdr)) return NULL;
|
||||
plen = ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen);
|
||||
last_proto = ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
|
||||
data = (uint8_t*)(ip6+1);
|
||||
@@ -521,18 +521,18 @@ uint8_t *proto_find_ip6_exthdr(struct ip6_hdr *ip6, size_t len, uint8_t proto)
|
||||
case IPPROTO_MH: // mobility header
|
||||
case IPPROTO_HIP: // Host Identity Protocol Version v2
|
||||
case IPPROTO_SHIM6:
|
||||
if (len < 2) return false; // error
|
||||
if (len < 2) return NULL; // error
|
||||
hdrlen = 8 + (data[1] << 3);
|
||||
break;
|
||||
case IPPROTO_FRAGMENT: // fragment. length fixed to 8, hdrlen field defined as reserved
|
||||
hdrlen = 8;
|
||||
if (len < hdrlen) return false; // error
|
||||
if (len < hdrlen) return NULL; // error
|
||||
fr_off = ntohs(((struct ip6_frag*)data)->ip6f_offlg & IP6F_OFF_MASK);
|
||||
fr = ((struct ip6_frag*)data)->ip6f_offlg & (IP6F_OFF_MASK|IP6F_MORE_FRAG);
|
||||
break;
|
||||
case IPPROTO_AH:
|
||||
// special case. length in ah header is in 32-bit words minus 2
|
||||
if (len < 2) return false; // error
|
||||
if (len < 2) return NULL; // error
|
||||
hdrlen = 8 + (data[1] << 2);
|
||||
break;
|
||||
default:
|
||||
@@ -540,7 +540,7 @@ uint8_t *proto_find_ip6_exthdr(struct ip6_hdr *ip6, size_t len, uint8_t proto)
|
||||
// exthdr was not found
|
||||
return NULL;
|
||||
}
|
||||
if (len < hdrlen) return false; // error
|
||||
if (len < hdrlen) return NULL; // error
|
||||
last_proto = *data;
|
||||
len -= hdrlen; data += hdrlen;
|
||||
}
|
||||
@@ -1557,7 +1557,6 @@ void rawsend_cleanup(void)
|
||||
{
|
||||
if (w_filter)
|
||||
{
|
||||
CancelIoEx(w_filter,&ovl);
|
||||
WinDivertClose(w_filter);
|
||||
w_filter=NULL;
|
||||
}
|
||||
@@ -1585,71 +1584,71 @@ bool windivert_init(const char *filter)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool windivert_recv_filter(HANDLE hFilter, uint8_t *packet, size_t *len, WINDIVERT_ADDRESS *wa, unsigned int *wa_count)
|
||||
static bool windivert_recv_exit(void)
|
||||
{
|
||||
UINT recv_len;
|
||||
DWORD err;
|
||||
DWORD rd;
|
||||
char c;
|
||||
sigset_t pending;
|
||||
|
||||
// make signals working
|
||||
usleep(0);
|
||||
|
||||
if (bQuit)
|
||||
{
|
||||
errno=EINTR;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (!logical_net_filter_match_rate_limited())
|
||||
{
|
||||
errno=ENODEV;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
usleep(0);
|
||||
return false;
|
||||
}
|
||||
static bool windivert_recv_filter(HANDLE hFilter, uint8_t *packet, size_t *len, WINDIVERT_ADDRESS *wa, unsigned int *wa_count)
|
||||
{
|
||||
UINT recv_len;
|
||||
DWORD rd;
|
||||
unsigned int wac;
|
||||
|
||||
*wa_count *= sizeof(WINDIVERT_ADDRESS);
|
||||
if (WinDivertRecvEx(hFilter, packet, *len, &recv_len, 0, wa, wa_count, &ovl))
|
||||
if (windivert_recv_exit()) return false;
|
||||
|
||||
wac = *wa_count * sizeof(WINDIVERT_ADDRESS);
|
||||
if (WinDivertRecvEx(hFilter, packet, *len, &recv_len, 0, wa, &wac, &ovl))
|
||||
{
|
||||
*wa_count /= sizeof(WINDIVERT_ADDRESS);
|
||||
*wa_count = wac/sizeof(WINDIVERT_ADDRESS);
|
||||
*len = recv_len;
|
||||
return true;
|
||||
}
|
||||
|
||||
for(;;)
|
||||
w_win32_error = GetLastError();
|
||||
switch(w_win32_error)
|
||||
{
|
||||
w_win32_error = GetLastError();
|
||||
|
||||
switch(w_win32_error)
|
||||
{
|
||||
case ERROR_IO_PENDING:
|
||||
// make signals working
|
||||
while (WaitForSingleObject(ovl.hEvent,50)==WAIT_TIMEOUT)
|
||||
{
|
||||
if (bQuit)
|
||||
{
|
||||
errno=EINTR;
|
||||
return false;
|
||||
}
|
||||
if (!logical_net_filter_match_rate_limited())
|
||||
{
|
||||
errno=ENODEV;
|
||||
return false;
|
||||
}
|
||||
usleep(0);
|
||||
}
|
||||
if (!GetOverlappedResult(hFilter,&ovl,&rd,TRUE))
|
||||
continue;
|
||||
*wa_count /= sizeof(WINDIVERT_ADDRESS);
|
||||
*len = rd;
|
||||
return true;
|
||||
case ERROR_INSUFFICIENT_BUFFER:
|
||||
errno = ENOBUFS;
|
||||
break;
|
||||
case ERROR_NO_DATA:
|
||||
errno = ESHUTDOWN;
|
||||
break;
|
||||
default:
|
||||
errno = EIO;
|
||||
}
|
||||
break;
|
||||
case ERROR_IO_PENDING:
|
||||
// make signals working
|
||||
while (WaitForSingleObject(ovl.hEvent,50)==WAIT_TIMEOUT)
|
||||
{
|
||||
if (windivert_recv_exit()) return false;
|
||||
}
|
||||
if (!GetOverlappedResult(hFilter,&ovl,&rd,FALSE))
|
||||
{
|
||||
errno=EIO;
|
||||
goto cancel;
|
||||
}
|
||||
*wa_count = wac/sizeof(WINDIVERT_ADDRESS);
|
||||
*len = rd;
|
||||
return true;
|
||||
case ERROR_INSUFFICIENT_BUFFER:
|
||||
errno = ENOBUFS;
|
||||
break;
|
||||
case ERROR_NO_DATA:
|
||||
errno = ESHUTDOWN;
|
||||
break;
|
||||
default:
|
||||
errno = EIO;
|
||||
}
|
||||
cancel:
|
||||
// make sure no pending operations
|
||||
CancelIoEx(w_filter,&ovl);
|
||||
GetOverlappedResult(hFilter, &ovl, &rd, TRUE);
|
||||
return false;
|
||||
}
|
||||
bool windivert_recv(uint8_t *packet, size_t *len, WINDIVERT_ADDRESS *wa, unsigned int *wa_count)
|
||||
@@ -1797,7 +1796,7 @@ static int rawsend_sendto_divert(sa_family_t family, int sock, const void *buf,
|
||||
char s[64];
|
||||
snprintf(s,sizeof(s),"rawsend_sendto_divert: sendto (%zu)",len);
|
||||
DLOG_PERROR(s);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return wr;
|
||||
@@ -1881,8 +1880,9 @@ static int rawsend_socket(sa_family_t family)
|
||||
}
|
||||
if (family==AF_INET && setsockopt(*sock, IPPROTO_IP, IP_NODEFRAG, &yes, sizeof(yes)) == -1)
|
||||
{
|
||||
// since 2.6.36
|
||||
DLOG_PERROR("rawsend: setsockopt(IP_NODEFRAG)");
|
||||
goto exiterr;
|
||||
//goto exiterr;
|
||||
}
|
||||
if (family==AF_INET && setsockopt(*sock, IPPROTO_IP, IP_FREEBIND, &yes, sizeof(yes)) == -1)
|
||||
{
|
||||
|
||||
@@ -289,11 +289,11 @@ static struct desync_profile *dp_find(
|
||||
struct desync_profile_list *dpl;
|
||||
if (params.debug)
|
||||
{
|
||||
char s[40];
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
ntopa46(ip, ip6, s, sizeof(s));
|
||||
if (ipr || ipr6)
|
||||
{
|
||||
char sr[40];
|
||||
char sr[INET6_ADDRSTRLEN];
|
||||
ntopa46(ipr, ipr6, sr, sizeof(sr));
|
||||
DLOG("desync profile search for %s ip1=%s ip2=%s port=%u icmp=%u:%u l7proto=%s ssid='%s' hostname='%s'\n",
|
||||
proto_name(l3proto), s, sr, port, icmp_type, icmp_code, l7proto_str(l7proto), ssid ? ssid : "", hostname ? hostname : "");
|
||||
@@ -737,7 +737,7 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr
|
||||
}
|
||||
if (params.debug)
|
||||
{
|
||||
char s[40];
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
ntopa46(a4, a6, s, sizeof(s));
|
||||
DLOG("ipcache hostname search for %s\n", s);
|
||||
}
|
||||
@@ -746,7 +746,7 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr
|
||||
{
|
||||
if (params.debug)
|
||||
{
|
||||
char s[40];
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
ntopa46(a4, a6, s, sizeof(s));
|
||||
DLOG("got cached hostname for %s : %s (is_ip=%u)\n", s, ipc->hostname, ipc->hostname_is_ip);
|
||||
}
|
||||
@@ -1137,7 +1137,7 @@ static void setup_direction(
|
||||
|
||||
if (params.debug)
|
||||
{
|
||||
char ip[40];
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
ntopa46(*sdip4, *sdip6, ip, sizeof(ip));
|
||||
DLOG("%s mode desync profile/ipcache search target ip=%s port=%u\n", params.server ? "server" : "client", ip, *sdport);
|
||||
}
|
||||
@@ -1574,8 +1574,9 @@ static uint8_t dpi_desync_tcp_packet_play(
|
||||
if (!bReqFull && ReasmIsEmpty(&ps.ctrack->reasm_client) && !is_retransmission(&ps.ctrack->pos.client))
|
||||
{
|
||||
// do not reconstruct unexpected large payload (they are feeding garbage ?)
|
||||
// also do not reconstruct if server window size is low
|
||||
if (!reasm_client_start(ps.ctrack, IPPROTO_TCP, TLSRecordLen(dis->data_payload), TCP_MAX_REASM, dis->data_payload, dis->len_payload))
|
||||
goto pass_reasm_cancel;
|
||||
goto rediscover;
|
||||
}
|
||||
|
||||
if (!ReasmIsEmpty(&ps.ctrack->reasm_client))
|
||||
@@ -1601,6 +1602,7 @@ static uint8_t dpi_desync_tcp_packet_play(
|
||||
}
|
||||
}
|
||||
|
||||
rediscover:
|
||||
if (!dp_rediscovery(&ps))
|
||||
goto pass_reasm_cancel;
|
||||
|
||||
@@ -1661,7 +1663,8 @@ static const uint8_t *dns_extract_name(const uint8_t *a, const uint8_t *b, const
|
||||
if (p>=e) return NULL;
|
||||
for (nl=0; *p ;)
|
||||
{
|
||||
if ((p+*p+1)>=e || (*p+1)>=(name_size-nl)) return NULL;
|
||||
// do not support mixed ptr+real
|
||||
if ((*p & 0xC0) || (p+*p+1)>=e || (*p+1)>=(name_size-nl)) return NULL;
|
||||
if (nl) name[nl++] = '.';
|
||||
memcpy(name + nl, p + 1, *p);
|
||||
nl += *p;
|
||||
@@ -1676,7 +1679,7 @@ static bool feed_dns_response(const uint8_t *a, size_t len)
|
||||
|
||||
// check of minimum header length and response flag
|
||||
uint16_t k, off, dlen, qcount = a[4]<<8 | a[5], acount = a[6]<<8 | a[7];
|
||||
char s_ip[40];
|
||||
char s_ip[INET6_ADDRSTRLEN];
|
||||
const uint8_t *b = a, *p;
|
||||
const uint8_t *e = b + len;
|
||||
size_t nl;
|
||||
|
||||
@@ -173,7 +173,7 @@ bool packet_range_parse(const char *s, struct packet_range *range)
|
||||
|
||||
void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr)
|
||||
{
|
||||
char s_ip[16];
|
||||
char s_ip[INET_ADDRSTRLEN];
|
||||
*s_ip=0;
|
||||
inet_ntop(AF_INET, &cidr->addr, s_ip, sizeof(s_ip));
|
||||
snprintf(s,s_len,cidr->preflen<32 ? "%s/%u" : "%s", s_ip, cidr->preflen);
|
||||
@@ -186,14 +186,14 @@ void print_cidr4(const struct cidr4 *cidr)
|
||||
}
|
||||
void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr)
|
||||
{
|
||||
char s_ip[40];
|
||||
char s_ip[INET6_ADDRSTRLEN];
|
||||
*s_ip=0;
|
||||
inet_ntop(AF_INET6, &cidr->addr, s_ip, sizeof(s_ip));
|
||||
snprintf(s,s_len,cidr->preflen<128 ? "%s/%u" : "%s", s_ip, cidr->preflen);
|
||||
}
|
||||
void print_cidr6(const struct cidr6 *cidr)
|
||||
{
|
||||
char s[44];
|
||||
char s[INET_ADDRSTRLEN+4];
|
||||
str_cidr6(s,sizeof(s),cidr);
|
||||
printf("%s",s);
|
||||
}
|
||||
|
||||
43
nfq2/gzip.c
43
nfq2/gzip.c
@@ -15,6 +15,7 @@ int z_readfile(FILE *F, char **buf, size_t *size, size_t extra_alloc)
|
||||
unsigned char in[ZCHUNK];
|
||||
size_t bufsize;
|
||||
void *newbuf;
|
||||
size_t rd;
|
||||
|
||||
memset(&zs, 0, sizeof(zs));
|
||||
|
||||
@@ -26,20 +27,21 @@ int z_readfile(FILE *F, char **buf, size_t *size, size_t extra_alloc)
|
||||
|
||||
do
|
||||
{
|
||||
zs.avail_in = fread_safe(in, 1, sizeof(in), F);
|
||||
if (ferror(F))
|
||||
if (!fread_safe(in, 1, sizeof(in), F, &rd))
|
||||
{
|
||||
r = Z_ERRNO;
|
||||
goto zerr;
|
||||
}
|
||||
if (!zs.avail_in)
|
||||
if (!rd)
|
||||
{
|
||||
// file is not full
|
||||
r = Z_DATA_ERROR;
|
||||
goto zerr;
|
||||
}
|
||||
zs.avail_in = rd;
|
||||
zs.next_in = in;
|
||||
do
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if ((bufsize - *size) < BUFMIN)
|
||||
{
|
||||
@@ -54,20 +56,41 @@ int z_readfile(FILE *F, char **buf, size_t *size, size_t extra_alloc)
|
||||
}
|
||||
zs.avail_out = bufsize - *size;
|
||||
zs.next_out = (unsigned char*)(*buf + *size);
|
||||
|
||||
r = inflate(&zs, Z_NO_FLUSH);
|
||||
if (r != Z_OK && r != Z_STREAM_END) goto zerr;
|
||||
|
||||
*size = bufsize - zs.avail_out;
|
||||
} while (r == Z_OK && zs.avail_in);
|
||||
if (r==Z_STREAM_END) break;
|
||||
if (r==Z_BUF_ERROR)
|
||||
{
|
||||
if (zs.avail_in)
|
||||
goto zerr;
|
||||
else
|
||||
{
|
||||
r = Z_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r!=Z_OK) goto zerr;
|
||||
}
|
||||
} while (r == Z_OK);
|
||||
|
||||
if (*size < bufsize)
|
||||
{
|
||||
// free extra space
|
||||
if ((newbuf = realloc(*buf, *size + extra_alloc))) *buf = newbuf;
|
||||
if (*size + extra_alloc)
|
||||
{
|
||||
// free extra space
|
||||
if ((newbuf = realloc(*buf, *size + extra_alloc))) *buf = newbuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(*buf);
|
||||
*buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inflateEnd(&zs);
|
||||
return Z_OK;
|
||||
return r;
|
||||
|
||||
zerr:
|
||||
inflateEnd(&zs);
|
||||
@@ -79,7 +102,7 @@ zerr:
|
||||
bool is_gzip(FILE* F)
|
||||
{
|
||||
unsigned char magic[2];
|
||||
bool b = !fseek(F, 0, SEEK_SET) && fread_safe(magic, 1, 2, F) == 2 && magic[0] == 0x1F && magic[1] == 0x8B;
|
||||
bool b = !fseek(F, 0, SEEK_SET) && fread(magic, 1, 2, F) == 2 && magic[0] == 0x1F && magic[1] == 0x8B;
|
||||
fseek(F, 0, SEEK_SET);
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,15 @@
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <libgen.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#include <sys/cygwin.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define UNIQ_SORT \
|
||||
{ \
|
||||
size_t i, j, u; \
|
||||
@@ -120,8 +126,7 @@ bool load_file(const char *filename, off_t offset, void *buffer, size_t *buffer_
|
||||
}
|
||||
}
|
||||
|
||||
*buffer_size = fread_safe(buffer, 1, *buffer_size, F);
|
||||
if (ferror(F))
|
||||
if (!fread_safe(buffer, 1, *buffer_size, F, buffer_size))
|
||||
{
|
||||
fclose(F);
|
||||
return false;
|
||||
@@ -241,7 +246,7 @@ void ntop46(const struct sockaddr *sa, char *str, size_t len)
|
||||
}
|
||||
void ntop46_port(const struct sockaddr *sa, char *str, size_t len)
|
||||
{
|
||||
char ip[40];
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
ntop46(sa, ip, sizeof(ip));
|
||||
switch (sa->sa_family)
|
||||
{
|
||||
@@ -512,21 +517,31 @@ ssize_t read_intr(int fd, void *buf, size_t count)
|
||||
return rd;
|
||||
}
|
||||
|
||||
size_t fread_safe(void *ptr, size_t size, size_t nmemb, FILE *F)
|
||||
bool fread_safe(void *ptr, size_t size, size_t nmemb, FILE *F, size_t *rd)
|
||||
{
|
||||
size_t result, total_read = 0;
|
||||
size_t result, to_read, total_read = 0;
|
||||
while (total_read < nmemb)
|
||||
{
|
||||
total_read += (result = fread((uint8_t*)ptr + (total_read * size), size, nmemb - total_read, F));
|
||||
if (result < (nmemb - total_read))
|
||||
to_read = nmemb - total_read;
|
||||
errno = 0;
|
||||
total_read += (result = fread((uint8_t*)ptr + (total_read * size), size, to_read, F));
|
||||
if (result < to_read)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
clearerr(F);
|
||||
else
|
||||
break;
|
||||
if (ferror(F))
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
clearerr(F);
|
||||
continue;
|
||||
}
|
||||
*rd = total_read;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return total_read;
|
||||
*rd = total_read;
|
||||
return true;
|
||||
}
|
||||
char* fgets_safe(char *s, int size, FILE *stream)
|
||||
{
|
||||
@@ -534,6 +549,7 @@ char* fgets_safe(char *s, int size, FILE *stream)
|
||||
|
||||
while (true)
|
||||
{
|
||||
errno = 0;
|
||||
if ((result = fgets(s, size, stream))) return result;
|
||||
if (ferror(stream))
|
||||
{
|
||||
@@ -649,12 +665,64 @@ bool set_env_exedir(const char *argv0)
|
||||
if ((s = strdup(argv0)))
|
||||
{
|
||||
if ((d = dirname(s)))
|
||||
{
|
||||
char d_abs[PATH_MAX];
|
||||
if (realpath(d, d_abs))
|
||||
d=d_abs;
|
||||
bOK = !setenv("EXEDIR", d, 1);
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
return bOK;
|
||||
}
|
||||
|
||||
// works for existing and new files
|
||||
bool realpath_any(const char *file, char *pabs)
|
||||
{
|
||||
bool b = true;
|
||||
char *s1=NULL, *s2=NULL;
|
||||
int res;
|
||||
size_t l;
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
l = cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, file, NULL, 0);
|
||||
char *rp_file = (char*)malloc(l);
|
||||
if (cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, file, rp_file, l))
|
||||
goto err;
|
||||
#else
|
||||
#define rp_file file
|
||||
#endif
|
||||
|
||||
if (!realpath(rp_file,pabs))
|
||||
{
|
||||
char pa[PATH_MAX], *dir, *base;
|
||||
if (!(s1 = strdup(rp_file))) goto err;
|
||||
dir = dirname(s1);
|
||||
if (!realpath(dir,pa))
|
||||
goto err;
|
||||
if (!(s2 = strdup(rp_file))) goto err;
|
||||
base = basename(s2);
|
||||
l = strlen(pa);
|
||||
if (l && pa[l-1]=='/')
|
||||
res=snprintf(pabs,PATH_MAX,"%s%s",pa, base);
|
||||
else
|
||||
res=snprintf(pabs,PATH_MAX,"%s/%s",pa,base);
|
||||
b = res>0 && res<PATH_MAX;
|
||||
}
|
||||
ex:
|
||||
#ifdef __CYGWIN__
|
||||
free(rp_file);
|
||||
#else
|
||||
#undef rp_file
|
||||
#endif
|
||||
free(s1);
|
||||
free(s2);
|
||||
return b;
|
||||
err:
|
||||
b = false;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
bool parse_int16(const char *p, int16_t *v)
|
||||
{
|
||||
if (*p == '+' || *p == '-' || *p >= '0' && *p <= '9')
|
||||
|
||||
@@ -34,7 +34,7 @@ const char *strncasestr(const char *s,const char *find, size_t slen);
|
||||
bool is_identifier(const char *p);
|
||||
|
||||
ssize_t read_intr(int fd, void *buf, size_t count);
|
||||
size_t fread_safe(void *ptr, size_t size, size_t nmemb, FILE *F);
|
||||
bool fread_safe(void *ptr, size_t size, size_t nmemb, FILE *F, size_t *rd);
|
||||
char* fgets_safe(char *s, int size, FILE *stream);
|
||||
|
||||
bool load_file(const char *filename, off_t offset, void *buffer, size_t *buffer_size);
|
||||
@@ -106,6 +106,7 @@ void set_console_io_buffering(void);
|
||||
void close_std(void);
|
||||
void close_std_and_exit(int code);
|
||||
bool set_env_exedir(const char *argv0);
|
||||
bool realpath_any(const char *file, char *pabs);
|
||||
|
||||
bool parse_int16(const char *p, int16_t *v);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ bool AppendHostList(hostlist_pool **hostlist, const char *filename)
|
||||
{
|
||||
r = z_readfile(F,&zbuf,&zsize,0);
|
||||
fclose(F);
|
||||
if (r==Z_OK)
|
||||
if (r==Z_STREAM_END)
|
||||
{
|
||||
DLOG_CONDUP("zlib compression detected. uncompressed size : %zu\n", zsize);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -274,13 +280,15 @@ bool HostlistCheck(const struct desync_profile *dp, const char *host, bool no_ma
|
||||
static struct hostlist_file *RegisterHostlist_(struct hostlist_files_head *hostlists, struct hostlist_collection_head *hl_collection, const char *filename)
|
||||
{
|
||||
struct hostlist_file *hfile;
|
||||
char pabs[PATH_MAX];
|
||||
|
||||
if (filename)
|
||||
{
|
||||
if (!(hfile=hostlist_files_search(hostlists, filename)))
|
||||
if (!(hfile=hostlist_files_add(hostlists, filename)))
|
||||
if (!realpath(filename,pabs)) return NULL;
|
||||
if (!(hfile=hostlist_files_search(hostlists, pabs)))
|
||||
if (!(hfile=hostlist_files_add(hostlists, pabs)))
|
||||
return NULL;
|
||||
if (!hostlist_collection_search(hl_collection, filename))
|
||||
if (!hostlist_collection_search(hl_collection, pabs))
|
||||
if (!hostlist_collection_add(hl_collection, hfile))
|
||||
return NULL;
|
||||
}
|
||||
@@ -296,13 +304,11 @@ static struct hostlist_file *RegisterHostlist_(struct hostlist_files_head *hostl
|
||||
}
|
||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename)
|
||||
{
|
||||
/*
|
||||
if (filename && !file_mod_time(filename))
|
||||
{
|
||||
DLOG_ERR("cannot access hostlist file '%s'\n",filename);
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
return RegisterHostlist_(
|
||||
¶ms.hostlists,
|
||||
bExclude ? &dp->hl_collection_exclude : &dp->hl_collection,
|
||||
|
||||
19
nfq2/ipset.c
19
nfq2/ipset.c
@@ -77,7 +77,7 @@ static bool AppendIpset(ipset *ips, const char *filename)
|
||||
{
|
||||
r = z_readfile(F,&zbuf,&zsize,0);
|
||||
fclose(F);
|
||||
if (r==Z_OK)
|
||||
if (r==Z_STREAM_END)
|
||||
{
|
||||
DLOG_CONDUP("zlib compression detected. uncompressed size : %zu\n", zsize);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -176,7 +182,7 @@ bool LoadAllIpsets()
|
||||
|
||||
static bool SearchIpset(const ipset *ips, const struct in_addr *ipv4, const struct in6_addr *ipv6)
|
||||
{
|
||||
char s_ip[40];
|
||||
char s_ip[INET6_ADDRSTRLEN];
|
||||
bool bInSet=false;
|
||||
|
||||
if (!!ipv4 != !!ipv6)
|
||||
@@ -272,12 +278,15 @@ bool IpsetCheck(
|
||||
static struct ipset_file *RegisterIpset_(struct ipset_files_head *ipsets, struct ipset_collection_head *ips_collection, const char *filename)
|
||||
{
|
||||
struct ipset_file *hfile;
|
||||
char pabs[PATH_MAX];
|
||||
|
||||
if (filename)
|
||||
{
|
||||
if (!(hfile=ipset_files_search(ipsets, filename)))
|
||||
if (!(hfile=ipset_files_add(ipsets, filename)))
|
||||
if (!realpath(filename,pabs)) return NULL;
|
||||
if (!(hfile=ipset_files_search(ipsets, pabs)))
|
||||
if (!(hfile=ipset_files_add(ipsets, pabs)))
|
||||
return NULL;
|
||||
if (!ipset_collection_search(ips_collection, filename))
|
||||
if (!ipset_collection_search(ips_collection, pabs))
|
||||
if (!ipset_collection_add(ips_collection, hfile))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
70
nfq2/lua.c
70
nfq2/lua.c
@@ -686,8 +686,8 @@ static int luacall_aes_gcm(lua_State *L)
|
||||
luaL_error(L, "aes_gcm: wrong key length %u. should be 16,24,32.", (unsigned)key_len);
|
||||
size_t iv_len;
|
||||
const uint8_t *iv = (uint8_t*)lua_reqlstring(L,3,&iv_len);
|
||||
if (iv_len!=12)
|
||||
luaL_error(L, "aes_gcm: wrong iv length %u. should be 12.", (unsigned)iv_len);
|
||||
if (!iv_len)
|
||||
luaL_error(L, "aes_gcm: zero iv length");
|
||||
size_t input_len;
|
||||
const uint8_t *input = (uint8_t*)lua_reqlstring(L,4,&input_len);
|
||||
size_t add_len=0;
|
||||
@@ -1901,7 +1901,7 @@ static bool lua_reconstruct_ip6exthdr(lua_State *L, int idx, struct ip6_hdr *ip6
|
||||
lua_getfield(L,-1, "data");
|
||||
if (lua_type(L,-1)!=LUA_TSTRING) goto err;
|
||||
if (!(p=(uint8_t*)lua_tolstring(L,-1,&l))) l=0;
|
||||
if (!l || (l+2)>left || ((type==IPPROTO_AH) ? (l<6 || ((l+2) & 3)) : ((l+2) & 7))) goto err;
|
||||
if (l<6 || (l+2)>left || (type==IPPROTO_AH ? (l>=1024 || ((l+2) & 3)) : (l>=2048 || ((l+2) & 7)))) goto err;
|
||||
memcpy(data+2,p,l);
|
||||
l+=2;
|
||||
data[0] = next; // may be overwritten later
|
||||
@@ -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");
|
||||
@@ -2569,12 +2569,13 @@ bool lua_reconstruct_dissect(lua_State *L, int idx, uint8_t *buf, size_t *len, b
|
||||
DLOG_ERR("ipv4 frag : invalid ip_len\n");
|
||||
goto err;
|
||||
}
|
||||
if (frag_start>l)
|
||||
size_t frag_len = iplen-l3;
|
||||
if ((frag_start+frag_len)>l)
|
||||
{
|
||||
DLOG_ERR("ipv4 frag : fragment offset is outside of the packet\n");
|
||||
DLOG_ERR("ipv4 frag : fragment end is outside of the packet\n");
|
||||
goto err;
|
||||
}
|
||||
if (off) memmove(buf+l3,buf+l3+off,iplen-l3);
|
||||
if (off) memmove(buf+l3,buf+frag_start,frag_len);
|
||||
l = iplen; // shrink packet to iplen
|
||||
}
|
||||
else
|
||||
@@ -2812,7 +2813,7 @@ static int luacall_ntop(lua_State *L)
|
||||
{
|
||||
size_t l;
|
||||
const char *p;
|
||||
char s[40];
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
int af=0;
|
||||
|
||||
lua_check_argc(L,"ntop",1);
|
||||
@@ -2832,9 +2833,10 @@ static int luacall_ntop(lua_State *L)
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
if (!inet_ntop(af,p,s,sizeof(s)))
|
||||
luaL_error(L, "inet_ntop error");
|
||||
lua_pushstring(L,s);
|
||||
if (inet_ntop(af,p,s,sizeof(s)))
|
||||
lua_pushstring(L,s);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
LUA_STACK_GUARD_RETURN(L,1)
|
||||
}
|
||||
@@ -3138,7 +3140,7 @@ static int lua_get_ifaddrs(lua_State *L)
|
||||
struct ifreq ifr;
|
||||
const char *ifname;
|
||||
#ifdef __CYGWIN__
|
||||
char ifname_buf[16];
|
||||
char ifname_buf[IFNAMSIZ];
|
||||
#endif
|
||||
memset(&ifr,0,sizeof(ifr));
|
||||
|
||||
@@ -3179,6 +3181,7 @@ static int lua_get_ifaddrs(lua_State *L)
|
||||
#ifdef HAS_FILTER_SSID
|
||||
lua_pushf_str(L, "ssid", wlan_ssid_search_ifname(ifname));
|
||||
#endif
|
||||
memset(ifr.ifr_name,0,sizeof(ifr.ifr_name));
|
||||
strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
|
||||
if (sock>=0 && !ioctl(sock, SIOCGIFMTU, &ifr))
|
||||
lua_pushf_int(L, "mtu", ifr.ifr_mtu);
|
||||
@@ -3467,7 +3470,7 @@ static int luacall_gunzip_inflate(lua_State *L)
|
||||
size_t increment = bufchunk / 2;
|
||||
if (increment < Z_INFL_BUF_INCREMENT) increment = Z_INFL_BUF_INCREMENT;
|
||||
|
||||
do
|
||||
for(;;)
|
||||
{
|
||||
if ((bufsize - size) < BUFMIN)
|
||||
{
|
||||
@@ -3490,11 +3493,20 @@ static int luacall_gunzip_inflate(lua_State *L)
|
||||
}
|
||||
uzs->zs.avail_out = bufsize - size;
|
||||
uzs->zs.next_out = buf + size;
|
||||
r = inflate(&uzs->zs, Z_NO_FLUSH);
|
||||
if (r != Z_OK && r != Z_STREAM_END) goto zerr;
|
||||
size = bufsize - uzs->zs.avail_out;
|
||||
} while (r == Z_OK && uzs->zs.avail_in);
|
||||
|
||||
r = inflate(&uzs->zs, Z_NO_FLUSH);
|
||||
|
||||
size = bufsize - uzs->zs.avail_out;
|
||||
if (r==Z_STREAM_END) break;
|
||||
if (r==Z_BUF_ERROR)
|
||||
{
|
||||
if (uzs->zs.avail_in)
|
||||
goto zerr;
|
||||
else
|
||||
break; // OK
|
||||
}
|
||||
if (r!=Z_OK) goto zerr;
|
||||
}
|
||||
lua_pushlstring(L, (const char*)buf, size);
|
||||
lua_pushboolean(L, r==Z_STREAM_END);
|
||||
end:
|
||||
@@ -3517,7 +3529,7 @@ static void z_free(voidpf opaque, voidpf address)
|
||||
static int luacall_gzip_init(lua_State *L)
|
||||
{
|
||||
// gzip_init(windowBits, level, memlevel) return zstream
|
||||
lua_check_argc_range(L,"gunzip_init",0,3);
|
||||
lua_check_argc_range(L,"gzip_init",0,3);
|
||||
|
||||
LUA_STACK_GUARD_ENTER(L)
|
||||
|
||||
@@ -3568,7 +3580,7 @@ static int luacall_gzip_deflate(lua_State *L)
|
||||
|
||||
int argc=lua_gettop(L);
|
||||
size_t l=0;
|
||||
int r;
|
||||
int r, flush;
|
||||
size_t bufsize=0, size=0;
|
||||
uint8_t *buf=NULL, *newbuf;
|
||||
struct userdata_zs *uzs = lua_uzs(L, 1, false);
|
||||
@@ -3581,7 +3593,8 @@ static int luacall_gzip_deflate(lua_State *L)
|
||||
size_t increment = bufchunk / 2;
|
||||
if (increment < Z_DEFL_BUF_INCREMENT) increment = Z_DEFL_BUF_INCREMENT;
|
||||
|
||||
do
|
||||
flush = l ? Z_NO_FLUSH : Z_FINISH;
|
||||
for(;;)
|
||||
{
|
||||
if ((bufsize - size) < BUFMIN)
|
||||
{
|
||||
@@ -3604,10 +3617,19 @@ static int luacall_gzip_deflate(lua_State *L)
|
||||
}
|
||||
uzs->zs.avail_out = bufsize - size;
|
||||
uzs->zs.next_out = buf + size;
|
||||
r = deflate(&uzs->zs, l ? Z_NO_FLUSH : Z_FINISH);
|
||||
if (r != Z_OK && r != Z_STREAM_END) goto zerr;
|
||||
|
||||
r = deflate(&uzs->zs, flush);
|
||||
|
||||
size = bufsize - uzs->zs.avail_out;
|
||||
} while (r == Z_OK && (uzs->zs.avail_in || !uzs->zs.avail_out));
|
||||
if (r==Z_STREAM_END) break;
|
||||
if (r==Z_OK)
|
||||
{
|
||||
if (uzs->zs.avail_out && !uzs->zs.avail_in && flush != Z_FINISH)
|
||||
break;
|
||||
}
|
||||
else
|
||||
goto zerr;
|
||||
}
|
||||
|
||||
lua_pushlstring(L, (const char*)buf, size);
|
||||
lua_pushboolean(L, r==Z_STREAM_END);
|
||||
@@ -3935,7 +3957,7 @@ static int luaL_doZfile(lua_State *L, const char *filename)
|
||||
luaL_error(L, "could not open lua file '%s'", fname);
|
||||
r = z_readfile(F, &buf, &size, 0);
|
||||
fclose(F);
|
||||
if (r != Z_OK)
|
||||
if (r != Z_STREAM_END)
|
||||
luaL_error(L, "could not unzip lua file '%s'", fname);
|
||||
r = luaL_loadbuffer(L, buf, size, fname);
|
||||
free(buf);
|
||||
|
||||
89
nfq2/nfqws.c
89
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;
|
||||
}
|
||||
@@ -183,7 +183,7 @@ static void fuzzPacketData(unsigned int count)
|
||||
*packet = *packet ? (*packet & 1) ? 0x40 : 0x60 | (*packet & 0x0F) : (uint8_t)random();
|
||||
}
|
||||
modlen = random()%(sizeof(mod)+1);
|
||||
verdict = processPacketData(&mark,random()%1 ? "ifin" : NULL,random()%1 ? "ifout" : NULL,packet,len,mod,&modlen);
|
||||
verdict = processPacketData(&mark,(random() & 1) ? "ifin" : NULL,(random() & 1) ? "ifout" : NULL,packet,len,mod,&modlen);
|
||||
free(packet);
|
||||
}
|
||||
}
|
||||
@@ -317,22 +317,29 @@ static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, uint8_t *m
|
||||
goto exiterr;
|
||||
}
|
||||
|
||||
// linux 3.8 - bind calls are NOOP. linux 3.8- - secondary bind to AF_INET6 will fail
|
||||
// old kernels seem to require both binds to ipv4 and ipv6. may not work without unbind
|
||||
|
||||
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()");
|
||||
DLOG_PERROR("nfq_unbind_pf(AF_INET)");
|
||||
goto exiterr;
|
||||
}
|
||||
|
||||
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("unbinding existing nf_queue handler for AF_INET6 (if any)\n");
|
||||
if (nfq_unbind_pf(*h, AF_INET6) < 0) {
|
||||
DLOG_PERROR("nfq_unbind_pf(AF_INET6)");
|
||||
}
|
||||
|
||||
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_PERROR("nfq_bind_pf(AF_INET6)");
|
||||
}
|
||||
|
||||
DLOG_CONDUP("binding this socket to queue '%u'\n", params.qnum);
|
||||
@@ -355,7 +362,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);
|
||||
@@ -1686,6 +1693,7 @@ static void exithelp(void)
|
||||
" --port=<port>\t\t\t\t\t\t; divert port\n"
|
||||
#endif
|
||||
" --daemon\t\t\t\t\t\t; daemonize\n"
|
||||
" --chdir[=path]\t\t\t\t\t\t; change current directory. if no path specified use EXEDIR\n"
|
||||
" --pidfile=<filename>\t\t\t\t\t; write pid to file\n"
|
||||
#ifndef __CYGWIN__
|
||||
" --user=<username>\t\t\t\t\t; drop root privs\n"
|
||||
@@ -1849,6 +1857,7 @@ enum opt_indices {
|
||||
IDX_PORT,
|
||||
#endif
|
||||
IDX_DAEMON,
|
||||
IDX_CHDIR,
|
||||
IDX_PIDFILE,
|
||||
#ifndef __CYGWIN__
|
||||
IDX_USER,
|
||||
@@ -1953,6 +1962,7 @@ static const struct option long_options[] = {
|
||||
[IDX_PORT] = {"port", required_argument, 0, 0},
|
||||
#endif
|
||||
[IDX_DAEMON] = {"daemon", no_argument, 0, 0},
|
||||
[IDX_CHDIR] = {"chdir", optional_argument, 0, 0},
|
||||
[IDX_PIDFILE] = {"pidfile", required_argument, 0, 0},
|
||||
#ifndef __CYGWIN__
|
||||
[IDX_USER] = {"user", required_argument, 0, 0},
|
||||
@@ -2170,8 +2180,11 @@ int main(int argc, char **argv)
|
||||
{
|
||||
if (*optarg == '@')
|
||||
{
|
||||
strncpy(params.debug_logfile, optarg + 1, sizeof(params.debug_logfile));
|
||||
params.debug_logfile[sizeof(params.debug_logfile) - 1] = 0;
|
||||
if (!realpath_any(optarg+1,params.debug_logfile))
|
||||
{
|
||||
DLOG_ERR("bad file '%s'\n",optarg+1);
|
||||
exit_clean(1);
|
||||
}
|
||||
FILE *F = fopen(params.debug_logfile, "wt");
|
||||
if (!F)
|
||||
{
|
||||
@@ -2258,8 +2271,28 @@ int main(int argc, char **argv)
|
||||
case IDX_DAEMON:
|
||||
params.daemon = true;
|
||||
break;
|
||||
case IDX_CHDIR:
|
||||
{
|
||||
const char *d = optarg ? optarg : getenv("EXEDIR");
|
||||
if (!d)
|
||||
{
|
||||
DLOG_ERR("chdir: directory unknown\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
DLOG("changing dir to '%s'\n",d);
|
||||
if (chdir(d))
|
||||
{
|
||||
DLOG_PERROR("chdir");
|
||||
exit_clean(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDX_PIDFILE:
|
||||
snprintf(params.pidfile, sizeof(params.pidfile), "%s", optarg);
|
||||
if (!realpath_any(optarg,params.pidfile))
|
||||
{
|
||||
DLOG_ERR("bad file '%s'\n",optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
#ifndef __CYGWIN__
|
||||
case IDX_USER:
|
||||
@@ -2363,8 +2396,11 @@ int main(int argc, char **argv)
|
||||
params.writeable_dir_enable = true;
|
||||
if (optarg)
|
||||
{
|
||||
strncpy(params.writeable_dir, optarg, sizeof(params.writeable_dir));
|
||||
params.writeable_dir[sizeof(params.writeable_dir) - 1] = 0;
|
||||
if (!realpath_any(optarg, params.writeable_dir))
|
||||
{
|
||||
DLOG_ERR("bad file '%s'\n",optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
*params.writeable_dir = 0;
|
||||
@@ -2375,10 +2411,22 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case IDX_LUA_INIT:
|
||||
if (!strlist_add_tail(¶ms.lua_init_scripts, optarg))
|
||||
{
|
||||
DLOG_ERR("out of memory\n");
|
||||
exit_clean(1);
|
||||
char pabs[PATH_MAX+1], *p=optarg;
|
||||
if (*p=='@')
|
||||
{
|
||||
if (!realpath_any(p+1,pabs+1))
|
||||
{
|
||||
DLOG_ERR("bad file '%s'\n",p+1);
|
||||
exit_clean(1);
|
||||
}
|
||||
*(p=pabs)='@';
|
||||
}
|
||||
if (!strlist_add_tail(¶ms.lua_init_scripts, p))
|
||||
{
|
||||
DLOG_ERR("out of memory\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDX_LUA_GC:
|
||||
@@ -2508,15 +2556,18 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
case IDX_HOSTLIST_AUTO_DEBUG:
|
||||
{
|
||||
FILE *F = fopen(optarg, "a+t");
|
||||
if (!realpath_any(optarg,params.hostlist_auto_debuglog))
|
||||
{
|
||||
DLOG_ERR("bad file '%s'\n",optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
FILE *F = fopen(params.hostlist_auto_debuglog, "a+t");
|
||||
if (!F)
|
||||
{
|
||||
DLOG_ERR("cannot create %s\n", optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
fclose(F);
|
||||
strncpy(params.hostlist_auto_debuglog, optarg, sizeof(params.hostlist_auto_debuglog));
|
||||
params.hostlist_auto_debuglog[sizeof(params.hostlist_auto_debuglog) - 1] = '\0';
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -1033,7 +1033,7 @@ static ip_cache4 *ipcache4Add(ip_cache4 **ipcache, const struct in_addr *a, cons
|
||||
}
|
||||
static void ipcache4Print(ip_cache4 *ipcache)
|
||||
{
|
||||
char s_ip[16];
|
||||
char s_ip[INET_ADDRSTRLEN];
|
||||
time_t now;
|
||||
ip_cache4 *ipc, *tmp;
|
||||
|
||||
@@ -1091,7 +1091,7 @@ static ip_cache6 *ipcache6Add(ip_cache6 **ipcache, const struct in6_addr *a, con
|
||||
}
|
||||
static void ipcache6Print(ip_cache6 *ipcache)
|
||||
{
|
||||
char s_ip[40];
|
||||
char s_ip[INET6_ADDRSTRLEN];
|
||||
time_t now;
|
||||
ip_cache6 *ipc, *tmp;
|
||||
|
||||
|
||||
@@ -145,7 +145,6 @@ bool posmarker_parse(const char *s, struct proto_pos *m)
|
||||
m->pos = 0;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
bool posmarker_list_parse(const char *s, struct proto_pos *m, int *mct)
|
||||
{
|
||||
@@ -551,10 +550,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;
|
||||
@@ -1191,16 +1194,16 @@ bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, si
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t payload_len,token_len;
|
||||
size_t pn_offset;
|
||||
uint64_t payload_len,token_len,pn_offset;
|
||||
pn_offset = 1 + 4 + 1 + data[5];
|
||||
if (pn_offset >= data_len) return false;
|
||||
// SCID length
|
||||
pn_offset += 1 + data[pn_offset];
|
||||
if ((pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false;
|
||||
if (pn_offset >= data_len || (pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false;
|
||||
// token length
|
||||
pn_offset += tvb_get_varint(data + pn_offset, &token_len);
|
||||
pn_offset += token_len;
|
||||
if (pn_offset >= data_len) return false;
|
||||
if ((pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false;
|
||||
if (pn_offset >= data_len || (pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false;
|
||||
pn_offset += tvb_get_varint(data + pn_offset, &payload_len);
|
||||
if (payload_len<20 || (pn_offset + payload_len)>data_len) return false;
|
||||
|
||||
@@ -1221,17 +1224,17 @@ bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, si
|
||||
|
||||
phton64(aesiv + sizeof(aesiv) - 8, pntoh64(aesiv + sizeof(aesiv) - 8) ^ pkn);
|
||||
|
||||
size_t cryptlen = payload_len - pkn_len - 16;
|
||||
uint64_t cryptlen = payload_len - pkn_len - 16;
|
||||
if (cryptlen > *clean_len) return false;
|
||||
*clean_len = cryptlen;
|
||||
*clean_len = (size_t)cryptlen;
|
||||
const uint8_t *decrypt_begin = data + pn_offset + pkn_len;
|
||||
|
||||
uint8_t atag[16],header[2048];
|
||||
size_t header_len = pn_offset + pkn_len;
|
||||
uint64_t header_len = pn_offset + pkn_len;
|
||||
if (header_len > sizeof(header)) return false; // not likely header will be so large
|
||||
memcpy(header, data, header_len);
|
||||
header[0] = packet0;
|
||||
for(size_t i = 0; i < pkn_len; i++) header[header_len - 1 - i] = (uint8_t)(pkn >> (8 * i));
|
||||
for(uint8_t i = 0; i < pkn_len; i++) header[header_len - 1 - i] = (uint8_t)(pkn >> (8 * i));
|
||||
|
||||
if (aes_gcm_crypt(AES_DECRYPT, clean, decrypt_begin, cryptlen, aeskey, sizeof(aeskey), aesiv, sizeof(aesiv), header, header_len, atag, sizeof(atag)))
|
||||
return false;
|
||||
|
||||
17
nfq2/sec.c
17
nfq2/sec.c
@@ -6,6 +6,7 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "params.h"
|
||||
|
||||
@@ -18,7 +19,6 @@
|
||||
// __X32_SYSCALL_BIT defined in linux/unistd.h
|
||||
#include <linux/unistd.h>
|
||||
#include <syscall.h>
|
||||
#include <errno.h>
|
||||
|
||||
/************ SECCOMP ************/
|
||||
|
||||
@@ -350,10 +350,19 @@ void daemonize(void)
|
||||
DLOG_PERROR("setsid");
|
||||
exit(21);
|
||||
}
|
||||
if (close(STDIN_FILENO)<0 || close(STDOUT_FILENO)<0 || close(STDERR_FILENO)<0)
|
||||
if (close(STDIN_FILENO)<0 && errno!=EBADF)
|
||||
{
|
||||
// will work only if debug not to console
|
||||
DLOG_PERROR("close");
|
||||
DLOG_PERROR("close(stdin)");
|
||||
exit(22);
|
||||
}
|
||||
if (close(STDOUT_FILENO)<0 && errno!=EBADF)
|
||||
{
|
||||
DLOG_PERROR("close(stdout)");
|
||||
exit(22);
|
||||
}
|
||||
if (close(STDERR_FILENO)<0 && errno!=EBADF)
|
||||
{
|
||||
DLOG_PERROR("close(stderr)");
|
||||
exit(22);
|
||||
}
|
||||
/* redirect fd's 0,1,2 to /dev/null */
|
||||
|
||||
23
nfq2/sec.h
23
nfq2/sec.h
@@ -18,6 +18,25 @@ bool dropcaps(void);
|
||||
#define arch_nr (offsetof(struct seccomp_data, arch))
|
||||
#define syscall_arg(x) (offsetof(struct seccomp_data, args[x]))
|
||||
|
||||
#ifndef __AUDIT_ARCH_64BIT
|
||||
#define __AUDIT_ARCH_64BIT 0x80000000
|
||||
#endif
|
||||
#ifndef __AUDIT_ARCH_LE
|
||||
#define __AUDIT_ARCH_LE 0x40000000
|
||||
#endif
|
||||
#ifndef EM_RISCV
|
||||
#define EM_RISCV 243
|
||||
#endif
|
||||
#ifndef AUDIT_ARCH_RISCV64
|
||||
#define AUDIT_ARCH_RISCV64 (EM_RISCV | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
|
||||
#endif
|
||||
#ifndef EM_LOONGARCH
|
||||
#define EM_LOONGARCH 258
|
||||
#endif
|
||||
#ifndef AUDIT_ARCH_LOONGARCH64
|
||||
#define AUDIT_ARCH_LOONGARCH64 (EM_LOONGARCH | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__)
|
||||
|
||||
# define ARCH_NR AUDIT_ARCH_AARCH64
|
||||
@@ -72,6 +91,10 @@ bool dropcaps(void);
|
||||
|
||||
# define ARCH_NR AUDIT_ARCH_RISCV64
|
||||
|
||||
#elif defined(__loongarch__) && __loongarch_grlen == 64
|
||||
|
||||
# define ARCH_NR AUDIT_ARCH_LOONGARCH64
|
||||
|
||||
#else
|
||||
|
||||
# error "Platform does not support seccomp filter yet"
|
||||
|
||||
Reference in New Issue
Block a user