Merge pull request #130 from SuperSandro2000/lints-agents

Fix whole bunch of lints
This commit is contained in:
Bernd Schoolmann 2024-03-05 15:06:13 +01:00 committed by GitHub
commit bc1a94ba71
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 221 additions and 141 deletions

View File

@ -144,7 +144,14 @@ func handleGetConfigEnvironment(request messages.IPCMessage, cfg *config.Config,
func handleSetClientID(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) { func handleSetClientID(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) {
clientID := messages.ParsePayload(request).(messages.SetClientIDRequest).Value clientID := messages.ParsePayload(request).(messages.SetClientIDRequest).Value
cfg.SetClientID(clientID) err = cfg.SetClientID(clientID)
if err != nil {
return messages.IPCMessageFromPayload(messages.ActionResponse{
Success: false,
Message: err.Error(),
})
}
err = cfg.WriteConfig() err = cfg.WriteConfig()
if err != nil { if err != nil {
return messages.IPCMessageFromPayload(messages.ActionResponse{ return messages.IPCMessageFromPayload(messages.ActionResponse{
@ -160,7 +167,14 @@ func handleSetClientID(request messages.IPCMessage, cfg *config.Config, vault *v
func handleSetClientSecret(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) { func handleSetClientSecret(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) {
clientSecret := messages.ParsePayload(request).(messages.SetClientSecretRequest).Value clientSecret := messages.ParsePayload(request).(messages.SetClientSecretRequest).Value
cfg.SetClientSecret(clientSecret) err = cfg.SetClientSecret(clientSecret)
if err != nil {
return messages.IPCMessageFromPayload(messages.ActionResponse{
Success: false,
Message: err.Error(),
})
}
err = cfg.WriteConfig() err = cfg.WriteConfig()
if err != nil { if err != nil {
return messages.IPCMessageFromPayload(messages.ActionResponse{ return messages.IPCMessageFromPayload(messages.ActionResponse{

View File

@ -57,7 +57,7 @@ func handleLogin(msg messages.IPCMessage, cfg *config.Config, vault *vault.Vault
return return
} }
cfg.SetToken(config.LoginToken{ _ = cfg.SetToken(config.LoginToken{
AccessToken: token.AccessToken, AccessToken: token.AccessToken,
ExpiresIn: token.ExpiresIn, ExpiresIn: token.ExpiresIn,
TokenType: token.TokenType, TokenType: token.TokenType,
@ -88,7 +88,7 @@ func handleLogin(msg messages.IPCMessage, cfg *config.Config, vault *vault.Vault
if err != nil { if err != nil {
defer func() { defer func() {
notify.Notify("Goldwarden", "Could not decrypt. Wrong password?", "", 10*time.Second, func() {}) notify.Notify("Goldwarden", "Could not decrypt. Wrong password?", "", 10*time.Second, func() {})
cfg.SetToken(config.LoginToken{}) _ = cfg.SetToken(config.LoginToken{})
vault.Clear() vault.Clear()
}() }()
@ -103,9 +103,9 @@ func handleLogin(msg messages.IPCMessage, cfg *config.Config, vault *vault.Vault
return return
} }
cfg.SetUserSymmetricKey(vault.Keyring.GetAccountKey().Bytes()) err = cfg.SetUserSymmetricKey(vault.Keyring.GetAccountKey().Bytes())
cfg.SetMasterPasswordHash([]byte(masterpasswordHash)) err = cfg.SetMasterPasswordHash([]byte(masterpasswordHash))
cfg.SetMasterKey([]byte(masterKey.GetBytes())) err = cfg.SetMasterKey([]byte(masterKey.GetBytes()))
var protectedUserSymetricKey crypto.SymmetricEncryptionKey var protectedUserSymetricKey crypto.SymmetricEncryptionKey
if vault.Keyring.IsMemguard { if vault.Keyring.IsMemguard {
protectedUserSymetricKey, err = crypto.MemguardSymmetricEncryptionKeyFromBytes(vault.Keyring.GetAccountKey().Bytes()) protectedUserSymetricKey, err = crypto.MemguardSymmetricEncryptionKeyFromBytes(vault.Keyring.GetAccountKey().Bytes())
@ -115,7 +115,7 @@ func handleLogin(msg messages.IPCMessage, cfg *config.Config, vault *vault.Vault
if err != nil { if err != nil {
defer func() { defer func() {
notify.Notify("Goldwarden", "Could not decrypt. Wrong password?", "", 10*time.Second, func() {}) notify.Notify("Goldwarden", "Could not decrypt. Wrong password?", "", 10*time.Second, func() {})
cfg.SetToken(config.LoginToken{}) _ = cfg.SetToken(config.LoginToken{})
vault.Clear() vault.Clear()
}() }()

View File

@ -69,11 +69,7 @@ func handleGetLoginCipher(request messages.IPCMessage, cfg *config.Config, vault
if !login.Login.Totp.IsNull() { if !login.Login.Totp.IsNull() {
decryptedTotp, err := crypto.DecryptWith(login.Login.Totp, cipherKey) decryptedTotp, err := crypto.DecryptWith(login.Login.Totp, cipherKey)
if err == nil { if err == nil {
if err == nil { decryptedLogin.TOTPSeed = string(decryptedTotp)
decryptedLogin.TOTPSeed = string(decryptedTotp)
} else {
fmt.Println(err)
}
} else { } else {
fmt.Println(string(decryptedTotp)) fmt.Println(string(decryptedTotp))
} }
@ -117,11 +113,7 @@ func handleListLoginsRequest(request messages.IPCMessage, cfg *config.Config, va
continue continue
} }
var decryptedName []byte = []byte{} var decryptedName, decryptedUsername, decryptedPassword, decryptedTotp, decryptedURL []byte
var decryptedUsername []byte = []byte{}
var decryptedPassword []byte = []byte{}
var decryptedTotp []byte = []byte{}
var decryptedURL []byte = []byte{}
if !login.Name.IsNull() { if !login.Name.IsNull() {
decryptedName, err = crypto.DecryptWith(login.Name, key) decryptedName, err = crypto.DecryptWith(login.Name, key)

View File

@ -146,7 +146,10 @@ func handleLockVault(request messages.IPCMessage, cfg *config.Config, vault *vau
func handleWipeVault(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) { func handleWipeVault(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) {
cfg.Purge() cfg.Purge()
cfg.WriteConfig() err = cfg.WriteConfig()
if err != nil {
panic(err)
}
vault.Clear() vault.Clear()
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{ response, err = messages.IPCMessageFromPayload(messages.ActionResponse{

View File

@ -208,7 +208,15 @@ func LoginWithDevice(ctx context.Context, email string, cfg *config.Config, vaul
} }
if authRequestData.RequestApproved { if authRequestData.RequestApproved {
masterKey, err := crypto.DecryptWithAsymmetric([]byte(authRequestData.Key), publicKey) masterKey, err := crypto.DecryptWithAsymmetric([]byte(authRequestData.Key), publicKey)
if err != nil {
return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("could not decrypt key with asymmetric key: %s", err.Error())
}
masterPasswordHash, err := crypto.DecryptWithAsymmetric([]byte(authRequestData.MasterPasswordHash), publicKey) masterPasswordHash, err := crypto.DecryptWithAsymmetric([]byte(authRequestData.MasterPasswordHash), publicKey)
if err != nil {
return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("could not decrypt master password hash with asymmetric key: %s", err.Error())
}
values := urlValues( values := urlValues(
"grant_type", "password", "grant_type", "password",
"username", email, "username", email,
@ -233,7 +241,7 @@ func LoginWithDevice(ctx context.Context, email string, cfg *config.Config, vaul
return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("captcha required, please login via the web interface") return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("captcha required, please login via the web interface")
} else if err != nil { } else if err != nil {
return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("could not login via password: %v", err) return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("could not login via password: %s", err.Error())
} }
return loginResponseToken, crypto.MasterKeyFromBytes(masterKey), string(masterPasswordHash), nil return loginResponseToken, crypto.MasterKeyFromBytes(masterKey), string(masterPasswordHash), nil
} }
@ -282,13 +290,17 @@ func RefreshToken(ctx context.Context, cfg *config.Config) bool {
return false return false
} }
cfg.SetToken(config.LoginToken{ err = cfg.SetToken(config.LoginToken{
AccessToken: loginResponseToken.AccessToken, AccessToken: loginResponseToken.AccessToken,
RefreshToken: "", RefreshToken: "",
Key: loginResponseToken.Key, Key: loginResponseToken.Key,
TokenType: loginResponseToken.TokenType, TokenType: loginResponseToken.TokenType,
ExpiresIn: loginResponseToken.ExpiresIn, ExpiresIn: loginResponseToken.ExpiresIn,
}) })
if err != nil {
authLog.Error("Could not set token: %s", err.Error())
return false
}
} else { } else {
authLog.Info("No api credentials set") authLog.Info("No api credentials set")
} }
@ -306,13 +318,17 @@ func RefreshToken(ctx context.Context, cfg *config.Config) bool {
notify.Notify("Goldwarden", fmt.Sprintf("Could not refresh token: %v", err), "", 0, func() {}) notify.Notify("Goldwarden", fmt.Sprintf("Could not refresh token: %v", err), "", 0, func() {})
return false return false
} }
cfg.SetToken(config.LoginToken{ err = cfg.SetToken(config.LoginToken{
AccessToken: loginResponseToken.AccessToken, AccessToken: loginResponseToken.AccessToken,
RefreshToken: loginResponseToken.RefreshToken, RefreshToken: loginResponseToken.RefreshToken,
Key: loginResponseToken.Key, Key: loginResponseToken.Key,
TokenType: loginResponseToken.TokenType, TokenType: loginResponseToken.TokenType,
ExpiresIn: loginResponseToken.ExpiresIn, ExpiresIn: loginResponseToken.ExpiresIn,
}) })
if err != nil {
authLog.Error("Could not set token: %s", err.Error())
return false
}
} }
authLog.Info("Token refreshed") authLog.Info("Token refreshed")

View File

@ -123,6 +123,9 @@ func MemguardAssymmetricEncryptionKeyFromBytes(key []byte) (MemguardAsymmetricEn
func (key MemoryAsymmetricEncryptionKey) PublicBytes() []byte { func (key MemoryAsymmetricEncryptionKey) PublicBytes() []byte {
privateKey, err := x509.ParsePKCS8PrivateKey(key.encKey) privateKey, err := x509.ParsePKCS8PrivateKey(key.encKey)
if err != nil {
panic(err)
}
pub := (privateKey.(*rsa.PrivateKey)).Public() pub := (privateKey.(*rsa.PrivateKey)).Public()
publicKeyBytes, err := x509.MarshalPKIXPublicKey(pub) publicKeyBytes, err := x509.MarshalPKIXPublicKey(pub)
if err != nil { if err != nil {
@ -137,6 +140,9 @@ func (key MemguardAsymmetricEncryptionKey) PublicBytes() []byte {
panic(err) panic(err)
} }
privateKey, err := x509.ParsePKCS8PrivateKey(buffer.Bytes()) privateKey, err := x509.ParsePKCS8PrivateKey(buffer.Bytes())
if err != nil {
panic(err)
}
pub := (privateKey.(*rsa.PrivateKey)).Public() pub := (privateKey.(*rsa.PrivateKey)).Public()
publicKeyBytes, err := x509.MarshalPKIXPublicKey(pub) publicKeyBytes, err := x509.MarshalPKIXPublicKey(pub)
if err != nil { if err != nil {

View File

@ -90,9 +90,15 @@ func stretchKey(masterKey MasterKey, useMemguard bool) (SymmetricEncryptionKey,
var r io.Reader var r io.Reader
r = hkdf.Expand(sha256.New, buffer.Data(), []byte("enc")) r = hkdf.Expand(sha256.New, buffer.Data(), []byte("enc"))
r.Read(key) _, err = r.Read(key)
if err != nil {
return nil, err
}
r = hkdf.Expand(sha256.New, buffer.Data(), []byte("mac")) r = hkdf.Expand(sha256.New, buffer.Data(), []byte("mac"))
r.Read(macKey) _, err = r.Read(macKey)
if err != nil {
return nil, err
}
if useMemguard { if useMemguard {
return MemguardSymmetricEncryptionKey{memguard.NewEnclave(key), memguard.NewEnclave(macKey)}, nil return MemguardSymmetricEncryptionKey{memguard.NewEnclave(key), memguard.NewEnclave(macKey)}, nil

View File

@ -71,7 +71,10 @@ func CreateSend(ctx context.Context, cfg *config.Config, vault *vault.Vault, nam
} }
sendUseKeyPairBytes := make([]byte, 64) sendUseKeyPairBytes := make([]byte, 64)
hkdf.New(sha256.New, sendSourceKey, []byte("bitwarden-send"), []byte("send")).Read(sendUseKeyPairBytes) _, err = hkdf.New(sha256.New, sendSourceKey, []byte("bitwarden-send"), []byte("send")).Read(sendUseKeyPairBytes)
if err != nil {
return "", err
}
sendUseKeyPair, err := crypto.MemorySymmetricEncryptionKeyFromBytes(sendUseKeyPairBytes) sendUseKeyPair, err := crypto.MemorySymmetricEncryptionKeyFromBytes(sendUseKeyPairBytes)
if err != nil { if err != nil {

View File

@ -25,7 +25,11 @@ func Sync(ctx context.Context, config *config.Config) (models.SyncData, error) {
} }
home, _ := os.UserHomeDir() home, _ := os.UserHomeDir()
WriteVault(sync, home+path) err := WriteVault(sync, home+path)
if err != nil {
return sync, err
}
return sync, nil return sync, nil
} }
@ -55,7 +59,10 @@ func DoFullSync(ctx context.Context, vault *vault.Vault, config *config.Config,
} }
if userSymmetricKey != nil { if userSymmetricKey != nil {
log.Info("Initializing keyring from user symmetric key...") log.Info("Initializing keyring from user symmetric key...")
crypto.InitKeyringFromUserSymmetricKey(vault.Keyring, *userSymmetricKey, sync.Profile.PrivateKey, orgKeys) err = crypto.InitKeyringFromUserSymmetricKey(vault.Keyring, *userSymmetricKey, sync.Profile.PrivateKey, orgKeys)
if err != nil {
return err
}
} }
log.Info("Clearing vault...") log.Info("Clearing vault...")

View File

@ -88,7 +88,10 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con
done := make(chan struct{}) done := make(chan struct{})
//handshake required for official bitwarden implementation //handshake required for official bitwarden implementation
c.WriteMessage(1, []byte(`{"protocol":"messagepack","version":1}`)) err = c.WriteMessage(1, []byte(`{"protocol":"messagepack","version":1}`))
if err != nil {
return err
}
go func() { go func() {
for { for {
@ -123,12 +126,14 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con
websocketLog.Error("Error getting token %s", err) websocketLog.Error("Error getting token %s", err)
break break
} }
DoFullSync(context.WithValue(ctx, AuthToken{}, token.AccessToken), vault, cfg, nil, false) err = DoFullSync(context.WithValue(ctx, AuthToken{}, token.AccessToken), vault, cfg, nil, false)
break if err != nil {
log.Error("could not perform full sync: %s", err.Error())
return
}
case SyncCipherDelete: case SyncCipherDelete:
websocketLog.Warn("Delete requested for cipher " + cipherid) websocketLog.Warn("Delete requested for cipher " + cipherid)
vault.DeleteCipher(cipherid) vault.DeleteCipher(cipherid)
break
case SyncCipherUpdate: case SyncCipherUpdate:
websocketLog.Warn("Update requested for cipher " + cipherid) websocketLog.Warn("Update requested for cipher " + cipherid)
token, err := cfg.GetToken() token, err := cfg.GetToken()
@ -154,8 +159,6 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con
vault.AddOrUpdateLogin(cipher) vault.AddOrUpdateLogin(cipher)
} }
vault.SetLastSynced(time.Now().Unix()) vault.SetLastSynced(time.Now().Unix())
break
case SyncCipherCreate: case SyncCipherCreate:
websocketLog.Warn("Create requested for cipher " + cipherid) websocketLog.Warn("Create requested for cipher " + cipherid)
token, err := cfg.GetToken() token, err := cfg.GetToken()
@ -176,11 +179,8 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con
vault.AddOrUpdateLogin(cipher) vault.AddOrUpdateLogin(cipher)
} }
vault.SetLastSynced(time.Now().Unix()) vault.SetLastSynced(time.Now().Unix())
break
case SyncSendCreate, SyncSendUpdate, SyncSendDelete: case SyncSendCreate, SyncSendUpdate, SyncSendDelete:
websocketLog.Warn("SyncSend requested: sends are not supported") websocketLog.Warn("SyncSend requested: sends are not supported")
break
case LogOut: case LogOut:
websocketLog.Info("LogOut received. Wiping vault and exiting...") websocketLog.Info("LogOut received. Wiping vault and exiting...")
if vault.Keyring.IsMemguard { if vault.Keyring.IsMemguard {
@ -213,17 +213,12 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con
websocketLog.Error("Error creating auth response %s", err) websocketLog.Error("Error creating auth response %s", err)
} }
}) })
break
case AuthRequestResponse: case AuthRequestResponse:
websocketLog.Info("AuthRequestResponse received") websocketLog.Info("AuthRequestResponse received")
break
case SyncFolderDelete, SyncFolderCreate, SyncFolderUpdate: case SyncFolderDelete, SyncFolderCreate, SyncFolderUpdate:
websocketLog.Warn("SyncFolder requested: folders are not supported") websocketLog.Warn("SyncFolder requested: folders are not supported")
break
case SyncOrgKeys, SyncSettings: case SyncOrgKeys, SyncSettings:
websocketLog.Warn("SyncOrgKeys requested: orgs / settings are not supported") websocketLog.Warn("SyncOrgKeys requested: orgs / settings are not supported")
break
default: default:
websocketLog.Warn("Unknown message type received %d", mt1) websocketLog.Warn("Unknown message type received %d", mt1)
} }

View File

@ -7,6 +7,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"os" "os"
"runtime/debug" "runtime/debug"
"strings" "strings"
@ -19,6 +20,7 @@ import (
"github.com/quexten/goldwarden/agent/pincache" "github.com/quexten/goldwarden/agent/pincache"
"github.com/quexten/goldwarden/agent/systemauth/pinentry" "github.com/quexten/goldwarden/agent/systemauth/pinentry"
"github.com/quexten/goldwarden/agent/vault" "github.com/quexten/goldwarden/agent/vault"
"github.com/quexten/goldwarden/logging"
"github.com/tink-crypto/tink-go/v2/aead/subtle" "github.com/tink-crypto/tink-go/v2/aead/subtle"
"golang.org/x/crypto/argon2" "golang.org/x/crypto/argon2"
"golang.org/x/crypto/sha3" "golang.org/x/crypto/sha3"
@ -78,6 +80,8 @@ type Config struct {
mu sync.Mutex mu sync.Mutex
} }
var log = logging.GetLogger("Goldwarden", "Config")
func DefaultConfig(useMemguard bool) Config { func DefaultConfig(useMemguard bool) Config {
deviceUUID, _ := uuid.NewUUID() deviceUUID, _ := uuid.NewUUID()
keyBuffer := NewBuffer(32, useMemguard) keyBuffer := NewBuffer(32, useMemguard)
@ -188,37 +192,65 @@ func (c *Config) UpdatePin(password string, write bool) {
c.ConfigFile.ConfigKeyHash = configKeyHash c.ConfigFile.ConfigKeyHash = configKeyHash
plaintextToken, err1 := c.decryptString(c.ConfigFile.EncryptedToken) plaintextToken, err1 := c.decryptString(c.ConfigFile.EncryptedToken)
plaintextUserSymmetricKey, err3 := c.decryptString(c.ConfigFile.EncryptedUserSymmetricKey) plaintextUserSymmetricKey, err2 := c.decryptString(c.ConfigFile.EncryptedUserSymmetricKey)
plaintextEncryptedMasterPasswordHash, err4 := c.decryptString(c.ConfigFile.EncryptedMasterPasswordHash) plaintextEncryptedMasterPasswordHash, err3 := c.decryptString(c.ConfigFile.EncryptedMasterPasswordHash)
plaintextMasterKey, err5 := c.decryptString(c.ConfigFile.EncryptedMasterKey) plaintextMasterKey, err4 := c.decryptString(c.ConfigFile.EncryptedMasterKey)
plaintextClientID, err6 := c.decryptString(c.ConfigFile.EncryptedClientID) plaintextClientID, err5 := c.decryptString(c.ConfigFile.EncryptedClientID)
plaintextClientSecret, err7 := c.decryptString(c.ConfigFile.EncryptedClientSecret) plaintextClientSecret, err6 := c.decryptString(c.ConfigFile.EncryptedClientSecret)
key := NewBufferFromBytes(newKey, c.useMemguard) key := NewBufferFromBytes(newKey, c.useMemguard)
c.key = &key c.key = &key
if err1 == nil { if err1 == nil {
c.ConfigFile.EncryptedToken, err1 = c.encryptString(plaintextToken) c.ConfigFile.EncryptedToken, err1 = c.encryptString(plaintextToken)
if err1 != nil {
log.Error("could not encrypt token: %s", err1.Error())
return
}
}
if err2 == nil {
c.ConfigFile.EncryptedUserSymmetricKey, err2 = c.encryptString(plaintextUserSymmetricKey)
if err2 != nil {
log.Error("could not encrypt user symmetric key: %s", err2.Error())
return
}
} }
if err3 == nil { if err3 == nil {
c.ConfigFile.EncryptedUserSymmetricKey, err3 = c.encryptString(plaintextUserSymmetricKey) c.ConfigFile.EncryptedMasterPasswordHash, err3 = c.encryptString(plaintextEncryptedMasterPasswordHash)
if err3 != nil {
log.Error("could not encrypt master password hash: %s", err3.Error())
return
}
} }
if err4 == nil { if err4 == nil {
c.ConfigFile.EncryptedMasterPasswordHash, err4 = c.encryptString(plaintextEncryptedMasterPasswordHash) c.ConfigFile.EncryptedMasterKey, err4 = c.encryptString(plaintextMasterKey)
if err4 != nil {
log.Error("could not encrypt master key: %s", err4.Error())
return
}
} }
if err5 == nil { if err5 == nil {
c.ConfigFile.EncryptedMasterKey, err5 = c.encryptString(plaintextMasterKey) c.ConfigFile.EncryptedClientID, err5 = c.encryptString(plaintextClientID)
if err5 != nil {
log.Error("could not encrypt client id: %s", err5.Error())
return
}
} }
if err6 == nil { if err6 == nil {
c.ConfigFile.EncryptedClientID, err6 = c.encryptString(plaintextClientID) c.ConfigFile.EncryptedClientSecret, err6 = c.encryptString(plaintextClientSecret)
} if err6 != nil {
if err7 == nil { log.Error("could not encrypt client secret: %s", err6.Error())
c.ConfigFile.EncryptedClientSecret, err7 = c.encryptString(plaintextClientSecret) return
}
} }
c.mu.Unlock() c.mu.Unlock()
if write { if write {
c.WriteConfig() err := c.WriteConfig()
if err != nil {
log.Error("could not write config: %s", err.Error())
return
}
} }
pincache.SetPin(c.useMemguard, []byte(password)) pincache.SetPin(c.useMemguard, []byte(password))
@ -247,6 +279,9 @@ func (c *Config) SetToken(token LoginToken) error {
} }
tokenJson, err := json.Marshal(token) tokenJson, err := json.Marshal(token)
if err != nil {
return fmt.Errorf("could not marshall json: %s", err.Error())
}
encryptedToken, err := c.encryptString(string(tokenJson)) encryptedToken, err := c.encryptString(string(tokenJson))
if err != nil { if err != nil {
return err return err
@ -254,8 +289,7 @@ func (c *Config) SetToken(token LoginToken) error {
// c.mu.Lock() // c.mu.Lock()
c.ConfigFile.EncryptedToken = encryptedToken c.ConfigFile.EncryptedToken = encryptedToken
// c.mu.Unlock() // c.mu.Unlock()
c.WriteConfig() return c.WriteConfig()
return nil
} }
func (c *Config) GetClientID() (string, error) { func (c *Config) GetClientID() (string, error) {
@ -281,8 +315,7 @@ func (c *Config) SetClientID(clientID string) error {
if clientID == "" { if clientID == "" {
c.ConfigFile.EncryptedClientID = "" c.ConfigFile.EncryptedClientID = ""
c.WriteConfig() return c.WriteConfig()
return nil
} }
encryptedClientID, err := c.encryptString(clientID) encryptedClientID, err := c.encryptString(clientID)
@ -292,8 +325,7 @@ func (c *Config) SetClientID(clientID string) error {
// c.mu.Lock() // c.mu.Lock()
c.ConfigFile.EncryptedClientID = encryptedClientID c.ConfigFile.EncryptedClientID = encryptedClientID
// c.mu.Unlock() // c.mu.Unlock()
c.WriteConfig() return c.WriteConfig()
return nil
} }
func (c *Config) GetClientSecret() (string, error) { func (c *Config) GetClientSecret() (string, error) {
@ -319,8 +351,7 @@ func (c *Config) SetClientSecret(clientSecret string) error {
if clientSecret == "" { if clientSecret == "" {
c.ConfigFile.EncryptedClientSecret = "" c.ConfigFile.EncryptedClientSecret = ""
c.WriteConfig() return c.WriteConfig()
return nil
} }
encryptedClientSecret, err := c.encryptString(clientSecret) encryptedClientSecret, err := c.encryptString(clientSecret)
@ -330,8 +361,7 @@ func (c *Config) SetClientSecret(clientSecret string) error {
// c.mu.Lock() // c.mu.Lock()
c.ConfigFile.EncryptedClientSecret = encryptedClientSecret c.ConfigFile.EncryptedClientSecret = encryptedClientSecret
// c.mu.Unlock() // c.mu.Unlock()
c.WriteConfig() return c.WriteConfig()
return nil
} }
func (c *Config) GetUserSymmetricKey() ([]byte, error) { func (c *Config) GetUserSymmetricKey() ([]byte, error) {
@ -356,8 +386,7 @@ func (c *Config) SetUserSymmetricKey(key []byte) error {
// c.mu.Lock() // c.mu.Lock()
c.ConfigFile.EncryptedUserSymmetricKey = encryptedKey c.ConfigFile.EncryptedUserSymmetricKey = encryptedKey
// c.mu.Unlock() // c.mu.Unlock()
c.WriteConfig() return c.WriteConfig()
return nil
} }
func (c *Config) GetMasterPasswordHash() ([]byte, error) { func (c *Config) GetMasterPasswordHash() ([]byte, error) {
@ -372,7 +401,6 @@ func (c *Config) GetMasterPasswordHash() ([]byte, error) {
} }
func (c *Config) SetMasterPasswordHash(hash []byte) error { func (c *Config) SetMasterPasswordHash(hash []byte) error {
if c.IsLocked() { if c.IsLocked() {
return errors.New("config is locked") return errors.New("config is locked")
} }
@ -386,8 +414,7 @@ func (c *Config) SetMasterPasswordHash(hash []byte) error {
c.ConfigFile.EncryptedMasterPasswordHash = encryptedHash c.ConfigFile.EncryptedMasterPasswordHash = encryptedHash
// c.mu.Unlock() // c.mu.Unlock()
c.WriteConfig() return c.WriteConfig()
return nil
} }
func (c *Config) GetMasterKey() ([]byte, error) { func (c *Config) GetMasterKey() ([]byte, error) {
@ -412,8 +439,7 @@ func (c *Config) SetMasterKey(key []byte) error {
// c.mu.Lock() // c.mu.Lock()
c.ConfigFile.EncryptedMasterKey = encryptedKey c.ConfigFile.EncryptedMasterKey = encryptedKey
// c.mu.Unlock() // c.mu.Unlock()
c.WriteConfig() return c.WriteConfig()
return nil
} }
func (c *Config) encryptString(data string) (string, error) { func (c *Config) encryptString(data string) (string, error) {
@ -499,9 +525,11 @@ func ReadConfig(rtCfg RuntimeConfig) (Config, error) {
if _, err := os.Stat(oldPath); err == nil { if _, err := os.Stat(oldPath); err == nil {
if _, err := os.Stat(newPath); err != nil { if _, err := os.Stat(newPath); err != nil {
if _, err := os.Stat(newPathParent); os.IsNotExist(err) { if _, err := os.Stat(newPathParent); os.IsNotExist(err) {
os.Mkdir(newPathParent, 0700) err = os.Mkdir(newPathParent, 0700)
return Config{}, err
} }
os.Rename(oldPath, newPath) err = os.Rename(oldPath, newPath)
return Config{}, err
} }
} }

View File

@ -6,15 +6,18 @@ import (
"time" "time"
"github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5"
"github.com/quexten/goldwarden/logging"
) )
var closeListenerMap = make(map[uint32]func()) var closeListenerMap = make(map[uint32]func())
var notificationID uint32 = 1000000 var notificationID uint32 = 1000000
var log = logging.GetLogger("Goldwarden", "Dbus")
func Notify(title string, body string, actionName string, timeout time.Duration, onclose func()) error { func Notify(title string, body string, actionName string, timeout time.Duration, onclose func()) {
bus, err := dbus.SessionBus() bus, err := dbus.SessionBus()
if err != nil { if err != nil {
return err log.Error("could not get a dbus session: %s", err.Error())
return
} }
obj := bus.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications") obj := bus.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
actions := []string{} actions := []string{}
@ -26,16 +29,17 @@ func Notify(title string, body string, actionName string, timeout time.Duration,
call := obj.Call("org.freedesktop.Notifications.Notify", 0, "goldwarden", uint32(notificationID), "", title, body, actions, map[string]dbus.Variant{}, int32(60000)) call := obj.Call("org.freedesktop.Notifications.Notify", 0, "goldwarden", uint32(notificationID), "", title, body, actions, map[string]dbus.Variant{}, int32(60000))
if call.Err != nil { if call.Err != nil {
return call.Err log.Error("could not call dbus object: %s", call.Err.Error())
return
} }
if len(call.Body) < 1 { if len(call.Body) < 1 {
return nil return
} }
id := call.Body[0].(uint32) id := call.Body[0].(uint32)
closeListenerMap[id] = onclose closeListenerMap[id] = onclose
if timeout == 0 { if timeout == 0 {
return nil return
} else { } else {
go func(id uint32) { go func(id uint32) {
time.Sleep(timeout) time.Sleep(timeout)
@ -45,8 +49,6 @@ func Notify(title string, body string, actionName string, timeout time.Duration,
} }
}(id) }(id)
} }
return nil
} }
func ListenForNotifications() error { func ListenForNotifications() error {
@ -62,26 +64,22 @@ func ListenForNotifications() error {
signals := make(chan *dbus.Signal, 10) signals := make(chan *dbus.Signal, 10)
bus.Signal(signals) bus.Signal(signals)
for { for {
select { message := <-signals
case message := <-signals: if message.Name == "org.freedesktop.Notifications.NotificationClosed" {
if message.Name == "org.freedesktop.Notifications.NotificationClosed" { if len(message.Body) < 1 {
if len(message.Body) < 1 { continue
continue }
} id, ok := message.Body[0].(uint32)
id, ok := message.Body[0].(uint32) if !ok {
if !ok { continue
continue }
} if id == 0 {
if id == 0 { continue
continue }
} if closeListener, ok := closeListenerMap[id]; ok {
if closeListener, ok := closeListenerMap[id]; ok { delete(closeListenerMap, id)
delete(closeListenerMap, id) closeListener()
closeListener()
}
} }
} }
} }
return nil
} }

View File

@ -37,30 +37,26 @@ func MonitorLocks(onlock func()) error {
signals := make(chan *dbus.Signal, 10) signals := make(chan *dbus.Signal, 10)
bus.Signal(signals) bus.Signal(signals)
for { for {
select { message := <-signals
case message := <-signals: if message.Name == "org.gnome.ScreenSaver.ActiveChanged" {
if message.Name == "org.gnome.ScreenSaver.ActiveChanged" { if len(message.Body) == 0 {
if len(message.Body) == 0 { continue
continue
}
locked, err := message.Body[0].(bool)
if err || locked {
onlock()
}
} }
if message.Name == "org.freedesktop.ScreenSaver.ActiveChanged" { locked, err := message.Body[0].(bool)
if len(message.Body) == 0 { if err || locked {
continue onlock()
} }
locked, err := message.Body[0].(bool) }
if err || locked { if message.Name == "org.freedesktop.ScreenSaver.ActiveChanged" {
onlock() if len(message.Body) == 0 {
} continue
}
locked, err := message.Body[0].(bool)
if err || locked {
onlock()
} }
} }
} }
return nil
} }
func MonitorIdle(onidle func()) error { func MonitorIdle(onidle func()) error {
@ -88,6 +84,4 @@ func MonitorIdle(onidle func()) error {
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
} }
return nil
} }

View File

@ -31,20 +31,20 @@ const (
var log = logging.GetLogger("Goldwarden", "Agent") var log = logging.GetLogger("Goldwarden", "Agent")
func writeError(c net.Conn, errMsg error) error { func writeError(c net.Conn, errMsg error) {
payload := messages.ActionResponse{ payload := messages.ActionResponse{
Success: false, Success: false,
Message: errMsg.Error(), Message: errMsg.Error(),
} }
payloadBytes, err := json.Marshal(payload) payloadBytes, err := json.Marshal(payload)
if err != nil { if err != nil {
return err log.Warn("Could not json marshall: %s", err.Error())
return
} }
_, err = c.Write(payloadBytes) _, err = c.Write(payloadBytes)
if err != nil { if err != nil {
return err log.Warn("Could not write payload: %s", err.Error())
} }
return nil
} }
func serveAgentSession(c net.Conn, vault *vault.Vault, cfg *config.Config) { func serveAgentSession(c net.Conn, vault *vault.Vault, cfg *config.Config) {
@ -145,9 +145,9 @@ func serveAgentSession(c net.Conn, vault *vault.Vault, cfg *config.Config) {
}, },
} }
pinnentrySetError := pinentry.SetExternalPinentry(pe) pinentrySetError := pinentry.SetExternalPinentry(pe)
payload := messages.PinentryRegistrationResponse{ payload := messages.PinentryRegistrationResponse{
Success: pinnentrySetError == nil, Success: pinentrySetError == nil,
} }
log.Info("Pinentry registration success: %t", payload.Success) log.Info("Pinentry registration success: %t", payload.Success)
@ -167,9 +167,12 @@ func serveAgentSession(c net.Conn, vault *vault.Vault, cfg *config.Config) {
log.Error("Failed writing to socket " + err.Error()) log.Error("Failed writing to socket " + err.Error())
} }
_, err = c.Write([]byte("\n")) _, err = c.Write([]byte("\n"))
if err != nil {
log.Error("Failed writing to socket " + err.Error())
}
time.Sleep(50 * time.Millisecond) //todo fix properly time.Sleep(50 * time.Millisecond) //todo fix properly
if pinnentrySetError != nil { if pinentrySetError != nil {
return return
} }
@ -266,8 +269,6 @@ func serveAgentSession(c net.Conn, vault *vault.Vault, cfg *config.Config) {
} }
} }
} }
continue
} }
var responseBytes []byte var responseBytes []byte
@ -322,7 +323,10 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error {
log.Warn("Could not read config: %s", err.Error()) log.Warn("Could not read config: %s", err.Error())
cfg = config.DefaultConfig(runtimeConfig.UseMemguard) cfg = config.DefaultConfig(runtimeConfig.UseMemguard)
cfg.ConfigFile.RuntimeConfig = runtimeConfig cfg.ConfigFile.RuntimeConfig = runtimeConfig
cfg.WriteConfig() err = cfg.WriteConfig()
if err != nil {
log.Warn("Could not write config: %s", err.Error())
}
} }
cfg.ConfigFile.RuntimeConfig = runtimeConfig cfg.ConfigFile.RuntimeConfig = runtimeConfig
if cfg.ConfigFile.RuntimeConfig.DeviceUUID != "" { if cfg.ConfigFile.RuntimeConfig.DeviceUUID != "" {
@ -348,14 +352,17 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error {
time.Sleep(60 * time.Second) time.Sleep(60 * time.Second)
continue continue
} }
var protectedUserSymetricKey crypto.SymmetricEncryptionKey var protectedUserSymmetricKey crypto.SymmetricEncryptionKey
if vault.Keyring.IsMemguard { if vault.Keyring.IsMemguard {
protectedUserSymetricKey, err = crypto.MemguardSymmetricEncryptionKeyFromBytes(userSymmetricKey) protectedUserSymmetricKey, err = crypto.MemguardSymmetricEncryptionKeyFromBytes(userSymmetricKey)
} else { } else {
protectedUserSymetricKey, err = crypto.MemorySymmetricEncryptionKeyFromBytes(userSymmetricKey) protectedUserSymmetricKey, err = crypto.MemorySymmetricEncryptionKeyFromBytes(userSymmetricKey)
}
if err != nil {
log.Error("could not get encryption key from bytes: %s", err.Error())
} }
err = bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, &cfg, &protectedUserSymetricKey, true) err = bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, &cfg, &protectedUserSymmetricKey, true)
if err != nil { if err != nil {
log.Error("Could not sync: %s", err.Error()) log.Error("Could not sync: %s", err.Error())
notify.Notify("Goldwarden", "Could not perform initial sync", "", 0, func() {}) notify.Notify("Goldwarden", "Could not perform initial sync", "", 0, func() {})
@ -369,7 +376,11 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error {
} }
} }
processsecurity.DisableDumpable() err = processsecurity.DisableDumpable()
if err != nil {
log.Warn("Could not disable dumpable: %s", err.Error())
}
go func() { go func() {
err = processsecurity.MonitorLocks(func() { err = processsecurity.MonitorLocks(func() {
cfg.Lock() cfg.Lock()
@ -435,14 +446,17 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error {
if err != nil { if err != nil {
log.Error("Could not get user symmetric key: %s", err.Error()) log.Error("Could not get user symmetric key: %s", err.Error())
} }
var protectedUserSymetricKey crypto.SymmetricEncryptionKey var protectedUserSymmetricKey crypto.SymmetricEncryptionKey
if vault.Keyring.IsMemguard { if vault.Keyring.IsMemguard {
protectedUserSymetricKey, err = crypto.MemguardSymmetricEncryptionKeyFromBytes(userSymmetricKey) protectedUserSymmetricKey, err = crypto.MemguardSymmetricEncryptionKeyFromBytes(userSymmetricKey)
} else { } else {
protectedUserSymetricKey, err = crypto.MemorySymmetricEncryptionKeyFromBytes(userSymmetricKey) protectedUserSymmetricKey, err = crypto.MemorySymmetricEncryptionKeyFromBytes(userSymmetricKey)
}
if err != nil {
log.Error("could not get encryption key from bytes: %s", err.Error())
} }
err = bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, &cfg, &protectedUserSymetricKey, true) err = bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, &cfg, &protectedUserSymmetricKey, true)
if err != nil { if err != nil {
log.Error("Could not sync: %s", err.Error()) log.Error("Could not sync: %s", err.Error())
notify.Notify("Goldwarden", "Could not perform initial sync on ssh unlock", "", 0, func() {}) notify.Notify("Goldwarden", "Could not perform initial sync on ssh unlock", "", 0, func() {})
@ -482,7 +496,11 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error {
continue continue
} }
bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, &cfg, nil, false) err = bitwarden.DoFullSync(context.WithValue(ctx, bitwarden.AuthToken{}, token.AccessToken), vault, &cfg, nil, false)
if err != nil {
log.Warn("Could not do full sync: %s", err.Error())
continue
}
} }
} }
}() }()