Add more logging

This commit is contained in:
Bernd Schoolmann 2023-12-22 10:44:49 +01:00
parent 82d576d546
commit 3a1e47ff67
No known key found for this signature in database
9 changed files with 113 additions and 22 deletions

View File

@ -15,28 +15,33 @@ import (
)
func handleGetBiometricsKey(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) {
actionsLog.Info("Browser Biometrics: Key requested, verifying biometrics...")
if !(systemauth.VerifyPinSession(*ctx) || biometrics.CheckBiometrics(biometrics.BrowserBiometrics)) {
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
Success: false,
Message: "not approved",
})
actionsLog.Info("Browser Biometrics: Biometrics not approved %v", err)
if err != nil {
return messages.IPCMessage{}, err
}
return response, nil
}
actionsLog.Info("Browser Biometrics: Biometrics verified, asking for approval...")
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 = messages.IPCMessageFromPayload(messages.ActionResponse{
Success: false,
Message: "not approved",
})
actionsLog.Info("Browser Biometrics: Biometrics not approved %v", err)
if err != nil {
return messages.IPCMessage{}, err
}
return response, nil
}
actionsLog.Info("Browser Biometrics: Approved, getting key...")
masterKey, err := cfg.GetMasterKey()
if err != nil {
return messages.IPCMessage{}, err
@ -45,6 +50,7 @@ func handleGetBiometricsKey(request messages.IPCMessage, cfg *config.Config, vau
response, err = messages.IPCMessageFromPayload(messages.GetBiometricsKeyResponse{
Key: masterKeyB64,
})
actionsLog.Info("Browser Biometrics: Sending key...")
return response, err
}

View File

@ -185,10 +185,20 @@ func handlePinStatus(request messages.IPCMessage, cfg *config.Config, vault *vau
return
}
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())
response, err = messages.IPCMessageFromPayload(vaultStatus)
return
}
func init() {
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{}), ensureBiometricsAuthorized(systemauth.AccessVault, handleUpdateVaultPin))
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.GetVaultPINRequest{}), handlePinStatus)
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.VaultStatusRequest{}), handleVaultStatus)
}

View File

