From 936798aefe227d2f98f2963a2752a02b203f9131 Mon Sep 17 00:00:00 2001 From: Odd Stranne Date: Tue, 7 May 2019 12:57:08 +0200 Subject: firewall: add permitHyperV() Signed-off-by: Odd Stranne --- service/firewall/blocker.go | 5 +++ service/firewall/rules.go | 73 +++++++++++++++++++++++++++++++++++++++ service/firewall/types_windows.go | 30 ++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/service/firewall/blocker.go b/service/firewall/blocker.go index b796aa7f..5e1fdab0 100644 --- a/service/firewall/blocker.go +++ b/service/firewall/blocker.go @@ -147,6 +147,11 @@ func EnableFirewall(luid uint64, restrictDNS bool, restrictAll bool) error { if err != nil { return wrapErr(err) } + + err = permitHyperV(session, baseObjects, 15) + if err != nil { + return wrapErr(err) + } } if restrictDNS { diff --git a/service/firewall/rules.go b/service/firewall/rules.go index cb920461..392c6b0c 100644 --- a/service/firewall/rules.go +++ b/service/firewall/rules.go @@ -7,6 +7,7 @@ package firewall import ( "golang.org/x/sys/windows" + "golang.zx2c4.com/wireguard/windows/version" "os" "unsafe" ) @@ -850,6 +851,78 @@ func permitNdp(session uintptr, baseObjects *baseObjects, weight uint8) error { return nil } +func permitHyperV(session uintptr, baseObjects *baseObjects, weight uint8) error { + // + // Only applicable on Win8+ + // + { + v, err := version.OsVersion() + if err != nil { + panic(err) + } + + win8plus := v.MajorVersion > 6 || (v.MajorVersion == 6 && v.MinorVersion >= 3) + + if !win8plus { + return nil + } + } + + condition := wtFwpmFilterCondition0{ + fieldKey: cFWPM_CONDITION_L2_FLAGS, + matchType: cFWP_MATCH_EQUAL, + conditionValue: wtFwpConditionValue0{ + _type: cFWP_UINT32, + value: uintptr(cFWP_CONDITION_L2_IS_VM2VM), + }, + } + + filter := wtFwpmFilter0{ + providerKey: &baseObjects.provider, + subLayerKey: baseObjects.filters, + weight: filterWeight(weight), + numFilterConditions: 1, + filterCondition: (*wtFwpmFilterCondition0)(unsafe.Pointer(&condition)), + action: wtFwpmAction0{ + _type: cFWP_ACTION_PERMIT, + }, + } + + filterId := uint64(0) + + { + displayData, err := createWtFwpmDisplayData0("Permit Hyper-V => Hyper-V outbound", "") + if err != nil { + return wrapErr(err) + } + + filter.displayData = *displayData + filter.layerKey = cFWPM_LAYER_OUTBOUND_MAC_FRAME_NATIVE + + err = fwpmFilterAdd0(session, &filter, 0, &filterId) + if err != nil { + return wrapErr(err) + } + } + + { + displayData, err := createWtFwpmDisplayData0("Permit Hyper-V => Hyper-V inbound", "") + if err != nil { + return wrapErr(err) + } + + filter.displayData = *displayData + filter.layerKey = cFWPM_LAYER_INBOUND_MAC_FRAME_NATIVE + + err = fwpmFilterAdd0(session, &filter, 0, &filterId) + if err != nil { + return wrapErr(err) + } + } + + return nil +} + // Block all traffic except what is explicitly permitted by other rules. func blockAll(session uintptr, baseObjects *baseObjects, weight uint8) error { filter := wtFwpmFilter0{ diff --git a/service/firewall/types_windows.go b/service/firewall/types_windows.go index 3b710f35..9be4d722 100644 --- a/service/firewall/types_windows.go +++ b/service/firewall/types_windows.go @@ -162,6 +162,20 @@ var cFWPM_CONDITION_IP_LOCAL_ADDRESS = windows.GUID{ var cFWPM_CONDITION_ICMP_TYPE = cFWPM_CONDITION_IP_LOCAL_PORT var cFWPM_CONDITION_ICMP_CODE = cFWPM_CONDITION_IP_REMOTE_PORT +// 7bc43cbf-37ba-45f1-b74a-82ff518eeb10 +var cFWPM_CONDITION_L2_FLAGS = windows.GUID{ + Data1: 0x7bc43cbf, + Data2: 0x37ba, + Data3: 0x45f1, + Data4: [8]byte{0xb7, 0x4a, 0x82, 0xff, 0x51, 0x8e, 0xeb, 0x10}, +} + +type wtFwpmL2Flags uint32 + +const ( + cFWP_CONDITION_L2_IS_VM2VM wtFwpmL2Flags = 0x00000010 +) + // Defined in fwpmtypes.h type wtFwpmFilterFlags uint32 @@ -213,6 +227,22 @@ var cFWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6 = windows.GUID{ Data4: [8]byte{0xb8, 0x7e, 0xce, 0xe9, 0xc4, 0x83, 0x25, 0x7f}, } +// 94c44912-9d6f-4ebf-b995-05ab8a088d1b +var cFWPM_LAYER_OUTBOUND_MAC_FRAME_NATIVE = windows.GUID{ + Data1: 0x94c44912, + Data2: 0x9d6f, + Data3: 0x4ebf, + Data4: [8]byte{0xb9, 0x95, 0x05, 0xab, 0x8a, 0x08, 0x8d, 0x1b}, +} + +// d4220bd3-62ce-4f08-ae88-b56e8526df50 +var cFWPM_LAYER_INBOUND_MAC_FRAME_NATIVE = windows.GUID{ + Data1: 0xd4220bd3, + Data2: 0x62ce, + Data3: 0x4f08, + Data4: [8]byte{0xae, 0x88, 0xb5, 0x6e, 0x85, 0x26, 0xdf, 0x50}, +} + // FWP_BITMAP_ARRAY64 defined in fwtypes.h type wtFwpBitmapArray64 struct { bitmapArray64 [8]uint8 // Windows type: [8]UINT8 -- cgit v1.2.3-59-g8ed1b