Add more logging
This commit is contained in:
parent
82d576d546
commit
3a1e47ff67
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
28
cmd/vault.go
28
cmd/vault.go
@ -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)
|
||||
}
|
||||
|
@ -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{})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user