goldwarden/agent/systemauth/systemauth.go

134 lines
4.1 KiB
Go
Raw Normal View History

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