mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 21:15:39 +00:00
37925b3e7a
* We update wingoes to pick up new version information functionality (See pe/version.go in the https://github.com/dblohm7/wingoes repo); * We move the existing LogSupportInfo code (including necessary syscall stubs) out of util/winutil into a new package, util/osdiag, and implement the public LogSupportInfo function may be implemented for other platforms as needed; * We add a new reason argument to LogSupportInfo and wire that into localapi's bugreport implementation; * We add module information to the Windows implementation of LogSupportInfo when reason indicates a bugreport. We enumerate all loaded modules in our process, and for each one we gather debug, authenticode signature, and version information. Fixes #7802 Signed-off-by: Aaron Klotz <aaron@tailscale.com>
129 lines
3.4 KiB
Go
129 lines
3.4 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package osdiag
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"golang.org/x/exp/maps"
|
|
"golang.org/x/sys/windows/registry"
|
|
)
|
|
|
|
func makeLongBinaryValue() []byte {
|
|
buf := make([]byte, maxBinaryValueLen*2)
|
|
for i, _ := range buf {
|
|
buf[i] = byte(i % 0xFF)
|
|
}
|
|
return buf
|
|
}
|
|
|
|
var testData = map[string]any{
|
|
"": "I am the default",
|
|
"StringEmpty": "",
|
|
"StringShort": "Hello",
|
|
"StringLong": strings.Repeat("7", initialValueBufLen+1),
|
|
"MultiStringEmpty": []string{},
|
|
"MultiStringSingle": []string{"Foo"},
|
|
"MultiStringSingleEmpty": []string{""},
|
|
"MultiString": []string{"Foo", "Bar", "Baz"},
|
|
"MultiStringWithEmptyBeginning": []string{"", "Foo", "Bar"},
|
|
"MultiStringWithEmptyMiddle": []string{"Foo", "", "Bar"},
|
|
"MultiStringWithEmptyEnd": []string{"Foo", "Bar", ""},
|
|
"DWord": uint32(0x12345678),
|
|
"QWord": uint64(0x123456789abcdef0),
|
|
"BinaryEmpty": []byte{},
|
|
"BinaryShort": []byte{0x01, 0x02, 0x03, 0x04},
|
|
"BinaryLong": makeLongBinaryValue(),
|
|
}
|
|
|
|
const (
|
|
keyNameTest = `SOFTWARE\Tailscale Test`
|
|
subKeyNameTest = "SubKey"
|
|
)
|
|
|
|
func setValues(t *testing.T, k registry.Key) {
|
|
for vk, v := range testData {
|
|
var err error
|
|
switch tv := v.(type) {
|
|
case string:
|
|
err = k.SetStringValue(vk, tv)
|
|
case []string:
|
|
err = k.SetStringsValue(vk, tv)
|
|
case uint32:
|
|
err = k.SetDWordValue(vk, tv)
|
|
case uint64:
|
|
err = k.SetQWordValue(vk, tv)
|
|
case []byte:
|
|
err = k.SetBinaryValue(vk, tv)
|
|
default:
|
|
t.Fatalf("Unknown type")
|
|
}
|
|
|
|
if err != nil {
|
|
t.Fatalf("Error setting %q: %v", vk, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRegistrySupportInfo(t *testing.T) {
|
|
// Make sure the key doesn't exist yet
|
|
k, err := registry.OpenKey(registry.CURRENT_USER, keyNameTest, registry.READ)
|
|
switch {
|
|
case err == nil:
|
|
k.Close()
|
|
t.Fatalf("Test key already exists")
|
|
case !errors.Is(err, registry.ErrNotExist):
|
|
t.Fatal(err)
|
|
}
|
|
|
|
func() {
|
|
k, _, err := registry.CreateKey(registry.CURRENT_USER, keyNameTest, registry.WRITE)
|
|
if err != nil {
|
|
t.Fatalf("Error creating test key: %v", err)
|
|
}
|
|
defer k.Close()
|
|
|
|
setValues(t, k)
|
|
|
|
sk, _, err := registry.CreateKey(k, subKeyNameTest, registry.WRITE)
|
|
if err != nil {
|
|
t.Fatalf("Error creating test subkey: %v", err)
|
|
}
|
|
defer sk.Close()
|
|
|
|
setValues(t, sk)
|
|
}()
|
|
|
|
t.Cleanup(func() {
|
|
registry.DeleteKey(registry.CURRENT_USER, keyNameTest+"\\"+subKeyNameTest)
|
|
registry.DeleteKey(registry.CURRENT_USER, keyNameTest)
|
|
})
|
|
|
|
wantValuesData := maps.Clone(testData)
|
|
wantValuesData["BinaryLong"] = (wantValuesData["BinaryLong"].([]byte))[:maxBinaryValueLen]
|
|
|
|
wantKeyData := make(map[string]any)
|
|
maps.Copy(wantKeyData, wantValuesData)
|
|
wantSubKeyData := make(map[string]any)
|
|
maps.Copy(wantSubKeyData, wantValuesData)
|
|
wantKeyData[subKeyNameTest] = wantSubKeyData
|
|
|
|
wantData := map[string]any{
|
|
"HKCU\\" + keyNameTest: wantKeyData,
|
|
}
|
|
|
|
gotData, err := getRegistrySupportInfo(registry.CURRENT_USER, []string{keyNameTest})
|
|
if err != nil {
|
|
t.Errorf("getRegistrySupportInfo error: %v", err)
|
|
}
|
|
|
|
want, got := fmt.Sprintf("%#v", wantData), fmt.Sprintf("%#v", gotData)
|
|
if want != got {
|
|
t.Errorf("Compare error: want\n%s,\ngot %s", want, got)
|
|
}
|
|
}
|