Rework systemauth
This commit is contained in:
parent
368fe2bae6
commit
e53a49b47a
1
PKGBUILD
1
PKGBUILD
|
@ -31,4 +31,5 @@ package() {
|
|||
cd "$pkgname-$pkgver"
|
||||
install -Dm755 build/$pkgname "$pkgdir"/usr/bin/$pkgname
|
||||
install -Dm644 "$srcdir/$pkgname-$pkgver/resources/com.quexten.goldwarden.policy" "$pkgdir/usr/share/polkit-1/actions/com.quexten.goldwarden.policy"
|
||||
chown root:root "$pkgdir/usr/share/polkit-1/actions/com.quexten.goldwarden.policy"
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/quexten/goldwarden/agent/config"
|
||||
"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/ipc"
|
||||
)
|
||||
|
@ -81,16 +80,16 @@ func ensureIsNotLocked(action Action) Action {
|
|||
})
|
||||
}
|
||||
|
||||
systemauth.CreateSession(*ctx)
|
||||
systemauth.CreatePinSession(*ctx)
|
||||
}
|
||||
|
||||
return action(request, cfg, vault, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func ensureBiometricsAuthorized(approvalType biometrics.Approval, action Action) Action {
|
||||
func ensureBiometricsAuthorized(approvalType systemauth.SessionType, action Action) Action {
|
||||
return func(request ipc.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (ipc.IPCMessage, error) {
|
||||
if !systemauth.CheckBiometrics(ctx, approvalType) {
|
||||
if permission, err := systemauth.GetPermission(approvalType, *ctx, cfg); err != nil || !permission {
|
||||
return ipc.IPCMessageFromPayload(ipc.ActionResponse{
|
||||
Success: false,
|
||||
Message: "Polkit authorization failed required",
|
||||
|
@ -101,6 +100,6 @@ func ensureBiometricsAuthorized(approvalType biometrics.Approval, action Action)
|
|||
}
|
||||
}
|
||||
|
||||
func ensureEverything(approvalType biometrics.Approval, action Action) Action {
|
||||
func ensureEverything(approvalType systemauth.SessionType, action Action) Action {
|
||||
return ensureIsNotLocked(ensureIsLoggedIn(ensureBiometricsAuthorized(approvalType, action)))
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/sockets"
|
||||
"github.com/quexten/goldwarden/agent/systemauth"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
|
||||
"github.com/quexten/goldwarden/agent/vault"
|
||||
|
@ -13,6 +14,17 @@ import (
|
|||
)
|
||||
|
||||
func handleGetBiometricsKey(request ipc.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response ipc.IPCMessage, err error) {
|
||||
if !(systemauth.VerifyPinSession(*ctx) || biometrics.CheckBiometrics(biometrics.BrowserBiometrics)) {
|
||||
response, err = ipc.IPCMessageFromPayload(ipc.ActionResponse{
|
||||
Success: false,
|
||||
Message: "not approved",
|
||||
})
|
||||
if err != nil {
|
||||
return ipc.IPCMessage{}, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
if approved, err := pinentry.GetApproval("Approve Credential Access", fmt.Sprintf("%s on %s>%s>%s is trying to access your vault encryption key for browser biometric unlock.", ctx.UserName, ctx.GrandParentProcessName, ctx.ParentProcessName, ctx.ProcessName)); err != nil || !approved {
|
||||
response, err = ipc.IPCMessageFromPayload(ipc.ActionResponse{
|
||||
Success: false,
|
||||
|
@ -25,6 +37,9 @@ func handleGetBiometricsKey(request ipc.IPCMessage, cfg *config.Config, vault *v
|
|||
}
|
||||
|
||||
masterKey, err := cfg.GetMasterKey()
|
||||
if err != nil {
|
||||
return ipc.IPCMessage{}, err
|
||||
}
|
||||
masterKeyB64 := base64.StdEncoding.EncodeToString(masterKey)
|
||||
response, err = ipc.IPCMessageFromPayload(ipc.GetBiometricsKeyResponse{
|
||||
Key: masterKeyB64,
|
||||
|
@ -33,5 +48,5 @@ func handleGetBiometricsKey(request ipc.IPCMessage, cfg *config.Config, vault *v
|
|||
}
|
||||
|
||||
func init() {
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeGetBiometricsKeyRequest, ensureEverything(biometrics.BrowserBiometrics, handleGetBiometricsKey))
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeGetBiometricsKeyRequest, ensureIsNotLocked(ensureIsLoggedIn(handleGetBiometricsKey)))
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/sockets"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
|
||||
"github.com/quexten/goldwarden/agent/systemauth"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
|
||||
"github.com/quexten/goldwarden/agent/vault"
|
||||
"github.com/quexten/goldwarden/ipc"
|
||||
|
@ -45,5 +45,5 @@ func handleGetCliCredentials(request ipc.IPCMessage, cfg *config.Config, vault *
|
|||
}
|
||||
|
||||
func init() {
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeGetCLICredentialsRequest, ensureEverything(biometrics.AccessCredential, handleGetCliCredentials))
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeGetCLICredentialsRequest, ensureEverything(systemauth.AccessVault, handleGetCliCredentials))
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/sockets"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
|
||||
"github.com/quexten/goldwarden/agent/systemauth"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
|
||||
"github.com/quexten/goldwarden/agent/vault"
|
||||
"github.com/quexten/goldwarden/ipc"
|
||||
|
@ -157,6 +157,6 @@ func handleListLoginsRequest(request ipc.IPCMessage, cfg *config.Config, vault *
|
|||
}
|
||||
|
||||
func init() {
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageGetLoginRequest, ensureEverything(biometrics.AccessCredential, handleGetLoginCipher))
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageListLoginsRequest, ensureEverything(biometrics.AccessCredential, handleListLoginsRequest))
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageGetLoginRequest, ensureEverything(systemauth.AccessVault, handleGetLoginCipher))
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageListLoginsRequest, ensureEverything(systemauth.AccessVault, handleListLoginsRequest))
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/sockets"
|
||||
"github.com/quexten/goldwarden/agent/ssh"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
|
||||
"github.com/quexten/goldwarden/agent/systemauth"
|
||||
"github.com/quexten/goldwarden/agent/vault"
|
||||
"github.com/quexten/goldwarden/ipc"
|
||||
"github.com/quexten/goldwarden/logging"
|
||||
|
@ -57,6 +57,6 @@ func handleListSSH(msg ipc.IPCMessage, cfg *config.Config, vault *vault.Vault, c
|
|||
}
|
||||
|
||||
func init() {
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeCreateSSHKeyRequest, ensureEverything(biometrics.SSHKey, handleAddSSH))
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeCreateSSHKeyRequest, ensureEverything(systemauth.SSHKey, handleAddSSH))
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeGetSSHKeysRequest, ensureIsNotLocked(ensureIsLoggedIn(handleListSSH)))
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/sockets"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
|
||||
"github.com/quexten/goldwarden/agent/systemauth"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
|
||||
"github.com/quexten/goldwarden/agent/vault"
|
||||
"github.com/quexten/goldwarden/ipc"
|
||||
|
@ -181,6 +181,6 @@ func init() {
|
|||
AgentActionsRegistry.Register(ipc.IPCMessageTypeUnlockVaultRequest, handleUnlockVault)
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeLockVaultRequest, handleLockVault)
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeWipeVaultRequest, handleWipeVault)
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeUpdateVaultPINRequest, ensureBiometricsAuthorized(biometrics.ChangePin, handleUpdateVaultPin))
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeUpdateVaultPINRequest, ensureBiometricsAuthorized(systemauth.AccessVault, handleUpdateVaultPin))
|
||||
AgentActionsRegistry.Register(ipc.IPCMessageTypeGetVaultPINStatusRequest, handlePinStatus)
|
||||
}
|
||||
|
|
|
@ -179,11 +179,12 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con
|
|||
}
|
||||
websocketLog.Info("AuthRequest details " + authRequest.RequestIpAddress + " " + authRequest.RequestDeviceType)
|
||||
|
||||
if approved, err := pinentry.GetApproval("Paswordless Login Request", "Do you want to allow "+authRequest.RequestIpAddress+" ("+authRequest.RequestDeviceType+") to login to your account?"); err != nil || !approved {
|
||||
var message = "Do you want to allow " + authRequest.RequestIpAddress + " (" + authRequest.RequestDeviceType + ") to login to your account?"
|
||||
if approved, err := pinentry.GetApproval("Paswordless Login Request", message); err != nil || !approved {
|
||||
websocketLog.Info("AuthRequest denied")
|
||||
break
|
||||
}
|
||||
if !biometrics.CheckBiometrics(biometrics.AccessCredential) {
|
||||
if !biometrics.CheckBiometrics(biometrics.AccessVault) {
|
||||
websocketLog.Info("AuthRequest denied - biometrics required")
|
||||
break
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ type RuntimeConfig struct {
|
|||
User string
|
||||
Password string
|
||||
Pin string
|
||||
SessionToken string
|
||||
}
|
||||
|
||||
type ConfigFile struct {
|
||||
|
@ -121,6 +120,18 @@ func (c *Config) Unlock(password string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (c *Config) VerifyPin(password string) bool {
|
||||
key := argon2.Key([]byte(password), []byte(c.ConfigFile.DeviceUUID), KDFIterations, KDFMemory, KDFThreads, 32)
|
||||
debug.FreeOSMemory()
|
||||
keyHash := sha3.Sum256(key)
|
||||
configKeyHash := hex.EncodeToString(keyHash[:])
|
||||
if cryptoSubtle.ConstantTimeCompare([]byte(configKeyHash), []byte(c.ConfigFile.ConfigKeyHash)) != 1 {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) Lock() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
|
|
@ -8,9 +8,9 @@ import (
|
|||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/sockets"
|
||||
"github.com/quexten/goldwarden/agent/systemauth"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
|
||||
"github.com/quexten/goldwarden/agent/vault"
|
||||
"github.com/quexten/goldwarden/logging"
|
||||
|
@ -22,6 +22,7 @@ var log = logging.GetLogger("Goldwarden", "SSH")
|
|||
|
||||
type vaultAgent struct {
|
||||
vault *vault.Vault
|
||||
config *config.Config
|
||||
unlockRequestAction func() bool
|
||||
context sockets.CallingContext
|
||||
}
|
||||
|
@ -77,7 +78,7 @@ func (vaultAgent vaultAgent) Sign(key ssh.PublicKey, data []byte) (*ssh.Signatur
|
|||
return nil, errors.New("vault is locked")
|
||||
}
|
||||
|
||||
systemauth.CreateSession(vaultAgent.context)
|
||||
systemauth.CreatePinSession(vaultAgent.context)
|
||||
}
|
||||
|
||||
var signer ssh.Signer
|
||||
|
@ -103,7 +104,7 @@ func (vaultAgent vaultAgent) Sign(key ssh.PublicKey, data []byte) (*ssh.Signatur
|
|||
return nil, errors.New("Approval not given")
|
||||
}
|
||||
|
||||
if !systemauth.CheckBiometrics(&vaultAgent.context, biometrics.SSHKey) {
|
||||
if permission, err := systemauth.GetPermission(systemauth.SSHKey, vaultAgent.context, vaultAgent.config); err != nil || !permission {
|
||||
log.Info("Sign Request for key: %s denied", key.Marshal())
|
||||
return nil, errors.New("Biometrics not checked")
|
||||
}
|
||||
|
@ -124,6 +125,7 @@ func (vaultAgent) Unlock(passphrase []byte) error {
|
|||
|
||||
type SSHAgentServer struct {
|
||||
vault *vault.Vault
|
||||
config *config.Config
|
||||
unlockRequestAction func() bool
|
||||
}
|
||||
|
||||
|
@ -131,9 +133,10 @@ func (v *SSHAgentServer) SetUnlockRequestAction(action func() bool) {
|
|||
v.unlockRequestAction = action
|
||||
}
|
||||
|
||||
func NewVaultAgent(vault *vault.Vault) SSHAgentServer {
|
||||
func NewVaultAgent(vault *vault.Vault, config *config.Config) SSHAgentServer {
|
||||
return SSHAgentServer{
|
||||
vault: vault,
|
||||
vault: vault,
|
||||
config: config,
|
||||
unlockRequestAction: func() bool {
|
||||
log.Info("Unlock Request, but no action defined")
|
||||
return false
|
||||
|
@ -175,6 +178,7 @@ func (v SSHAgentServer) Serve() {
|
|||
|
||||
go agent.ServeAgent(vaultAgent{
|
||||
vault: v.vault,
|
||||
config: v.config,
|
||||
unlockRequestAction: v.unlockRequestAction,
|
||||
context: callingContext,
|
||||
}, conn)
|
||||
|
|
|
@ -19,10 +19,8 @@ func init() {
|
|||
type Approval string
|
||||
|
||||
const (
|
||||
AccessCredential Approval = "com.quexten.goldwarden.accesscredential"
|
||||
ChangePin Approval = "com.quexten.goldwarden.changepin"
|
||||
AccessVault Approval = "com.quexten.goldwarden.accessvault"
|
||||
SSHKey Approval = "com.quexten.goldwarden.usesshkey"
|
||||
ModifyVault Approval = "com.quexten.goldwarden.modifyvault"
|
||||
BrowserBiometrics Approval = "com.quexten.goldwarden.browserbiometrics"
|
||||
)
|
||||
|
||||
|
|
|
@ -12,18 +12,9 @@ const POLICY = `<?xml version="1.0" encoding="UTF-8"?>
|
|||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
|
||||
<policyconfig>
|
||||
<action id="com.quexten.goldwarden.accesscredential">
|
||||
<description>Allow Credential Access</description>
|
||||
<message>Authenticate to allow access to a single credential</message>
|
||||
<defaults>
|
||||
<allow_any>auth_self</allow_any>
|
||||
<allow_inactive>auth_self</allow_inactive>
|
||||
<allow_active>auth_self</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
<action id="com.quexten.goldwarden.changepin">
|
||||
<description>Approve Pin Change</description>
|
||||
<message>Authenticate to change your Goldwarden PIN.</message>
|
||||
<action id="com.quexten.goldwarden.accessvault">
|
||||
<description>Allow access to the vault</description>
|
||||
<message>Allows access to the vault entries</message>
|
||||
<defaults>
|
||||
<allow_any>auth_self</allow_any>
|
||||
<allow_inactive>auth_self</allow_inactive>
|
||||
|
@ -31,7 +22,7 @@ const POLICY = `<?xml version="1.0" encoding="UTF-8"?>
|
|||
</defaults>
|
||||
</action>
|
||||
<action id="com.quexten.goldwarden.usesshkey">
|
||||
<description>Use Bitwarden SSH Key</description>
|
||||
<description>Use SSH Key</description>
|
||||
<message>Authenticate to use an SSH Key from your vault</message>
|
||||
<defaults>
|
||||
<allow_any>auth_self</allow_any>
|
||||
|
@ -39,15 +30,6 @@ const POLICY = `<?xml version="1.0" encoding="UTF-8"?>
|
|||
<allow_active>auth_self</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
<action id="com.quexten.goldwarden.modifyvault">
|
||||
<description>Modify Bitwarden Vault</description>
|
||||
<message>Authenticate to allow modification of your Bitvarden vault in Goldwarden</message>
|
||||
<defaults>
|
||||
<allow_any>auth_self</allow_any>
|
||||
<allow_inactive>auth_self</allow_inactive>
|
||||
<allow_active>auth_self</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
<action id="com.quexten.goldwarden.browserbiometrics">
|
||||
<description>Browser Biometrics</description>
|
||||
<message>Authenticate to allow Goldwarden to unlock your browser.</message>
|
||||
|
@ -68,16 +50,18 @@ func CheckBiometrics(approvalType Approval) bool {
|
|||
|
||||
authority, err := polkit.NewAuthority()
|
||||
if err != nil {
|
||||
log.Error("Failed to create polkit authority: %s", err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
result, err := authority.CheckAuthorization(
|
||||
approvalType.String(),
|
||||
nil,
|
||||
polkit.CheckAuthorizationAllowUserInteraction, "",
|
||||
uint32(polkit.AuthenticationRequiredRetained), "",
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Error("Failed to create polkit authority: %s", err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -85,3 +69,32 @@ func CheckBiometrics(approvalType Approval) bool {
|
|||
|
||||
return result.IsAuthorized
|
||||
}
|
||||
|
||||
func BiometricsWorking() bool {
|
||||
if biometricsDisabled {
|
||||
return false
|
||||
}
|
||||
|
||||
authority, err := polkit.NewAuthority()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
result, err := authority.EnumerateActions("en")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(result) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
testFor := AccessVault
|
||||
for _, action := range result {
|
||||
if Approval(action.ActionID) == testFor {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
package systemauth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/sockets"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
|
||||
"github.com/quexten/goldwarden/logging"
|
||||
)
|
||||
|
||||
var log = logging.GetLogger("Goldwarden", "Systemauth")
|
||||
|
||||
const tokenExpiry = 10 * time.Minute
|
||||
|
||||
type SessionType string
|
||||
|
||||
const (
|
||||
AccessVault SessionType = "com.quexten.goldwarden.accessvault"
|
||||
SSHKey SessionType = "com.quexten.goldwarden.usesshkey"
|
||||
Pin SessionType = "com.quexten.goldwarden.pin" // this counts as all other permissions
|
||||
)
|
||||
|
||||
var sessionStore = SessionStore{
|
||||
Store: []Session{},
|
||||
}
|
||||
|
@ -19,26 +33,28 @@ type Session struct {
|
|||
ParentPid int
|
||||
GrandParentPid int
|
||||
Expires time.Time
|
||||
sessionType SessionType
|
||||
}
|
||||
|
||||
type SessionStore struct {
|
||||
Store []Session
|
||||
}
|
||||
|
||||
func (s *SessionStore) CreateSession(pid int, parentpid int, grandparentpid int) Session {
|
||||
func (s *SessionStore) CreateSession(pid int, parentpid int, grandparentpid int, sessionType SessionType) Session {
|
||||
var session = Session{
|
||||
Pid: pid,
|
||||
ParentPid: parentpid,
|
||||
GrandParentPid: grandparentpid,
|
||||
Expires: time.Now().Add(tokenExpiry),
|
||||
sessionType: sessionType,
|
||||
}
|
||||
s.Store = append(s.Store, session)
|
||||
return session
|
||||
}
|
||||
|
||||
func (s *SessionStore) VerifySession(ctx sockets.CallingContext) bool {
|
||||
func (s *SessionStore) verifySession(ctx sockets.CallingContext, sessionType SessionType) bool {
|
||||
for _, session := range s.Store {
|
||||
if session.ParentPid == ctx.ParentProcessPid && session.GrandParentPid == ctx.GrandParentProcessPid {
|
||||
if session.ParentPid == ctx.ParentProcessPid && session.GrandParentPid == ctx.GrandParentProcessPid && (session.sessionType == sessionType || session.sessionType == Pin) {
|
||||
if session.Expires.After(time.Now()) {
|
||||
return true
|
||||
}
|
||||
|
@ -47,34 +63,70 @@ func (s *SessionStore) VerifySession(ctx sockets.CallingContext) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func GetApproval(title string, description string, requriesBiometrics bool) (bool, error) {
|
||||
approval, err := pinentry.GetApproval(title, description)
|
||||
if err != nil {
|
||||
return false, err
|
||||
// with session
|
||||
func GetPermission(sessionType SessionType, ctx sockets.CallingContext, config *config.Config) (bool, error) {
|
||||
log.Info("Checking permission for " + ctx.ProcessName + " with session type " + string(sessionType))
|
||||
var actionDescription = ""
|
||||
biometricsApprovalType := biometrics.AccessVault
|
||||
switch sessionType {
|
||||
case AccessVault:
|
||||
actionDescription = "access the vault"
|
||||
biometricsApprovalType = biometrics.AccessVault
|
||||
case SSHKey:
|
||||
actionDescription = "use an SSH key for signing"
|
||||
biometricsApprovalType = biometrics.SSHKey
|
||||
}
|
||||
if requriesBiometrics {
|
||||
biometricsApproval := biometrics.CheckBiometrics(biometrics.AccessCredential)
|
||||
if !biometricsApproval {
|
||||
return false, nil
|
||||
var message = fmt.Sprintf("Do you want to authorize %s>%s>%s to %s? (This choice will be remembered for %d minutes)", ctx.GrandParentProcessName, ctx.ParentProcessName, ctx.ProcessName, actionDescription, int(math.Floor(tokenExpiry.Minutes())))
|
||||
|
||||
if sessionStore.verifySession(ctx, sessionType) {
|
||||
log.Info("Permission granted from cached session")
|
||||
} else {
|
||||
if biometrics.BiometricsWorking() {
|
||||
biometricsApproval := biometrics.CheckBiometrics(biometricsApprovalType)
|
||||
if !biometricsApproval {
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
pin, err := pinentry.GetPassword("Enter PIN", "Biometrics is not available. Enter your pin to authorize this action. "+message)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !config.VerifyPin(pin) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
approval, err := pinentry.GetApproval("Goldwarden authorization", message)
|
||||
if err != nil || !approval {
|
||||
return false, err
|
||||
}
|
||||
|
||||
log.Info("Permission granted, creating session")
|
||||
sessionStore.CreateSession(ctx.ProcessPid, ctx.ParentProcessPid, ctx.GrandParentProcessPid, sessionType)
|
||||
}
|
||||
return approval, nil
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// no session
|
||||
func CheckBiometrics(callingContext *sockets.CallingContext, approvalType biometrics.Approval) bool {
|
||||
if sessionStore.VerifySession(*callingContext) {
|
||||
return true
|
||||
}
|
||||
|
||||
var approval = biometrics.CheckBiometrics(approvalType)
|
||||
if !approval {
|
||||
var message = fmt.Sprintf("Do you want to grant %s>%s>%s one-time access your vault?", callingContext.GrandParentProcessName, callingContext.ParentProcessName, callingContext.ProcessName)
|
||||
var bioApproval = biometrics.CheckBiometrics(approvalType)
|
||||
if !bioApproval {
|
||||
return false
|
||||
}
|
||||
|
||||
sessionStore.CreateSession(callingContext.ProcessPid, callingContext.ParentProcessPid, callingContext.GrandParentProcessPid)
|
||||
return true
|
||||
approval, err := pinentry.GetApproval("Goldwarden authorization", message)
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
}
|
||||
|
||||
return approval
|
||||
}
|
||||
|
||||
func CreateSession(ctx sockets.CallingContext) {
|
||||
sessionStore.CreateSession(ctx.ProcessPid, ctx.ParentProcessPid, ctx.GrandParentProcessPid)
|
||||
func CreatePinSession(ctx sockets.CallingContext) {
|
||||
sessionStore.CreateSession(ctx.ProcessPid, ctx.ParentProcessPid, ctx.GrandParentProcessPid, Pin)
|
||||
}
|
||||
|
||||
func VerifyPinSession(ctx sockets.CallingContext) bool {
|
||||
return sessionStore.verifySession(ctx, Pin)
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error {
|
|||
}
|
||||
|
||||
if !runtimeConfig.DisableSSHAgent {
|
||||
vaultAgent := ssh.NewVaultAgent(vault)
|
||||
vaultAgent := ssh.NewVaultAgent(vault, &cfg)
|
||||
vaultAgent.SetUnlockRequestAction(func() bool {
|
||||
err := cfg.TryUnlock(vault)
|
||||
if err == nil {
|
||||
|
|
6
main.go
6
main.go
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/browserbiometrics"
|
||||
"github.com/quexten/goldwarden/client/setup"
|
||||
"github.com/quexten/goldwarden/cmd"
|
||||
)
|
||||
|
||||
|
@ -39,7 +38,6 @@ func main() {
|
|||
User: os.Getenv("GOLDWARDEN_AUTH_USER"),
|
||||
Password: os.Getenv("GOLDWARDEN_AUTH_PASSWORD"),
|
||||
Pin: os.Getenv("GOLDWARDEN_PIN"),
|
||||
SessionToken: os.Getenv("GOLDWARDEN_SESSION_TOKEN"),
|
||||
|
||||
ConfigDirectory: configPath,
|
||||
}
|
||||
|
@ -57,9 +55,5 @@ func main() {
|
|||
os.Setenv("GOLDWARDEN_SYSTEM_AUTH_DISABLED", "true")
|
||||
}
|
||||
|
||||
if !setup.VerifySetup(runtimeConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
cmd.Execute(runtimeConfig)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue