From 73106f4ef71673a0953c428fc9a86d898b8a095b Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Wed, 27 May 2020 03:57:03 -0600 Subject: [PATCH] update deps --- .../denisbrodbeck/machineid/.gitignore | 29 ++ .../denisbrodbeck/machineid/LICENSE.md | 22 + .../denisbrodbeck/machineid/README.md | 182 +++++++++ .../denisbrodbeck/machineid/helper.go | 36 ++ .../github.com/denisbrodbeck/machineid/id.go | 45 ++ .../denisbrodbeck/machineid/id_bsd.go | 42 ++ .../denisbrodbeck/machineid/id_darwin.go | 37 ++ .../denisbrodbeck/machineid/id_linux.go | 27 ++ .../denisbrodbeck/machineid/id_windows.go | 23 ++ .../denisbrodbeck/machineid/logo.png | Bin 0 -> 20212 bytes .../denisbrodbeck/machineid/makefile | 12 + .../golang.org/x/sys/windows/registry/key.go | 198 +++++++++ .../x/sys/windows/registry/mksyscall.go | 9 + .../x/sys/windows/registry/syscall.go | 32 ++ .../x/sys/windows/registry/value.go | 386 ++++++++++++++++++ .../sys/windows/registry/zsyscall_windows.go | 120 ++++++ 16 files changed, 1200 insertions(+) create mode 100644 vendor/github.com/denisbrodbeck/machineid/.gitignore create mode 100644 vendor/github.com/denisbrodbeck/machineid/LICENSE.md create mode 100644 vendor/github.com/denisbrodbeck/machineid/README.md create mode 100644 vendor/github.com/denisbrodbeck/machineid/helper.go create mode 100644 vendor/github.com/denisbrodbeck/machineid/id.go create mode 100644 vendor/github.com/denisbrodbeck/machineid/id_bsd.go create mode 100644 vendor/github.com/denisbrodbeck/machineid/id_darwin.go create mode 100644 vendor/github.com/denisbrodbeck/machineid/id_linux.go create mode 100644 vendor/github.com/denisbrodbeck/machineid/id_windows.go create mode 100644 vendor/github.com/denisbrodbeck/machineid/logo.png create mode 100644 vendor/github.com/denisbrodbeck/machineid/makefile create mode 100644 vendor/golang.org/x/sys/windows/registry/key.go create mode 100644 vendor/golang.org/x/sys/windows/registry/mksyscall.go create mode 100644 vendor/golang.org/x/sys/windows/registry/syscall.go create mode 100644 vendor/golang.org/x/sys/windows/registry/value.go create mode 100644 vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go diff --git a/vendor/github.com/denisbrodbeck/machineid/.gitignore b/vendor/github.com/denisbrodbeck/machineid/.gitignore new file mode 100644 index 0000000..9a40b5c --- /dev/null +++ b/vendor/github.com/denisbrodbeck/machineid/.gitignore @@ -0,0 +1,29 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +.DS_Store +.vscode +result +/machineid diff --git a/vendor/github.com/denisbrodbeck/machineid/LICENSE.md b/vendor/github.com/denisbrodbeck/machineid/LICENSE.md new file mode 100644 index 0000000..31c4e67 --- /dev/null +++ b/vendor/github.com/denisbrodbeck/machineid/LICENSE.md @@ -0,0 +1,22 @@ + +The MIT License (MIT) + +Copyright (c) 2017 Denis Brodbeck + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/denisbrodbeck/machineid/README.md b/vendor/github.com/denisbrodbeck/machineid/README.md new file mode 100644 index 0000000..b82802e --- /dev/null +++ b/vendor/github.com/denisbrodbeck/machineid/README.md @@ -0,0 +1,182 @@ +# machineid provides support for reading the unique machine id of most host OS's (without admin privileges) + +![Image of Gopher 47](logo.png) + +… because sometimes you just need to reliably identify your machines. + +[![GoDoc](https://godoc.org/github.com/denisbrodbeck/machineid?status.svg)](https://godoc.org/github.com/denisbrodbeck/machineid) [![Go Report Card](https://goreportcard.com/badge/github.com/denisbrodbeck/machineid)](https://goreportcard.com/report/github.com/denisbrodbeck/machineid) + +## Main Features + +* Cross-Platform (tested on Win7+, Debian 8+, Ubuntu 14.04+, OS X 10.6+, FreeBSD 11+) +* No admin privileges required +* Hardware independent (no usage of MAC, BIOS or CPU — those are too unreliable, especially in a VM environment) +* IDs are unique[1](#unique-key-reliability) to the installed OS + +## Installation + +Get the library with + +```bash +go get github.com/denisbrodbeck/machineid +``` + +You can also add the cli app directly to your `$GOPATH/bin` with + +```bash +go get github.com/denisbrodbeck/machineid/cmd/machineid +``` + +## Usage + +```golang +package main + +import ( + "fmt" + "log" + "github.com/denisbrodbeck/machineid" +) + +func main() { + id, err := machineid.ID() + if err != nil { + log.Fatal(err) + } + fmt.Println(id) +} +``` + +Or even better, use securely hashed machine IDs: + +```golang +package main + +import ( + "fmt" + "log" + "github.com/denisbrodbeck/machineid" +) + +func main() { + id, err := machineid.ProtectedID("myAppName") + if err != nil { + log.Fatal(err) + } + fmt.Println(id) +} +``` + +### Function: ID() (string, error) + +Returns original machine id as a `string`. + +### Function: ProtectedID(appID string) (string, error) + +Returns hashed version of the machine ID as a `string`. The hash is generated in a cryptographically secure way, using a fixed, application-specific key (calculates HMAC-SHA256 of the app ID, keyed by the machine ID). + +## What you get + +This package returns the OS native machine UUID/GUID, which the OS uses for internal needs. + +All machine IDs are usually generated during system installation and stay constant for all subsequent boots. + +The following sources are used: + +* **BSD** uses `/etc/hostid` and `smbios.system.uuid` as a fallback +* **Linux** uses `/var/lib/dbus/machine-id` ([man](http://man7.org/linux/man-pages/man5/machine-id.5.html)) +* **OS X** uses `IOPlatformUUID` +* **Windows** uses the `MachineGuid` from `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography` + +## Unique Key Reliability + +Do note, that `machine-id` and `MachineGuid` can be changed by root/admin, although that may not come without cost (broken system services and more). +Most IDs won't be regenerated by the OS, when you clone/image/restore a particular OS installation. This is a well known issue with cloned windows installs (not using the official sysprep tools). + +**Linux** users can generate a new id with `dbus-uuidgen` and put the id into `/var/lib/dbus/machine-id` and `/etc/machine-id`. +**Windows** users can use the `sysprep` [toolchain](https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/sysprep--generalize--a-windows-installation) to create images, which produce valid images ready for distribution. Such images produce a new unique machine ID on each deployment. + +## Security Considerations + +A machine ID uniquely identifies the host. Therefore it should be considered "confidential", and must not be exposed in untrusted environments. If you need a stable unique identifier for your app, do not use the machine ID directly. + +> A reliable solution is to hash the machine ID in a cryptographically secure way, using a fixed, application-specific key. + +That way the ID will be properly unique, and derived in a constant way from the machine ID but there will be no way to retrieve the original machine ID from the application-specific one. + +Do something along these lines: + +```golang +package main + +import ( + "crypto/hmac" + "crypto/sha256" + "fmt" + "github.com/denisbrodbeck/machineid" +) + +const appKey = "WowSuchNiceApp" + +func main() { + id, _ := machineid.ID() + fmt.Println(protect(appKey, id)) + // Output: dbabdb7baa54845f9bec96e2e8a87be2d01794c66fdebac3df7edd857f3d9f97 +} + +func protect(appID, id string) string { + mac := hmac.New(sha256.New, []byte(id)) + mac.Write([]byte(appID)) + return fmt.Sprintf("%x", mac.Sum(nil)) +} +``` + +Or simply use the convenience API call: + +```golang +hashedID, err := machineid.ProtectedID("myAppName") +``` + +## Snippets + +Don't want to download code, and just need a way to get the data by yourself? + +BSD: + +```bash +cat /etc/hostid +# or (might be empty) +kenv -q smbios.system.uuid +``` + +Linux: + +```bash +cat /var/lib/dbus/machine-id +# or when not found (e.g. Fedora 20) +cat /etc/machine-id +``` + +OS X: + +```bash +ioreg -rd1 -c IOPlatformExpertDevice | grep IOPlatformUUID +``` + +Windows: + +```batch +reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography /v MachineGuid +``` +or +* Open Windows Registry via `regedit` +* Navigate to `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography` +* Take value of key `MachineGuid` + +## Credits + +The Go gopher was created by [Denis Brodbeck](https://github.com/denisbrodbeck) with [gopherize.me](https://gopherize.me/), based on original artwork from [Renee French](http://reneefrench.blogspot.com/). + +## License + +The MIT License (MIT) — [Denis Brodbeck](https://github.com/denisbrodbeck). Please have a look at the [LICENSE.md](LICENSE.md) for more details. diff --git a/vendor/github.com/denisbrodbeck/machineid/helper.go b/vendor/github.com/denisbrodbeck/machineid/helper.go new file mode 100644 index 0000000..a16056d --- /dev/null +++ b/vendor/github.com/denisbrodbeck/machineid/helper.go @@ -0,0 +1,36 @@ +package machineid + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "io" + "io/ioutil" + "os" + "os/exec" + "strings" +) + +// run wraps `exec.Command` with easy access to stdout and stderr. +func run(stdout, stderr io.Writer, cmd string, args ...string) error { + c := exec.Command(cmd, args...) + c.Stdin = os.Stdin + c.Stdout = stdout + c.Stderr = stderr + return c.Run() +} + +// protect calculates HMAC-SHA256 of the application ID, keyed by the machine ID and returns a hex-encoded string. +func protect(appID, id string) string { + mac := hmac.New(sha256.New, []byte(id)) + mac.Write([]byte(appID)) + return hex.EncodeToString(mac.Sum(nil)) +} + +func readFile(filename string) ([]byte, error) { + return ioutil.ReadFile(filename) +} + +func trim(s string) string { + return strings.TrimSpace(strings.Trim(s, "\n")) +} diff --git a/vendor/github.com/denisbrodbeck/machineid/id.go b/vendor/github.com/denisbrodbeck/machineid/id.go new file mode 100644 index 0000000..3c7fb94 --- /dev/null +++ b/vendor/github.com/denisbrodbeck/machineid/id.go @@ -0,0 +1,45 @@ +// Package machineid provides support for reading the unique machine id of most OSs (without admin privileges). +// +// https://github.com/denisbrodbeck/machineid +// +// https://godoc.org/github.com/denisbrodbeck/machineid/cmd/machineid +// +// This package is Cross-Platform (tested on Win7+, Debian 8+, Ubuntu 14.04+, OS X 10.6+, FreeBSD 11+) +// and does not use any internal hardware IDs (no MAC, BIOS, or CPU). +// +// Returned machine IDs are generally stable for the OS installation +// and usually stay the same after updates or hardware changes. +// +// This package allows sharing of machine IDs in a secure way by +// calculating HMAC-SHA256 over a user provided app ID, which is keyed by the machine id. +// +// Caveat: Image-based environments have usually the same machine-id (perfect clone). +// Linux users can generate a new id with `dbus-uuidgen` and put the id into +// `/var/lib/dbus/machine-id` and `/etc/machine-id`. +// Windows users can use the `sysprep` toolchain to create images, which produce valid images ready for distribution. +package machineid // import "github.com/denisbrodbeck/machineid" + +import ( + "fmt" +) + +// ID returns the platform specific machine id of the current host OS. +// Regard the returned id as "confidential" and consider using ProtectedID() instead. +func ID() (string, error) { + id, err := machineID() + if err != nil { + return "", fmt.Errorf("machineid: %v", err) + } + return id, nil +} + +// ProtectedID returns a hashed version of the machine ID in a cryptographically secure way, +// using a fixed, application-specific key. +// Internally, this function calculates HMAC-SHA256 of the application ID, keyed by the machine ID. +func ProtectedID(appID string) (string, error) { + id, err := ID() + if err != nil { + return "", fmt.Errorf("machineid: %v", err) + } + return protect(appID, id), nil +} diff --git a/vendor/github.com/denisbrodbeck/machineid/id_bsd.go b/vendor/github.com/denisbrodbeck/machineid/id_bsd.go new file mode 100644 index 0000000..241b0f7 --- /dev/null +++ b/vendor/github.com/denisbrodbeck/machineid/id_bsd.go @@ -0,0 +1,42 @@ +// +build freebsd netbsd openbsd dragonfly solaris + +package machineid + +import ( + "bytes" + "os" +) + +const hostidPath = "/etc/hostid" + +// machineID returns the uuid specified at `/etc/hostid`. +// If the returned value is empty, the uuid from a call to `kenv -q smbios.system.uuid` is returned. +// If there is an error an empty string is returned. +func machineID() (string, error) { + id, err := readHostid() + if err != nil { + // try fallback + id, err = readKenv() + } + if err != nil { + return "", err + } + return id, nil +} + +func readHostid() (string, error) { + buf, err := readFile(hostidPath) + if err != nil { + return "", err + } + return trim(string(buf)), nil +} + +func readKenv() (string, error) { + buf := &bytes.Buffer{} + err := run(buf, os.Stderr, "kenv", "-q", "smbios.system.uuid") + if err != nil { + return "", err + } + return trim(buf.String()), nil +} diff --git a/vendor/github.com/denisbrodbeck/machineid/id_darwin.go b/vendor/github.com/denisbrodbeck/machineid/id_darwin.go new file mode 100644 index 0000000..08510e4 --- /dev/null +++ b/vendor/github.com/denisbrodbeck/machineid/id_darwin.go @@ -0,0 +1,37 @@ +// +build darwin + +package machineid + +import ( + "bytes" + "fmt" + "os" + "strings" +) + +// machineID returns the uuid returned by `ioreg -rd1 -c IOPlatformExpertDevice`. +// If there is an error running the commad an empty string is returned. +func machineID() (string, error) { + buf := &bytes.Buffer{} + err := run(buf, os.Stderr, "ioreg", "-rd1", "-c", "IOPlatformExpertDevice") + if err != nil { + return "", err + } + id, err := extractID(buf.String()) + if err != nil { + return "", err + } + return trim(id), nil +} + +func extractID(lines string) (string, error) { + for _, line := range strings.Split(lines, "\n") { + if strings.Contains(line, "IOPlatformUUID") { + parts := strings.SplitAfter(line, `" = "`) + if len(parts) == 2 { + return strings.TrimRight(parts[1], `"`), nil + } + } + } + return "", fmt.Errorf("Failed to extract 'IOPlatformUUID' value from `ioreg` output.\n%s", lines) +} diff --git a/vendor/github.com/denisbrodbeck/machineid/id_linux.go b/vendor/github.com/denisbrodbeck/machineid/id_linux.go new file mode 100644 index 0000000..e68eb45 --- /dev/null +++ b/vendor/github.com/denisbrodbeck/machineid/id_linux.go @@ -0,0 +1,27 @@ +// +build linux + +package machineid + +const ( + // dbusPath is the default path for dbus machine id. + dbusPath = "/var/lib/dbus/machine-id" + // dbusPathEtc is the default path for dbus machine id located in /etc. + // Some systems (like Fedora 20) only know this path. + // Sometimes it's the other way round. + dbusPathEtc = "/etc/machine-id" +) + +// machineID returns the uuid specified at `/var/lib/dbus/machine-id` or `/etc/machine-id`. +// If there is an error reading the files an empty string is returned. +// See https://unix.stackexchange.com/questions/144812/generate-consistent-machine-unique-id +func machineID() (string, error) { + id, err := readFile(dbusPath) + if err != nil { + // try fallback path + id, err = readFile(dbusPathEtc) + } + if err != nil { + return "", err + } + return trim(string(id)), nil +} diff --git a/vendor/github.com/denisbrodbeck/machineid/id_windows.go b/vendor/github.com/denisbrodbeck/machineid/id_windows.go new file mode 100644 index 0000000..4b778ae --- /dev/null +++ b/vendor/github.com/denisbrodbeck/machineid/id_windows.go @@ -0,0 +1,23 @@ +// +build windows + +package machineid + +import ( + "golang.org/x/sys/windows/registry" +) + +// machineID returns the key MachineGuid in registry `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography`. +// If there is an error running the commad an empty string is returned. +func machineID() (string, error) { + k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Cryptography`, registry.QUERY_VALUE|registry.WOW64_64KEY) + if err != nil { + return "", err + } + defer k.Close() + + s, _, err := k.GetStringValue("MachineGuid") + if err != nil { + return "", err + } + return s, nil +} diff --git a/vendor/github.com/denisbrodbeck/machineid/logo.png b/vendor/github.com/denisbrodbeck/machineid/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..01536427401757f513e51adad0c17bafc876623d GIT binary patch literal 20212 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%0At;>A<#0A#saS1K9_E0u-&BnKi-L9DP#7m$Pc? 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 UAJF!>k^lez07*qoM6N<$f*ag?!2kdN literal 0 HcmV?d00001 diff --git a/vendor/github.com/denisbrodbeck/machineid/makefile b/vendor/github.com/denisbrodbeck/machineid/makefile new file mode 100644 index 0000000..e947a81 --- /dev/null +++ b/vendor/github.com/denisbrodbeck/machineid/makefile @@ -0,0 +1,12 @@ +.PHONY: build clean default test + +build: clean + @go build -o machineid ./cmd/machineid/main.go + +clean: + @rm -rf ./machineid + +test: + go test ./... + +default: build diff --git a/vendor/golang.org/x/sys/windows/registry/key.go b/vendor/golang.org/x/sys/windows/registry/key.go new file mode 100644 index 0000000..c256483 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/registry/key.go @@ -0,0 +1,198 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +// Package registry provides access to the Windows registry. +// +// Here is a simple example, opening a registry key and reading a string value from it. +// +// k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) +// if err != nil { +// log.Fatal(err) +// } +// defer k.Close() +// +// s, _, err := k.GetStringValue("SystemRoot") +// if err != nil { +// log.Fatal(err) +// } +// fmt.Printf("Windows system root is %q\n", s) +// +package registry + +import ( + "io" + "syscall" + "time" +) + +const ( + // Registry key security and access rights. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx + // for details. + ALL_ACCESS = 0xf003f + CREATE_LINK = 0x00020 + CREATE_SUB_KEY = 0x00004 + ENUMERATE_SUB_KEYS = 0x00008 + EXECUTE = 0x20019 + NOTIFY = 0x00010 + QUERY_VALUE = 0x00001 + READ = 0x20019 + SET_VALUE = 0x00002 + WOW64_32KEY = 0x00200 + WOW64_64KEY = 0x00100 + WRITE = 0x20006 +) + +// Key is a handle to an open Windows registry key. +// Keys can be obtained by calling OpenKey; there are +// also some predefined root keys such as CURRENT_USER. +// Keys can be used directly in the Windows API. +type Key syscall.Handle + +const ( + // Windows defines some predefined root keys that are always open. + // An application can use these keys as entry points to the registry. + // Normally these keys are used in OpenKey to open new keys, + // but they can also be used anywhere a Key is required. + CLASSES_ROOT = Key(syscall.HKEY_CLASSES_ROOT) + CURRENT_USER = Key(syscall.HKEY_CURRENT_USER) + LOCAL_MACHINE = Key(syscall.HKEY_LOCAL_MACHINE) + USERS = Key(syscall.HKEY_USERS) + CURRENT_CONFIG = Key(syscall.HKEY_CURRENT_CONFIG) + PERFORMANCE_DATA = Key(syscall.HKEY_PERFORMANCE_DATA) +) + +// Close closes open key k. +func (k Key) Close() error { + return syscall.RegCloseKey(syscall.Handle(k)) +} + +// OpenKey opens a new key with path name relative to key k. +// It accepts any open key, including CURRENT_USER and others, +// and returns the new key and an error. +// The access parameter specifies desired access rights to the +// key to be opened. +func OpenKey(k Key, path string, access uint32) (Key, error) { + p, err := syscall.UTF16PtrFromString(path) + if err != nil { + return 0, err + } + var subkey syscall.Handle + err = syscall.RegOpenKeyEx(syscall.Handle(k), p, 0, access, &subkey) + if err != nil { + return 0, err + } + return Key(subkey), nil +} + +// OpenRemoteKey opens a predefined registry key on another +// computer pcname. The key to be opened is specified by k, but +// can only be one of LOCAL_MACHINE, PERFORMANCE_DATA or USERS. +// If pcname is "", OpenRemoteKey returns local computer key. +func OpenRemoteKey(pcname string, k Key) (Key, error) { + var err error + var p *uint16 + if pcname != "" { + p, err = syscall.UTF16PtrFromString(`\\` + pcname) + if err != nil { + return 0, err + } + } + var remoteKey syscall.Handle + err = regConnectRegistry(p, syscall.Handle(k), &remoteKey) + if err != nil { + return 0, err + } + return Key(remoteKey), nil +} + +// ReadSubKeyNames returns the names of subkeys of key k. +// The parameter n controls the number of returned names, +// analogous to the way os.File.Readdirnames works. +func (k Key) ReadSubKeyNames(n int) ([]string, error) { + names := make([]string, 0) + // Registry key size limit is 255 bytes and described there: + // https://msdn.microsoft.com/library/windows/desktop/ms724872.aspx + buf := make([]uint16, 256) //plus extra room for terminating zero byte +loopItems: + for i := uint32(0); ; i++ { + if n > 0 { + if len(names) == n { + return names, nil + } + } + l := uint32(len(buf)) + for { + err := syscall.RegEnumKeyEx(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil) + if err == nil { + break + } + if err == syscall.ERROR_MORE_DATA { + // Double buffer size and try again. + l = uint32(2 * len(buf)) + buf = make([]uint16, l) + continue + } + if err == _ERROR_NO_MORE_ITEMS { + break loopItems + } + return names, err + } + names = append(names, syscall.UTF16ToString(buf[:l])) + } + if n > len(names) { + return names, io.EOF + } + return names, nil +} + +// CreateKey creates a key named path under open key k. +// CreateKey returns the new key and a boolean flag that reports +// whether the key already existed. +// The access parameter specifies the access rights for the key +// to be created. +func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) { + var h syscall.Handle + var d uint32 + err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path), + 0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d) + if err != nil { + return 0, false, err + } + return Key(h), d == _REG_OPENED_EXISTING_KEY, nil +} + +// DeleteKey deletes the subkey path of key k and its values. +func DeleteKey(k Key, path string) error { + return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path)) +} + +// A KeyInfo describes the statistics of a key. It is returned by Stat. +type KeyInfo struct { + SubKeyCount uint32 + MaxSubKeyLen uint32 // size of the key's subkey with the longest name, in Unicode characters, not including the terminating zero byte + ValueCount uint32 + MaxValueNameLen uint32 // size of the key's longest value name, in Unicode characters, not including the terminating zero byte + MaxValueLen uint32 // longest data component among the key's values, in bytes + lastWriteTime syscall.Filetime +} + +// ModTime returns the key's last write time. +func (ki *KeyInfo) ModTime() time.Time { + return time.Unix(0, ki.lastWriteTime.Nanoseconds()) +} + +// Stat retrieves information about the open key k. +func (k Key) Stat() (*KeyInfo, error) { + var ki KeyInfo + err := syscall.RegQueryInfoKey(syscall.Handle(k), nil, nil, nil, + &ki.SubKeyCount, &ki.MaxSubKeyLen, nil, &ki.ValueCount, + &ki.MaxValueNameLen, &ki.MaxValueLen, nil, &ki.lastWriteTime) + if err != nil { + return nil, err + } + return &ki, nil +} diff --git a/vendor/golang.org/x/sys/windows/registry/mksyscall.go b/vendor/golang.org/x/sys/windows/registry/mksyscall.go new file mode 100644 index 0000000..50c32a3 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/registry/mksyscall.go @@ -0,0 +1,9 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build generate + +package registry + +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall.go diff --git a/vendor/golang.org/x/sys/windows/registry/syscall.go b/vendor/golang.org/x/sys/windows/registry/syscall.go new file mode 100644 index 0000000..e66643c --- /dev/null +++ b/vendor/golang.org/x/sys/windows/registry/syscall.go @@ -0,0 +1,32 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package registry + +import "syscall" + +const ( + _REG_OPTION_NON_VOLATILE = 0 + + _REG_CREATED_NEW_KEY = 1 + _REG_OPENED_EXISTING_KEY = 2 + + _ERROR_NO_MORE_ITEMS syscall.Errno = 259 +) + +func LoadRegLoadMUIString() error { + return procRegLoadMUIStringW.Find() +} + +//sys regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) = advapi32.RegCreateKeyExW +//sys regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) = advapi32.RegDeleteKeyW +//sys regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) = advapi32.RegSetValueExW +//sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegEnumValueW +//sys regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) = advapi32.RegDeleteValueW +//sys regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) = advapi32.RegLoadMUIStringW +//sys regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) = advapi32.RegConnectRegistryW + +//sys expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) = kernel32.ExpandEnvironmentStringsW diff --git a/vendor/golang.org/x/sys/windows/registry/value.go b/vendor/golang.org/x/sys/windows/registry/value.go new file mode 100644 index 0000000..f25e7e9 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/registry/value.go @@ -0,0 +1,386 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package registry + +import ( + "errors" + "io" + "syscall" + "unicode/utf16" + "unsafe" +) + +const ( + // Registry value types. + NONE = 0 + SZ = 1 + EXPAND_SZ = 2 + BINARY = 3 + DWORD = 4 + DWORD_BIG_ENDIAN = 5 + LINK = 6 + MULTI_SZ = 7 + RESOURCE_LIST = 8 + FULL_RESOURCE_DESCRIPTOR = 9 + RESOURCE_REQUIREMENTS_LIST = 10 + QWORD = 11 +) + +var ( + // ErrShortBuffer is returned when the buffer was too short for the operation. + ErrShortBuffer = syscall.ERROR_MORE_DATA + + // ErrNotExist is returned when a registry key or value does not exist. + ErrNotExist = syscall.ERROR_FILE_NOT_FOUND + + // ErrUnexpectedType is returned by Get*Value when the value's type was unexpected. + ErrUnexpectedType = errors.New("unexpected key value type") +) + +// GetValue retrieves the type and data for the specified value associated +// with an open key k. It fills up buffer buf and returns the retrieved +// byte count n. If buf is too small to fit the stored value it returns +// ErrShortBuffer error along with the required buffer size n. +// If no buffer is provided, it returns true and actual buffer size n. +// If no buffer is provided, GetValue returns the value's type only. +// If the value does not exist, the error returned is ErrNotExist. +// +// GetValue is a low level function. If value's type is known, use the appropriate +// Get*Value function instead. +func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) { + pname, err := syscall.UTF16PtrFromString(name) + if err != nil { + return 0, 0, err + } + var pbuf *byte + if len(buf) > 0 { + pbuf = (*byte)(unsafe.Pointer(&buf[0])) + } + l := uint32(len(buf)) + err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l) + if err != nil { + return int(l), valtype, err + } + return int(l), valtype, nil +} + +func (k Key) getValue(name string, buf []byte) (data []byte, valtype uint32, err error) { + p, err := syscall.UTF16PtrFromString(name) + if err != nil { + return nil, 0, err + } + var t uint32 + n := uint32(len(buf)) + for { + err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n) + if err == nil { + return buf[:n], t, nil + } + if err != syscall.ERROR_MORE_DATA { + return nil, 0, err + } + if n <= uint32(len(buf)) { + return nil, 0, err + } + buf = make([]byte, n) + } +} + +// GetStringValue retrieves the string value for the specified +// value name associated with an open key k. It also returns the value's type. +// If value does not exist, GetStringValue returns ErrNotExist. +// If value is not SZ or EXPAND_SZ, it will return the correct value +// type and ErrUnexpectedType. +func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) { + data, typ, err2 := k.getValue(name, make([]byte, 64)) + if err2 != nil { + return "", typ, err2 + } + switch typ { + case SZ, EXPAND_SZ: + default: + return "", typ, ErrUnexpectedType + } + if len(data) == 0 { + return "", typ, nil + } + u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[: len(data)/2 : len(data)/2] + return syscall.UTF16ToString(u), typ, nil +} + +// GetMUIStringValue retrieves the localized string value for +// the specified value name associated with an open key k. +// If the value name doesn't exist or the localized string value +// can't be resolved, GetMUIStringValue returns ErrNotExist. +// GetMUIStringValue panics if the system doesn't support +// regLoadMUIString; use LoadRegLoadMUIString to check if +// regLoadMUIString is supported before calling this function. +func (k Key) GetMUIStringValue(name string) (string, error) { + pname, err := syscall.UTF16PtrFromString(name) + if err != nil { + return "", err + } + + buf := make([]uint16, 1024) + var buflen uint32 + var pdir *uint16 + + err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir) + if err == syscall.ERROR_FILE_NOT_FOUND { // Try fallback path + + // Try to resolve the string value using the system directory as + // a DLL search path; this assumes the string value is of the form + // @[path]\dllname,-strID but with no path given, e.g. @tzres.dll,-320. + + // This approach works with tzres.dll but may have to be revised + // in the future to allow callers to provide custom search paths. + + var s string + s, err = ExpandString("%SystemRoot%\\system32\\") + if err != nil { + return "", err + } + pdir, err = syscall.UTF16PtrFromString(s) + if err != nil { + return "", err + } + + err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir) + } + + for err == syscall.ERROR_MORE_DATA { // Grow buffer if needed + if buflen <= uint32(len(buf)) { + break // Buffer not growing, assume race; break + } + buf = make([]uint16, buflen) + err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir) + } + + if err != nil { + return "", err + } + + return syscall.UTF16ToString(buf), nil +} + +// ExpandString expands environment-variable strings and replaces +// them with the values defined for the current user. +// Use ExpandString to expand EXPAND_SZ strings. +func ExpandString(value string) (string, error) { + if value == "" { + return "", nil + } + p, err := syscall.UTF16PtrFromString(value) + if err != nil { + return "", err + } + r := make([]uint16, 100) + for { + n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r))) + if err != nil { + return "", err + } + if n <= uint32(len(r)) { + return syscall.UTF16ToString(r[:n]), nil + } + r = make([]uint16, n) + } +} + +// GetStringsValue retrieves the []string value for the specified +// value name associated with an open key k. It also returns the value's type. +// If value does not exist, GetStringsValue returns ErrNotExist. +// If value is not MULTI_SZ, it will return the correct value +// type and ErrUnexpectedType. +func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) { + data, typ, err2 := k.getValue(name, make([]byte, 64)) + if err2 != nil { + return nil, typ, err2 + } + if typ != MULTI_SZ { + return nil, typ, ErrUnexpectedType + } + if len(data) == 0 { + return nil, typ, nil + } + p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[: len(data)/2 : len(data)/2] + if len(p) == 0 { + return nil, typ, nil + } + if p[len(p)-1] == 0 { + p = p[:len(p)-1] // remove terminating null + } + val = make([]string, 0, 5) + from := 0 + for i, c := range p { + if c == 0 { + val = append(val, string(utf16.Decode(p[from:i]))) + from = i + 1 + } + } + return val, typ, nil +} + +// GetIntegerValue retrieves the integer value for the specified +// value name associated with an open key k. It also returns the value's type. +// If value does not exist, GetIntegerValue returns ErrNotExist. +// If value is not DWORD or QWORD, it will return the correct value +// type and ErrUnexpectedType. +func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) { + data, typ, err2 := k.getValue(name, make([]byte, 8)) + if err2 != nil { + return 0, typ, err2 + } + switch typ { + case DWORD: + if len(data) != 4 { + return 0, typ, errors.New("DWORD value is not 4 bytes long") + } + var val32 uint32 + copy((*[4]byte)(unsafe.Pointer(&val32))[:], data) + return uint64(val32), DWORD, nil + case QWORD: + if len(data) != 8 { + return 0, typ, errors.New("QWORD value is not 8 bytes long") + } + copy((*[8]byte)(unsafe.Pointer(&val))[:], data) + return val, QWORD, nil + default: + return 0, typ, ErrUnexpectedType + } +} + +// GetBinaryValue retrieves the binary value for the specified +// value name associated with an open key k. It also returns the value's type. +// If value does not exist, GetBinaryValue returns ErrNotExist. +// If value is not BINARY, it will return the correct value +// type and ErrUnexpectedType. +func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) { + data, typ, err2 := k.getValue(name, make([]byte, 64)) + if err2 != nil { + return nil, typ, err2 + } + if typ != BINARY { + return nil, typ, ErrUnexpectedType + } + return data, typ, nil +} + +func (k Key) setValue(name string, valtype uint32, data []byte) error { + p, err := syscall.UTF16PtrFromString(name) + if err != nil { + return err + } + if len(data) == 0 { + return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0) + } + return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data))) +} + +// SetDWordValue sets the data and type of a name value +// under key k to value and DWORD. +func (k Key) SetDWordValue(name string, value uint32) error { + return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:]) +} + +// SetQWordValue sets the data and type of a name value +// under key k to value and QWORD. +func (k Key) SetQWordValue(name string, value uint64) error { + return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:]) +} + +func (k Key) setStringValue(name string, valtype uint32, value string) error { + v, err := syscall.UTF16FromString(value) + if err != nil { + return err + } + buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[: len(v)*2 : len(v)*2] + return k.setValue(name, valtype, buf) +} + +// SetStringValue sets the data and type of a name value +// under key k to value and SZ. The value must not contain a zero byte. +func (k Key) SetStringValue(name, value string) error { + return k.setStringValue(name, SZ, value) +} + +// SetExpandStringValue sets the data and type of a name value +// under key k to value and EXPAND_SZ. The value must not contain a zero byte. +func (k Key) SetExpandStringValue(name, value string) error { + return k.setStringValue(name, EXPAND_SZ, value) +} + +// SetStringsValue sets the data and type of a name value +// under key k to value and MULTI_SZ. The value strings +// must not contain a zero byte. +func (k Key) SetStringsValue(name string, value []string) error { + ss := "" + for _, s := range value { + for i := 0; i < len(s); i++ { + if s[i] == 0 { + return errors.New("string cannot have 0 inside") + } + } + ss += s + "\x00" + } + v := utf16.Encode([]rune(ss + "\x00")) + buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[: len(v)*2 : len(v)*2] + return k.setValue(name, MULTI_SZ, buf) +} + +// SetBinaryValue sets the data and type of a name value +// under key k to value and BINARY. +func (k Key) SetBinaryValue(name string, value []byte) error { + return k.setValue(name, BINARY, value) +} + +// DeleteValue removes a named value from the key k. +func (k Key) DeleteValue(name string) error { + return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name)) +} + +// ReadValueNames returns the value names of key k. +// The parameter n controls the number of returned names, +// analogous to the way os.File.Readdirnames works. +func (k Key) ReadValueNames(n int) ([]string, error) { + ki, err := k.Stat() + if err != nil { + return nil, err + } + names := make([]string, 0, ki.ValueCount) + buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character +loopItems: + for i := uint32(0); ; i++ { + if n > 0 { + if len(names) == n { + return names, nil + } + } + l := uint32(len(buf)) + for { + err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil) + if err == nil { + break + } + if err == syscall.ERROR_MORE_DATA { + // Double buffer size and try again. + l = uint32(2 * len(buf)) + buf = make([]uint16, l) + continue + } + if err == _ERROR_NO_MORE_ITEMS { + break loopItems + } + return names, err + } + names = append(names, syscall.UTF16ToString(buf[:l])) + } + if n > len(names) { + return names, io.EOF + } + return names, nil +} diff --git a/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go new file mode 100644 index 0000000..3778075 --- /dev/null +++ b/vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go @@ -0,0 +1,120 @@ +// Code generated by 'go generate'; DO NOT EDIT. + +package registry + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +var _ unsafe.Pointer + +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return nil + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + +var ( + modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") + modkernel32 = windows.NewLazySystemDLL("kernel32.dll") + + procRegCreateKeyExW = modadvapi32.NewProc("RegCreateKeyExW") + procRegDeleteKeyW = modadvapi32.NewProc("RegDeleteKeyW") + procRegSetValueExW = modadvapi32.NewProc("RegSetValueExW") + procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW") + procRegDeleteValueW = modadvapi32.NewProc("RegDeleteValueW") + procRegLoadMUIStringW = modadvapi32.NewProc("RegLoadMUIStringW") + procRegConnectRegistryW = modadvapi32.NewProc("RegConnectRegistryW") + procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW") +) + +func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) { + r0, _, _ := syscall.Syscall9(procRegCreateKeyExW.Addr(), 9, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) { + r0, _, _ := syscall.Syscall(procRegDeleteKeyW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(subkey)), 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) { + r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize)) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { + r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)), 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) { + r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) { + r0, _, _ := syscall.Syscall9(procRegLoadMUIStringW.Addr(), 7, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir)), 0, 0) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) { + r0, _, _ := syscall.Syscall(procRegConnectRegistryW.Addr(), 3, uintptr(unsafe.Pointer(machinename)), uintptr(key), uintptr(unsafe.Pointer(result))) + if r0 != 0 { + regerrno = syscall.Errno(r0) + } + return +} + +func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size)) + n = uint32(r0) + if n == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +}