Change Kill Switch behavior
This commit is contained in:
parent
e499a3d4f7
commit
437c90b6bf
8 changed files with 102 additions and 103 deletions
|
@ -18,6 +18,7 @@
|
|||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_SVE)
|
||||
LANGUAGE LANG_SWEDISH, SUBLANG_SWEDISH
|
||||
#pragma code_page(1252)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -160,10 +161,11 @@ BEGIN
|
|||
POPUP "Internet &Kill Switch"
|
||||
BEGIN
|
||||
MENUITEM "&Off", IDSETT_BLOCKINTERNET_OFF
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Yes, with &Routing Rules", IDSETT_BLOCKINTERNET_ROUTE
|
||||
MENUITEM "Yes, with &Firewall Rules", IDSETT_BLOCKINTERNET_FIREWALL
|
||||
MENUITEM "Yes, &Both Methods", IDSETT_BLOCKINTERNET_BOTH
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Block While &Disconnected", IDSETT_BLOCKINTERNET_DISCONN
|
||||
END
|
||||
POPUP "&Service Mode"
|
||||
BEGIN
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2018-??-?? - TunSafe v1.4-rc2
|
||||
|
||||
Changes:
|
||||
1.The kill switch is now remembered across computer restarts and
|
||||
is deactivated when disconnecting. Without this behavior, the
|
||||
kill switch is unusable when auto connecting on Windows startup.
|
||||
|
||||
2018-08-11 - TunSafe v1.4-rc1
|
||||
|
||||
Changes:
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "util.h"
|
||||
#include <algorithm>
|
||||
#include "network_win32_dnsblock.h"
|
||||
#include "util_win32.h"
|
||||
|
||||
enum {
|
||||
HARD_MAXIMUM_QUEUE_SIZE = 102400,
|
||||
|
@ -27,13 +28,6 @@ enum {
|
|||
MAX_BYTES_IN_UDP_OUT_QUEUE_SMALL = (256 + 64) * 1024,
|
||||
};
|
||||
|
||||
enum {
|
||||
ROUTE_BLOCK_UNKNOWN = 0,
|
||||
ROUTE_BLOCK_OFF = 1,
|
||||
ROUTE_BLOCK_ON = 2,
|
||||
ROUTE_BLOCK_PENDING = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
kMetricNone = -1,
|
||||
kMetricAutomatic = 0,
|
||||
|
@ -41,10 +35,13 @@ enum {
|
|||
|
||||
static uint8 internet_route_blocking_state;
|
||||
static SLIST_HEADER freelist_head;
|
||||
static HKEY g_hklm_reg_key;
|
||||
static uint8 g_killswitch_curr = 255, g_killswitch_want;
|
||||
|
||||
bool g_allow_pre_post;
|
||||
|
||||
static InternetBlockState GetInternetBlockState(bool *is_activated);
|
||||
static void DeactivateKillSwitch(InternetBlockState want);
|
||||
|
||||
Packet *AllocPacket() {
|
||||
Packet *packet = (Packet*)InterlockedPopEntrySList(&freelist_head);
|
||||
|
@ -899,7 +896,6 @@ void ThreadedPacketQueue::Stop() {
|
|||
CloseHandle(handle_);
|
||||
handle_ = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ThreadedPacketQueue::AbortingDriver() {
|
||||
|
@ -1289,9 +1285,12 @@ bool TunWin32Adapter::InitAdapter(const TunInterface::TunConfig &&config, TunInt
|
|||
dns_blocker_->RestoreDns();
|
||||
}
|
||||
|
||||
// Cache the state of internet blocking
|
||||
GetInternetBlockState(NULL);
|
||||
|
||||
uint8 ibs = config.internet_blocking;
|
||||
if (ibs == kBlockInternet_Default || ibs == kBlockInternet_DefaultOn) {
|
||||
uint8 new_ibs = GetInternetBlockState(NULL);
|
||||
uint8 new_ibs = (g_killswitch_want & (kBlockInternet_Firewall | kBlockInternet_Route));
|
||||
ibs = (new_ibs == kBlockInternet_Off && ibs == kBlockInternet_DefaultOn) ? kBlockInternet_Firewall : new_ibs;
|
||||
}
|
||||
|
||||
|
@ -1331,18 +1330,18 @@ bool TunWin32Adapter::InitAdapter(const TunInterface::TunConfig &&config, TunInt
|
|||
if (!AddMultipleCatchallRoutes(AF_INET6, 1, (uint8*)&dst, localhost_luid, NULL))
|
||||
RERROR("Unable to add IPv6 routes for route based blocking.");
|
||||
}
|
||||
g_killswitch_curr |= kBlockInternet_Route;
|
||||
}
|
||||
}
|
||||
|
||||
internet_route_blocking_state = block_all_traffic_route + ROUTE_BLOCK_OFF;
|
||||
|
||||
if (ibs & kBlockInternet_Firewall) {
|
||||
RINFO("Blocking all regular Internet traffic%s", ri.found_default_adapter ? " (except DHCP)" : "");
|
||||
AddPersistentInternetBlocking(ri.found_default_adapter ? &ri.default_adapter : NULL, interface_luid_, config.ipv6_cidr != 0);
|
||||
} else {
|
||||
SetInternetFwBlockingState(false);
|
||||
RINFO("Blocking all regular Internet traffic using firewall rules");
|
||||
if (AddKillSwitchFirewall(ri.found_default_adapter ? &ri.default_adapter : NULL, interface_luid_, config.ipv6_cidr != 0))
|
||||
g_killswitch_curr |= kBlockInternet_Firewall;
|
||||
}
|
||||
|
||||
DeactivateKillSwitch((InternetBlockState)ibs);
|
||||
|
||||
// Configure default route?
|
||||
if (config.use_ipv4_default_route) {
|
||||
// Add a bypass route to the original gateway?
|
||||
|
@ -2040,8 +2039,10 @@ TunsafeBackendWin32::TunsafeBackendWin32(Delegate *delegate) : delegate_(delegat
|
|||
last_tun_adapter_failed_ = 0;
|
||||
want_periodic_stats_ = false;
|
||||
|
||||
internet_route_blocking_state = ROUTE_BLOCK_UNKNOWN;
|
||||
ClearInternetFwBlockingStateCache();
|
||||
if (g_hklm_reg_key == NULL) {
|
||||
RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\TunSafe", NULL, NULL, 0, KEY_ALL_ACCESS, NULL, &g_hklm_reg_key, NULL);
|
||||
g_killswitch_want = RegReadInt(g_hklm_reg_key, "KillSwitch", 0);
|
||||
}
|
||||
|
||||
delegate_->OnStateChanged();
|
||||
}
|
||||
|
@ -2115,6 +2116,9 @@ void TunsafeBackendWin32::StopInner(bool is_restart) {
|
|||
config_file_ = NULL;
|
||||
is_started_ = false;
|
||||
status_ = kStatusStopped;
|
||||
|
||||
if (!is_restart && !(g_killswitch_want & kBlockInternet_BlockOnDisconnect))
|
||||
DeactivateKillSwitch(kBlockInternet_Off);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2149,46 +2153,60 @@ LinearizedGraph *TunsafeBackendWin32::GetGraph(int type) {
|
|||
return graph;
|
||||
}
|
||||
|
||||
|
||||
static uint8 GetInternetRouteBlockingState() {
|
||||
if (internet_route_blocking_state == ROUTE_BLOCK_UNKNOWN) {
|
||||
RouteInfo ri;
|
||||
internet_route_blocking_state =
|
||||
(GetDefaultRouteAndDeleteOldRoutes(AF_INET, NULL, TRUE, NULL, &ri) && ri.found_null_routes == 2) + ROUTE_BLOCK_OFF;
|
||||
}
|
||||
return internet_route_blocking_state;
|
||||
static bool GetKillSwitchRouteActive() {
|
||||
RouteInfo ri;
|
||||
return (GetDefaultRouteAndDeleteOldRoutes(AF_INET, NULL, TRUE, NULL, &ri) && ri.found_null_routes == 2);
|
||||
}
|
||||
|
||||
static void SetInternetRouteBlockingState(bool want) {
|
||||
if (want) {
|
||||
internet_route_blocking_state = ROUTE_BLOCK_PENDING;
|
||||
} else if (internet_route_blocking_state != ROUTE_BLOCK_OFF) {
|
||||
RouteInfo ri;
|
||||
GetDefaultRouteAndDeleteOldRoutes(AF_INET, NULL, FALSE, NULL, &ri);
|
||||
GetDefaultRouteAndDeleteOldRoutes(AF_INET6, NULL, FALSE, NULL, &ri);
|
||||
internet_route_blocking_state = ROUTE_BLOCK_OFF;
|
||||
}
|
||||
static void RemoveKillSwitchRoute() {
|
||||
RouteInfo ri;
|
||||
GetDefaultRouteAndDeleteOldRoutes(AF_INET, NULL, FALSE, NULL, &ri);
|
||||
GetDefaultRouteAndDeleteOldRoutes(AF_INET6, NULL, FALSE, NULL, &ri);
|
||||
}
|
||||
|
||||
static InternetBlockState GetInternetBlockState(bool *is_activated) {
|
||||
int a = GetInternetRouteBlockingState();
|
||||
int b = GetInternetFwBlockingState();
|
||||
|
||||
// Read the value only once.
|
||||
if (g_killswitch_curr == 255) {
|
||||
g_killswitch_curr = GetKillSwitchRouteActive() * kBlockInternet_Route +
|
||||
GetKillSwitchFirewallActive() * kBlockInternet_Firewall;
|
||||
}
|
||||
if (is_activated)
|
||||
*is_activated = (a == ROUTE_BLOCK_ON || b == IBS_ACTIVE);
|
||||
|
||||
return (InternetBlockState)(
|
||||
(a >= ROUTE_BLOCK_ON) * kBlockInternet_Route +
|
||||
(b >= IBS_ACTIVE) * kBlockInternet_Firewall);
|
||||
*is_activated = g_killswitch_curr != 0;
|
||||
return (InternetBlockState)g_killswitch_want;
|
||||
}
|
||||
|
||||
InternetBlockState TunsafeBackendWin32::GetInternetBlockState(bool *is_activated) {
|
||||
return ::GetInternetBlockState(is_activated);
|
||||
}
|
||||
|
||||
void TunsafeBackendWin32::SetInternetBlockState(InternetBlockState s) {
|
||||
SetInternetRouteBlockingState((s & kBlockInternet_Route) != 0);
|
||||
SetInternetFwBlockingState((s & kBlockInternet_Firewall) != 0);
|
||||
static void DeactivateKillSwitch(InternetBlockState want) {
|
||||
// Disable blocking without reconnecting
|
||||
int maybeon = g_killswitch_curr | g_killswitch_want;
|
||||
if ((maybeon & kBlockInternet_Route) > (want & kBlockInternet_Route)) {
|
||||
if (g_killswitch_curr & kBlockInternet_Route) {
|
||||
g_killswitch_curr &= ~kBlockInternet_Route;
|
||||
RINFO("Removing the routing rule internet block");
|
||||
}
|
||||
RemoveKillSwitchRoute();
|
||||
}
|
||||
if ((maybeon & kBlockInternet_Firewall) > (want & kBlockInternet_Firewall)) {
|
||||
if (g_killswitch_curr & kBlockInternet_Firewall) {
|
||||
g_killswitch_curr &= ~kBlockInternet_Firewall;
|
||||
RINFO("Removing the firewall internet block");
|
||||
}
|
||||
RemoveKillSwitchFirewall();
|
||||
}
|
||||
}
|
||||
|
||||
void TunsafeBackendWin32::SetInternetBlockState(InternetBlockState want) {
|
||||
GetInternetBlockState(NULL); // ensure cache is read
|
||||
|
||||
if (worker_thread_ == NULL && !(want & kBlockInternet_BlockOnDisconnect))
|
||||
DeactivateKillSwitch(kBlockInternet_Off);
|
||||
else
|
||||
DeactivateKillSwitch(want);
|
||||
g_killswitch_want = want;
|
||||
RegWriteInt(g_hklm_reg_key, "KillSwitch", (int)want);
|
||||
}
|
||||
|
||||
void TunsafeBackendWin32::SetServiceStartupFlags(uint32 flags) {
|
||||
|
|
|
@ -203,8 +203,6 @@ static bool RemovePersistentInternetBlockingInner(HANDLE handle) {
|
|||
goto getout;
|
||||
}
|
||||
|
||||
internet_fw_blocking_state = IBS_INACTIVE;
|
||||
|
||||
getout:
|
||||
if (enum_handle != NULL) {
|
||||
FwpmFilterDestroyEnumHandle0(handle, enum_handle);
|
||||
|
@ -212,7 +210,7 @@ getout:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool AddPersistentInternetBlocking(const NET_LUID *default_interface, const NET_LUID &luid_to_allow, bool also_ipv6) {
|
||||
bool AddKillSwitchFirewall(const NET_LUID *default_interface, const NET_LUID &luid_to_allow, bool also_ipv6) {
|
||||
FWPM_SUBLAYER0 *sublayer_p = NULL;
|
||||
FWP_BYTE_BLOB *fwp_appid = NULL;
|
||||
FWPM_FILTER0 filter;
|
||||
|
@ -312,7 +310,6 @@ bool AddPersistentInternetBlocking(const NET_LUID *default_interface, const NET_
|
|||
goto getout;
|
||||
|
||||
success = true;
|
||||
internet_fw_blocking_state = IBS_ACTIVE;
|
||||
|
||||
getout:
|
||||
if (handle != NULL) {
|
||||
|
@ -327,7 +324,7 @@ getout:
|
|||
return success;
|
||||
}
|
||||
|
||||
static bool RemovePersistentInternetBlocking() {
|
||||
void RemoveKillSwitchFirewall() {
|
||||
DWORD err;
|
||||
HANDLE handle = NULL;
|
||||
FWPM_SUBLAYER0 *sublayer_p = NULL;
|
||||
|
@ -345,8 +342,6 @@ static bool RemovePersistentInternetBlocking() {
|
|||
// The sublayer exists
|
||||
FwpmFreeMemory0((void **)&sublayer_p);
|
||||
} else {
|
||||
// Sublayer does not exist
|
||||
internet_fw_blocking_state = IBS_INACTIVE;
|
||||
goto getout;
|
||||
}
|
||||
|
||||
|
@ -357,17 +352,9 @@ getout:
|
|||
FwpmEngineClose0(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClearInternetFwBlockingStateCache() {
|
||||
internet_fw_blocking_state = 0;
|
||||
}
|
||||
|
||||
uint8 GetInternetFwBlockingState() {
|
||||
if (internet_fw_blocking_state != 0)
|
||||
return internet_fw_blocking_state;
|
||||
|
||||
bool GetKillSwitchFirewallActive() {
|
||||
DWORD err;
|
||||
HANDLE handle = NULL;
|
||||
FWPM_SUBLAYER0 *sublayer_p = NULL;
|
||||
|
@ -395,18 +382,5 @@ getout:
|
|||
FwpmEngineClose0(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
return internet_fw_blocking_state = result + IBS_INACTIVE;
|
||||
return result;
|
||||
}
|
||||
|
||||
void SetInternetFwBlockingState(bool want) {
|
||||
uint8 old_state = GetInternetFwBlockingState();
|
||||
if ((old_state >= IBS_ACTIVE) != want) {
|
||||
if (!want) {
|
||||
RemovePersistentInternetBlocking();
|
||||
} else {
|
||||
internet_fw_blocking_state = IBS_PENDING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,16 +18,6 @@ public:
|
|||
bool also_ipv6_;
|
||||
};
|
||||
|
||||
|
||||
bool AddPersistentInternetBlocking(const NET_LUID *default_interface, const NET_LUID &luid_to_allow, bool also_ipv6);
|
||||
|
||||
enum {
|
||||
IBS_UNKOWN,
|
||||
IBS_INACTIVE,
|
||||
IBS_ACTIVE,
|
||||
IBS_PENDING,
|
||||
};
|
||||
void SetInternetFwBlockingState(bool want);
|
||||
uint8 GetInternetFwBlockingState();
|
||||
|
||||
void ClearInternetFwBlockingStateCache();
|
||||
bool AddKillSwitchFirewall(const NET_LUID *default_interface, const NET_LUID &luid_to_allow, bool also_ipv6);
|
||||
void RemoveKillSwitchFirewall();
|
||||
bool GetKillSwitchFirewallActive();
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define IDSETT_SERVICE_BACKGROUND 23
|
||||
#define IDSETT_SERVICE_CONNECT_AUTO 24
|
||||
#define IDSETT_SERVICE_MINIMIZE_AUTO 25
|
||||
#define IDSETT_BLOCKINTERNET_DISCONN 26
|
||||
#define IDC_PAINTBOX 30
|
||||
#define IDC_GRAPHBOX 31
|
||||
#define IDC_ADVANCEDBOX 32
|
||||
|
@ -40,12 +41,13 @@
|
|||
#define IDC_PUBLIC_KEY 109
|
||||
#define IDC_TAB 110
|
||||
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 113
|
||||
#define _APS_NEXT_COMMAND_VALUE 40023
|
||||
#define _APS_NEXT_COMMAND_VALUE 40026
|
||||
#define _APS_NEXT_CONTROL_VALUE 1016
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
|
|
@ -123,7 +123,6 @@ static bool GetConfigFullName(const char *basename, char *fullname, size_t fulln
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void StopTunsafeBackend(UpdateIconWhy why) {
|
||||
if (g_backend->is_started()) {
|
||||
g_backend->Stop();
|
||||
|
@ -916,20 +915,25 @@ static void HandleClickedItem(HWND hWnd, int wParam) {
|
|||
case IDSETT_BLOCKINTERNET_FIREWALL:
|
||||
case IDSETT_BLOCKINTERNET_BOTH:
|
||||
{
|
||||
InternetBlockState old_state = g_backend->GetInternetBlockState(NULL);
|
||||
InternetBlockState new_state = (InternetBlockState)(wParam - IDSETT_BLOCKINTERNET_OFF);
|
||||
uint32 old_state = g_backend->GetInternetBlockState(NULL);
|
||||
uint32 new_state = wParam - IDSETT_BLOCKINTERNET_OFF;
|
||||
|
||||
if (old_state == kBlockInternet_Off && new_state != kBlockInternet_Off) {
|
||||
if (MessageBoxA(g_ui_window, "Warning! All Internet traffic will be blocked until you restart your computer. Only traffic through TunSafe will be allowed.\r\n\r\nThe blocking is activated the next time you connect to a VPN server.\r\n\r\nDo you want to continue?", "TunSafe", MB_ICONWARNING | MB_OKCANCEL) == IDCANCEL)
|
||||
if ((old_state & kBlockInternet_Both) == kBlockInternet_Off && new_state != kBlockInternet_Off) {
|
||||
if (MessageBoxA(g_ui_window, "Warning! All Internet traffic will be blocked while TunSafe is active. Only traffic through TunSafe will be allowed.\r\n\r\nThe blocking is activated the next time TunSafe connects.\r\n\r\nDo you want to continue?", "TunSafe", MB_ICONWARNING | MB_OKCANCEL) == IDCANCEL)
|
||||
return;
|
||||
}
|
||||
|
||||
g_backend->SetInternetBlockState(new_state);
|
||||
g_backend->SetInternetBlockState((InternetBlockState)(new_state | (old_state & kBlockInternet_BlockOnDisconnect)));
|
||||
|
||||
if ((~old_state & new_state) && g_backend->is_started())
|
||||
StartTunsafeBackend(UIW_START);
|
||||
return;
|
||||
}
|
||||
case IDSETT_BLOCKINTERNET_DISCONN: {
|
||||
uint32 old_state = g_backend->GetInternetBlockState(NULL);
|
||||
g_backend->SetInternetBlockState((InternetBlockState)(old_state ^ kBlockInternet_BlockOnDisconnect));
|
||||
return;
|
||||
}
|
||||
|
||||
case IDSETT_SERVICE_OFF:
|
||||
case IDSETT_SERVICE_FOREGROUND:
|
||||
case IDSETT_SERVICE_BACKGROUND:
|
||||
|
@ -1034,9 +1038,9 @@ static INT_PTR WINAPI DlgProc(HWND hWnd, UINT message, WPARAM wParam,
|
|||
|
||||
bool is_activated = false;
|
||||
int value = g_backend->GetInternetBlockState(&is_activated);
|
||||
CheckMenuRadioItem(menu, IDSETT_BLOCKINTERNET_OFF, IDSETT_BLOCKINTERNET_BOTH, IDSETT_BLOCKINTERNET_OFF + value, MF_BYCOMMAND);
|
||||
CheckMenuRadioItem(menu, IDSETT_BLOCKINTERNET_OFF, IDSETT_BLOCKINTERNET_BOTH, IDSETT_BLOCKINTERNET_OFF + (value & kBlockInternet_Both), MF_BYCOMMAND);
|
||||
CheckMenuRadioItem(menu, IDSETT_SERVICE_OFF, IDSETT_SERVICE_BACKGROUND, IDSETT_SERVICE_OFF + (g_startup_flags & 3), MF_BYCOMMAND);
|
||||
|
||||
CheckMenuItem(menu, IDSETT_BLOCKINTERNET_DISCONN, (value & kBlockInternet_BlockOnDisconnect) ? MF_CHECKED : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
10
wireguard.h
10
wireguard.h
|
@ -52,10 +52,12 @@ public:
|
|||
};
|
||||
|
||||
enum InternetBlockState {
|
||||
kBlockInternet_Off,
|
||||
kBlockInternet_Route,
|
||||
kBlockInternet_Firewall,
|
||||
kBlockInternet_Both,
|
||||
kBlockInternet_Off = 0,
|
||||
kBlockInternet_Route = 1,
|
||||
kBlockInternet_Firewall = 2,
|
||||
kBlockInternet_Both = 3,
|
||||
|
||||
kBlockInternet_BlockOnDisconnect = 16,
|
||||
|
||||
// An unspecified value that uses either route or firewall
|
||||
kBlockInternet_DefaultOn = 254,
|
||||
|
|
Loading…
Reference in a new issue