Add VPN detection by mac-address for Windows

This patch adds VPN detection for windows
based on known MAC addresses.
- Cisco AnyConnect
- GlobalProtect Virtual Ethernet

Bug: webrtc:13097
Change-Id: Ia90ee50be0dc2dcd2e6e9de1493fdd2c5e7d9d3a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/230245
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#34997}
This commit is contained in:
Jonas Oreland 2021-08-27 09:43:38 +02:00 committed by WebRTC LUCI CQ
parent 225cd47445
commit ac554ebbc5
3 changed files with 51 additions and 0 deletions

View file

@ -40,6 +40,14 @@
namespace rtc {
namespace {
// List of MAC addresses of known VPN (for windows).
constexpr uint8_t kVpns[2][6] = {
// Cisco AnyConnect.
{0x0, 0x5, 0x9A, 0x3C, 0x7A, 0x0},
// GlobalProtect Virtual Ethernet.
{0x2, 0x50, 0x41, 0x0, 0x0, 0x1},
};
const uint32_t kUpdateNetworksMessage = 1;
const uint32_t kSignalNetworksMessage = 2;
@ -486,6 +494,20 @@ Network* NetworkManagerBase::GetNetworkFromAddress(
return nullptr;
}
bool NetworkManagerBase::IsVpnMacAddress(
rtc::ArrayView<const uint8_t> address) {
if (address.data() == nullptr && address.size() == 0) {
return false;
}
for (const auto& vpn : kVpns) {
if (sizeof(vpn) == address.size() &&
memcmp(vpn, address.data(), address.size()) == 0) {
return true;
}
}
return false;
}
BasicNetworkManager::BasicNetworkManager() : BasicNetworkManager(nullptr) {}
BasicNetworkManager::BasicNetworkManager(
@ -781,6 +803,15 @@ bool BasicNetworkManager::CreateNetworks(bool include_ignored,
vpn_underlying_adapter_type = adapter_type;
adapter_type = ADAPTER_TYPE_VPN;
}
if (adapter_type != ADAPTER_TYPE_VPN &&
IsVpnMacAddress(rtc::ArrayView<const uint8_t>(
reinterpret_cast<const uint8_t*>(
adapter_addrs->PhysicalAddress),
adapter_addrs->PhysicalAddressLength))) {
vpn_underlying_adapter_type = adapter_type;
adapter_type = ADAPTER_TYPE_VPN;
}
std::unique_ptr<Network> network(new Network(
name, description, prefix, prefix_length, adapter_type));
network->set_underlying_type_for_vpn(vpn_underlying_adapter_type);

View file

@ -19,6 +19,7 @@
#include <string>
#include <vector>
#include "api/array_view.h"
#include "api/sequence_checker.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/mdns_responder_interface.h"
@ -194,6 +195,10 @@ class RTC_EXPORT NetworkManagerBase : public NetworkManager {
bool GetDefaultLocalAddress(int family, IPAddress* ipaddr) const override;
// Check if MAC address in |bytes| is one of the pre-defined
// MAC addresses for know VPNs.
static bool IsVpnMacAddress(rtc::ArrayView<const uint8_t> address);
protected:
typedef std::map<std::string, Network*> NetworkMap;
// Updates `networks_` with the networks listed in `list`. If

View file

@ -1434,4 +1434,19 @@ TEST_F(NetworkTest, VpnListOverrideAdapterType) {
}
#endif // defined(WEBRTC_POSIX)
TEST_F(NetworkTest, HardcodedVpn) {
const uint8_t cisco[] = {0x0, 0x5, 0x9A, 0x3C, 0x7A, 0x0};
const uint8_t global[] = {0x2, 0x50, 0x41, 0x0, 0x0, 0x1};
const uint8_t unknown[] = {0x2, 0x50, 0x41, 0x0, 0x0, 0x0};
const uint8_t five_bytes[] = {0x2, 0x50, 0x41, 0x0, 0x0};
EXPECT_TRUE(NetworkManagerBase::IsVpnMacAddress(cisco));
EXPECT_TRUE(NetworkManagerBase::IsVpnMacAddress(global));
EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress(
rtc::ArrayView<const uint8_t>(cisco, 5)));
EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress(five_bytes));
EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress(unknown));
EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress(nullptr));
}
} // namespace rtc