Implement pincache

This commit is contained in:
Bernd Schoolmann 2024-02-09 20:48:44 +01:00
parent dc05cdfee6
commit 01f36cc571
No known key found for this signature in database
6 changed files with 65 additions and 23 deletions

View File

@ -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")
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")

View File

@ -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
}

View File

@ -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()

View File

@ -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 (

View File

@ -43,10 +43,6 @@ const POLICY = `<?xml version="1.0" encoding="UTF-8"?>
</policyconfig>`
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())

View File

@ -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())