Skip to content

Commit

Permalink
Improve Windows firewall logging (#10162)
Browse files Browse the repository at this point in the history
* Add some extra error logging to Windows firewall
* Simplify firewall activation with a QScopeGuard
* A wee dash of lint
  • Loading branch information
oskirby authored Jan 6, 2025
1 parent 38d84b8 commit 8701d63
Showing 1 changed file with 63 additions and 53 deletions.
116 changes: 63 additions & 53 deletions src/platforms/windows/daemon/windowsfirewall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ bool WindowsFirewall::initSublayer() {
logger.debug() << "Opening the filter engine";
result = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &wfp);
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmEngineOpen0 failed. Return value:.\n" << result;
logger.error() << "FwpmEngineOpen0 failed:" << QString::number(result, 16);
return false;
}
auto cleanup = qScopeGuard([&] { FwpmEngineClose0(wfp); });
Expand All @@ -128,8 +128,8 @@ bool WindowsFirewall::initSublayer() {
// Step 1: Start Transaction
result = FwpmTransactionBegin(wfp, NULL);
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmTransactionBegin0 failed. Return value:.\n"
<< result;
logger.error() << "FwpmTransactionBegin0 failed:"
<< QString::number(result, 16);
return false;
}

Expand All @@ -144,59 +144,66 @@ bool WindowsFirewall::initSublayer() {

result = FwpmSubLayerAdd0(wfp, &subLayer, NULL);
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmSubLayerAdd0 failed. Return value:.\n" << result;
logger.error() << "FwpmSubLayerAdd0 failed:" << QString::number(result, 16);
return false;
}
// Step 4: Commit!
result = FwpmTransactionCommit0(wfp);
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmTransactionCommit0 failed. Return value:.\n"
<< result;
logger.error() << "FwpmTransactionCommit0 failed:"
<< QString::number(result, 16);
return false;
}
logger.debug() << "Initialised Sublayer";
return true;
}

bool WindowsFirewall::enableInterface(int vpnAdapterIndex) {
// Checks if the FW_Rule was enabled succesfully,
// disables the whole killswitch and returns false if not.
#define FW_OK(rule) \
{ \
auto result = FwpmTransactionBegin(m_sessionHandle, NULL); \
if (result != ERROR_SUCCESS) { \
disableKillSwitch(); \
return false; \
} \
if (!rule) { \
FwpmTransactionAbort0(m_sessionHandle); \
disableKillSwitch(); \
return false; \
} \
result = FwpmTransactionCommit0(m_sessionHandle); \
if (result != ERROR_SUCCESS) { \
logger.error() << "FwpmTransactionCommit0 failed. Return value:.\n" \
<< result; \
return false; \
} \
logger.info() << "Enabling firewall Using Adapter:" << vpnAdapterIndex;
DWORD result = FwpmTransactionBegin(m_sessionHandle, NULL);
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmTransactionBegin0 failed:"
<< QString::number(result, 16);
disableKillSwitch();
return false;
}
auto guard = qScopeGuard([&] { FwpmTransactionAbort0(m_sessionHandle); });

logger.info() << "Enabling firewall Using Adapter:" << vpnAdapterIndex;
FW_OK(allowTrafficOfAdapter(vpnAdapterIndex, MED_WEIGHT,
"Allow usage of VPN Adapter"));
FW_OK(allowDHCPTraffic(MED_WEIGHT, "Allow DHCP Traffic"));
FW_OK(allowHyperVTraffic(MED_WEIGHT, "Allow Hyper-V Traffic"));
FW_OK(allowTrafficForAppOnAll(getCurrentPath(), MAX_WEIGHT,
"Allow all for Mozilla VPN.exe"));
FW_OK(allowTrafficForAppOnAll(getProxyPath(), MAX_WEIGHT,
"Allow all for socksproxy.exe"));
FW_OK(blockTrafficOnPort(53, MED_WEIGHT, "Block all DNS"));
FW_OK(
allowLoopbackTraffic(MED_WEIGHT, "Allow Loopback traffic on device %1"));
QString msg = "Allow usage of VPN Adapter";
if (!allowTrafficOfAdapter(vpnAdapterIndex, MED_WEIGHT, msg)) {
return false;
}
if (!allowDHCPTraffic(MED_WEIGHT, "Allow DHCP Traffic")) {
return false;
}
if (!allowHyperVTraffic(MED_WEIGHT, "Allow Hyper-V Traffic")) {
return false;
}
msg = "Allow all for Mozilla VPN.exe";
if (!allowTrafficForAppOnAll(getCurrentPath(), MAX_WEIGHT, msg)) {
return false;
}
msg = "Allow all for socksproxy.exe";
if (!allowTrafficForAppOnAll(getProxyPath(), MAX_WEIGHT, msg)) {
return false;
}
if (!blockTrafficOnPort(53, MED_WEIGHT, "Block all DNS")) {
return false;
}
msg = "Allow Loopback traffic on device %1";
if (!allowLoopbackTraffic(MED_WEIGHT, msg)) {
return false;
}

// Commit the transaction.
result = FwpmTransactionCommit0(m_sessionHandle);
if (result != ERROR_SUCCESS) {
logger.warning() << "Killswitch failed:" << QString::number(result, 16);
return false;
}
guard.dismiss();
logger.debug() << "Killswitch on! Rules:" << m_activeRules.length();
return true;
#undef FW_OK
}

