mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-26 20:20:53 +03:00
winws: ssid-filter
This commit is contained in:
parent
eebe68ca65
commit
fc6bae8fcd
Binary file not shown.
Binary file not shown.
@ -49,6 +49,7 @@ Task of `iptables` is done inside `winws` through `windivert` filters. `Windiver
|
|||||||
--wf-udp=[~]port1[-port2] ; UDP port filter. ~ means negation. multiple comma separated values allowed.
|
--wf-udp=[~]port1[-port2] ; UDP port filter. ~ means negation. multiple comma separated values allowed.
|
||||||
--wf-raw=<filter>|@<filename> ; raw windivert filter string or filename
|
--wf-raw=<filter>|@<filename> ; raw windivert filter string or filename
|
||||||
--wf-save=<filename> ; save windivert filter string to a file and exit
|
--wf-save=<filename> ; save windivert filter string to a file and exit
|
||||||
|
--ssid-filter=ssid1[,ssid2,ssid3,...] ; enable winws only if any of specified wifi SSIDs connected
|
||||||
```
|
```
|
||||||
|
|
||||||
`--wf-l3`, `--wf-tcp`, `--wf-udp` can take multiple comma separated arguments.
|
`--wf-l3`, `--wf-tcp`, `--wf-udp` can take multiple comma separated arguments.
|
||||||
@ -59,6 +60,8 @@ If you can't find index this way use `winws --debug` to see index there. Subinte
|
|||||||
|
|
||||||
Multiple `winws` processes are allowed. However, it's discouraged to intersect their filters.
|
Multiple `winws` processes are allowed. However, it's discouraged to intersect their filters.
|
||||||
|
|
||||||
|
`--ssid-filter` allows to enable `winws` only if specified wifi networks are connected. `winws` auto detects SSID appearance and disappearance.
|
||||||
|
|
||||||
`Cygwin` shell does not run binaries if their directory has it's own copy of `cygwin1.dll`.
|
`Cygwin` shell does not run binaries if their directory has it's own copy of `cygwin1.dll`.
|
||||||
That's why exists separate standalone version in `binaries/win64/zapret-tpws`.
|
That's why exists separate standalone version in `binaries/win64/zapret-tpws`.
|
||||||
`Cygwin` is required for `blockcheck.sh` support but `winws` itself can be run standalone without cygwin.
|
`Cygwin` is required for `blockcheck.sh` support but `winws` itself can be run standalone without cygwin.
|
||||||
|
@ -55,6 +55,7 @@ https://learn.microsoft.com/en-us/security-updates/SecurityAdvisories/2015/30339
|
|||||||
--wf-udp=[~]port1[-port2] ; фильтр портов для udp. ~ означает отрицание
|
--wf-udp=[~]port1[-port2] ; фильтр портов для udp. ~ означает отрицание
|
||||||
--wf-raw=<filter>|@<filename> ; задать напрямую фильтр windivert из параметра или из файла. имени файла предшествует символ @.
|
--wf-raw=<filter>|@<filename> ; задать напрямую фильтр windivert из параметра или из файла. имени файла предшествует символ @.
|
||||||
--wf-save=<filename> ; сохранить сконструированный фильтр windivert в файл для последующей правки вручную
|
--wf-save=<filename> ; сохранить сконструированный фильтр windivert в файл для последующей правки вручную
|
||||||
|
--ssid-filter=ssid1[,ssid2,ssid3,...] ; включать winws только когда подключена любая из указанных wifi сетей
|
||||||
|
|
||||||
Параметры --wf-l3, --wf-tcp, --wf-udp могут брать несколько значений через запятую.
|
Параметры --wf-l3, --wf-tcp, --wf-udp могут брать несколько значений через запятую.
|
||||||
|
|
||||||
@ -70,6 +71,10 @@ autottl и autohostlist. При включении autohostlist так же пе
|
|||||||
|
|
||||||
Можно запускать несколько процессов winws с разными стратегиями. Однако, не следует делать пересекающиеся фильтры.
|
Можно запускать несколько процессов winws с разными стратегиями. Однако, не следует делать пересекающиеся фильтры.
|
||||||
|
|
||||||
|
В --ssid-filter можно через запятую задать неограниченное количество имен wifi сетей (SSID). Если задана хотя бы одна сеть,
|
||||||
|
то winws включается только, если подключен указанный SSID. Если SSID исчезает, winws отключается. Если SSID появляется снова,
|
||||||
|
winws включается. Это нужно, чтобы можно было применять раздельное дурение к каждой отдельной wifi сети.
|
||||||
|
|
||||||
Если в путях присутствуют национальные символы, то при вызове winws из cmd или bat кодировку нужно использовать OEM.
|
Если в путях присутствуют национальные символы, то при вызове winws из cmd или bat кодировку нужно использовать OEM.
|
||||||
Для русского языка это 866. Пути с пробелами нужно брать в кавычки.
|
Для русского языка это 866. Пути с пробелами нужно брать в кавычки.
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ CFLAGS_MAC = -mmacosx-version-min=10.8
|
|||||||
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static
|
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static
|
||||||
LIBS_LINUX = -lnetfilter_queue -lnfnetlink -lz
|
LIBS_LINUX = -lnetfilter_queue -lnfnetlink -lz
|
||||||
LIBS_BSD = -lz
|
LIBS_BSD = -lz
|
||||||
LIBS_CYGWIN = -lz -Lwindivert -lwindivert
|
LIBS_CYGWIN = -lz -Lwindivert -lwindivert -lwlanapi
|
||||||
SRC_FILES = *.c crypto/*.c
|
SRC_FILES = *.c crypto/*.c
|
||||||
|
|
||||||
all: nfqws
|
all: nfqws
|
||||||
|
@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
#include "gcm.h"
|
#include "gcm.h"
|
||||||
|
|
||||||
// mode : ENCRYPT, DECRYPT
|
// mode : AES_ENCRYPT, AES_DECRYPT
|
||||||
int aes_gcm_crypt(int mode, uint8_t *output, const uint8_t *input, size_t input_length, const uint8_t *key, const size_t key_len, const uint8_t *iv, const size_t iv_len, const uint8_t *adata, size_t adata_len, uint8_t *atag, size_t atag_len);
|
int aes_gcm_crypt(int mode, uint8_t *output, const uint8_t *input, size_t input_length, const uint8_t *key, const size_t key_len, const uint8_t *iv, const size_t iv_len, const uint8_t *adata, size_t adata_len, uint8_t *atag, size_t atag_len);
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define ENCRYPT 1 // specify whether we're encrypting
|
#define AES_ENCRYPT 1 // specify whether we're encrypting
|
||||||
#define DECRYPT 0 // or decrypting
|
#define AES_DECRYPT 0 // or decrypting
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#include <basetsd.h>
|
#include <basetsd.h>
|
||||||
|
@ -186,7 +186,7 @@ int gcm_setkey(gcm_context *ctx, // pointer to caller-provided gcm context
|
|||||||
|
|
||||||
// encrypt the null 128-bit block to generate a key-based value
|
// encrypt the null 128-bit block to generate a key-based value
|
||||||
// which is then used to initialize our GHASH lookup tables
|
// which is then used to initialize our GHASH lookup tables
|
||||||
if ((ret = aes_setkey(&ctx->aes_ctx, ENCRYPT, key, keysize)) != 0)
|
if ((ret = aes_setkey(&ctx->aes_ctx, AES_ENCRYPT, key, keysize)) != 0)
|
||||||
return(ret);
|
return(ret);
|
||||||
if ((ret = aes_cipher(&ctx->aes_ctx, h, h)) != 0)
|
if ((ret = aes_cipher(&ctx->aes_ctx, h, h)) != 0)
|
||||||
return(ret);
|
return(ret);
|
||||||
@ -266,7 +266,7 @@ int gcm_start(gcm_context *ctx, // pointer to user-provided GCM context
|
|||||||
ctx->add_len = 0;
|
ctx->add_len = 0;
|
||||||
|
|
||||||
ctx->mode = mode; // set the GCM encryption/decryption mode
|
ctx->mode = mode; // set the GCM encryption/decryption mode
|
||||||
ctx->aes_ctx.mode = ENCRYPT; // GCM *always* runs AES in ENCRYPTION mode
|
ctx->aes_ctx.mode = AES_ENCRYPT; // GCM *always* runs AES in ENCRYPTION mode
|
||||||
|
|
||||||
if (iv_len == 12) { // GCM natively uses a 12-byte, 96-bit IV
|
if (iv_len == 12) { // GCM natively uses a 12-byte, 96-bit IV
|
||||||
memcpy(ctx->y, iv, iv_len); // copy the IV to the top of the 'y' buff
|
memcpy(ctx->y, iv, iv_len); // copy the IV to the top of the 'y' buff
|
||||||
@ -338,7 +338,7 @@ int gcm_update(gcm_context *ctx, // pointer to user-provided GCM context
|
|||||||
return(ret);
|
return(ret);
|
||||||
|
|
||||||
// encrypt or decrypt the input to the output
|
// encrypt or decrypt the input to the output
|
||||||
if (ctx->mode == ENCRYPT)
|
if (ctx->mode == AES_ENCRYPT)
|
||||||
{
|
{
|
||||||
for (i = 0; i < use_len; i++) {
|
for (i = 0; i < use_len; i++) {
|
||||||
// XOR the cipher's ouptut vector (ectr) with our input
|
// XOR the cipher's ouptut vector (ectr) with our input
|
||||||
@ -481,7 +481,7 @@ int gcm_auth_decrypt(
|
|||||||
(which is an identical XORing to reverse the previous one)
|
(which is an identical XORing to reverse the previous one)
|
||||||
and also to re-generate the matching authentication tag
|
and also to re-generate the matching authentication tag
|
||||||
*/
|
*/
|
||||||
gcm_crypt_and_tag(ctx, DECRYPT, iv, iv_len, add, add_len,
|
gcm_crypt_and_tag(ctx, AES_DECRYPT, iv, iv_len, add, add_len,
|
||||||
input, output, length, check_tag, tag_len);
|
input, output, length, check_tag, tag_len);
|
||||||
|
|
||||||
// now we verify the authentication tag in 'constant time'
|
// now we verify the authentication tag in 'constant time'
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
#include "params.h"
|
#include "params.h"
|
||||||
#include "nfqws.h"
|
#include "nfqws.h"
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
#include <wlanapi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment)
|
uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment)
|
||||||
{
|
{
|
||||||
@ -959,8 +962,83 @@ void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize, uint8_t scale_fac
|
|||||||
|
|
||||||
static HANDLE w_filter = NULL;
|
static HANDLE w_filter = NULL;
|
||||||
static OVERLAPPED ovl = { .hEvent = NULL };
|
static OVERLAPPED ovl = { .hEvent = NULL };
|
||||||
|
static const struct str_list_head *wlan_filter_ssid = NULL;
|
||||||
|
static DWORD wlan_filter_tick=0;
|
||||||
uint32_t w_win32_error=0;
|
uint32_t w_win32_error=0;
|
||||||
|
|
||||||
|
bool wlan_filter_match(const struct str_list_head *ssid_list)
|
||||||
|
{
|
||||||
|
DWORD dwCurVersion;
|
||||||
|
HANDLE hClient = NULL;
|
||||||
|
PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
|
||||||
|
PWLAN_INTERFACE_INFO pIfInfo;
|
||||||
|
PWLAN_CONNECTION_ATTRIBUTES pConnectInfo;
|
||||||
|
DWORD connectInfoSize, k;
|
||||||
|
bool bRes;
|
||||||
|
struct str_list *ssid;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
// no filter given. always matches.
|
||||||
|
if (!ssid_list || LIST_EMPTY(ssid_list))
|
||||||
|
{
|
||||||
|
w_win32_error = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
w_win32_error = WlanOpenHandle(2, NULL, &dwCurVersion, &hClient);
|
||||||
|
if (w_win32_error != ERROR_SUCCESS) goto fail;
|
||||||
|
w_win32_error = WlanEnumInterfaces(hClient, NULL, &pIfList);
|
||||||
|
if (w_win32_error != ERROR_SUCCESS) goto fail;
|
||||||
|
for (k = 0; k < pIfList->dwNumberOfItems; k++)
|
||||||
|
{
|
||||||
|
pIfInfo = pIfList->InterfaceInfo + k;
|
||||||
|
if (pIfInfo->isState == wlan_interface_state_connected)
|
||||||
|
{
|
||||||
|
w_win32_error = WlanQueryInterface(hClient,
|
||||||
|
&pIfInfo->InterfaceGuid,
|
||||||
|
wlan_intf_opcode_current_connection,
|
||||||
|
NULL,
|
||||||
|
&connectInfoSize,
|
||||||
|
(PVOID *)&pConnectInfo,
|
||||||
|
NULL);
|
||||||
|
if (w_win32_error != ERROR_SUCCESS) goto fail;
|
||||||
|
|
||||||
|
// printf("%s\n", pConnectInfo->wlanAssociationAttributes.dot11Ssid.ucSSID);
|
||||||
|
|
||||||
|
LIST_FOREACH(ssid, ssid_list, next)
|
||||||
|
{
|
||||||
|
len = strlen(ssid->str);
|
||||||
|
if (len==pConnectInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength && !memcmp(ssid->str,pConnectInfo->wlanAssociationAttributes.dot11Ssid.ucSSID,len))
|
||||||
|
{
|
||||||
|
WlanFreeMemory(pConnectInfo);
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WlanFreeMemory(pConnectInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w_win32_error = 0;
|
||||||
|
fail:
|
||||||
|
bRes = false;
|
||||||
|
ex:
|
||||||
|
if (pIfList) WlanFreeMemory(pIfList);
|
||||||
|
if (hClient) WlanCloseHandle(hClient, 0);
|
||||||
|
return bRes;
|
||||||
|
found:
|
||||||
|
w_win32_error = 0;
|
||||||
|
bRes = true;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool wlan_filter_match_rate_limited(void)
|
||||||
|
{
|
||||||
|
DWORD dwTick = GetTickCount() / 1000;
|
||||||
|
if (wlan_filter_tick == dwTick) return true;
|
||||||
|
wlan_filter_tick = dwTick;
|
||||||
|
return wlan_filter_match(wlan_filter_ssid);
|
||||||
|
}
|
||||||
|
|
||||||
static HANDLE windivert_init_filter(const char *filter, UINT64 flags)
|
static HANDLE windivert_init_filter(const char *filter, UINT64 flags)
|
||||||
{
|
{
|
||||||
LPSTR errormessage = NULL;
|
LPSTR errormessage = NULL;
|
||||||
@ -1006,8 +1084,9 @@ void rawsend_cleanup(void)
|
|||||||
CloseHandle(ovl.hEvent);
|
CloseHandle(ovl.hEvent);
|
||||||
ovl.hEvent=NULL;
|
ovl.hEvent=NULL;
|
||||||
}
|
}
|
||||||
|
wlan_filter_ssid = NULL;
|
||||||
}
|
}
|
||||||
bool windivert_init(const char *filter)
|
bool windivert_init(const char *filter, const struct str_list_head *ssid_filter)
|
||||||
{
|
{
|
||||||
rawsend_cleanup();
|
rawsend_cleanup();
|
||||||
w_filter = windivert_init_filter(filter, 0);
|
w_filter = windivert_init_filter(filter, 0);
|
||||||
@ -1020,6 +1099,7 @@ bool windivert_init(const char *filter)
|
|||||||
rawsend_cleanup();
|
rawsend_cleanup();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
wlan_filter_ssid = ssid_filter;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -1037,6 +1117,11 @@ static bool windivert_recv_filter(HANDLE hFilter, uint8_t *packet, size_t *len,
|
|||||||
errno=EINTR;
|
errno=EINTR;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!wlan_filter_match_rate_limited())
|
||||||
|
{
|
||||||
|
errno=ENODEV;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
usleep(0);
|
usleep(0);
|
||||||
if (WinDivertRecvEx(hFilter, packet, *len, &recv_len, 0, wa, NULL, &ovl))
|
if (WinDivertRecvEx(hFilter, packet, *len, &recv_len, 0, wa, NULL, &ovl))
|
||||||
{
|
{
|
||||||
@ -1057,6 +1142,11 @@ static bool windivert_recv_filter(HANDLE hFilter, uint8_t *packet, size_t *len,
|
|||||||
errno=EINTR;
|
errno=EINTR;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!wlan_filter_match_rate_limited())
|
||||||
|
{
|
||||||
|
errno=ENODEV;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
usleep(0);
|
usleep(0);
|
||||||
}
|
}
|
||||||
if (!GetOverlappedResult(hFilter,&ovl,&rd,TRUE))
|
if (!GetOverlappedResult(hFilter,&ovl,&rd,TRUE))
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "packet_queue.h"
|
#include "packet_queue.h"
|
||||||
|
#include "pools.h"
|
||||||
|
|
||||||
#ifndef IPPROTO_DIVERT
|
#ifndef IPPROTO_DIVERT
|
||||||
#define IPPROTO_DIVERT 258
|
#define IPPROTO_DIVERT 258
|
||||||
@ -151,9 +152,10 @@ bool tcp_has_fastopen(const struct tcphdr *tcp);
|
|||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
extern uint32_t w_win32_error;
|
extern uint32_t w_win32_error;
|
||||||
|
|
||||||
bool windivert_init(const char *filter);
|
bool windivert_init(const char *filter, const struct str_list_head *ssid_filter);
|
||||||
bool windivert_recv(uint8_t *packet, size_t *len, WINDIVERT_ADDRESS *wa);
|
bool windivert_recv(uint8_t *packet, size_t *len, WINDIVERT_ADDRESS *wa);
|
||||||
bool windivert_send(const uint8_t *packet, size_t len, const WINDIVERT_ADDRESS *wa);
|
bool windivert_send(const uint8_t *packet, size_t len, const WINDIVERT_ADDRESS *wa);
|
||||||
|
bool wlan_filter_match(const struct str_list_head *ssid_list);
|
||||||
#else
|
#else
|
||||||
// should pre-do it if dropping privileges. otherwise its not necessary
|
// should pre-do it if dropping privileges. otherwise its not necessary
|
||||||
bool rawsend_preinit(bool bind_fix4, bool bind_fix6);
|
bool rawsend_preinit(bool bind_fix4, bool bind_fix6);
|
||||||
|
63
nfq/nfqws.c
63
nfq/nfqws.c
@ -410,13 +410,33 @@ static int win_main(const char *windivert_filter)
|
|||||||
WINDIVERT_ADDRESS wa;
|
WINDIVERT_ADDRESS wa;
|
||||||
char ifout[22];
|
char ifout[22];
|
||||||
|
|
||||||
if (!windivert_init(windivert_filter))
|
pre_desync();
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if (!wlan_filter_match(¶ms.ssid_filter))
|
||||||
|
{
|
||||||
|
printf("logical network is not present. waiting it to appear.\n");
|
||||||
|
fflush(stdout);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (bQuit)
|
||||||
|
{
|
||||||
|
DLOG("QUIT requested\n")
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
usleep(500000);
|
||||||
|
}
|
||||||
|
while (!wlan_filter_match(¶ms.ssid_filter));
|
||||||
|
printf("logical network now present\n");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!windivert_init(windivert_filter, ¶ms.ssid_filter))
|
||||||
return w_win32_error;
|
return w_win32_error;
|
||||||
|
|
||||||
printf("windivert initialized. capture is started.\n");
|
printf("windivert initialized. capture is started.\n");
|
||||||
|
|
||||||
pre_desync();
|
|
||||||
|
|
||||||
// cygwin auto flush fails when piping
|
// cygwin auto flush fails when piping
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
@ -431,10 +451,16 @@ static int win_main(const char *windivert_filter)
|
|||||||
DLOG("windivert: ignoring too large packet\n")
|
DLOG("windivert: ignoring too large packet\n")
|
||||||
continue; // too large packet
|
continue; // too large packet
|
||||||
}
|
}
|
||||||
|
else if (errno==ENODEV)
|
||||||
|
{
|
||||||
|
printf("logical network disappeared. deinitializing windivert.\n");
|
||||||
|
rawsend_cleanup();
|
||||||
|
break;
|
||||||
|
}
|
||||||
else if (errno==EINTR)
|
else if (errno==EINTR)
|
||||||
{
|
{
|
||||||
DLOG("QUIT requested\n")
|
DLOG("QUIT requested\n")
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "windivert: recv failed. errno %d\n", errno);
|
fprintf(stderr, "windivert: recv failed. errno %d\n", errno);
|
||||||
return w_win32_error;
|
return w_win32_error;
|
||||||
@ -477,6 +503,7 @@ static int win_main(const char *windivert_filter)
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,6 +548,9 @@ static void cleanup_params(void)
|
|||||||
StrPoolDestroy(¶ms.hostlist_exclude);
|
StrPoolDestroy(¶ms.hostlist_exclude);
|
||||||
StrPoolDestroy(¶ms.hostlist);
|
StrPoolDestroy(¶ms.hostlist);
|
||||||
HostFailPoolDestroy(¶ms.hostlist_auto_fail_counters);
|
HostFailPoolDestroy(¶ms.hostlist_auto_fail_counters);
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
strlist_destroy(¶ms.ssid_filter);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
static void exit_clean(int code)
|
static void exit_clean(int code)
|
||||||
{
|
{
|
||||||
@ -760,6 +790,8 @@ static void exithelp(void)
|
|||||||
" --wf-udp=[~]port1[-port2]\t\t\t; UDP port filter. ~ means negation. multiple comma separated values allowed.\n"
|
" --wf-udp=[~]port1[-port2]\t\t\t; UDP port filter. ~ means negation. multiple comma separated values allowed.\n"
|
||||||
" --wf-raw=<filter>|@<filename>\t\t\t; raw windivert filter string or filename\n"
|
" --wf-raw=<filter>|@<filename>\t\t\t; raw windivert filter string or filename\n"
|
||||||
" --wf-save=<filename>\t\t\t\t; save windivert filter string to a file and exit\n"
|
" --wf-save=<filename>\t\t\t\t; save windivert filter string to a file and exit\n"
|
||||||
|
"\nLOGICAL NETWORK FILTER:\n"
|
||||||
|
" --ssid-filter=ssid1[,ssid2,ssid3,...]\t\t; enable winws only if any of specified wifi SSIDs connected\n"
|
||||||
#endif
|
#endif
|
||||||
"\nHOSTLIST FILTER:\n"
|
"\nHOSTLIST FILTER:\n"
|
||||||
" --hostlist=<filename>\t\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n"
|
" --hostlist=<filename>\t\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n"
|
||||||
@ -915,7 +947,9 @@ int main(int argc, char **argv)
|
|||||||
LIST_INIT(¶ms.hostlist_files);
|
LIST_INIT(¶ms.hostlist_files);
|
||||||
LIST_INIT(¶ms.hostlist_exclude_files);
|
LIST_INIT(¶ms.hostlist_exclude_files);
|
||||||
|
|
||||||
#ifndef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
|
LIST_INIT(¶ms.ssid_filter);
|
||||||
|
#else
|
||||||
if (can_drop_root()) // are we root ?
|
if (can_drop_root()) // are we root ?
|
||||||
{
|
{
|
||||||
params.uid = params.gid = 0x7FFFFFFF; // default uid:gid
|
params.uid = params.gid = 0x7FFFFFFF; // default uid:gid
|
||||||
@ -1002,6 +1036,7 @@ int main(int argc, char **argv)
|
|||||||
{"wf-udp",required_argument,0,0}, // optidx=53
|
{"wf-udp",required_argument,0,0}, // optidx=53
|
||||||
{"wf-raw",required_argument,0,0}, // optidx=54
|
{"wf-raw",required_argument,0,0}, // optidx=54
|
||||||
{"wf-save",required_argument,0,0}, // optidx=55
|
{"wf-save",required_argument,0,0}, // optidx=55
|
||||||
|
{"ssid-filter",required_argument,0,0}, // optidx=56
|
||||||
#endif
|
#endif
|
||||||
{NULL,0,NULL,0}
|
{NULL,0,NULL,0}
|
||||||
};
|
};
|
||||||
@ -1499,6 +1534,24 @@ int main(int argc, char **argv)
|
|||||||
strncpy(wf_save_file, optarg, sizeof(wf_save_file));
|
strncpy(wf_save_file, optarg, sizeof(wf_save_file));
|
||||||
wf_save_file[sizeof(wf_save_file) - 1] = '\0';
|
wf_save_file[sizeof(wf_save_file) - 1] = '\0';
|
||||||
break;
|
break;
|
||||||
|
case 56: /* ssid-filter */
|
||||||
|
{
|
||||||
|
char *e,*p = optarg;
|
||||||
|
while (p)
|
||||||
|
{
|
||||||
|
e = strchr(p,',');
|
||||||
|
if (e) *e++=0;
|
||||||
|
if (*p && !strlist_add(¶ms.ssid_filter, p))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "strlist_add failed\n");
|
||||||
|
exit_clean(1);
|
||||||
|
}
|
||||||
|
p = e;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,9 @@ struct params_s
|
|||||||
size_t fake_http_size,fake_tls_size,fake_quic_size,fake_wg_size,fake_dht_size,fake_unknown_size,fake_syndata_size,fake_unknown_udp_size;
|
size_t fake_http_size,fake_tls_size,fake_quic_size,fake_wg_size,fake_dht_size,fake_unknown_size,fake_syndata_size,fake_unknown_udp_size;
|
||||||
int udplen_increment;
|
int udplen_increment;
|
||||||
|
|
||||||
#ifndef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
|
struct str_list_head ssid_filter;
|
||||||
|
#else
|
||||||
bool droproot;
|
bool droproot;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
|
@ -600,7 +600,7 @@ bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, si
|
|||||||
header[0] = packet0;
|
header[0] = packet0;
|
||||||
for(uint8_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(DECRYPT, clean, decrypt_begin, cryptlen, aeskey, sizeof(aeskey), aesiv, sizeof(aesiv), header, header_len, atag, sizeof(atag)))
|
if (aes_gcm_crypt(AES_DECRYPT, clean, decrypt_begin, cryptlen, aeskey, sizeof(aeskey), aesiv, sizeof(aesiv), header, header_len, atag, sizeof(atag)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check if message was decrypted correctly : good keys , no data corruption
|
// check if message was decrypted correctly : good keys , no data corruption
|
||||||
|
Loading…
Reference in New Issue
Block a user