Move daemon and ssh socket paths

This commit is contained in:
Bernd Schoolmann 2023-12-30 18:53:01 +01:00
parent 71398d0cea
commit 0e7561bd61
No known key found for this signature in database
14 changed files with 143 additions and 48 deletions

View file

@ -55,8 +55,17 @@ func handleSetNotifications(request messages.IPCMessage, cfg *config.Config, vau
}) })
} }
func handleGetRuntimeConfig(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) {
return messages.IPCMessageFromPayload(messages.GetRuntimeConfigResponse{
UseMemguard: cfg.ConfigFile.RuntimeConfig.UseMemguard,
SSHAgentSocketPath: cfg.ConfigFile.RuntimeConfig.SSHAgentSocketPath,
GoldwardenSocketPath: cfg.ConfigFile.RuntimeConfig.GoldwardenSocketPath,
})
}
func init() { func init() {
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.SetIdentityURLRequest{}), handleSetIdentity) AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.SetIdentityURLRequest{}), handleSetIdentity)
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.SetApiURLRequest{}), handleSetApiURL) AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.SetApiURLRequest{}), handleSetApiURL)
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.SetNotificationsURLRequest{}), handleSetNotifications) AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.SetNotificationsURLRequest{}), handleSetNotifications)
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.GetRuntimeConfigRequest{}), handleGetRuntimeConfig)
} }

View file

