Merge pull request #113 from quexten/feature/pin-cache

Implement pincache
This commit is contained in:
Bernd Schoolmann 2024-02-09 21:05:15 +01:00 committed by GitHub
commit c1f21768a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 65 additions and 23 deletions

View File

@ -16,6 +16,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/quexten/goldwarden/agent/bitwarden/crypto" "github.com/quexten/goldwarden/agent/bitwarden/crypto"
"github.com/quexten/goldwarden/agent/notify" "github.com/quexten/goldwarden/agent/notify"
"github.com/quexten/goldwarden/agent/pincache"
"github.com/quexten/goldwarden/agent/systemauth/pinentry" "github.com/quexten/goldwarden/agent/systemauth/pinentry"
"github.com/quexten/goldwarden/agent/vault" "github.com/quexten/goldwarden/agent/vault"
"github.com/tink-crypto/tink-go/v2/aead/subtle" "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) keyBuffer := NewBufferFromBytes(key, c.useMemguard)
c.key = &keyBuffer c.key = &keyBuffer
notify.Notify("Goldwarden", "Vault Unlocked", "", 60*time.Second, func() {}) notify.Notify("Goldwarden", "Vault Unlocked", "", 60*time.Second, func() {})
pincache.SetPin(c.useMemguard, []byte(password))
return true return true
} }
@ -218,6 +220,8 @@ func (c *Config) UpdatePin(password string, write bool) {
if write { if write {
c.WriteConfig() c.WriteConfig()
} }
pincache.SetPin(c.useMemguard, []byte(password))
} }
func (c *Config) GetToken() (LoginToken, error) { func (c *Config) GetToken() (LoginToken, error) {
@ -536,10 +540,21 @@ func ReadConfig(rtCfg RuntimeConfig) (Config, error) {
} }
func (cfg *Config) TryUnlock(vault *vault.Vault) error { func (cfg *Config) TryUnlock(vault *vault.Vault) error {
pin, err := pinentry.GetPassword("Unlock Goldwarden", "Enter the vault PIN") var pin string
if err != nil { if pincache.HasPin() {
return err 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) success := cfg.Unlock(pin)
if !success { if !success {
return errors.New("invalid PIN") 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" "golang.org/x/sys/unix"
) )
const IDLE_TIME = 60 * 15
func DisableDumpable() error { func DisableDumpable() error {
return unix.Prctl(unix.PR_SET_DUMPABLE, 0, 0, 0, 0) return unix.Prctl(unix.PR_SET_DUMPABLE, 0, 0, 0, 0)
} }
@ -70,7 +72,7 @@ func MonitorIdle(onidle func()) error {
return err return err
} }
secondsIdle := res / 1000 secondsIdle := res / 1000
if secondsIdle > 60*1 { if secondsIdle > IDLE_TIME {
if !wasidle { if !wasidle {
wasidle = true wasidle = true
onidle() onidle()

View File

@ -1,21 +1,11 @@
package biometrics package biometrics
import ( import (
"os"
"github.com/quexten/goldwarden/logging" "github.com/quexten/goldwarden/logging"
) )
var log = logging.GetLogger("Goldwarden", "Biometrics") var log = logging.GetLogger("Goldwarden", "Biometrics")
var biometricsDisabled = false
func init() {
if os.Getenv("GOLDWARDEN_SYSTEM_AUTH_DISABLED") == "true" {
biometricsDisabled = true
}
}
type Approval string type Approval string
const ( const (

View File

@ -43,10 +43,6 @@ const POLICY = `<?xml version="1.0" encoding="UTF-8"?>
</policyconfig>` </policyconfig>`
func CheckBiometrics(approvalType Approval) bool { func CheckBiometrics(approvalType Approval) bool {
if biometricsDisabled {
return true
}
log.Info("Checking biometrics for %s", approvalType.String()) log.Info("Checking biometrics for %s", approvalType.String())
authority, err := polkit.NewAuthority() authority, err := polkit.NewAuthority()
@ -84,10 +80,6 @@ func CheckBiometrics(approvalType Approval) bool {
} }
func BiometricsWorking() bool { func BiometricsWorking() bool {
if biometricsDisabled {
return false
}
authority, err := polkit.NewAuthority() authority, err := polkit.NewAuthority()
if err != nil { if err != nil {
log.Warn("Failed to create polkit authority: %s", err.Error()) 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() { go func() {
err = processsecurity.MonitorIdle(func() { err = processsecurity.MonitorIdle(func() {
log.Warn("Idling detected but no action is implemented") cfg.Lock()
vault.Clear()
vault.Keyring.Lock()
}) })
if err != nil { if err != nil {
log.Warn("Could not monitor idle: %s", err.Error()) log.Warn("Could not monitor idle: %s", err.Error())