The 'Kill Switch' option (used Mozilla VPN sources) is activated by default

This commit is contained in:
Fedotov Anton
2022-02-17 19:31:45 +03:00
parent 858537df1f
commit 7bc520819a
3 changed files with 112 additions and 42 deletions

View File

@@ -140,7 +140,7 @@ bool WindowsFirewall::init() {
FWPM_SUBLAYER0 subLayer;
memset(&subLayer, 0, sizeof(subLayer));
subLayer.subLayerKey = ST_FW_WINFW_BASELINE_SUBLAYER_KEY;
subLayer.displayData.name = (PWSTR)L"MozillaVPN-SplitTunnel-Sublayer";
subLayer.displayData.name = (PWSTR)L"AmneziaVPN-SplitTunnel-Sublayer";
subLayer.displayData.description =
(PWSTR)L"Filters that enforce a good baseline";
subLayer.weight = 0xFFFF;

View File

@@ -17,7 +17,7 @@ public:
qDebug()<<__FUNCTION__;
auto cf = WindowsFirewall::instance();
cf->init();
//cf->disableKillSwitch();
cf->disableKillSwitch();
}
~KillSwitch(){
qDebug()<<__FUNCTION__;
@@ -25,6 +25,7 @@ public:
cf->disableKillSwitch();
}
};
std::unique_ptr<KillSwitch>ks;
#endif
int runApplication(int argc, char** argv)
@@ -35,14 +36,13 @@ int runApplication(int argc, char** argv)
return app.exec();
}
int main(int argc, char **argv)
{
Utils::initializePath(Utils::systemLogPath());
Log::initialize();
#ifdef Q_OS_WIN
KillSwitch ks;
ks = std::make_unique<KillSwitch>();
#endif
if (argc == 2) {

View File

@@ -2,7 +2,7 @@
#ifdef Q_OS_WIN
#include "router_win.h"
#elif defined (Q_OS_MAC)
#elif defined(Q_OS_MAC)
#include "router_mac.h"
#elif defined Q_OS_LINUX
#include "router_linux.h"
@@ -11,77 +11,148 @@
#ifdef Q_OS_WIN
#include <QNetworkInterface>
#include "windowsfirewall.h"
//#include "netadpinfo.h"
#include <cstring>
namespace {
namespace
{
// TODO:FIXME try to get this constexpr variable from CORE code
constexpr char IKEV2[]{"AmneziaVPN IKEv2"};
constexpr char WG[]{"AmneziaVPN.WireGuard0"};
constexpr char OVPN[]{"TAP-Windows Adapter V9"};
constexpr char IKEV2[] {"AmneziaVPN IKEv2"};
constexpr char WG[] {"AmneziaVPN.WireGuard0"};
constexpr char OVPN[] {"TAP-Windows Adapter V9"};
bool is_eth_adapter_activated(char* ethName)
{
auto convert_wide_to_ansi = [](const std::wstring& widestring)->std::string{
auto nchars = WideCharToMultiByte(
CP_ACP,
0,
widestring.c_str(),
static_cast<int>(widestring.length() + 1),
nullptr,
0,
nullptr,
nullptr);
std::string converted_string{};
converted_string.resize(nchars);
WideCharToMultiByte(CP_ACP,
0,
widestring.c_str(),
-1,
&converted_string[0],
static_cast<int>(widestring.length()),
nullptr,
nullptr);
return converted_string;
};
bool get_eth_name(const QString &adp_name){
//char buff[128]{};
PIP_ADAPTER_INFO pAdapterInfo{};
pAdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof(IP_ADAPTER_INFO));
constexpr ULONG MAX_BUFFER_SIZE = 15000;
ULONG bufferSize = MAX_BUFFER_SIZE;
IP_ADAPTER_ADDRESSES *pAdapterAddresses = (IP_ADAPTER_ADDRESSES *)HeapAlloc(GetProcessHeap(), 0, bufferSize);
::GetAdaptersAddresses(AF_INET, 0, nullptr, pAdapterAddresses, &bufferSize);
do
{
const auto Descr = convert_wide_to_ansi(pAdapterAddresses->Description);
if (strcmp(ethName, Descr.data()) == 0) //the same
{
if (pAdapterAddresses->OperStatus == IfOperStatusUp){
return true;
}
}
if (pAdapterAddresses->Next != 0)
{
pAdapterAddresses = pAdapterAddresses->Next;
}
} while (pAdapterAddresses->Next != 0);
//::HeapFree(GetProcessHeap(), 0, pAdapterAddresses);
return false;
}
bool get_eth_name(const QString &adp_name)
{
IP_ADAPTER_INFO *pAdapterInfo{nullptr};
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
ULONG buflen = sizeof(IP_ADAPTER_INFO);
if(GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW)
if (GetAdaptersInfo(pAdapterInfo, &buflen) == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *)
malloc(buflen);
}
if(GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR) {
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter) {
qDebug()<<"Adapter Name: "<< pAdapter->AdapterName;
qDebug()<<"Adapter Desc: "<<pAdapter->Description;
if (adp_name == pAdapter->Description)
if (GetAdaptersInfo(pAdapterInfo, &buflen) == NO_ERROR)
{
IP_ADAPTER_INFO *pAdapter{pAdapterInfo};
if (pAdapter == nullptr)
return false;
while (pAdapter != nullptr)
{
const auto adp_acitvated = is_eth_adapter_activated(pAdapter->Description);
if (adp_name == pAdapter->Description && adp_acitvated){
qDebug() << "We will work with:";
qDebug() << "Adapter Name: " << pAdapter->AdapterName;
qDebug() << "Adapter Desc: " << pAdapter->Description;
qDebug() << "Adapter Index: " << pAdapter->Index;
qDebug() << "Adapter activated:"<<adp_acitvated;
free(pAdapterInfo);
return true;
}
pAdapter = pAdapter->Next;
}
}
free(pAdapterInfo);
return false;
}
void enable_killswitch(){
auto VPN_LIST = []()->int{
auto adapterList = QNetworkInterface::allInterfaces();
for (const auto& adapter : adapterList) {
void enable_killswitch()
{
auto VPN_LIST = []() -> int
{
const auto adapterList = QNetworkInterface::allInterfaces();
//qAsConst
for (const auto &adapter : adapterList)
{
bool finded{false};
finded = get_eth_name(OVPN);
if ( adapter.humanReadableName().contains(IKEV2) ||
if (adapter.humanReadableName().contains(IKEV2) ||
adapter.humanReadableName().contains(WG) ||
finded ||
adapter.humanReadableName().contains(OVPN)
) {
adapter.humanReadableName().contains(OVPN))
{
qDebug() << "Network adapter for 'kill switch' option finded: " << adapter.humanReadableName();
return adapter.index();
}
}
return -1;
};
const auto &current_vpn = VPN_LIST();
if (current_vpn != -1){
qInfo()<<"KillSwitch activated";
if (current_vpn != -1)
{
qInfo() << "KillSwitch option activated";
auto cf = WindowsFirewall::instance();
//cf->enableKillSwitch(current_vpn);
cf->disableKillSwitch();
}else{
qCritical().noquote() <<"No any adapters was found";
cf->enableKillSwitch(current_vpn);
}
else
{
// TODO::FIXME
qCritical().noquote() << "No any adapters was found, it's error";
}
}
}// end namespace
} // end namespace
#endif
// TODO::FIXME when wireguard is activated, the adapter will alaviable
// after a couple of seconds
#include <thread>
int Router::routeAddList(const QString &gw, const QStringList &ips)
{
#ifdef Q_OS_WIN
auto value = RouterWin::Instance().routeAddList(gw, ips);
// TODO::FIXME the next sleep is need only for wireguard
std::this_thread::sleep_for(std::chrono::seconds(5));
enable_killswitch();
return value;
//return RouterWin::Instance().routeAddList(gw, ips);
#elif defined (Q_OS_MAC)
// return RouterWin::Instance().routeAddList(gw, ips);
#elif defined(Q_OS_MAC)
return RouterMac::Instance().routeAddList(gw, ips);
#elif defined Q_OS_LINUX
return RouterLinux::Instance().routeAddList(gw, ips);
@@ -92,7 +163,7 @@ bool Router::clearSavedRoutes()
{
#ifdef Q_OS_WIN
return RouterWin::Instance().clearSavedRoutes();
#elif defined (Q_OS_MAC)
#elif defined(Q_OS_MAC)
return RouterMac::Instance().clearSavedRoutes();
#elif defined Q_OS_LINUX
return RouterLinux::Instance().clearSavedRoutes();
@@ -103,7 +174,7 @@ int Router::routeDeleteList(const QString &gw, const QStringList &ips)
{
#ifdef Q_OS_WIN
return RouterWin::Instance().routeDeleteList(gw, ips);
#elif defined (Q_OS_MAC)
#elif defined(Q_OS_MAC)
return RouterMac::Instance().routeDeleteList(gw, ips);
#elif defined Q_OS_LINUX
return RouterLinux::Instance().routeDeleteList(gw, ips);
@@ -114,7 +185,7 @@ void Router::flushDns()
{
#ifdef Q_OS_WIN
RouterWin::Instance().flushDns();
#elif defined (Q_OS_MAC)
#elif defined(Q_OS_MAC)
RouterMac::Instance().flushDns();
#elif defined Q_OS_LINUX
RouterLinux::Instance().flushDns();
@@ -125,10 +196,9 @@ void Router::resetIpStack()
{
#ifdef Q_OS_WIN
RouterWin::Instance().resetIpStack();
#elif defined (Q_OS_MAC)
#elif defined(Q_OS_MAC)
// todo fixme
#elif defined Q_OS_LINUX
// todo fixme
#endif
}