| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- // Copyright (c) Tailscale Inc & AUTHORS
- // SPDX-License-Identifier: BSD-3-Clause
- package syspolicy
- import (
- "errors"
- "sync/atomic"
- )
- var (
- handlerUsed atomic.Bool
- handler Handler = defaultHandler{}
- )
- // Handler reads system policies from OS-specific storage.
- type Handler interface {
- // ReadString reads the policy setting's string value for the given key.
- // It should return ErrNoSuchKey if the key does not have a value set.
- ReadString(key string) (string, error)
- // ReadUInt64 reads the policy setting's uint64 value for the given key.
- // It should return ErrNoSuchKey if the key does not have a value set.
- ReadUInt64(key string) (uint64, error)
- // ReadBool reads the policy setting's boolean value for the given key.
- // It should return ErrNoSuchKey if the key does not have a value set.
- ReadBoolean(key string) (bool, error)
- // ReadStringArray reads the policy setting's string array value for the given key.
- // It should return ErrNoSuchKey if the key does not have a value set.
- ReadStringArray(key string) ([]string, error)
- }
- // ErrNoSuchKey is returned by a Handler when the specified key does not have a
- // value set.
- var ErrNoSuchKey = errors.New("no such key")
- // defaultHandler is the catch all syspolicy type for anything that isn't windows or apple.
- type defaultHandler struct{}
- func (defaultHandler) ReadString(_ string) (string, error) {
- return "", ErrNoSuchKey
- }
- func (defaultHandler) ReadUInt64(_ string) (uint64, error) {
- return 0, ErrNoSuchKey
- }
- func (defaultHandler) ReadBoolean(_ string) (bool, error) {
- return false, ErrNoSuchKey
- }
- func (defaultHandler) ReadStringArray(_ string) ([]string, error) {
- return nil, ErrNoSuchKey
- }
- // markHandlerInUse is called before handler methods are called.
- func markHandlerInUse() {
- handlerUsed.Store(true)
- }
- // RegisterHandler initializes the policy handler and ensures registration will happen once.
- func RegisterHandler(h Handler) {
- // Technically this assignment is not concurrency safe, but in the
- // event that there was any risk of a data race, we will panic due to
- // the CompareAndSwap failing.
- handler = h
- if !handlerUsed.CompareAndSwap(false, true) {
- panic("handler was already used before registration")
- }
- }
- // TB is a subset of testing.TB that we use to set up test helpers.
- // It's defined here to avoid pulling in the testing package.
- type TB interface {
- Helper()
- Cleanup(func())
- }
- func SetHandlerForTest(tb TB, h Handler) {
- tb.Helper()
- oldHandler := handler
- handler = h
- tb.Cleanup(func() { handler = oldHandler })
- }
|