@ -2,8 +2,12 @@ package crypto
import (
"errors"
"github.com/quexten/goldwarden/logging"
)
var keyringLog = logging.GetLogger("Goldwarden", "Keyring")
type Keyring struct {
AccountKey SymmetricEncryptionKey
AsymmetricEncyryptionKey AsymmetricEncryptionKey
@ -12,12 +16,14 @@ type Keyring struct {
}
func NewMemoryKeyring(accountKey *MemorySymmetricEncryptionKey) Keyring {
keyringLog.Info("Creating new memory keyring")
return Keyring{
AccountKey: accountKey,
}
}
func NewMemguardKeyring(accountKey *MemguardSymmetricEncryptionKey) Keyring {
keyringLog.Info("Creating new memguard keyring")
return Keyring{
AccountKey: accountKey,
}
@ -28,6 +34,7 @@ func (keyring Keyring) IsLocked() bool {
}
func (keyring *Keyring) Lock() {
keyringLog.Info("Locking keyring")
keyring.AccountKey = nil
keyring.AsymmetricEncyryptionKey = MemoryAsymmetricEncryptionKey{}
keyring.OrganizationKeys = nil

View File

@ -30,35 +30,39 @@ func Sync(ctx context.Context, config *config.Config) (models.SyncData, error) {
func DoFullSync(ctx context.Context, vault *vault.Vault, config *config.Config, userSymmetricKey *crypto.SymmetricEncryptionKey, allowCache bool) error {
log.Info("Performing full sync...")
sync, err := Sync(ctx, config)
if err != nil {
log.Error("Could not sync: %v", err)
if allowCache {
home, _ := os.UserHomeDir()
sync, err = ReadVault(home + path)
} else {
return err
}
} else {
log.Info("Sync successful, initializing keyring and vault...")
}
var orgKeys map[string]string = make(map[string]string)
log.Info("Initializing %d org keys...", len(sync.Profile.Organizations))
for _, org := range sync.Profile.Organizations {
orgId := org.Id.String()
orgKeys[orgId] = org.Key
}
if userSymmetricKey != nil {
log.Info("Initializing keyring from user symmetric key...")
crypto.InitKeyringFromUserSymmetricKey(vault.Keyring, *userSymmetricKey, sync.Profile.PrivateKey, orgKeys)
}
log.Info("Clearing vault...")
vault.Clear()
log.Info("Adding %d ciphers to vault...", len(sync.Ciphers))
for _, cipher := range sync.Ciphers {
switch cipher.Type {
case models.CipherLogin:
vault.AddOrUpdateLogin(cipher)
break
case models.CipherNote:
vault.AddOrUpdateSecureNote(cipher)
break
}
}

View File

@ -3,7 +3,6 @@ package bitwarden
import (
"bytes"
"context"
"fmt"
"net/url"
"os"
"os/signal"
@ -49,7 +48,7 @@ const (
)
const (
WEBSOCKET_SLEEP_DURATION_SECONDS = 5
WEBSOCKET_SLEEP_DURATION_SECONDS = 60
)
func RunWebsocketDaemon(ctx context.Context, vault *vault.Vault, cfg *config.Config) {
@ -95,12 +94,15 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con
go func() {
defer close(done)
for {
mt, message, err := c.ReadMessage()
fmt.Println(mt)
_, message, err := c.ReadMessage()
if err != nil {
websocketLog.Error("Error reading websocket message %s", err)
return
}
if len(message) < 3 {
//ignore empty messages
continue
}
if messageType, cipherid, success := websocketMessageType(message); success {
var mt1 = NotificationMessageType(messageType)

View File

@ -2,8 +2,7 @@
package processsecurity
import "golang.org/x/sys/unix"
func DisableDumpable() error {
return unix.Prctl(unix.PR_SET_DUMPABLE, 0, 0, 0, 0)
// return unix.Prctl(unix.PR_SET_DUMPABLE, 0, 0, 0, 0)
return nil
}

View File

@ -7,10 +7,12 @@ import (
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
"github.com/quexten/goldwarden/agent/bitwarden/models"
"github.com/rs/zerolog/log"
"github.com/quexten/goldwarden/logging"
"golang.org/x/exp/slices"
)
var vaultLog = logging.GetLogger("Goldwarden", "Vault")
type Vault struct {
Keyring *crypto.Keyring
logins map[string]models.Cipher
@ -94,7 +96,7 @@ func (vault *Vault) isEnv(cipher models.Cipher) (string, bool) {
key, err := cipher.GetKeyForCipher(*vault.Keyring)
if err != nil {
log.Warn().Err(err).Msg("Failed to get key for cipher " + cipher.ID.String())
vaultLog.Error("Failed to get key for cipher "+cipher.ID.String(), err.Error())
return "", false
}
@ -132,7 +134,7 @@ func (vault *Vault) isSSHKey(cipher models.Cipher) bool {
key, err := cipher.GetKeyForCipher(*vault.Keyring)
if err != nil {
log.Warn().Err(err).Msg("Failed to get key for cipher " + cipher.ID.String())
vaultLog.Error("Failed to get key for cipher "+cipher.ID.String(), err.Error())
return false
}
@ -140,8 +142,12 @@ func (vault *Vault) isSSHKey(cipher models.Cipher) bool {
fieldName, err := crypto.DecryptWith(field.Name, key)
if err != nil {
cipherID := cipher.ID.String()
orgID := cipher.OrganizationID.String()
log.Warn().Err(err).Msg("Failed to decrypt field name with on cipher " + cipherID + " in organization " + orgID)
if cipher.OrganizationID != nil {
orgID := cipher.OrganizationID.String()
vaultLog.Error("Failed to decrypt field name with on cipher "+cipherID+" in organization "+orgID, err.Error())
} else {
vaultLog.Error("Failed to decrypt field name with on cipher "+cipherID, err.Error())
}
continue
}
fieldValue, err := crypto.DecryptWith(field.Value, key)
@ -229,7 +235,7 @@ func (vault *Vault) GetEnvCredentialForExecutable(executableName string) (map[st
if id, ok := vault.envCredentials[executableName]; ok {
key, err := vault.secureNotes[id].GetKeyForCipher(*vault.Keyring)
if err != nil {
log.Warn().Err(err).Msg("Failed to get key for cipher " + id)
vaultLog.Error("Failed to get key for cipher " + id)
return make(map[string]string), false
}
@ -302,7 +308,7 @@ func (vault *Vault) GetLoginByFilter(uuid string, orgId string, name string, use
key, err := cipher.GetKeyForCipher(*vault.Keyring)
if err != nil {
log.Warn().Err(err).Msg("Failed to get key for cipher " + cipher.ID.String())
vaultLog.Error("Failed to get key for cipher " + cipher.ID.String())
continue
}
if name != "" {
@ -312,7 +318,7 @@ func (vault *Vault) GetLoginByFilter(uuid string, orgId string, name string, use
decryptedName, err := crypto.DecryptWith(cipher.Name, key)
if err != nil {
log.Warn().Err(err).Msg("Failed to decrypt name for cipher " + cipher.ID.String())
vaultLog.Error("Failed to decrypt name for cipher " + cipher.ID.String())
continue
}
if name != "" && string(decryptedName) != name {
@ -327,7 +333,7 @@ func (vault *Vault) GetLoginByFilter(uuid string, orgId string, name string, use
decryptedUsername, err := crypto.DecryptWith(cipher.Login.Username, key)
if err != nil {
log.Warn().Err(err).Msg("Failed to decrypt username for cipher " + cipher.ID.String())
vaultLog.Error("Failed to decrypt username for cipher " + cipher.ID.String())
continue
}
if username != "" && string(decryptedUsername) != username {
@ -338,7 +344,7 @@ func (vault *Vault) GetLoginByFilter(uuid string, orgId string, name string, use
return cipher, nil
}
return models.Cipher{}, errors.New("Cipher not found")
return models.Cipher{}, errors.New("cipher not found")
}
func (vault *Vault) GetNoteByFilter(uuid string, orgId string, name string) (models.Cipher, error) {
@ -355,12 +361,12 @@ func (vault *Vault) GetNoteByFilter(uuid string, orgId string, name string) (mod
key, err := cipher.GetKeyForCipher(*vault.Keyring)
if err != nil {
log.Warn().Err(err).Msg("Failed to get key for cipher " + cipher.ID.String())
vaultLog.Error("Failed to get key for cipher "+cipher.ID.String(), err.Error())
continue
}
decryptedName, err := crypto.DecryptWith(cipher.Name, key)
if err != nil {
log.Warn().Err(err).Msg("Failed to decrypt name for cipher " + cipher.ID.String())
vaultLog.Error("Failed to decrypt name for cipher "+cipher.ID.String(), err.Error())
continue
}
if name != "" && string(decryptedName) != name {

View File

@ -1,6 +1,8 @@
package cmd
import (
"fmt"
"github.com/quexten/goldwarden/ipc/messages"
"github.com/spf13/cobra"
)
@ -89,9 +91,35 @@ var purgeCmd = &cobra.Command{
},
}
var statusCmd = &cobra.Command{
Use: "status",
Short: "Shows the vault status",
Long: `Shows the vault status.`,
Run: func(cmd *cobra.Command, args []string) {
request := messages.VaultStatusRequest{}
result, err := commandClient.SendToAgent(request)
if err != nil {
handleSendToAgentError(err)
return
}
switch result.(type) {
case messages.VaultStatusResponse:
status := result.(messages.VaultStatusResponse)
fmt.Println("Locked: ", status.Locked)
fmt.Println("Number of logins: ", status.NumberOfLogins)
fmt.Println("Number of notes: ", status.NumberOfNotes)
default:
println("Wrong response type")
}
},
}
func init() {
rootCmd.AddCommand(vaultCmd)
vaultCmd.AddCommand(unlockCmd)
vaultCmd.AddCommand(lockCmd)
vaultCmd.AddCommand(purgeCmd)
vaultCmd.AddCommand(statusCmd)
}

View File

@ -17,6 +17,17 @@ type WipeVaultRequest struct {
type GetVaultPINRequest struct {
}
type VaultStatusRequest struct {
}
type VaultStatusResponse struct {
Locked bool
NumberOfLogins int
NumberOfNotes int
// todo websocket status
// todo last synced
}
func init() {
registerPayloadParser(func(payload []byte) (interface{}, error) {
var req LockVaultRequest
@ -62,4 +73,22 @@ func init() {
}
return req, nil
}, GetVaultPINRequest{})
registerPayloadParser(func(payload []byte) (interface{}, error) {
var req VaultStatusRequest
err := json.Unmarshal(payload, &req)
if err != nil {
panic("Unmarshal: " + err.Error())
}
return req, nil
}, VaultStatusRequest{})
registerPayloadParser(func(payload []byte) (interface{}, error) {
var req VaultStatusResponse
err := json.Unmarshal(payload, &req)
if err != nil {
panic("Unmarshal: " + err.Error())
}
return req, nil
}, VaultStatusResponse{})
}