From 01f36cc57183e91828f6392db5ed252bb538d8f6 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Fri, 9 Feb 2024 20:48:44 +0100 Subject: [PATCH] Implement pincache --- agent/config/config.go | 21 ++++++++++-- agent/pincache/pincache.go | 41 +++++++++++++++++++++++ agent/processsecurity/unix.go | 4 ++- agent/systemauth/biometrics/biometrics.go | 10 ------ agent/systemauth/biometrics/polkit.go | 8 ----- agent/unixsocketagent.go | 4 ++- 6 files changed, 65 insertions(+), 23 deletions(-) create mode 100644 agent/pincache/pincache.go diff --git a/agent/config/config.go b/agent/config/config.go index 9e9dd3d..4dfadb9 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -16,6 +16,7 @@ import ( "github.com/google/uuid" "github.com/quexten/goldwarden/agent/bitwarden/crypto" "github.com/quexten/goldwarden/agent/notify" + "github.com/quexten/goldwarden/agent/pincache" "github.com/quexten/goldwarden/agent/systemauth/pinentry" "github.com/quexten/goldwarden/agent/vault" "github.com/tink-crypto/tink-go/v2/aead/subtle" @@ -130,6 +131,7 @@ func (c *Config) Unlock(password string) bool { keyBuffer := NewBufferFromBytes(key, c.useMemguard) c.key = &keyBuffer notify.Notify("Goldwarden", "Vault Unlocked", "", 60*time.Second, func() {}) + pincache.SetPin(c.useMemguard, []byte(password)) return true } @@ -218,6 +220,8 @@ func (c *Config) UpdatePin(password string, write bool) { if write { c.WriteConfig() } + + pincache.SetPin(c.useMemguard, []byte(password)) } func (c *Config) GetToken() (LoginToken, error) { @@ -536,10 +540,21 @@ func ReadConfig(rtCfg RuntimeConfig) (Config, error) { } func (cfg *Config) TryUnlock(vault *vault.Vault) error { - pin, err := pinentry.GetPassword("Unlock Goldwarden", "Enter the vault PIN") - if err != nil { - return err + var pin string + if pincache.HasPin() { + pinBytes, err := pincache.GetPin() + if err != nil { + return err + } + pin = string(pinBytes) + } else { + var err error + pin, err = pinentry.GetPassword("Unlock Goldwarden", "Enter the vault PIN") + if err != nil { + return err + } } + success := cfg.Unlock(pin) if !success { return errors.New("invalid PIN") diff --git a/agent/pincache/pincache.go b/agent/pincache/pincache.go new file mode 100644 index 0000000..2e65786 --- /dev/null +++ b/agent/pincache/pincache.go @@ -0,0 +1,41 @@ +package pincache + +import ( + "errors" + + "github.com/awnumar/memguard" + "github.com/quexten/goldwarden/agent/systemauth/biometrics" +) + +var cachedPin *memguard.Enclave + +func SetPin(useMemguard bool, pin []byte) { + cachedPin = memguard.NewEnclave(pin) +} + +func GetPin() ([]byte, error) { + approved := biometrics.CheckBiometrics(biometrics.SSHKey) + if approved { + bufer, err := cachedPin.Open() + if err != nil { + return nil, err + } + return bufer.Bytes(), nil + } else { + return nil, errors.New("biometrics not approved") + } +} + +func HasPin() bool { + return cachedPin != nil +} + +func ClearPin() { + pin, err := cachedPin.Open() + if err != nil { + cachedPin = nil + return + } + pin.Destroy() + cachedPin = nil +} diff --git a/agent/processsecurity/unix.go b/agent/processsecurity/unix.go index 71cf416..ca71f7b 100644 --- a/agent/processsecurity/unix.go +++ b/agent/processsecurity/unix.go @@ -9,6 +9,8 @@ import ( "golang.org/x/sys/unix" ) +const IDLE_TIME = 60 * 15 + func DisableDumpable() error { return unix.Prctl(unix.PR_SET_DUMPABLE, 0, 0, 0, 0) } @@ -70,7 +72,7 @@ func MonitorIdle(onidle func()) error { return err } secondsIdle := res / 1000 - if secondsIdle > 60*1 { + if secondsIdle > IDLE_TIME { if !wasidle { wasidle = true onidle() diff --git a/agent/systemauth/biometrics/biometrics.go b/agent/systemauth/biometrics/biometrics.go index 327a445..159146f 100644 --- a/agent/systemauth/biometrics/biometrics.go +++ b/agent/systemauth/biometrics/biometrics.go @@ -1,21 +1,11 @@ package biometrics import ( - "os" - "github.com/quexten/goldwarden/logging" ) var log = logging.GetLogger("Goldwarden", "Biometrics") -var biometricsDisabled = false - -func init() { - if os.Getenv("GOLDWARDEN_SYSTEM_AUTH_DISABLED") == "true" { - biometricsDisabled = true - } -} - type Approval string const ( diff --git a/agent/systemauth/biometrics/polkit.go b/agent/systemauth/biometrics/polkit.go index c22ade2..a45b941 100644 --- a/agent/systemauth/biometrics/polkit.go +++ b/agent/systemauth/biometrics/polkit.go @@ -43,10 +43,6 @@ const POLICY = ` ` func CheckBiometrics(approvalType Approval) bool { - if biometricsDisabled { - return true - } - log.Info("Checking biometrics for %s", approvalType.String()) authority, err := polkit.NewAuthority() @@ -84,10 +80,6 @@ func CheckBiometrics(approvalType Approval) bool { } func BiometricsWorking() bool { - if biometricsDisabled { - return false - } - authority, err := polkit.NewAuthority() if err != nil { log.Warn("Failed to create polkit authority: %s", err.Error()) diff --git a/agent/unixsocketagent.go b/agent/unixsocketagent.go index 45204e2..c6306f9 100644 --- a/agent/unixsocketagent.go +++ b/agent/unixsocketagent.go @@ -382,7 +382,9 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error { }() go func() { err = processsecurity.MonitorIdle(func() { - log.Warn("Idling detected but no action is implemented") + cfg.Lock() + vault.Clear() + vault.Keyring.Lock() }) if err != nil { log.Warn("Could not monitor idle: %s", err.Error())