Add notification support to the goldwarden daemon
This commit is contained in:
parent
8263094c03
commit
5c7de72da7
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
|
||||
"github.com/quexten/goldwarden/agent/bitwarden/twofactor"
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/notify"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
|
||||
"github.com/quexten/goldwarden/agent/vault"
|
||||
"github.com/quexten/goldwarden/logging"
|
||||
|
@ -68,6 +69,7 @@ func LoginWithMasterpassword(ctx context.Context, email string, cfg *config.Conf
|
|||
if err := authenticatedHTTPPost(ctx, cfg.ConfigFile.ApiUrl+"/accounts/prelogin", &preLogin, preLoginRequest{
|
||||
Email: email,
|
||||
}); err != nil {
|
||||
notify.Notify("Goldwarden", fmt.Sprintf("Could not pre-login: %v", err), "", func() {})
|
||||
return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("could not pre-login: %v", err)
|
||||
}
|
||||
|
||||
|
@ -77,11 +79,13 @@ func LoginWithMasterpassword(ctx context.Context, email string, cfg *config.Conf
|
|||
|
||||
password, err := pinentry.GetPassword("Bitwarden Password", "Enter your Bitwarden password")
|
||||
if err != nil {
|
||||
notify.Notify("Goldwarden", fmt.Sprintf("Could not get password: %v", err), "", func() {})
|
||||
return LoginResponseToken{}, crypto.MasterKey{}, "", err
|
||||
}
|
||||
|
||||
masterKey, err = crypto.DeriveMasterKey([]byte(strings.Clone(password)), email, crypto.KDFConfig{Type: crypto.KDFType(preLogin.KDF), Iterations: uint32(preLogin.KDFIterations), Memory: uint32(preLogin.KDFMemory), Parallelism: uint32(preLogin.KDFParallelism)})
|
||||
if err != nil {
|
||||
notify.Notify("Goldwarden", fmt.Sprintf("Could not derive master key: %v", err), "", func() {})
|
||||
return LoginResponseToken{}, crypto.MasterKey{}, "", err
|
||||
}
|
||||
|
||||
|
@ -104,12 +108,14 @@ func LoginWithMasterpassword(ctx context.Context, email string, cfg *config.Conf
|
|||
if ok && bytes.Contains(errsc.body, []byte("TwoFactor")) {
|
||||
loginResponseToken, err = Perform2FA(values, errsc, cfg, ctx)
|
||||
if err != nil {
|
||||
notify.Notify("Goldwarden", fmt.Sprintf("Could not login via two-factor: %v", err), "", func() {})
|
||||
return LoginResponseToken{}, crypto.MasterKey{}, "", err
|
||||
}
|
||||
} else if err != nil && strings.Contains(err.Error(), "Captcha required.") {
|
||||
notify.Notify("Goldwarden", fmt.Sprintf("Captcha required"), "", func() {})
|
||||
return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("captcha required, please login via the web interface")
|
||||
|
||||
} else if err != nil {
|
||||
notify.Notify("Goldwarden", fmt.Sprintf("Could not login via password: %v", err), "", func() {})
|
||||
return LoginResponseToken{}, crypto.MasterKey{}, "", fmt.Errorf("could not login via password: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
|
||||
"github.com/quexten/goldwarden/agent/bitwarden/models"
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/notify"
|
||||
"github.com/quexten/goldwarden/agent/vault"
|
||||
"github.com/quexten/goldwarden/logging"
|
||||
)
|
||||
|
@ -34,6 +35,7 @@ func DoFullSync(ctx context.Context, vault *vault.Vault, config *config.Config,
|
|||
sync, err := Sync(ctx, config)
|
||||
if err != nil {
|
||||
log.Error("Could not sync: %v", err)
|
||||
notify.Notify("Goldwarden", "Could not sync", "", func() {})
|
||||
if allowCache {
|
||||
home, _ := os.UserHomeDir()
|
||||
sync, err = ReadVault(home + path)
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
"github.com/google/uuid"
|
||||
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
|
||||
"github.com/quexten/goldwarden/agent/notify"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
|
||||
"github.com/quexten/goldwarden/agent/vault"
|
||||
"github.com/tink-crypto/tink-go/v2/aead/subtle"
|
||||
|
@ -146,6 +147,7 @@ func (c *Config) Lock() {
|
|||
return
|
||||
}
|
||||
(*c.key).Wipe()
|
||||
notify.Notify("Goldwarden", "Vault Locked", "", func() {})
|
||||
}
|
||||
|
||||
func (c *Config) Purge() {
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
//go:build linux || freebsd
|
||||
|
||||
package notify
|
||||
|
||||
import (
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
var closeListenerMap = make(map[uint32]func())
|
||||
|
||||
func Notify(title string, body string, actionName string, onclose func()) error {
|
||||
bus, err := dbus.SessionBus()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
obj := bus.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
|
||||
actions := []string{}
|
||||
if actionName != "" {
|
||||
actions = append(actions, actionName)
|
||||
}
|
||||
call := obj.Call("org.freedesktop.Notifications.Notify", 0, "goldwarden", uint32(0), "", title, body, actions, map[string]dbus.Variant{}, int32(60000))
|
||||
if call.Err != nil {
|
||||
return call.Err
|
||||
}
|
||||
if len(call.Body) < 1 {
|
||||
return nil
|
||||
}
|
||||
id := call.Body[0].(uint32)
|
||||
closeListenerMap[id] = onclose
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ListenForNotifications() error {
|
||||
bus, err := dbus.SessionBus()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = bus.AddMatchSignal(dbus.WithMatchInterface("org.freedesktop.Notifications"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
signals := make(chan *dbus.Signal, 10)
|
||||
bus.Signal(signals)
|
||||
for {
|
||||
select {
|
||||
case message := <-signals:
|
||||
if message.Name == "org.freedesktop.Notifications.NotificationClosed" {
|
||||
if len(message.Body) < 1 {
|
||||
continue
|
||||
}
|
||||
id, ok := message.Body[0].(uint32)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if id == 0 {
|
||||
continue
|
||||
}
|
||||
if closeListener, ok := closeListenerMap[id]; ok {
|
||||
delete(closeListenerMap, id)
|
||||
closeListener()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
//go:build windows || darwin
|
||||
|
||||
package notify
|
||||
|
||||
func Notify(title string, body string) error {
|
||||
// no notifications on windows or darwin
|
||||
return nil
|
||||
}
|
||||
|
||||
func ListenForNotifications() error {
|
||||
return nil
|
||||
}
|
|
@ -9,6 +9,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/notify"
|
||||
"github.com/quexten/goldwarden/agent/sockets"
|
||||
"github.com/quexten/goldwarden/agent/systemauth"
|
||||
"github.com/quexten/goldwarden/agent/systemauth/pinentry"
|
||||
|
@ -113,6 +114,7 @@ func (vaultAgent vaultAgent) Sign(key ssh.PublicKey, data []byte) (*ssh.Signatur
|
|||
|
||||
var rand = rand.Reader
|
||||
log.Info("Sign Request for key: %s %s accepted", ssh.FingerprintSHA256(key), sshKey.Name)
|
||||
notify.Notify("Goldwarden", fmt.Sprintf("SSH Key Signing Request Approved for %s", sshKey.Name), "", func() {})
|
||||
return signer.Sign(rand, data)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/quexten/goldwarden/agent/bitwarden"
|
||||
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
|
||||
"github.com/quexten/goldwarden/agent/config"
|
||||
"github.com/quexten/goldwarden/agent/notify"
|
||||
"github.com/quexten/goldwarden/agent/processsecurity"
|
||||
"github.com/quexten/goldwarden/agent/sockets"
|
||||
"github.com/quexten/goldwarden/agent/ssh"
|
||||
|
@ -181,6 +182,12 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error {
|
|||
log.Warn("Could not monitor idle: %s", err.Error())
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
err = notify.ListenForNotifications()
|
||||
if err != nil {
|
||||
log.Warn("Could not listen for notifications: %s", err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
if !runtimeConfig.WebsocketDisabled {
|
||||
|
|
Loading…
Reference in New Issue