aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-08-20 15:12:02 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-08-20 15:12:02 +0200
commita352bde85d5d3790ac869c5d0a58de68f60cf5fc (patch)
tree6b49160afe90760872dfb7889d85acc53fd41b1b
parentwintun: also set friendly name after setting interface name (diff)
downloadwireguard-go-jd/friendlynametrick.tar.xz
wireguard-go-jd/friendlynametrick.zip
WIP: set friendly name with reversed keyjd/friendlynametrick
-rw-r--r--tun/wintun/setupapi/setupapi_windows.go18
-rw-r--r--tun/wintun/setupapi/types_windows.go52
-rw-r--r--tun/wintun/setupapi/zsetupapi_windows.go13
-rw-r--r--tun/wintun/wintun_windows.go74
4 files changed, 111 insertions, 46 deletions
diff --git a/tun/wintun/setupapi/setupapi_windows.go b/tun/wintun/setupapi/setupapi_windows.go
index 60a8eb7..2901e42 100644
--- a/tun/wintun/setupapi/setupapi_windows.go
+++ b/tun/wintun/setupapi/setupapi_windows.go
@@ -332,6 +332,24 @@ func (deviceInfoSet DevInfo) SetDeviceRegistryPropertyString(deviceInfoData *Dev
return err
}
+//sys setupDiSetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, propertyKey *DevPropKey, propertyType DevPropType, propertyBuffer *byte, propertyBufferSize uint32, flags uint32) (err error) = setupapi.SetupDiSetDevicePropertyW
+
+// SetupDiSetDeviceProperty function sets a Plug and Play device property for a device.
+func SetupDiSetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, propertyKey *DevPropKey, propertyType DevPropType, propertyBuffers []byte) error {
+ return setupDiSetDeviceProperty(deviceInfoSet, deviceInfoData, propertyKey, propertyType, &propertyBuffers[0], uint32(len(propertyBuffers)), 0)
+}
+
+// SetDevicePropertyString method sets a Plug and Play device property string for a device.
+func (deviceInfoSet DevInfo) SetDevicePropertyString(deviceInfoData *DevInfoData, propertyKey *DevPropKey, str string) error {
+ str16, err := windows.UTF16FromString(str)
+ if err != nil {
+ return err
+ }
+ err = setupDiSetDeviceProperty(deviceInfoSet, deviceInfoData, propertyKey, DEVPROP_TYPE_STRING, (*byte)(unsafe.Pointer(&str16[0])), uint32(len(str16) * 2), 0)
+ runtime.KeepAlive(str16)
+ return err
+}
+
//sys setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) = setupapi.SetupDiGetDeviceInstallParamsW
// SetupDiGetDeviceInstallParams function retrieves device installation parameters for a device information set or a particular device information element.
diff --git a/tun/wintun/setupapi/types_windows.go b/tun/wintun/setupapi/types_windows.go
index 136b4be..adff625 100644
--- a/tun/wintun/setupapi/types_windows.go
+++ b/tun/wintun/setupapi/types_windows.go
@@ -566,3 +566,55 @@ const (
CM_GET_DEVICE_INTERFACE_LIST_PRESENT = 0 // only currently 'live' device interfaces
CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES = 1 // all registered device interfaces, live or not
)
+
+type DevPropKey struct {
+ FmtID windows.GUID
+ PID uint32
+}
+
+type DevPropType uint32
+
+const (
+ // Property type modifiers. Used to modify base DEVPROP_TYPE_ values, as
+ // appropriate. Not valid as standalone DEVPROPTYPE values.
+ DEVPROP_TYPEMOD_ARRAY = 0x00001000 // array of fixed-sized data elements
+ DEVPROP_TYPEMOD_LIST = 0x00002000 // list of variable-sized data elements
+
+ // Property data types.
+ DEVPROP_TYPE_EMPTY = 0x00000000 // nothing, no property data
+ DEVPROP_TYPE_NULL = 0x00000001 // null property data
+ DEVPROP_TYPE_SBYTE = 0x00000002 // 8-bit signed int (SBYTE)
+ DEVPROP_TYPE_BYTE = 0x00000003 // 8-bit unsigned int (BYTE)
+ DEVPROP_TYPE_INT16 = 0x00000004 // 16-bit signed int (SHORT)
+ DEVPROP_TYPE_UINT16 = 0x00000005 // 16-bit unsigned int (USHORT)
+ DEVPROP_TYPE_INT32 = 0x00000006 // 32-bit signed int (LONG)
+ DEVPROP_TYPE_UINT32 = 0x00000007 // 32-bit unsigned int (ULONG)
+ DEVPROP_TYPE_INT64 = 0x00000008 // 64-bit signed int (LONG64)
+ DEVPROP_TYPE_UINT64 = 0x00000009 // 64-bit unsigned int (ULONG64)
+ DEVPROP_TYPE_FLOAT = 0x0000000A // 32-bit floating-point (FLOAT)
+ DEVPROP_TYPE_DOUBLE = 0x0000000B // 64-bit floating-point (DOUBLE)
+ DEVPROP_TYPE_DECIMAL = 0x0000000C // 128-bit data (DECIMAL)
+ DEVPROP_TYPE_GUID = 0x0000000D // 128-bit unique identifier (GUID)
+ DEVPROP_TYPE_CURRENCY = 0x0000000E // 64 bit signed int currency value (CURRENCY)
+ DEVPROP_TYPE_DATE = 0x0000000F // date (DATE)
+ DEVPROP_TYPE_FILETIME = 0x00000010 // file time (FILETIME)
+ DEVPROP_TYPE_BOOLEAN = 0x00000011 // 8-bit boolean (DEVPROP_BOOLEAN)
+ DEVPROP_TYPE_STRING = 0x00000012 // null-terminated string
+ DEVPROP_TYPE_STRING_LIST = DEVPROP_TYPE_STRING | DEVPROP_TYPEMOD_LIST // multi-sz string list
+ DEVPROP_TYPE_SECURITY_DESCRIPTOR = 0x00000013 // self-relative binary SECURITY_DESCRIPTOR
+ DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING = 0x00000014 // security descriptor string (SDDL format)
+ DEVPROP_TYPE_DEVPROPKEY = 0x00000015 // device property key (DEVPROPKEY)
+ DEVPROP_TYPE_DEVPROPTYPE = 0x00000016 // device property type (DEVPROPTYPE)
+ DEVPROP_TYPE_BINARY = DEVPROP_TYPE_BYTE | DEVPROP_TYPEMOD_ARRAY // custom binary data
+ DEVPROP_TYPE_ERROR = 0x00000017 // 32-bit Win32 system error code
+ DEVPROP_TYPE_NTSTATUS = 0x00000018 // 32-bit NTSTATUS code
+ DEVPROP_TYPE_STRING_INDIRECT = 0x00000019 // string resource (@[path\]<dllname>,-<strId>)
+
+ // Max base DEVPROP_TYPE_ and DEVPROP_TYPEMOD_ values.
+ MAX_DEVPROP_TYPE = 0x00000019 // max valid DEVPROP_TYPE_ value
+ MAX_DEVPROP_TYPEMOD = 0x00002000 // max valid DEVPROP_TYPEMOD_ value
+
+ // Bitmasks for extracting DEVPROP_TYPE_ and DEVPROP_TYPEMOD_ values.
+ DEVPROP_MASK_TYPE = 0x00000FFF // range for base DEVPROP_TYPE_ values
+ DEVPROP_MASK_TYPEMOD = 0x0000F000 // mask for DEVPROP_TYPEMOD_ type modifiers
+)
diff --git a/tun/wintun/setupapi/zsetupapi_windows.go b/tun/wintun/setupapi/zsetupapi_windows.go
index 375862d..d1cedde 100644
--- a/tun/wintun/setupapi/zsetupapi_windows.go
+++ b/tun/wintun/setupapi/zsetupapi_windows.go
@@ -57,6 +57,7 @@ var (
procSetupDiOpenDevRegKey = modsetupapi.NewProc("SetupDiOpenDevRegKey")
procSetupDiGetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiGetDeviceRegistryPropertyW")
procSetupDiSetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiSetDeviceRegistryPropertyW")
+ procSetupDiSetDevicePropertyW = modsetupapi.NewProc("SetupDiSetDevicePropertyW")
procSetupDiGetDeviceInstallParamsW = modsetupapi.NewProc("SetupDiGetDeviceInstallParamsW")
procSetupDiGetDeviceInstanceIdW = modsetupapi.NewProc("SetupDiGetDeviceInstanceIdW")
procSetupDiGetClassInstallParamsW = modsetupapi.NewProc("SetupDiGetClassInstallParamsW")
@@ -277,6 +278,18 @@ func setupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *Dev
return
}
+func setupDiSetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, propertyKey *DevPropKey, propertyType DevPropType, propertyBuffer *byte, propertyBufferSize uint32, flags uint32) (err error) {
+ r1, _, e1 := syscall.Syscall9(procSetupDiSetDevicePropertyW.Addr(), 7, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(propertyKey)), uintptr(propertyType), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(flags), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
func setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) {
r1, _, e1 := syscall.Syscall(procSetupDiGetDeviceInstallParamsW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams)))
if r1 == 0 {
diff --git a/tun/wintun/wintun_windows.go b/tun/wintun/wintun_windows.go
index 4bf17e6..8de5f8e 100644
--- a/tun/wintun/wintun_windows.go
+++ b/tun/wintun/wintun_windows.go
@@ -30,6 +30,14 @@ type Wintun struct {
var deviceClassNetGUID = windows.GUID{Data1: 0x4d36e972, Data2: 0xe325, Data3: 0x11ce, Data4: [8]byte{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}
var deviceInterfaceNetGUID = windows.GUID{Data1: 0xcac88484, Data2: 0x7515, Data3: 0x4c03, Data4: [8]byte{0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61}}
+var netSetupPKeyDriverFriendlyName = setupapi.DevPropKey{ // Reverse engineered from NetSetupEngine.dll
+ FmtID: windows.GUID{Data1: 0xa111f1f0, Data2: 0x5923, Data3: 0x47c0, Data4: [8]byte{0x9a, 0x68, 0xd0, 0xba, 0xfb, 0x57, 0x79, 0x01}},
+ PID: 6,
+}
+var netSetupPKeyDriverDescription = setupapi.DevPropKey{ // Reverse engineered from NetSetupEngine.dll
+ FmtID: windows.GUID{Data1: 0xa111f1f0, Data2: 0x5923, Data3: 0x47c0, Data4: [8]byte{0x9a, 0x68, 0xd0, 0xba, 0xfb, 0x57, 0x79, 0x01}},
+ PID: 8,
+}
const (
deviceTypeName = "WireGuard Tunnel"
@@ -316,6 +324,18 @@ func CreateInterface(description string, requestedGUID *windows.GUID) (wintun *W
}
rebootRequired = checkReboot(devInfoList, deviceData)
+ err = devInfoList.SetDeviceRegistryPropertyString(deviceData, setupapi.SPDRP_DEVICEDESC, deviceTypeName)
+ if err != nil {
+ err = fmt.Errorf("SetupDiSetDeviceRegistryProperty(SPDRP_DEVICEDESC) failed: %v", err)
+ return
+ }
+
+ err = devInfoList.SetDevicePropertyString(deviceData, &netSetupPKeyDriverFriendlyName, deviceTypeName)
+ if err != nil {
+ err = fmt.Errorf("SetDevicePropertyString(NETSETUPPKEY_Driver_FriendlyName) failed: %v", err)
+ return
+ }
+
// DIF_INSTALLDEVICE returns almost immediately, while the device installation
// continues in the background. It might take a while, before all registry
// keys and values are populated.
@@ -342,24 +362,6 @@ func CreateInterface(description string, requestedGUID *windows.GUID) (wintun *W
return
}
- // Name ourselves.
- deviceRegKey, err := registry.OpenKey(registry.LOCAL_MACHINE, wintun.deviceRegKeyName(), registry.SET_VALUE)
- if err != nil {
- err = fmt.Errorf("Device-level registry key open failed: %v", err)
- return
- }
- defer deviceRegKey.Close()
- err = deviceRegKey.SetStringValue("DeviceDesc", deviceTypeName)
- if err != nil {
- err = fmt.Errorf("SetStringValue(DeviceDesc) failed: %v", err)
- return
- }
- err = deviceRegKey.SetStringValue("FriendlyName", deviceTypeName)
- if err != nil {
- err = fmt.Errorf("SetStringValue(FriendlyName) failed: %v", err)
- return
- }
-
// Wait for network registry key to emerge and populate.
netRegKey, err := registryEx.OpenKeyWait(
registry.LOCAL_MACHINE,
@@ -563,34 +565,19 @@ func (wintun *Wintun) InterfaceName() (string, error) {
// SetInterfaceName sets name of the Wintun interface.
func (wintun *Wintun) SetInterfaceName(ifname string) error {
- netRegKey, err := registry.OpenKey(registry.LOCAL_MACHINE, wintun.netRegKeyName(), registry.SET_VALUE)
- if err != nil {
- return fmt.Errorf("Network-specific registry key open failed: %v", err)
- }
- defer netRegKey.Close()
- err = netRegKey.SetStringValue("Name", ifname)
- if err != nil {
- return err
- }
- deviceRegKey, err := registry.OpenKey(registry.LOCAL_MACHINE, wintun.deviceRegKeyName(), registry.SET_VALUE)
- if err != nil {
- return fmt.Errorf("Device-level registry key open failed: %v", err)
- }
- defer deviceRegKey.Close()
- err = deviceRegKey.SetStringValue("DeviceDesc", deviceTypeName)
- if err != nil {
- return err
- }
- err = deviceRegKey.SetStringValue("FriendlyName", deviceTypeName)
- if err != nil {
- return err
- }
// We have to tell the various runtime COM services about the new name too. We ignore the
// error because netshell isn't available on servercore.
// TODO: netsh.exe falls back to NciSetConnection in this case. If somebody complains, maybe
// we should do the same.
netshell.HrRenameConnection(&wintun.cfgInstanceID, windows.StringToUTF16Ptr(ifname))
- return nil
+
+ // Set the interface name. The above line should have done this too, but in case it failed, we force it.
+ key, err := registry.OpenKey(registry.LOCAL_MACHINE, wintun.netRegKeyName(), registry.SET_VALUE)
+ if err != nil {
+ return fmt.Errorf("Network-specific registry key open failed: %v", err)
+ }
+ defer key.Close()
+ return key.SetStringValue("Name", ifname)
}
// netRegKeyName returns the interface-specific network registry key name.
@@ -603,11 +590,6 @@ func (wintun *Wintun) tcpipAdapterRegKeyName() string {
return fmt.Sprintf("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters\\%v", wintun.cfgInstanceID)
}
-// deviceRegKeyName returns the device-level registry key name
-func (wintun *Wintun) deviceRegKeyName() string {
- return fmt.Sprintf("SYSTEM\\CurrentControlSet\\Enum\\%v", wintun.devInstanceID)
-}
-
// tcpipInterfaceRegKeyName returns the interface-specific TCP/IP network registry key name.
func (wintun *Wintun) tcpipInterfaceRegKeyName() (path string, err error) {
key, err := registry.OpenKey(registry.LOCAL_MACHINE, wintun.tcpipAdapterRegKeyName(), registry.QUERY_VALUE)