@ -46,6 +46,8 @@ type RuntimeConfig struct {
Password string Password string
Pin string Pin string
UseMemguard bool UseMemguard bool
SSHAgentSocketPath string
GoldwardenSocketPath string
} }
type ConfigFile struct { type ConfigFile struct {

View file

@ -144,6 +144,7 @@ func (vaultAgent) Unlock(passphrase []byte) error {
type SSHAgentServer struct { type SSHAgentServer struct {
vault *vault.Vault vault *vault.Vault
config *config.Config config *config.Config
runtimeConfig *config.RuntimeConfig
unlockRequestAction func() bool unlockRequestAction func() bool
} }
@ -151,10 +152,11 @@ func (v *SSHAgentServer) SetUnlockRequestAction(action func() bool) {
v.unlockRequestAction = action v.unlockRequestAction = action
} }
func NewVaultAgent(vault *vault.Vault, config *config.Config) SSHAgentServer { func NewVaultAgent(vault *vault.Vault, config *config.Config, runtimeConfig *config.RuntimeConfig) SSHAgentServer {
return SSHAgentServer{ return SSHAgentServer{
vault: vault, vault: vault,
config: config, config: config,
runtimeConfig: runtimeConfig,
unlockRequestAction: func() bool { unlockRequestAction: func() bool {
log.Info("Unlock Request, but no action defined") log.Info("Unlock Request, but no action defined")
return false return false
@ -163,13 +165,7 @@ func NewVaultAgent(vault *vault.Vault, config *config.Config) SSHAgentServer {
} }
func (v SSHAgentServer) Serve() { func (v SSHAgentServer) Serve() {
home, err := os.UserHomeDir() path := v.runtimeConfig.SSHAgentSocketPath
if err != nil {
panic(err)
}
path := home + "/.goldwarden-ssh-agent.sock"
if _, err := os.Stat(path); err == nil { if _, err := os.Stat(path); err == nil {
if err := os.Remove(path); err != nil { if err := os.Remove(path); err != nil {
log.Error("Could not remove old socket file: %s", err) log.Error("Could not remove old socket file: %s", err)

View file

@ -203,7 +203,7 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error {
}() }()
if !runtimeConfig.DisableSSHAgent { if !runtimeConfig.DisableSSHAgent {
vaultAgent := ssh.NewVaultAgent(vault, &cfg) vaultAgent := ssh.NewVaultAgent(vault, &cfg, &runtimeConfig)
vaultAgent.SetUnlockRequestAction(func() bool { vaultAgent.SetUnlockRequestAction(func() bool {
err := cfg.TryUnlock(vault) err := cfg.TryUnlock(vault)
if err == nil { if err == nil {

View file

@ -6,6 +6,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/browserbiometrics/logging" "github.com/quexten/goldwarden/browserbiometrics/logging"
) )
@ -13,7 +14,7 @@ const appID = "com.quexten.bw-bio-handler"
var transportKey []byte var transportKey []byte
func Main() { func Main(rtCfg *config.RuntimeConfig) {
if os.Args[1] == "install" { if os.Args[1] == "install" {
var err error var err error
err = detectAndInstallBrowsers(".config") err = detectAndInstallBrowsers(".config")
@ -32,7 +33,7 @@ func Main() {
logging.Debugf("Generated transport key") logging.Debugf("Generated transport key")
setupCommunication() setupCommunication()
readLoop() readLoop(rtCfg)
} }
func DetectAndInstallBrowsers() error { func DetectAndInstallBrowsers() error {

View file

@ -6,12 +6,16 @@ import (
"io" "io"
"os" "os"
"github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/browserbiometrics/logging" "github.com/quexten/goldwarden/browserbiometrics/logging"
"github.com/quexten/goldwarden/client" "github.com/quexten/goldwarden/client"
"github.com/quexten/goldwarden/ipc/messages" "github.com/quexten/goldwarden/ipc/messages"
) )
func readLoop() { var runtimeConfig *config.RuntimeConfig
func readLoop(rtCfg *config.RuntimeConfig) {
runtimeConfig = rtCfg
v := bufio.NewReader(os.Stdin) v := bufio.NewReader(os.Stdin)
s := bufio.NewReaderSize(v, bufferSize) s := bufio.NewReaderSize(v, bufferSize)
@ -101,7 +105,7 @@ func handlePayloadMessage(msg PayloadMessage, appID string) {
case "biometricUnlock": case "biometricUnlock":
logging.Debugf("Biometric unlock requested") logging.Debugf("Biometric unlock requested")
// logging.Debugf("Biometrics authorized: %t", isAuthorized) // logging.Debugf("Biometrics authorized: %t", isAuthorized)
result, err := client.NewUnixSocketClient().SendToAgent(messages.GetBiometricsKeyRequest{}) result, err := client.NewUnixSocketClient(runtimeConfig).SendToAgent(messages.GetBiometricsKeyRequest{})
if err != nil { if err != nil {
logging.Errorf("Unable to send message to agent: %s", err.Error()) logging.Errorf("Unable to send message to agent: %s", err.Error())
return return

View file

@ -5,18 +5,21 @@ import (
"io" "io"
"log" "log"
"net" "net"
"os"
"github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/ipc/messages" "github.com/quexten/goldwarden/ipc/messages"
) )
const READ_BUFFER = 1 * 1024 * 1024 // 1MB const READ_BUFFER = 1 * 1024 * 1024 // 1MB
type UnixSocketClient struct { type UnixSocketClient struct {
runtimeConfig *config.RuntimeConfig
} }
func NewUnixSocketClient() UnixSocketClient { func NewUnixSocketClient(runtimeConfig *config.RuntimeConfig) UnixSocketClient {
return UnixSocketClient{} return UnixSocketClient{
runtimeConfig: runtimeConfig,
}
} }
func reader(r io.Reader) interface{} { func reader(r io.Reader) interface{} {
@ -37,12 +40,7 @@ func reader(r io.Reader) interface{} {
} }
func (client UnixSocketClient) SendToAgent(request interface{}) (interface{}, error) { func (client UnixSocketClient) SendToAgent(request interface{}) (interface{}, error) {
home, err := os.UserHomeDir() c, err := net.Dial("unix", client.runtimeConfig.GoldwardenSocketPath)
if err != nil {
panic(err)
}
c, err := net.Dial("unix", home+"/.goldwarden.sock")
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -1,6 +1,8 @@
package cmd package cmd
import ( import (
"fmt"
"github.com/quexten/goldwarden/ipc/messages" "github.com/quexten/goldwarden/ipc/messages"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -104,6 +106,32 @@ var setNotificationsURLCmd = &cobra.Command{
}, },
} }
var getRuntimeConfigCmd = &cobra.Command{
Use: "get-runtime-config",
Short: "Get the runtime config",
Long: `Get the runtime config.`,
Run: func(cmd *cobra.Command, args []string) {
request := messages.GetRuntimeConfigRequest{}
result, err := commandClient.SendToAgent(request)
if err != nil {
handleSendToAgentError(err)
return
}
switch result := result.(type) {
case messages.GetRuntimeConfigResponse:
fmt.Println("{")
fmt.Println(" \"useMemguard\": " + fmt.Sprintf("%t", result.UseMemguard) + ",")
fmt.Println(" \"SSHAgentSocketPath\": \"" + result.SSHAgentSocketPath + "\",")
fmt.Println(" \"goldwardenSocketPath\": \"" + result.GoldwardenSocketPath + "\"")
fmt.Println("}")
default:
println("Wrong IPC response type")
}
},
}
var configCmd = &cobra.Command{ var configCmd = &cobra.Command{
Use: "config", Use: "config",
Short: "Manage the configuration", Short: "Manage the configuration",
@ -115,4 +143,5 @@ func init() {
configCmd.AddCommand(setApiUrlCmd) configCmd.AddCommand(setApiUrlCmd)
configCmd.AddCommand(setIdentityURLCmd) configCmd.AddCommand(setIdentityURLCmd)
configCmd.AddCommand(setNotificationsURLCmd) configCmd.AddCommand(setNotificationsURLCmd)
configCmd.AddCommand(getRuntimeConfigCmd)
} }

View file

@ -3,7 +3,6 @@ package cmd
import ( import (
"os" "os"
"os/signal" "os/signal"
"strings"
"github.com/awnumar/memguard" "github.com/awnumar/memguard"
"github.com/quexten/goldwarden/agent" "github.com/quexten/goldwarden/agent"
@ -19,15 +18,6 @@ var daemonizeCmd = &cobra.Command{
websocketDisabled := runtimeConfig.WebsocketDisabled websocketDisabled := runtimeConfig.WebsocketDisabled
sshDisabled := runtimeConfig.DisableSSHAgent sshDisabled := runtimeConfig.DisableSSHAgent
_, err := os.Stat("/.flatpak-info")
isFlatpak := err == nil
if isFlatpak {
runtimeConfig.ConfigDirectory = "~/.var/app/com.quexten.Goldwarden/config/goldwarden.json"
userHome, _ := os.UserHomeDir()
runtimeConfig.ConfigDirectory = strings.ReplaceAll(runtimeConfig.ConfigDirectory, "~", userHome)
println("Flatpak Config directory: " + runtimeConfig.ConfigDirectory)
}
if websocketDisabled { if websocketDisabled {
println("Websocket disabled") println("Websocket disabled")
} }
@ -42,11 +32,7 @@ var daemonizeCmd = &cobra.Command{
<-signalChannel <-signalChannel
memguard.SafeExit(0) memguard.SafeExit(0)
}() }()
home, err := os.UserHomeDir() err := agent.StartUnixAgent(runtimeConfig.GoldwardenSocketPath, runtimeConfig)
if err != nil {
panic(err)
}
err = agent.StartUnixAgent(home+"/.goldwarden.sock", runtimeConfig)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View file

@ -29,7 +29,7 @@ func Execute(cfg config.RuntimeConfig) {
recv, send := agent.StartVirtualAgent(runtimeConfig) recv, send := agent.StartVirtualAgent(runtimeConfig)
commandClient = client.NewVirtualClient(send, recv) commandClient = client.NewVirtualClient(send, recv)
} else { } else {
commandClient = client.NewUnixSocketClient() commandClient = client.NewUnixSocketClient(&cfg)
} }
err := rootCmd.Execute() err := rootCmd.Execute()

View file

@ -14,6 +14,14 @@ type SetNotificationsURLRequest struct {
Value string Value string
} }
type GetRuntimeConfigRequest struct{}
type GetRuntimeConfigResponse struct {
UseMemguard bool
SSHAgentSocketPath string
GoldwardenSocketPath string
}
func init() { func init() {
registerPayloadParser(func(payload []byte) (interface{}, error) { registerPayloadParser(func(payload []byte) (interface{}, error) {
var req SetApiURLRequest var req SetApiURLRequest
@ -41,4 +49,22 @@ func init() {
} }
return req, nil return req, nil
}, SetNotificationsURLRequest{}) }, SetNotificationsURLRequest{})
registerPayloadParser(func(payload []byte) (interface{}, error) {
var req GetRuntimeConfigRequest
err := json.Unmarshal(payload, &req)
if err != nil {
panic("Unmarshal: " + err.Error())
}
return req, nil
}, GetRuntimeConfigRequest{})
registerPayloadParser(func(payload []byte) (interface{}, error) {
var req GetRuntimeConfigResponse
err := json.Unmarshal(payload, &req)
if err != nil {
panic("Unmarshal: " + err.Error())
}
return req, nil
}, GetRuntimeConfigResponse{})
} }

34
main.go
View file

@ -10,11 +10,6 @@ import (
) )
func main() { func main() {
if len(os.Args) > 1 && (strings.Contains(os.Args[1], "com.8bit.bitwarden.json") || strings.Contains(os.Args[1], "chrome-extension://")) {
browserbiometrics.Main()
return
}
var configPath string var configPath string
if path, found := os.LookupEnv("GOLDWARDEN_CONFIG_DIRECTORY"); found { if path, found := os.LookupEnv("GOLDWARDEN_CONFIG_DIRECTORY"); found {
configPath = path configPath = path
@ -39,10 +34,39 @@ func main() {
Password: os.Getenv("GOLDWARDEN_AUTH_PASSWORD"), Password: os.Getenv("GOLDWARDEN_AUTH_PASSWORD"),
Pin: os.Getenv("GOLDWARDEN_PIN"), Pin: os.Getenv("GOLDWARDEN_PIN"),
UseMemguard: os.Getenv("GOLDWARDEN_NO_MEMGUARD") != "true", UseMemguard: os.Getenv("GOLDWARDEN_NO_MEMGUARD") != "true",
SSHAgentSocketPath: os.Getenv("GOLDWARDEN_SSH_AUTH_SOCK"),
GoldwardenSocketPath: os.Getenv("GOLDWARDEN_SOCKET_PATH"),
ConfigDirectory: configPath, ConfigDirectory: configPath,
} }
if len(os.Args) > 1 && (strings.Contains(os.Args[1], "com.8bit.bitwarden.json") || strings.Contains(os.Args[1], "chrome-extension://")) {
browserbiometrics.Main(&runtimeConfig)
return
}
home, err := os.UserHomeDir()
if err != nil {
panic(err)
}
if runtimeConfig.SSHAgentSocketPath == "" {
runtimeConfig.SSHAgentSocketPath = home + "/.goldwarden-ssh-agent.sock"
}
if runtimeConfig.GoldwardenSocketPath == "" {
runtimeConfig.GoldwardenSocketPath = home + "/.goldwarden.sock"
}
_, err = os.Stat("/.flatpak-info")
isFlatpak := err == nil
if isFlatpak {
userHome, _ := os.UserHomeDir()
runtimeConfig.ConfigDirectory = userHome + "/.var/app/com.quexten.Goldwarden/config/goldwarden.json"
runtimeConfig.ConfigDirectory = strings.ReplaceAll(runtimeConfig.ConfigDirectory, "~", userHome)
println("Flatpak Config directory: " + runtimeConfig.ConfigDirectory)
runtimeConfig.SSHAgentSocketPath = userHome + "/.var/app/com.quexten.Goldwarden/data/ssh-auth-sock"
runtimeConfig.GoldwardenSocketPath = userHome + "/.var/app/com.quexten.Goldwarden/data/goldwarden.sock"
}
if runtimeConfig.SingleProcess { if runtimeConfig.SingleProcess {
runtimeConfig.DisablePinRequirement = true runtimeConfig.DisablePinRequirement = true
runtimeConfig.DisableAuth = true runtimeConfig.DisableAuth = true

View file

@ -103,6 +103,17 @@ def get_vault_logins():
except Exception as e: except Exception as e:
print(e) print(e)
return None return None
def get_runtime_config():
restic_cmd = f"{BINARY_PATH} config get-runtime-config"
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
if result.returncode != 0:
return None
try:
return json.loads(result.stdout)
except Exception as e:
print(e)
return None
def autotype(username, password): def autotype(username, password):
# environment # environment

View file

@ -30,11 +30,15 @@ class SettingsWinvdow(Gtk.ApplicationWindow):
self.ssh_row = Adw.ActionRow() self.ssh_row = Adw.ActionRow()
self.ssh_row.set_title("SSH Daemon") self.ssh_row.set_title("SSH Daemon")
self.ssh_row.set_subtitle("Listening at ~/.goldwarden-ssh-agent.sock") self.ssh_row.set_subtitle("Getting status...")
self.ssh_row.set_icon_name("emblem-default")
self.preferences_group.add(self.ssh_row) self.preferences_group.add(self.ssh_row)
self.icon = components.status_icon_ok("emblem-default") self.goldwarden_daemon_row = Adw.ActionRow()
self.ssh_row.add_prefix(self.icon) self.goldwarden_daemon_row.set_title("Goldwarden Daemon")
self.goldwarden_daemon_row.set_subtitle("Getting status...")
self.goldwarden_daemon_row.set_icon_name("emblem-default")
self.preferences_group.add(self.goldwarden_daemon_row)
self.login_with_device = Adw.ActionRow() self.login_with_device = Adw.ActionRow()
self.login_with_device.set_title("Login with device") self.login_with_device.set_title("Login with device")
@ -168,6 +172,11 @@ class SettingsWinvdow(Gtk.ApplicationWindow):
pin_set = goldwarden.is_pin_enabled() pin_set = goldwarden.is_pin_enabled()
status = goldwarden.get_vault_status() status = goldwarden.get_vault_status()
runtimeCfg = goldwarden.get_runtime_config()
if runtimeCfg != None:
self.ssh_row.set_subtitle("Listening at "+runtimeCfg["SSHAgentSocketPath"])
self.goldwarden_daemon_row.set_subtitle("Listening at "+runtimeCfg["goldwardenSocketPath"])
if status != None: if status != None:
if pin_set: if pin_set:
self.unlock_button.set_sensitive(True) self.unlock_button.set_sensitive(True)