goldwarden-vaultwarden-bitw.../agent/systemauth/systemauth.go

139 lines
4.2 KiB
Go
Raw Normal View History

2023-09-12 18:56:35 +02:00
package systemauth
import (
2023-09-19 21:49:56 +02:00
"fmt"
"math"
2023-09-12 18:56:35 +02:00
"time"
2023-09-19 21:49:56 +02:00
"github.com/quexten/goldwarden/agent/config"
2023-09-12 18:56:35 +02:00
"github.com/quexten/goldwarden/agent/sockets"
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
2023-09-19 21:49:56 +02:00
"github.com/quexten/goldwarden/logging"
2023-09-12 18:56:35 +02:00
)
2023-09-19 21:49:56 +02:00
var log = logging.GetLogger("Goldwarden", "Systemauth")
2024-02-09 19:32:01 +01:00
const tokenExpiry = 60 * time.Minute
const SSHTTL = 60 * time.Minute
2023-09-12 18:56:35 +02:00
2023-09-19 21:49:56 +02:00
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
)
2023-09-12 18:56:35 +02:00
var sessionStore = SessionStore{
Store: []Session{},
}
type Session struct {
Pid int
ParentPid int
GrandParentPid int
Expires time.Time
2023-09-19 21:49:56 +02:00
sessionType SessionType
2023-09-12 18:56:35 +02:00
}
type SessionStore struct {
Store []Session
}
2024-02-09 19:32:01 +01:00
func (s *SessionStore) CreateSession(pid int, parentpid int, grandparentpid int, sessionType SessionType, ttl time.Duration) Session {
2023-09-12 18:56:35 +02:00
var session = Session{
Pid: pid,
ParentPid: parentpid,
GrandParentPid: grandparentpid,
2024-02-09 19:32:01 +01:00
Expires: time.Now().Add(ttl),
2023-09-19 21:49:56 +02:00
sessionType: sessionType,
2023-09-12 18:56:35 +02:00
}
s.Store = append(s.Store, session)
return session
}
2023-09-19 21:49:56 +02:00
func (s *SessionStore) verifySession(ctx sockets.CallingContext, sessionType SessionType) bool {
2023-09-12 18:56:35 +02:00
for _, session := range s.Store {
2023-09-19 21:49:56 +02:00
if session.ParentPid == ctx.ParentProcessPid && session.GrandParentPid == ctx.GrandParentProcessPid && (session.sessionType == sessionType || session.sessionType == Pin) {
2023-09-12 18:56:35 +02:00
if session.Expires.After(time.Now()) {
return true
}
}
}
return false
}
2023-09-19 21:49:56 +02:00
// with session
func GetPermission(sessionType SessionType, ctx sockets.CallingContext, config *config.Config) (bool, error) {
if ctx.Authenticated {
return true, nil
}
2023-09-19 21:49:56 +02:00
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
2023-09-12 18:56:35 +02:00
}
2023-09-19 21:49:56 +02:00
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 {
log.Warn("Biometrics is not available, asking for pin")
2023-09-19 21:49:56 +02:00
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
}
2023-09-12 18:56:35 +02:00
}
2023-09-19 21:49:56 +02:00
// approval, err := pinentry.GetApproval("Goldwarden authorization", message)
// if err != nil || !approval {
// return false, err
// }
2023-09-19 21:49:56 +02:00
log.Info("Permission granted, creating session")
2024-02-09 19:32:01 +01:00
sessionStore.CreateSession(ctx.ProcessPid, ctx.ParentProcessPid, ctx.GrandParentProcessPid, sessionType, tokenExpiry)
2023-09-12 18:56:35 +02:00
}
2023-09-19 21:49:56 +02:00
return true, nil
2023-09-12 18:56:35 +02:00
}
2023-09-19 21:49:56 +02:00
// no session
2023-09-12 18:56:35 +02:00
func CheckBiometrics(callingContext *sockets.CallingContext, approvalType biometrics.Approval) bool {
2023-09-19 21:49:56 +02:00
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
2023-09-12 18:56:35 +02:00
}
2023-09-19 21:49:56 +02:00
approval, err := pinentry.GetApproval("Goldwarden authorization", message)
if err != nil {
log.Error(err.Error())
2023-09-12 18:56:35 +02:00
}
2023-09-19 21:49:56 +02:00
return approval
}
2024-02-09 19:32:01 +01:00
func CreatePinSession(ctx sockets.CallingContext, ttl time.Duration) Session {
return sessionStore.CreateSession(ctx.ProcessPid, ctx.ParentProcessPid, ctx.GrandParentProcessPid, Pin, ttl)
2023-09-12 18:56:35 +02:00
}
2023-09-19 21:49:56 +02:00
func VerifyPinSession(ctx sockets.CallingContext) bool {
return sessionStore.verifySession(ctx, Pin)
2023-09-12 18:56:35 +02:00
}