From a94d8f052bb54ee5cc7550b5f676ccdc2cb77780 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 12 Feb 2024 17:41:23 +0100 Subject: [PATCH] Reduce number of ssh approval prompts --- agent/ssh/ssh.go | 23 ++++++++++++++++------- agent/systemauth/systemauth.go | 16 ++++++++++++++-- agent/unixsocketagent.go | 2 ++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/agent/ssh/ssh.go b/agent/ssh/ssh.go index 415780d..e0e1d65 100644 --- a/agent/ssh/ssh.go +++ b/agent/ssh/ssh.go @@ -130,14 +130,23 @@ func (vaultAgent vaultAgent) Sign(key ssh.PublicKey, data []byte) (*ssh.Signatur message = fmt.Sprintf(requestTemplate, vaultAgent.context.UserName, sshKey.Name) } - if approved, err := pinentry.GetApproval("SSH Key Signing Request", message); err != nil || !approved { - log.Info("Sign Request for key: %s denied", sshKey.Name) - return nil, errors.New("Approval not given") - } + // todo refactor + if !systemauth.GetSSHSession(vaultAgent.context) { + if approved, err := pinentry.GetApproval("SSH Key Signing Request", message); err != nil || !approved { + log.Info("Sign Request for key: %s denied", sshKey.Name) + return nil, errors.New("Approval not given") + } - 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") + if !systemauth.VerifyPinSession(vaultAgent.context) { + 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") + } + } + + systemauth.CreateSSHSession(vaultAgent.context) + } else { + log.Info("Using cached session approval") } var rand = rand.Reader diff --git a/agent/systemauth/systemauth.go b/agent/systemauth/systemauth.go index b889d70..8f44099 100644 --- a/agent/systemauth/systemauth.go +++ b/agent/systemauth/systemauth.go @@ -22,7 +22,7 @@ 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 + Pin SessionType = "com.quexten.goldwarden.pin" ) var sessionStore = SessionStore{ @@ -55,7 +55,7 @@ func (s *SessionStore) CreateSession(pid int, parentpid int, grandparentpid int, func (s *SessionStore) verifySession(ctx sockets.CallingContext, sessionType SessionType) bool { for _, session := range s.Store { - if session.ParentPid == ctx.ParentProcessPid && session.GrandParentPid == ctx.GrandParentProcessPid && (session.sessionType == sessionType || session.sessionType == Pin) { + if session.ParentPid == ctx.ParentProcessPid && session.GrandParentPid == ctx.GrandParentProcessPid && session.sessionType == sessionType { if session.Expires.After(time.Now()) { return true } @@ -136,3 +136,15 @@ func CreatePinSession(ctx sockets.CallingContext, ttl time.Duration) Session { func VerifyPinSession(ctx sockets.CallingContext) bool { return sessionStore.verifySession(ctx, Pin) } + +func CreateSSHSession(ctx sockets.CallingContext) Session { + return sessionStore.CreateSession(ctx.ProcessPid, ctx.ParentProcessPid, ctx.GrandParentProcessPid, SSHKey, SSHTTL) +} + +func GetSSHSession(ctx sockets.CallingContext) bool { + return sessionStore.verifySession(ctx, SSHKey) +} + +func WipeSessions() { + sessionStore.Store = []Session{} +} diff --git a/agent/unixsocketagent.go b/agent/unixsocketagent.go index c6306f9..149f1a5 100644 --- a/agent/unixsocketagent.go +++ b/agent/unixsocketagent.go @@ -375,6 +375,7 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error { cfg.Lock() vault.Clear() vault.Keyring.Lock() + systemauth.WipeSessions() }) if err != nil { log.Warn("Could not monitor screensaver: %s", err.Error()) @@ -385,6 +386,7 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error { cfg.Lock() vault.Clear() vault.Keyring.Lock() + systemauth.WipeSessions() }) if err != nil { log.Warn("Could not monitor idle: %s", err.Error())