diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 3e9c32c..ca33e0c 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -10,6 +10,23 @@ env: GO_VERSION: '1.20' jobs: + build_linux_x86_64_debug: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: ${{ env.GO_VERSION }} + - name: Install libfido2-dev + run: sudo apt-get install -y libfido2-dev + - name: Build Debug + run: go build -tags debuglogging -o goldwarden_linux_x86_64_debug -v . + - uses: actions/upload-artifact@v3 + with: + name: goldwarden_linux_x86_64_debug + path: ./goldwarden_linux_x86_64_debug + build_linux_x86_64: runs-on: ubuntu-latest steps: diff --git a/PKGBUILD b/PKGBUILD index a59f7ed..797e9bc 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,5 +1,5 @@ pkgname=goldwarden -pkgver=0.2.12 +pkgver=0.2.13 pkgrel=1 pkgdesc='A feature-packed Bitwarden compatible desktop integration' arch=('x86_64' 'aarch64') diff --git a/Readme.md b/Readme.md index 777369f..2401688 100644 --- a/Readme.md +++ b/Readme.md @@ -1,4 +1,6 @@ -## Goldwarden + + +# Goldwarden Goldwarden is a Bitwarden compatible desktop client. It focuses on providing useful desktop features that the official tools do not (yet) have or are not willing to add, and enhanced security measures that other tools do not provide, such as: @@ -28,7 +30,8 @@ There is a flatpak that includes a small UI, autotype functionality and autostar [Download on Flathub](https://flathub.org/apps/details/com.quexten.Goldwarden) - + + #### CLI ##### Arch (AUR) diff --git a/agent/bitwarden/crypto/encstring.go b/agent/bitwarden/crypto/encstring.go index b61c503..f0b381f 100644 --- a/agent/bitwarden/crypto/encstring.go +++ b/agent/bitwarden/crypto/encstring.go @@ -47,13 +47,13 @@ func (s *EncString) UnmarshalText(data []byte) error { i := bytes.IndexByte(data, '.') if i < 0 { - return errors.New("invalid cipher string format") + return errors.New("invalid cipher string format, missign type. total length: " + strconv.Itoa(len(data))) } typStr := string(data[:i]) var err error if t, err := strconv.Atoi(typStr); err != nil { - return errors.New("invalid cipher string type") + return errors.New("invalid cipher string type, could not parse, length: " + strconv.Itoa(len(data))) } else { s.Type = EncStringType(t) } @@ -61,13 +61,13 @@ func (s *EncString) UnmarshalText(data []byte) error { switch s.Type { case AesCbc128_HmacSha256_B64, AesCbc256_HmacSha256_B64, AesCbc256_B64: default: - return errors.New("invalid cipher string type") + return errors.New("invalid cipher string type, unknown type: " + strconv.Itoa(int(s.Type))) } data = data[i+1:] parts := bytes.Split(data, []byte("|")) if len(parts) != 3 { - return errors.New("invalid cipher string format") + return errors.New("invalid cipher string format, missing parts, length: " + strconv.Itoa(len(data)) + "type: " + strconv.Itoa(int(s.Type))) } if s.IV, err = b64decode(parts[0]); err != nil { diff --git a/browserbiometrics/main.go b/browserbiometrics/main.go index bc65d2e..384c8f8 100644 --- a/browserbiometrics/main.go +++ b/browserbiometrics/main.go @@ -111,16 +111,20 @@ func detectAndInstallBrowsers(startPath string) error { if info.IsDir() && info.Name() == "native-messaging-hosts" { fmt.Printf("Found mozilla-like browser: %s\n", path) + fmt.Println("Removing old manifest and proxy script") os.Chown(path+"/com.8bit.bitwarden.json", 7, 7) os.Remove(path + "/com.8bit.bitwarden.json") os.Chown(path+"/goldwarden-proxy.sh", 7, 7) os.Remove(path + "/goldwarden-proxy.sh") + fmt.Println("Writing new manifest") manifest := strings.Replace(templateMozilla, "PATH", path+"/goldwarden-proxy.sh", 1) err = os.WriteFile(path+"/com.8bit.bitwarden.json", []byte(manifest), 0444) if err != nil { return err } + + fmt.Println("Writing new proxy script") err = os.WriteFile(path+"/goldwarden-proxy.sh", []byte(proxyScript), 0755) if err != nil { return err @@ -128,16 +132,20 @@ func detectAndInstallBrowsers(startPath string) error { } else if info.IsDir() && info.Name() == "NativeMessagingHosts" { fmt.Printf("Found chrome-like browser: %s\n", path) + fmt.Println("Removing old manifest and proxy script") os.Chown(path+"/com.8bit.bitwarden.json", 7, 7) os.Remove(path + "/com.8bit.bitwarden.json") os.Chown(path+"/goldwarden-proxy.sh", 7, 7) os.Remove(path + "/goldwarden-proxy.sh") + fmt.Println("Writing new manifest") manifest := strings.Replace(templateChrome, "PATH", path+"/goldwarden-proxy.sh", 1) err = os.WriteFile(path+"/com.8bit.bitwarden.json", []byte(manifest), 0444) if err != nil { return err } + + fmt.Println("Writing new proxy script") err = os.WriteFile(path+"/goldwarden-proxy.sh", []byte(proxyScript), 0755) if err != nil { return err diff --git a/browserbiometrics/protocol.go b/browserbiometrics/protocol.go index cb75359..8eef4d2 100644 --- a/browserbiometrics/protocol.go +++ b/browserbiometrics/protocol.go @@ -105,7 +105,26 @@ func handlePayloadMessage(msg PayloadMessage, appID string) { case "biometricUnlock": logging.Debugf("Biometric unlock requested") // logging.Debugf("Biometrics authorized: %t", isAuthorized) + + home, err := os.UserHomeDir() + if err != nil { + panic(err) + } + + if runtimeConfig.GoldwardenSocketPath == "" { + if _, err := os.Stat(home + "/.goldwarden.sock"); err == nil { + runtimeConfig.GoldwardenSocketPath = home + "/.goldwarden.sock" + } else if _, err := os.Stat(home + "/.var/app/com.quexten.Goldwarden/data/goldwarden.sock"); err == nil { + runtimeConfig.GoldwardenSocketPath = home + "/.var/app/com.quexten.Goldwarden/data/goldwarden.sock" + } + + if _, err = os.Stat("/.flatpak-info"); err == nil { + runtimeConfig.GoldwardenSocketPath = home + "/.var/app/com.quexten.Goldwarden/data/goldwarden.sock" + } + } + logging.Debugf("Connecting to agent at path %s", runtimeConfig.GoldwardenSocketPath) + result, err := client.NewUnixSocketClient(runtimeConfig).SendToAgent(messages.GetBiometricsKeyRequest{}) if err != nil { logging.Errorf("Unable to send message to agent: %s", err.Error()) diff --git a/client/unixsocketclient.go b/client/unixsocketclient.go index b66571b..1da325e 100644 --- a/client/unixsocketclient.go +++ b/client/unixsocketclient.go @@ -4,6 +4,7 @@ import ( "encoding/json" "io" "net" + "os" "github.com/quexten/goldwarden/agent/config" "github.com/quexten/goldwarden/ipc/messages" @@ -52,6 +53,26 @@ func (client UnixSocketClient) SendToAgent(request interface{}) (interface{}, er } func (client UnixSocketClient) Connect() (UnixSocketConnection, error) { + runtimeConfig := client.runtimeConfig + home, err := os.UserHomeDir() + if err != nil { + panic(err) + } + if runtimeConfig.SSHAgentSocketPath == "" { + if _, err := os.Stat(home + "/.goldwarden-ssh-agent.sock"); err == nil { + runtimeConfig.SSHAgentSocketPath = home + "/.goldwarden-ssh-agent.sock" + } else if _, err := os.Stat(home + "/.var/app/com.quexten.Goldwarden/data/ssh-auth-sock"); err == nil { + runtimeConfig.SSHAgentSocketPath = home + "/.var/app/com.quexten.Goldwarden/data/ssh-auth-sock" + } + } + if runtimeConfig.GoldwardenSocketPath == "" { + if _, err := os.Stat(home + "/.goldwarden.sock"); err == nil { + runtimeConfig.GoldwardenSocketPath = home + "/.goldwarden.sock" + } else if _, err := os.Stat(home + "/.var/app/com.quexten.Goldwarden/data/goldwarden.sock"); err == nil { + runtimeConfig.GoldwardenSocketPath = home + "/.var/app/com.quexten.Goldwarden/data/goldwarden.sock" + } + } + c, err := net.Dial("unix", client.runtimeConfig.GoldwardenSocketPath) if err != nil { return UnixSocketConnection{}, err diff --git a/cmd/daemonize.go b/cmd/daemonize.go index 8f4b9e9..8f98aaf 100644 --- a/cmd/daemonize.go +++ b/cmd/daemonize.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "os" "syscall" "github.com/awnumar/memguard" @@ -42,7 +43,29 @@ var daemonizeCmd = &cobra.Command{ memguard.SafeExit(0) } - err := agent.StartUnixAgent(runtimeConfig.GoldwardenSocketPath, runtimeConfig) + home, _ := os.UserHomeDir() + _, err := os.Stat("/.flatpak-info") + isFlatpak := err == nil + if runtimeConfig.GoldwardenSocketPath == "" { + if isFlatpak { + fmt.Println("Socket path is empty, overwriting with flatpak path.") + runtimeConfig.GoldwardenSocketPath = home + "/.var/app/com.quexten.Goldwarden/data/goldwarden.sock" + } else { + fmt.Println("Socket path is empty, overwriting with default path.") + runtimeConfig.GoldwardenSocketPath = home + "/.goldwarden.sock" + } + } + if runtimeConfig.SSHAgentSocketPath == "" { + if isFlatpak { + fmt.Println("SSH Agent socket path is empty, overwriting with flatpak path.") + runtimeConfig.SSHAgentSocketPath = home + "/.var/app/com.quexten.Goldwarden/data/ssh-auth-sock" + } else { + fmt.Println("SSH Agent socket path is empty, overwriting with default path.") + runtimeConfig.SSHAgentSocketPath = home + "/.goldwarden-ssh-agent.sock" + } + } + + err = agent.StartUnixAgent(runtimeConfig.GoldwardenSocketPath, runtimeConfig) if err != nil { panic(err) } diff --git a/gui/com.quexten.Goldwarden.metainfo.xml b/gui/com.quexten.Goldwarden.metainfo.xml index f03b3f3..abce7ec 100644 --- a/gui/com.quexten.Goldwarden.metainfo.xml +++ b/gui/com.quexten.Goldwarden.metainfo.xml @@ -36,7 +36,8 @@ Bernd Schoolmann mail@quexten.com - + + diff --git a/gui/goldwarden.svg b/gui/goldwarden.svg index c26e20f..7ce3ca4 100644 --- a/gui/goldwarden.svg +++ b/gui/goldwarden.svg @@ -24,11 +24,11 @@ inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" - inkscape:zoom="1.6792579" - inkscape:cx="142.62253" - inkscape:cy="292.09332" + inkscape:zoom="3.3585158" + inkscape:cx="193.53787" + inkscape:cy="151.70392" inkscape:window-width="3840" - inkscape:window-height="2091" + inkscape:window-height="2083" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" @@ -39,45 +39,39 @@ id="linearGradient17" inkscape:collect="always"> - - + id="linearGradient1" + x1="-11.825131" + y1="23.294865" + x2="107.26698" + y2="86.020233" + gradientUnits="userSpaceOnUse" /> + width="84" + height="84" + x="8" + y="8" + ry="11.519571" /> + transform="matrix(1.3540167,0,0,1.3477391,-44.781168,-16.956296)"> 1 && (strings.Contains(os.Args[1], "com.8bit.bitwarden.json") || strings.Contains(os.Args[1], "chrome-extension://")) {