diff options
| -rw-r--r-- | windows/winfw/src/winfw/fwcontext.cpp | 11 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/rules/permittunneldns.cpp | 64 | ||||
| -rw-r--r-- | windows/winfw/src/winfw/rules/permittunneldns.h | 7 |
3 files changed, 55 insertions, 27 deletions
diff --git a/windows/winfw/src/winfw/fwcontext.cpp b/windows/winfw/src/winfw/fwcontext.cpp index bf7301a464..7b7c0d94c2 100644 --- a/windows/winfw/src/winfw/fwcontext.cpp +++ b/windows/winfw/src/winfw/fwcontext.cpp @@ -164,10 +164,17 @@ bool FwContext::applyPolicyConnected tunnelInterfaceAlias )); + std::vector<wfp::IpAddress> dnsHosts; + dnsHosts.push_back(wfp::IpAddress(v4DnsHost)); + + if (nullptr != v6DnsHost) + { + dnsHosts.push_back(wfp::IpAddress(v6DnsHost)); + } + ruleset.emplace_back(std::make_unique<rules::PermitTunnelDns>( tunnelInterfaceAlias, - wfp::IpAddress(v4DnsHost), - nullptr != v6DnsHost ? std::optional(wfp::IpAddress(v6DnsHost)) : std::nullopt + dnsHosts )); return applyRuleset(ruleset); diff --git a/windows/winfw/src/winfw/rules/permittunneldns.cpp b/windows/winfw/src/winfw/rules/permittunneldns.cpp index 1aafc15f99..57c1d39763 100644 --- a/windows/winfw/src/winfw/rules/permittunneldns.cpp +++ b/windows/winfw/src/winfw/rules/permittunneldns.cpp @@ -22,38 +22,54 @@ namespace rules PermitTunnelDns::PermitTunnelDns( const std::wstring &tunnelInterfaceAlias, - const wfp::IpAddress v4DnsHost, - const std::optional<wfp::IpAddress> v6DnsHost + const std::vector<wfp::IpAddress> &dnsHosts ) : m_tunnelInterfaceAlias(tunnelInterfaceAlias) - , m_v4DnsHost(v4DnsHost) - , m_v6DnsHost(v6DnsHost) { - + for (const auto &host : dnsHosts) + { + if (wfp::IpAddress::Ipv4 == host.type()) + { + m_v4DnsHosts.push_back(host); + } + else + { + m_v6DnsHosts.push_back(host); + } + } } bool PermitTunnelDns::apply(IObjectInstaller &objectInstaller) { // - // Permit outbound DNS traffic to a specific DNS server (IPv4) + // Permit outbound DNS traffic to specific servers (IPv4) // wfp::FilterBuilder filterBuilder; filterBuilder .provider(MullvadGuids::Provider()) - .key(MullvadGuids::FilterPermitTunnelDns_Ipv4()) - .name(L"Permit outbound DNS traffic on tunnel interface (IPv4)") .description(L"This filter is part of a rule that permits DNS traffic inside the VPN tunnel") - .layer(FWPM_LAYER_ALE_AUTH_CONNECT_V4) .sublayer(MullvadGuids::SublayerWhitelist()) .weight(wfp::FilterBuilder::WeightClass::Max) .permit(); + if (!m_v4DnsHosts.empty()) { + filterBuilder + .key(MullvadGuids::FilterPermitTunnelDns_Ipv4()) + .name(L"Permit select outbound DNS traffic on tunnel interface (IPv4)") + .layer(FWPM_LAYER_ALE_AUTH_CONNECT_V4); + wfp::ConditionBuilder conditionBuilder(FWPM_LAYER_ALE_AUTH_CONNECT_V4); conditionBuilder.add_condition(ConditionInterface::Alias(m_tunnelInterfaceAlias)); - conditionBuilder.add_condition(ConditionIp::Remote(m_v4DnsHost)); + + for (const auto &host : m_v4DnsHosts) + { + // Multiple conditions of same type are OR'ed + conditionBuilder.add_condition(ConditionIp::Remote(host)); + } + conditionBuilder.add_condition(ConditionPort::Remote(DNS_PORT)); if (!objectInstaller.addFilter(filterBuilder, conditionBuilder)) @@ -63,28 +79,34 @@ bool PermitTunnelDns::apply(IObjectInstaller &objectInstaller) } // - // Permit outbound DNS traffic to a specific DNS server (IPv6) + // Permit outbound DNS traffic to specific servers (IPv6) // - if (m_v6DnsHost.has_value()) + if (!m_v6DnsHosts.empty()) { filterBuilder .key(MullvadGuids::FilterPermitTunnelDns_Ipv6()) - .name(L"Permit outbound DNS traffic on tunnel interface (IPv6)") + .name(L"Permit select outbound DNS traffic on tunnel interface (IPv6)") .layer(FWPM_LAYER_ALE_AUTH_CONNECT_V6); - { - wfp::ConditionBuilder conditionBuilder(FWPM_LAYER_ALE_AUTH_CONNECT_V6); - - conditionBuilder.add_condition(ConditionInterface::Alias(m_tunnelInterfaceAlias)); - conditionBuilder.add_condition(ConditionIp::Remote(m_v6DnsHost.value())); - conditionBuilder.add_condition(ConditionPort::Remote(DNS_PORT)); + wfp::ConditionBuilder conditionBuilder(FWPM_LAYER_ALE_AUTH_CONNECT_V6); + conditionBuilder.add_condition(ConditionInterface::Alias(m_tunnelInterfaceAlias)); - if (!objectInstaller.addFilter(filterBuilder, conditionBuilder)) + for (const auto &host : m_v6DnsHosts) + { + // Multiple conditions of same type are OR'ed + if (wfp::IpAddress::Ipv6 == host.type()) { - return false; + conditionBuilder.add_condition(ConditionIp::Remote(host)); } } + + conditionBuilder.add_condition(ConditionPort::Remote(DNS_PORT)); + + if (!objectInstaller.addFilter(filterBuilder, conditionBuilder)) + { + return false; + } } return true; diff --git a/windows/winfw/src/winfw/rules/permittunneldns.h b/windows/winfw/src/winfw/rules/permittunneldns.h index 6c3baab25f..eec22b0924 100644 --- a/windows/winfw/src/winfw/rules/permittunneldns.h +++ b/windows/winfw/src/winfw/rules/permittunneldns.h @@ -2,7 +2,6 @@ #include "ifirewallrule.h" #include "libwfp/ipaddress.h" -#include <optional> #include <string> #include <cstdint> @@ -13,15 +12,15 @@ class PermitTunnelDns : public IFirewallRule { public: - PermitTunnelDns::PermitTunnelDns(const std::wstring &tunnelInterfaceAlias, const wfp::IpAddress v4DnsHost, const std::optional<wfp::IpAddress> v6DnsHost); + PermitTunnelDns(const std::wstring &tunnelInterfaceAlias, const std::vector<wfp::IpAddress> &dnsHosts); bool apply(IObjectInstaller &objectInstaller) override; private: const std::wstring m_tunnelInterfaceAlias; - const wfp::IpAddress m_v4DnsHost; - const std::optional<wfp::IpAddress> m_v6DnsHost; + std::vector<wfp::IpAddress> m_v4DnsHosts; + std::vector<wfp::IpAddress> m_v6DnsHosts; }; |
