Add touchid biometrics

This commit is contained in:
Bernd Schoolmann 2023-09-12 01:22:48 +02:00
parent 9c157e17ac
commit 5f06f46534
No known key found for this signature in database
13 changed files with 78 additions and 33 deletions

View File

@ -7,7 +7,7 @@ import (
"github.com/quexten/goldwarden/agent/bitwarden/crypto" "github.com/quexten/goldwarden/agent/bitwarden/crypto"
"github.com/quexten/goldwarden/agent/config" "github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/agent/sockets" "github.com/quexten/goldwarden/agent/sockets"
"github.com/quexten/goldwarden/agent/systemauth" "github.com/quexten/goldwarden/agent/systemauth/biometrics"
"github.com/quexten/goldwarden/agent/vault" "github.com/quexten/goldwarden/agent/vault"
"github.com/quexten/goldwarden/ipc" "github.com/quexten/goldwarden/ipc"
) )
@ -85,9 +85,9 @@ func ensureIsNotLocked(action Action) Action {
} }
} }
func ensureBiometricsAuthorized(approvalType systemauth.Approval, action Action) Action { func ensureBiometricsAuthorized(approvalType biometrics.Approval, action Action) Action {
return func(request ipc.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx sockets.CallingContext) (interface{}, error) { return func(request ipc.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx sockets.CallingContext) (interface{}, error) {
if !systemauth.CheckBiometrics(approvalType) { if !biometrics.CheckBiometrics(approvalType) {
return ipc.IPCMessageFromPayload(ipc.ActionResponse{ return ipc.IPCMessageFromPayload(ipc.ActionResponse{
Success: false, Success: false,
Message: "Polkit authorization failed required", Message: "Polkit authorization failed required",
@ -98,6 +98,6 @@ func ensureBiometricsAuthorized(approvalType systemauth.Approval, action Action)
} }
} }
func ensureEverything(approvalType systemauth.Approval, action Action) Action { func ensureEverything(approvalType biometrics.Approval, action Action) Action {
return ensureIsNotLocked(ensureIsLoggedIn(ensureBiometricsAuthorized(approvalType, action))) return ensureIsNotLocked(ensureIsLoggedIn(ensureBiometricsAuthorized(approvalType, action)))
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/quexten/goldwarden/agent/config" "github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/agent/sockets" "github.com/quexten/goldwarden/agent/sockets"
"github.com/quexten/goldwarden/agent/systemauth" "github.com/quexten/goldwarden/agent/systemauth"
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
"github.com/quexten/goldwarden/agent/vault" "github.com/quexten/goldwarden/agent/vault"
"github.com/quexten/goldwarden/ipc" "github.com/quexten/goldwarden/ipc"
) )
@ -32,5 +33,5 @@ func handleGetBiometricsKey(request ipc.IPCMessage, cfg *config.Config, vault *v
} }
func init() { func init() {
AgentActionsRegistry.Register(ipc.IPCMessageTypeGetBiometricsKeyRequest, ensureEverything(systemauth.BrowserBiometrics, handleGetBiometricsKey)) AgentActionsRegistry.Register(ipc.IPCMessageTypeGetBiometricsKeyRequest, ensureEverything(biometrics.BrowserBiometrics, handleGetBiometricsKey))
} }

View File

@ -6,6 +6,7 @@ import (
"github.com/quexten/goldwarden/agent/config" "github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/agent/sockets" "github.com/quexten/goldwarden/agent/sockets"
"github.com/quexten/goldwarden/agent/systemauth" "github.com/quexten/goldwarden/agent/systemauth"
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
"github.com/quexten/goldwarden/agent/vault" "github.com/quexten/goldwarden/agent/vault"
"github.com/quexten/goldwarden/ipc" "github.com/quexten/goldwarden/ipc"
) )
@ -44,5 +45,5 @@ func handleGetCliCredentials(request ipc.IPCMessage, cfg *config.Config, vault *
} }
func init() { func init() {
AgentActionsRegistry.Register(ipc.IPCMessageTypeGetCLICredentialsRequest, ensureEverything(systemauth.AccessCredential, handleGetCliCredentials)) AgentActionsRegistry.Register(ipc.IPCMessageTypeGetCLICredentialsRequest, ensureEverything(biometrics.AccessCredential, handleGetCliCredentials))
} }

View File

@ -11,6 +11,7 @@ import (
"github.com/quexten/goldwarden/agent/config" "github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/agent/sockets" "github.com/quexten/goldwarden/agent/sockets"
"github.com/quexten/goldwarden/agent/systemauth" "github.com/quexten/goldwarden/agent/systemauth"
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
"github.com/quexten/goldwarden/agent/vault" "github.com/quexten/goldwarden/agent/vault"
"github.com/quexten/goldwarden/ipc" "github.com/quexten/goldwarden/ipc"
) )
@ -156,6 +157,6 @@ func handleListLoginsRequest(request ipc.IPCMessage, cfg *config.Config, vault *
} }
func init() { func init() {
AgentActionsRegistry.Register(ipc.IPCMessageGetLoginRequest, ensureEverything(systemauth.AccessCredential, handleGetLoginCipher)) AgentActionsRegistry.Register(ipc.IPCMessageGetLoginRequest, ensureEverything(biometrics.AccessCredential, handleGetLoginCipher))
AgentActionsRegistry.Register(ipc.IPCMessageListLoginsRequest, ensureEverything(systemauth.AccessCredential, handleListLoginsRequest)) AgentActionsRegistry.Register(ipc.IPCMessageListLoginsRequest, ensureEverything(biometrics.AccessCredential, handleListLoginsRequest))
} }

View File

@ -8,7 +8,7 @@ import (
"github.com/quexten/goldwarden/agent/config" "github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/agent/sockets" "github.com/quexten/goldwarden/agent/sockets"
"github.com/quexten/goldwarden/agent/ssh" "github.com/quexten/goldwarden/agent/ssh"
"github.com/quexten/goldwarden/agent/systemauth" "github.com/quexten/goldwarden/agent/systemauth/biometrics"
"github.com/quexten/goldwarden/agent/vault" "github.com/quexten/goldwarden/agent/vault"
"github.com/quexten/goldwarden/ipc" "github.com/quexten/goldwarden/ipc"
"github.com/quexten/goldwarden/logging" "github.com/quexten/goldwarden/logging"
@ -57,6 +57,6 @@ func handleListSSH(msg ipc.IPCMessage, cfg *config.Config, vault *vault.Vault, c
} }
func init() { func init() {
AgentActionsRegistry.Register(ipc.IPCMessageTypeCreateSSHKeyRequest, ensureEverything(systemauth.SSHKey, handleAddSSH)) AgentActionsRegistry.Register(ipc.IPCMessageTypeCreateSSHKeyRequest, ensureEverything(biometrics.SSHKey, handleAddSSH))
AgentActionsRegistry.Register(ipc.IPCMessageTypeGetSSHKeysRequest, ensureIsNotLocked(ensureIsLoggedIn(handleListSSH))) AgentActionsRegistry.Register(ipc.IPCMessageTypeGetSSHKeysRequest, ensureIsNotLocked(ensureIsLoggedIn(handleListSSH)))
} }

View File

@ -9,6 +9,7 @@ import (
"github.com/quexten/goldwarden/agent/config" "github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/agent/sockets" "github.com/quexten/goldwarden/agent/sockets"
"github.com/quexten/goldwarden/agent/systemauth" "github.com/quexten/goldwarden/agent/systemauth"
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
"github.com/quexten/goldwarden/agent/vault" "github.com/quexten/goldwarden/agent/vault"
"github.com/quexten/goldwarden/ipc" "github.com/quexten/goldwarden/ipc"
) )
@ -180,6 +181,6 @@ func init() {
AgentActionsRegistry.Register(ipc.IPCMessageTypeUnlockVaultRequest, handleUnlockVault) AgentActionsRegistry.Register(ipc.IPCMessageTypeUnlockVaultRequest, handleUnlockVault)
AgentActionsRegistry.Register(ipc.IPCMessageTypeLockVaultRequest, handleLockVault) AgentActionsRegistry.Register(ipc.IPCMessageTypeLockVaultRequest, handleLockVault)
AgentActionsRegistry.Register(ipc.IPCMessageTypeWipeVaultRequest, handleWipeVault) AgentActionsRegistry.Register(ipc.IPCMessageTypeWipeVaultRequest, handleWipeVault)
AgentActionsRegistry.Register(ipc.IPCMessageTypeUpdateVaultPINRequest, ensureBiometricsAuthorized(systemauth.ChangePin, handleUpdateVaultPin)) AgentActionsRegistry.Register(ipc.IPCMessageTypeUpdateVaultPINRequest, ensureBiometricsAuthorized(biometrics.ChangePin, handleUpdateVaultPin))
AgentActionsRegistry.Register(ipc.IPCMessageTypeGetVaultPINStatusRequest, handlePinStatus) AgentActionsRegistry.Register(ipc.IPCMessageTypeGetVaultPINStatusRequest, handlePinStatus)
} }

