goldwarden-vaultwarden-bitw.../agent/actions/vault.go

271 lines
7.6 KiB
Go
Raw Normal View History

2023-07-17 03:23:26 +02:00
package actions
import (
"context"
"github.com/quexten/goldwarden/agent/bitwarden"
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
2023-07-17 03:23:26 +02:00
"github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/agent/sockets"
"github.com/quexten/goldwarden/agent/systemauth/biometrics"
2023-09-12 02:54:46 +02:00
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
2023-07-17 03:23:26 +02:00
"github.com/quexten/goldwarden/agent/vault"
2023-09-20 03:05:44 +02:00
"github.com/quexten/goldwarden/ipc/messages"
2023-07-17 03:23:26 +02:00
)
2023-09-20 03:05:44 +02:00
func handleUnlockVault(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) {
2023-07-17 03:23:26 +02:00
if !cfg.HasPin() {
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: false,
Message: "No pin set",
})
if err != nil {
panic(err)
}
return
}
if !cfg.IsLocked() {
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: true,
Message: "Unlocked",
})
if err != nil {
panic(err)
}
return
}
err = cfg.TryUnlock(vault)
if err != nil {
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: false,
2023-07-17 05:42:21 +02:00
Message: "wrong pin: " + err.Error(),
2023-07-17 03:23:26 +02:00
})
if err != nil {
panic(err)
}
return
}
2024-01-19 05:14:25 +01:00
actionsLog.Info("Unlocking vault...")
2023-07-17 05:42:21 +02:00
if cfg.IsLoggedIn() {
token, err := cfg.GetToken()
if err == nil {
if token.AccessToken != "" {
ctx := context.Background()
2024-01-19 05:14:25 +01:00
gotToken := bitwarden.RefreshToken(ctx, cfg)
if gotToken {
actionsLog.Info("Token refreshed")
} else {
actionsLog.Warn("Token refresh failed")
}
2023-07-17 05:42:21 +02:00
token, err := cfg.GetToken()
2024-01-19 05:14:25 +01:00
if err != nil {
actionsLog.Error("Could not get token: %s", err.Error())
}
userSymmkey, err := cfg.GetUserSymmetricKey()
if err != nil {
2024-01-19 05:14:25 +01:00
actionsLog.Error("Could not get user symmetric key: %s", err.Error())
}
2023-12-22 08:02:23 +01:00
var safeUserSymmkey crypto.SymmetricEncryptionKey
if vault.Keyring.IsMemguard {
safeUserSymmkey, err = crypto.MemguardSymmetricEncryptionKeyFromBytes(userSymmkey)
} else {
safeUserSymmkey, err = crypto.MemorySymmetricEncryptionKeyFromBytes(userSymmkey)
}
if err != nil {
2024-01-19 05:14:25 +01:00
actionsLog.Error("Could not create safe user symmetric key: %s", err.Error())
}
2023-12-22 08:02:23 +01:00
err = bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, cfg, &safeUserSymmkey, true)
2023-07-17 05:42:21 +02:00
if err != nil {
2024-01-19 05:14:25 +01:00
actionsLog.Error("Could not sync: %s", err.Error())
2023-07-17 05:42:21 +02:00
}
2024-01-19 05:14:25 +01:00
} else {
actionsLog.Warn("Access token is empty")
2023-07-17 03:23:26 +02:00
}
2024-01-19 05:14:25 +01:00
} else {
actionsLog.Warn("Could not get token: %s", err.Error())
2023-07-17 03:23:26 +02:00
}
}
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: true,
})
if err != nil {
panic(err)
}
return
}
2023-09-20 03:05:44 +02:00
func handleLockVault(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) {
2023-07-17 03:23:26 +02:00
if !cfg.HasPin() {
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: false,
Message: "No pin set",
})
if err != nil {
panic(err)
}
return
}
if cfg.IsLocked() {
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: true,
Message: "Locked",
})
if err != nil {
panic(err)
}
return
}
cfg.Lock()
vault.Clear()
vault.Keyring.Lock()
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: true,
})
if err != nil {
panic(err)
}
return
}
2023-09-20 03:05:44 +02:00
func handleWipeVault(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) {
2023-07-17 03:23:26 +02:00
cfg.Purge()
cfg.WriteConfig()
vault.Clear()
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: true,
})
if err != nil {
panic(err)
}
return
}
2023-09-20 03:05:44 +02:00
func handleUpdateVaultPin(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) {
//todo refactor
if cfg.HasPin() {
authenticated := false
if cfg.IsLocked() {
actionsLog.Info("Browser Biometrics: Vault is locked, asking for pin...")
err := cfg.TryUnlock(vault)
if err != nil {
actionsLog.Info("Browser Biometrics: Vault not unlocked")
return messages.IPCMessage{}, err
}
ctx1 := context.Background()
success := sync(ctx1, vault, cfg)
if !success {
actionsLog.Info("Browser Biometrics: Vault not synced")
return messages.IPCMessage{}, err
}
actionsLog.Info("Browser Biometrics: Vault unlocked")
authenticated = true
} else {
authenticated = biometrics.CheckBiometrics(biometrics.BrowserBiometrics)
if !authenticated {
// todo, skip when explicitly denied instead of error
actionsLog.Info("Browser Biometrics: Biometrics not approved, asking for pin...")
pin, err := pinentry.GetPassword("Goldwarden", "Enter your pin to unlock your vault")
if err == nil {
authenticated = cfg.VerifyPin(pin)
if !authenticated {
actionsLog.Info("Browser Biometrics: Pin not approved")
} else {
actionsLog.Info("Browser Biometrics: Pin approved")
}
}
} else {
actionsLog.Info("Browser Biometrics: Biometrics approved")
}
}
if !authenticated {
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
Success: false,
Message: "Not authenticated",
})
if err != nil {
return messages.IPCMessage{}, err
} else {
return response, nil
}
}
}
2023-09-12 02:54:46 +02:00
pin, err := pinentry.GetPassword("Pin Change", "Enter your desired pin")
2023-07-17 03:23:26 +02:00
if err != nil {
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: false,
Message: err.Error(),
})
if err != nil {
2023-09-20 03:05:44 +02:00
return messages.IPCMessage{}, err
2023-07-17 03:23:26 +02:00
} else {
return response, nil
}
}
cfg.UpdatePin(pin, true)
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: true,
})
return
}
2023-09-20 03:05:44 +02:00
func handlePinStatus(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) {
2023-07-17 03:23:26 +02:00
var pinStatus string
if cfg.HasPin() {
pinStatus = "enabled"
} else {
pinStatus = "disabled"
}
2023-09-20 03:05:44 +02:00
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
2023-07-17 03:23:26 +02:00
Success: true,
Message: pinStatus,
})
return
}
2023-12-22 10:44:49 +01:00
func handleVaultStatus(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) {
var vaultStatus messages.VaultStatusResponse = messages.VaultStatusResponse{}
vaultStatus.Locked = cfg.IsLocked()
vaultStatus.NumberOfLogins = len(vault.GetLogins())
vaultStatus.NumberOfNotes = len(vault.GetNotes())
vaultStatus.LastSynced = vault.GetLastSynced()
vaultStatus.WebsockedConnected = vault.IsWebsocketConnected()
2023-12-28 01:09:49 +01:00
vaultStatus.PinSet = cfg.HasPin()
vaultStatus.LoggedIn = cfg.IsLoggedIn()
2023-12-22 10:44:49 +01:00
response, err = messages.IPCMessageFromPayload(vaultStatus)
return
}
2023-07-17 03:23:26 +02:00
func init() {
2023-09-20 03:05:44 +02:00
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.UnlockVaultRequest{}), handleUnlockVault)
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.LockVaultRequest{}), handleLockVault)
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.WipeVaultRequest{}), handleWipeVault)
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.UpdateVaultPINRequest{}), handleUpdateVaultPin)
2023-09-20 03:05:44 +02:00
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.GetVaultPINRequest{}), handlePinStatus)
2023-12-22 10:44:49 +01:00
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.VaultStatusRequest{}), handleVaultStatus)
2023-07-17 03:23:26 +02:00
}