// Allow unprotected traffic sent to the following local address ranges.
Expand All @@ -221,7 +228,8 @@ bool WindowsFirewall::enableLanBypass(const QList<IPAddress>& ranges) {

result = FwpmTransactionCommit0(m_sessionHandle);
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmTransactionCommit0 failed with error:" << result;
logger.error() << "FwpmTransactionCommit0 failed:"
<< QString::number(result, 16);
return false;
}

Expand Down Expand Up @@ -267,7 +275,8 @@ bool WindowsFirewall::enablePeerTraffic(const InterfaceConfig& config) {

result = FwpmTransactionCommit0(m_sessionHandle);
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmTransactionCommit0 failed with error:" << result;
logger.error() << "FwpmTransactionCommit0 failed:"
<< QString::number(result, 16);
return false;
}

Expand All @@ -283,8 +292,8 @@ bool WindowsFirewall::disablePeerTraffic(const QString& pubkey) {
}
});
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmTransactionBegin0 failed. Return value:.\n"
<< result;
logger.error() << "FwpmTransactionBegin0 failed:"
<< QString::number(result, 16);
return false;
}

Expand All @@ -297,8 +306,8 @@ bool WindowsFirewall::disablePeerTraffic(const QString& pubkey) {
// Commit!
result = FwpmTransactionCommit0(m_sessionHandle);
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmTransactionCommit0 failed. Return value:.\n"
<< result;
logger.error() << "FwpmTransactionCommit0 failed:"
<< QString::number(result, 16);
return false;
}
return true;
Expand All @@ -312,8 +321,8 @@ bool WindowsFirewall::disableKillSwitch() {
}
});
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmTransactionBegin0 failed. Return value:.\n"
<< result;
logger.error() << "FwpmTransactionBegin0 failed:"
<< QString::number(result, 16);
return false;
}

Expand All @@ -328,8 +337,8 @@ bool WindowsFirewall::disableKillSwitch() {
// Commit!
result = FwpmTransactionCommit0(m_sessionHandle);
if (result != ERROR_SUCCESS) {
logger.error() << "FwpmTransactionCommit0 failed. Return value:.\n"
<< result;
logger.error() << "FwpmTransactionCommit0 failed:"
<< QString::number(result, 16);
return false;
}
m_peerRules.clear();
Expand All @@ -351,7 +360,8 @@ bool WindowsFirewall::allowTrafficForAppOnAll(const QString& exePath,
FWP_BYTE_BLOB* appID = NULL;
result = FwpmGetAppIdFromFileName0(appPath, &appID);
if (result != ERROR_SUCCESS) {
WindowsUtils::windowsLog("FwpmGetAppIdFromFileName0 failure");
logger.warning() << "FwpmGetAppIdFromFileName0 failed:"
<< QString::number(result, 16);
return false;
}
auto guard = qScopeGuard([appID]() { FwpmFreeMemory0((void**)&appID); });
Expand Down Expand Up @@ -918,11 +928,11 @@ bool WindowsFirewall::enableFilter(FWPM_FILTER0* filter, const QString& title,
filter->displayData.description = (PWSTR)desc.c_str();
auto result = FwpmFilterAdd0(m_sessionHandle, filter, NULL, &filterID);
if (result != ERROR_SUCCESS) {
logger.error() << "Failed to enable filter: " << title << " "
<< description;
logger.error() << "Failed to enable filter:" << title << ":" << description;
logger.error() << "Error:" << QString::number(result, 16);
return false;
}
logger.info() << "Filter added: " << title << ":" << description;
logger.info() << "Filter added:" << title << ":" << description;
if (peer.isEmpty()) {
m_activeRules.append(filterID);
} else {
Expand Down

0 comments on commit 8701d63

Please sign in to comment.