View File

@ -14,6 +14,7 @@ import (
"github.com/quexten/goldwarden/agent/bitwarden/models" "github.com/quexten/goldwarden/agent/bitwarden/models"
"github.com/quexten/goldwarden/agent/config" "github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/agent/systemauth" "github.com/quexten/goldwarden/agent/systemauth"
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
"github.com/quexten/goldwarden/agent/vault" "github.com/quexten/goldwarden/agent/vault"
"github.com/quexten/goldwarden/logging" "github.com/quexten/goldwarden/logging"
"github.com/vmihailenco/msgpack/v5" "github.com/vmihailenco/msgpack/v5"
@ -182,7 +183,7 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con
websocketLog.Info("AuthRequest denied") websocketLog.Info("AuthRequest denied")
break break
} }
if !systemauth.CheckBiometrics(systemauth.AccessCredential) { if !biometrics.CheckBiometrics(biometrics.AccessCredential) {
websocketLog.Info("AuthRequest denied - biometrics required") websocketLog.Info("AuthRequest denied - biometrics required")
break break
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/quexten/goldwarden/agent/sockets" "github.com/quexten/goldwarden/agent/sockets"
"github.com/quexten/goldwarden/agent/systemauth" "github.com/quexten/goldwarden/agent/systemauth"
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
"github.com/quexten/goldwarden/agent/vault" "github.com/quexten/goldwarden/agent/vault"
"github.com/quexten/goldwarden/logging" "github.com/quexten/goldwarden/logging"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
@ -99,7 +100,7 @@ func (vaultAgent vaultAgent) Sign(key ssh.PublicKey, data []byte) (*ssh.Signatur
return nil, errors.New("Approval not given") return nil, errors.New("Approval not given")
} }
if !systemauth.CheckBiometrics(systemauth.SSHKey) { if !biometrics.CheckBiometrics(biometrics.SSHKey) {
log.Info("Sign Request for key: %s denied", key.Marshal()) log.Info("Sign Request for key: %s denied", key.Marshal())
return nil, errors.New("Biometrics not checked") return nil, errors.New("Biometrics not checked")
} }

View File

@ -0,0 +1,25 @@
package biometrics
import "os"
var biometricsDisabled = false
func init() {
if os.Getenv("GOLDWARDEN_SYSTEM_AUTH_DISABLED") == "true" {
biometricsDisabled = true
}
}
type Approval string
const (
AccessCredential Approval = "com.quexten.goldwarden.accesscredential"
ChangePin Approval = "com.quexten.goldwarden.changepin"
SSHKey Approval = "com.quexten.goldwarden.usesshkey"
ModifyVault Approval = "com.quexten.goldwarden.modifyvault"
BrowserBiometrics Approval = "com.quexten.goldwarden.browserbiometrics"
)
func (a Approval) String() string {
return string(a)
}

View File

@ -1,21 +1,13 @@
package systemauth //go:build linux || freebsd
package biometrics
import ( import (
"github.com/amenzhinsky/go-polkit" "github.com/amenzhinsky/go-polkit"
"github.com/quexten/goldwarden/logging" "github.com/quexten/goldwarden/logging"
) )
var log = logging.GetLogger("Goldwarden", "Systemauth") var log = logging.GetLogger("Goldwarden", "Biometrics")
type Approval string
const (
AccessCredential Approval = "com.quexten.goldwarden.accesscredential"
ChangePin Approval = "com.quexten.goldwarden.changepin"
SSHKey Approval = "com.quexten.goldwarden.usesshkey"
ModifyVault Approval = "com.quexten.goldwarden.modifyvault"
BrowserBiometrics Approval = "com.quexten.goldwarden.browserbiometrics"
)
const POLICY = `<?xml version="1.0" encoding="UTF-8"?> const POLICY = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC <!DOCTYPE policyconfig PUBLIC
@ -70,12 +62,8 @@ const POLICY = `<?xml version="1.0" encoding="UTF-8"?>
</action> </action>
</policyconfig>` </policyconfig>`
func (a Approval) String() string {
return string(a)
}
func CheckBiometrics(approvalType Approval) bool { func CheckBiometrics(approvalType Approval) bool {
if systemAuthDisabled { if biometricsDisabled {
return true return true
} }

View File

@ -0,0 +1,18 @@
//go:build windows || darwin
package biometrics
func CheckBiometrics(approvalType Approval) bool {
ok, err := touchid.Authenticate(approvalType.String()
if err != nil {
log.Fatal(err)
}
if ok {
log.Printf("Authenticated")
return true
} else {
log.Fatal("Failed to authenticate")
return false
}
}

View File

@ -1,6 +1,12 @@
package systemauth package systemauth
import "os" import (
"os"
"github.com/quexten/goldwarden/logging"
)
var log = logging.GetLogger("Goldwarden", "Systemauth")
var systemAuthDisabled = false var systemAuthDisabled = false

View File

@ -1,3 +1,5 @@
//go:build linux || freebsd
package cmd package cmd
import ( import (
@ -6,7 +8,7 @@ import (
"os/exec" "os/exec"
"strings" "strings"
"github.com/quexten/goldwarden/agent/systemauth" "github.com/quexten/goldwarden/agent/systemauth/biometrics"
"github.com/quexten/goldwarden/browserbiometrics" "github.com/quexten/goldwarden/browserbiometrics"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -16,7 +18,7 @@ func setupPolkit() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
_, err = file.WriteString(systemauth.POLICY) _, err = file.WriteString(biometrics.POLICY)
if err != nil { if err != nil {
panic(err) panic(err)
} }