mirror of
https://github.com/fleetdm/fleet
synced 2026-05-03 03:17:21 +00:00
For https://github.com/fleetdm/fleet/issues/9943 This will help us avoid issues like this where the log message never worked right: https://github.com/fleetdm/fleet/pull/28296#discussion_r2047505191 Most of the changes are no-op type changes like removing unneeded typecast or disabling gosec on reviewed lines of code # Checklist for submitter If some of the following don't apply, delete the relevant line. <!-- Note that API documentation changes are now addressed by the product design team. --> - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [x] Added/updated automated tests - [x] A detailed QA plan exists on the associated ticket (if it isn't there, work with the product group's QA engineer to add it) - [x] Manual QA for all new/changed functionality - For Orbit and Fleet Desktop changes: - [x] Make sure fleetd is compatible with the latest released version of Fleet (see [Must rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/fleetd-development-and-release-strategy.md)). - [x] Orbit runs on macOS, Linux and Windows. Check if the orbit feature/bugfix should only apply to one platform (`runtime.GOOS`). - [x] Manual QA must be performed in the three main OSs, macOS, Windows and Linux. - [x] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)).
92 lines
3.6 KiB
Go
92 lines
3.6 KiB
Go
//go:build windows
|
|
|
|
package update
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"golang.org/x/sys/windows/registry"
|
|
)
|
|
|
|
const (
|
|
REG_FLEETD_DISPLAY_NAME = "Fleet osquery"
|
|
// registry paths, absolute and relative to the HKEY_LOCAL_MACHINE root key - see
|
|
// https://pkg.go.dev/golang.org/x/sys/windows/registry#LOCAL_MACHINE and
|
|
// https://learn.microsoft.com/en-us/troubleshoot/windows-server/performance/windows-registry-advanced-users
|
|
HKEY_LOCAL_MACHINE_PATH = `Computer\HKEY_LOCAL_MACHINE`
|
|
REG_UNINSTALL_REL_PATH = `SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall`
|
|
REG_UNINSTALL_ABS_PATH = HKEY_LOCAL_MACHINE_PATH + `\` + REG_UNINSTALL_REL_PATH
|
|
)
|
|
|
|
func updateUninstallFleetdRegistryVersion(newVersion string) error {
|
|
// Since fleetd doesn't know its GUID key in the registry, iterate through all of them until we find
|
|
// the appropriate key
|
|
|
|
// path from the HKEY_LOCAL_MACHINE registry root key ("Computer\HKEY_LOCAL_MACHINE") to the key
|
|
// for the uninstall Fleetd registry entry. That is, REG_UNINSTALL_REL_PATH + `\` + (GUID of
|
|
// Fleetd entry ). This format is for compatibility with the registry.OpenKey function signature
|
|
uninstallFleetdRegRelPath, err := findUninstallFleetdRegKeyRelPath()
|
|
if err != nil {
|
|
return fmt.Errorf(`couldn't find the uninstall fleetd registry key in '%v': %w`, REG_UNINSTALL_ABS_PATH, err)
|
|
}
|
|
|
|
setKey, err := registry.OpenKey(registry.LOCAL_MACHINE, uninstallFleetdRegRelPath, registry.SET_VALUE)
|
|
if err != nil {
|
|
return fmt.Errorf(`couldn't open 'SET_VALUE' key handle for '%v\%v": %w`, HKEY_LOCAL_MACHINE_PATH, uninstallFleetdRegRelPath, err)
|
|
}
|
|
defer setKey.Close()
|
|
|
|
if err := setKey.SetStringValue("DisplayVersion", newVersion); err != nil {
|
|
return fmt.Errorf(`couldn't set value 'DisplayVersion' for '%v\%v: %w`, HKEY_LOCAL_MACHINE_PATH, uninstallFleetdRegRelPath, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func findUninstallFleetdRegKeyRelPath() (string, error) {
|
|
// get the existing keys in the Uninstall registry directory
|
|
enumerateKeyHandle, err := registry.OpenKey(registry.LOCAL_MACHINE, REG_UNINSTALL_REL_PATH, registry.READ)
|
|
if err != nil {
|
|
return "", fmt.Errorf(`couldn't open registry key '%v': %w`, REG_UNINSTALL_ABS_PATH, err)
|
|
}
|
|
defer enumerateKeyHandle.Close()
|
|
|
|
stat, err := enumerateKeyHandle.Stat()
|
|
if err != nil {
|
|
return "", fmt.Errorf(`couldn't get stat from registry key handle for '%v': %w`, REG_UNINSTALL_ABS_PATH, err)
|
|
}
|
|
subKeyCount := stat.SubKeyCount
|
|
|
|
keys, err := enumerateKeyHandle.ReadSubKeyNames(int(subKeyCount))
|
|
if err != nil {
|
|
return "", fmt.Errorf(`couldn't read subkeys of registry key handle for '%v': %w`, REG_UNINSTALL_ABS_PATH, err)
|
|
}
|
|
|
|
// find the Fleetd entry in the existing keys
|
|
var fleetdKey string
|
|
for _, key := range keys {
|
|
keyHandle, err := registry.OpenKey(registry.LOCAL_MACHINE, REG_UNINSTALL_REL_PATH+`\`+key, registry.READ)
|
|
if err != nil {
|
|
return "", fmt.Errorf(`couldn't open registry subkey handle for '%v\%v': %w`, REG_UNINSTALL_ABS_PATH, key, err)
|
|
}
|
|
defer keyHandle.Close()
|
|
displayName, _, err := keyHandle.GetStringValue("DisplayName")
|
|
if err != nil {
|
|
if errors.Is(err, registry.ErrNotExist) {
|
|
// this key doesn't have a `DisplayName`, so it's not the entry for Fleetd - keep looking
|
|
continue
|
|
}
|
|
return "", fmt.Errorf(`couldn't get registry string value 'DisplayName' for '%v\%v': %w`, REG_UNINSTALL_ABS_PATH, key, err)
|
|
}
|
|
if displayName == REG_FLEETD_DISPLAY_NAME {
|
|
fleetdKey = key
|
|
break
|
|
}
|
|
}
|
|
|
|
if fleetdKey == "" {
|
|
return "", errors.New(`couldn't find a corresponding registry value for fleetd in 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall`)
|
|
}
|
|
|
|
return REG_UNINSTALL_REL_PATH + `\` + fleetdKey, nil
|
|
}
|