Compare commits

...

77 Commits

Author SHA1 Message Date
Bernd Schoolmann
829193e70c
Fixes 2024-11-07 00:23:54 +01:00
Bernd Schoolmann
dd063cc768
Add support for new ssh key cipher type 2024-11-06 01:39:34 +01:00
Bernd Schoolmann
eae9246310
Update http headers 2024-11-06 01:07:39 +01:00
Bernd Schoolmann
6cbebdf6c7
Merge pull request #302 from quexten/dependabot/go_modules/github.com/icza/gox-0.2.0
Bump github.com/icza/gox from 0.0.0-20230924165045-adcb03233bb5 to 0.2.0
2024-11-01 22:10:11 +01:00
Bernd Schoolmann
490dfae155
Merge pull request #299 from soraxas/feat/more-generic-cache
Remove checking for parent / grandparent process
2024-11-01 22:09:47 +01:00
dependabot[bot]
d3bc35deb2
Bump github.com/icza/gox from 0.0.0-20230924165045-adcb03233bb5 to 0.2.0
Bumps [github.com/icza/gox](https://github.com/icza/gox) from 0.0.0-20230924165045-adcb03233bb5 to 0.2.0.
- [Commits](https://github.com/icza/gox/commits/v0.2.0)

---
updated-dependencies:
- dependency-name: github.com/icza/gox
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-01 19:58:32 +00:00
Tin Lai
cffa650124 only check for ancestor if the session is not a ssh session
Signed-off-by: Tin Lai <tin@tinyiu.com>
2024-11-01 09:57:59 +10:00
Bernd Schoolmann
51940fa770
Merge pull request #298 from soraxas/feat/use-ssh-key-standard
Use regex to extract begin and end marker
2024-10-30 23:24:34 +01:00
Bernd Schoolmann
b62ffb2cb4
Merge pull request #300 from Oisann/oisann/macos-ssh-agent-pinentry-fix
Fix: Use pinentry-mac as pinentry binary on macOS for approvals
2024-10-30 23:23:44 +01:00
Jonas Myhr Refseth
ff1ae8316e Fix: Use pinentry-mac as pinentry binary on macOS for approvals 2024-10-28 13:46:40 +01:00
Tin Lai
49ee2cbe29 remove checking for parent process
Signed-off-by: Tin Lai <tin@tinyiu.com>
2024-10-28 13:41:05 +10:00
Tin Lai
4b0b90699f use regex to extract begin and end marker
Signed-off-by: Tin Lai <tin@tinyiu.com>
2024-10-26 14:38:42 +10:00
Bernd Schoolmann
1317e1e037
Merge pull request #280 from quexten/dependabot/go_modules/github.com/rymdport/portal-0.2.6
Bump github.com/rymdport/portal from 0.2.3 to 0.2.6
2024-10-20 20:34:40 +02:00
Bernd Schoolmann
b15c883559
Merge pull request #297 from quexten/dependabot/go_modules/golang.org/x/crypto-0.28.0
Bump golang.org/x/crypto from 0.25.0 to 0.28.0
2024-10-20 20:33:31 +02:00
dependabot[bot]
2bce296d6a
Bump golang.org/x/crypto from 0.25.0 to 0.28.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.25.0 to 0.28.0.
- [Commits](https://github.com/golang/crypto/compare/v0.25.0...v0.28.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-20 18:32:02 +00:00
Bernd Schoolmann
8175406617
Merge pull request #295 from 0n-s/main
Readme: update logo filename (hotfix for https://github.com/quexten/goldwarden/pull/293)
2024-10-20 20:31:42 +02:00
Bernd Schoolmann
f05ab33670
Merge pull request #291 from quexten/dependabot/go_modules/golang.org/x/sys-0.25.0
Bump golang.org/x/sys from 0.22.0 to 0.25.0
2024-10-20 20:31:08 +02:00
Bernd Schoolmann
16b86527ad
Merge pull request #296 from ManInDark/main
update up- & download-artifact actions
2024-10-20 20:30:37 +02:00
ManInDark
c5d57c95e1
updated version of upload-artifact 2024-10-19 23:07:17 +02:00
ManInDark
6c17984bd0
updated version of download-artifact 2024-10-19 23:03:02 +02:00
ns
9daaf53d39 Readme: update logo filename
Commit 0dd6ac11889ad195c99e8f708d6c3c2db293163b ("gui: rename logo's
filename to icon name") caused the filename of the logo to change. All
instances of the filename were also renamed, besides in Readme.md.

Fix it here too.

Fixes: 0dd6ac11889ad195c99e8f708d6c3c2db293163b ("gui: rename logo's filename to icon name")
Reported-by: @ozmodeuz
2024-10-17 21:16:44 +03:30
Bernd Schoolmann
59be4814a1
Merge pull request #293 from 0n-s/main
gui: rename logo's filename to icon name
2024-10-03 08:40:08 -07:00
ns
0dd6ac1188 gui: rename logo's filename to icon name
The desktop file specifies the name of the icon with its app ID, while
the logo file is named "goldwarden.svg". Make the filename & the icon
name match.
2024-10-03 08:22:16 +03:30
dependabot[bot]
140026386e
Bump golang.org/x/sys from 0.22.0 to 0.25.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.22.0 to 0.25.0.
- [Commits](https://github.com/golang/sys/compare/v0.22.0...v0.25.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-01 19:28:52 +00:00
Bernd Schoolmann
aab01aaf6c
Merge pull request #286 from bb010g/fix/libportal-autotype
fix: autotypeing with libportal
2024-09-29 11:52:22 -07:00
Dusk Banks
ad1ab73d71 fix: autotypeing with libportal 2024-09-26 21:48:29 -07:00
dependabot[bot]
927b08d441
Bump github.com/rymdport/portal from 0.2.3 to 0.2.6
Bumps [github.com/rymdport/portal](https://github.com/rymdport/portal) from 0.2.3 to 0.2.6.
- [Release notes](https://github.com/rymdport/portal/releases)
- [Commits](https://github.com/rymdport/portal/compare/v0.2.3...v0.2.6)

---
updated-dependencies:
- dependency-name: github.com/rymdport/portal
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-01 19:56:44 +00:00
Bernd Schoolmann
5806475998
Merge pull request #270 from quexten/dependabot/go_modules/golang.org/x/crypto-0.25.0
Bump golang.org/x/crypto from 0.24.0 to 0.25.0
2024-08-04 00:16:56 +02:00
Bernd Schoolmann
f38fd2edec
Merge pull request #265 from quexten/fix/camelcase-requests
Force camelcase on requests
2024-08-04 00:16:43 +02:00
Bernd Schoolmann
71b145ad41
Merge branch 'main' into fix/camelcase-requests 2024-08-04 00:16:30 +02:00
dependabot[bot]
2f93774405
Bump golang.org/x/crypto from 0.24.0 to 0.25.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.24.0 to 0.25.0.
- [Commits](https://github.com/golang/crypto/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-01 19:43:04 +00:00
Bernd Schoolmann
c86e32de7e
Force camelcase on requests 2024-07-28 18:05:48 +02:00
Bernd Schoolmann
a938090de7
Merge pull request #258 from quexten/fix/prelogin-url
Fix auth url by moving it to identity server
2024-07-20 00:37:39 +02:00
Bernd Schoolmann
3c3c54906a
Merge pull request #257 from quexten/feature/cipherkey-encryption
Implement cipherkey decryption
2024-07-20 00:37:32 +02:00
Bernd Schoolmann
bc133ee2c6
Fix auth url by moving it to identity server 2024-07-20 00:36:57 +02:00
Bernd Schoolmann
5d1192113a
Implement cipherkey decryption 2024-07-20 00:36:07 +02:00
Bernd Schoolmann
fa4b735635
Merge pull request #241 from iron3oxide/main
style: Fix typo: Websocked -> Websocket
2024-07-04 21:26:13 +02:00
Bernd Schoolmann
4a2d3a9e92
Merge pull request #246 from quexten/dependabot/go_modules/github.com/gorilla/websocket-1.5.3
Bump github.com/gorilla/websocket from 1.5.1 to 1.5.3
2024-07-01 23:21:10 +02:00
Bernd Schoolmann
553f88a66e
Merge pull request #247 from quexten/dependabot/go_modules/github.com/spf13/cobra-1.8.1
Bump github.com/spf13/cobra from 1.8.0 to 1.8.1
2024-07-01 23:21:05 +02:00
Bernd Schoolmann
55c6aa2b8c
Merge pull request #244 from quexten/dependabot/go_modules/golang.org/x/crypto-0.24.0
Bump golang.org/x/crypto from 0.23.0 to 0.24.0
2024-07-01 23:20:47 +02:00
dependabot[bot]
7ea364b1c3
Bump github.com/spf13/cobra from 1.8.0 to 1.8.1
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-01 19:39:19 +00:00
dependabot[bot]
977f21c4a9
Bump github.com/gorilla/websocket from 1.5.1 to 1.5.3
Bumps [github.com/gorilla/websocket](https://github.com/gorilla/websocket) from 1.5.1 to 1.5.3.
- [Release notes](https://github.com/gorilla/websocket/releases)
- [Commits](https://github.com/gorilla/websocket/compare/v1.5.1...v1.5.3)

---
updated-dependencies:
- dependency-name: github.com/gorilla/websocket
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-01 19:39:15 +00:00
dependabot[bot]
f80982a24f
Bump golang.org/x/crypto from 0.23.0 to 0.24.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.23.0 to 0.24.0.
- [Commits](https://github.com/golang/crypto/compare/v0.23.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-01 19:39:07 +00:00
iron3oxide
b1e632588f style: rename more instances of same typo 2024-06-27 22:29:27 +02:00
iron3oxide
2bf75430f3 style: Fix typo: Websocked -> Websocket 2024-06-24 02:07:08 +02:00
Bernd Schoolmann
f7e1cae015
Print error if no files are given on ssh import 2024-06-03 23:54:47 +02:00
Bernd Schoolmann
1c9bf6101b
Fix incorrectly named method 2024-06-02 23:23:07 +02:00
Bernd Schoolmann
9a0ffded83
Merge pull request #233 from quexten/feature/import-ssh
Implement ssh import
2024-06-02 23:20:03 +02:00
Bernd Schoolmann
97a485712e
Implement ssh import 2024-06-02 23:18:37 +02:00
Bernd Schoolmann
79bfc43ab8
Update websocket.go 2024-06-02 21:45:12 +02:00
Bernd Schoolmann
d32147bdf8
Merge pull request #228 from quexten/feature/macos
Mac Support
2024-06-02 21:13:59 +02:00
Bernd Schoolmann
53271c3331
Implement mac main 2024-06-02 18:54:15 +02:00
Bernd Schoolmann
5af6771460
Fix autotype on mac 2024-06-02 17:17:15 +02:00
Bernd Schoolmann
9ae9401542
Merge pull request #232 from quexten/dependabot/go_modules/golang.org/x/crypto-0.23.0
Bump golang.org/x/crypto from 0.22.0 to 0.23.0
2024-06-01 23:43:37 +02:00
dependabot[bot]
833b0225f1
Bump golang.org/x/crypto from 0.22.0 to 0.23.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.22.0 to 0.23.0.
- [Commits](https://github.com/golang/crypto/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-01 20:37:20 +00:00
Bernd Schoolmann
bcecb10e22
Merge pull request #231 from quexten/dependabot/go_modules/golang.org/x/sys-0.20.0
Bump golang.org/x/sys from 0.19.0 to 0.20.0
2024-06-01 22:36:55 +02:00
Bernd Schoolmann
dc32d85fcb
Merge pull request #230 from quexten/dependabot/go_modules/github.com/tink-crypto/tink-go/v2-2.2.0
Bump github.com/tink-crypto/tink-go/v2 from 2.1.0 to 2.2.0
2024-06-01 22:36:36 +02:00
dependabot[bot]
6323babce0
Bump golang.org/x/sys from 0.19.0 to 0.20.0
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.19.0 to 0.20.0.
- [Commits](https://github.com/golang/sys/compare/v0.19.0...v0.20.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-01 19:59:38 +00:00
dependabot[bot]
670efc076f
Bump github.com/tink-crypto/tink-go/v2 from 2.1.0 to 2.2.0
Bumps [github.com/tink-crypto/tink-go/v2](https://github.com/tink-crypto/tink-go) from 2.1.0 to 2.2.0.
- [Release notes](https://github.com/tink-crypto/tink-go/releases)
- [Commits](https://github.com/tink-crypto/tink-go/compare/v2.1.0...v2.2.0)

---
updated-dependencies:
- dependency-name: github.com/tink-crypto/tink-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-01 19:59:32 +00:00
Bernd Schoolmann
2651a36d3c
Fix pinentry 2024-06-01 15:18:11 +02:00
Bernd Schoolmann
a41c91ca6b
Add macos startup scripts 2024-06-01 14:32:25 +02:00
Bernd Schoolmann
275ba9a3d2
Fix crash on daemon not running 2024-06-01 14:32:15 +02:00
Bernd Schoolmann
0146533075
Merge pull request #225 from argonaut0/patch-1
Fix SSH add command's help string
2024-05-27 19:55:25 +02:00
Jason
d85cea14ff
Fix SSH add command's help string 2024-05-26 21:55:08 -07:00
Bernd Schoolmann
09c7e7521f
Update release.yml 2024-05-25 09:36:16 +02:00
Bernd Schoolmann
aed218429a
Merge pull request #223 from quexten/fix/status-py
Make sure status.py exits
2024-05-25 09:33:17 +02:00
Bernd Schoolmann
b9b10fd6e8
Make sure status.py exits 2024-05-25 09:32:34 +02:00
Bernd Schoolmann
e9471caede
Merge pull request #220 from quexten/fix/rename-directive
Remove replace directive
2024-05-17 21:12:25 +02:00
Bernd Schoolmann
259d8eb437
Remove replace directive 2024-05-15 20:36:31 +02:00
Bernd Schoolmann
742ceddf15
Merge pull request #215 from quexten/feature/error-dialogs-on-login
Present error on failed login
2024-05-11 04:29:19 +02:00
Bernd Schoolmann
26d12fd5ce
Merge branch 'main' into feature/error-dialogs-on-login 2024-05-11 04:28:46 +02:00
Bernd Schoolmann
50451914f2
Present error on failed login 2024-05-11 04:26:21 +02:00
Bernd Schoolmann
b8b0dd9bf9
Merge pull request #213 from quexten/fix/wrong_server_in_gui
Fix server not being set when logging in from UI
2024-05-11 03:37:21 +02:00
Bernd Schoolmann
08f419ac36
Merge pull request #212 from quexten/fix/client-credentials
Attempt to fix credentials not being set in gui
2024-05-11 03:37:09 +02:00
Bernd Schoolmann
e913180798
Merge pull request #214 from quexten/fix/goldwarden_ui_main_executable_bit
Fix executable bit on main python file
2024-05-11 03:36:57 +02:00
Bernd Schoolmann
d70dd90630
Fix executable bit on main python file 2024-05-11 03:35:30 +02:00
Bernd Schoolmann
9fbf1a08ee
Attempt to fix credentials not being set in gui 2024-05-10 11:31:24 +02:00
35 changed files with 557 additions and 185 deletions

View File

@ -40,7 +40,7 @@ modules:
- cp -R ./* /app/bin
- chmod +x /app/bin/goldwarden_ui_main.py
- install -D ./com.quexten.Goldwarden.desktop /app/share/applications/com.quexten.Goldwarden.desktop
- install -D ./goldwarden.svg /app/share/icons/hicolor/scalable/apps/com.quexten.Goldwarden.svg
- install -D ./com.quexten.Goldwarden.svg /app/share/icons/hicolor/scalable/apps/com.quexten.Goldwarden.svg
- install -Dm644 ./com.quexten.Goldwarden.metainfo.xml -t /app/share/metainfo/
- blueprint-compiler batch-compile /app/bin/src/gui/.templates/ /app/bin/src/gui/ /app/bin/src/gui/*.blp
sources:

View File

@ -19,7 +19,7 @@ jobs:
run: sudo apt-get install -y libfido2-dev
- name: Build
run: go build -o goldwarden -v .
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: goldwarden
path: ./goldwarden
@ -37,7 +37,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Download daemon
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4
with:
name: goldwarden
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6

View File

@ -114,7 +114,7 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}
build_macos_x86_64:
runs-on: macos-latest
runs-on: macos-13
steps:
- name: Checkout
uses: actions/checkout@v1

View File

@ -1,4 +1,4 @@
<img src="https://raw.githubusercontent.com/quexten/goldwarden/main/gui/goldwarden.svg" width=200>
<img src="https://raw.githubusercontent.com/quexten/goldwarden/main/gui/com.quexten.Goldwarden.svg" width=200>
# Goldwarden

View File

@ -16,12 +16,24 @@ import (
func handleAddSSH(msg messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) {
req := messages.ParsePayload(msg).(messages.CreateSSHKeyRequest)
cipher, publicKey := ssh.NewSSHKeyCipher(req.Name, vault.Keyring)
cipher, publicKey, err := ssh.NewSSHKeyCipher(req.Name, vault.Keyring)
if err != nil {
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
Success: false,
Message: err.Error(),
})
return
}
_, err = messages.IPCMessageFromPayload(messages.ActionResponse{
Success: true,
})
if err != nil {
panic(err)
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
Success: false,
Message: err.Error(),
})
return
}
token, err := cfg.GetToken()
@ -56,7 +68,49 @@ func handleListSSH(msg messages.IPCMessage, cfg *config.Config, vault *vault.Vau
return
}
func handleImportSSH(msg messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) {
req := messages.ParsePayload(msg).(messages.ImportSSHKeyRequest)
cipher, _, err := ssh.SSHKeyCipherFromKey(req.Name, req.Key, vault.Keyring)
if err != nil {
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
Success: false,
Message: err.Error(),
})
return
}
_, err = messages.IPCMessageFromPayload(messages.ActionResponse{
Success: true,
})
if err != nil {
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
Success: false,
Message: err.Error(),
})
return
}
token, err := cfg.GetToken()
if err != nil {
actionsLog.Warn(err.Error())
}
ctx := context.WithValue(context.TODO(), bitwarden.AuthToken{}, token.AccessToken)
postedCipher, err := bitwarden.PostCipher(ctx, cipher, cfg)
if err == nil {
vault.AddOrUpdateSecureNote(postedCipher)
} else {
actionsLog.Warn("Error posting ssh key cipher: " + err.Error())
}
response, err = messages.IPCMessageFromPayload(messages.ImportSSHKeyResponse{
Success: true,
})
return
}
func init() {
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.CreateSSHKeyRequest{}), ensureEverything(systemauth.SSHKey, handleAddSSH))
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.GetSSHKeysRequest{}), ensureIsNotLocked(ensureIsLoggedIn(handleListSSH)))
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.ImportSSHKeyRequest{}), ensureEverything(systemauth.SSHKey, handleImportSSH))
}

View File

@ -256,7 +256,7 @@ func handleVaultStatus(request messages.IPCMessage, cfg *config.Config, vault *v
vaultStatus.NumberOfLogins = len(vault.GetLogins())
vaultStatus.NumberOfNotes = len(vault.GetNotes())
vaultStatus.LastSynced = vault.GetLastSynced()
vaultStatus.WebsockedConnected = vault.IsWebsocketConnected()
vaultStatus.WebsocketConnected = vault.IsWebsocketConnected()
vaultStatus.PinSet = cfg.HasPin()
vaultStatus.LoggedIn = cfg.IsLoggedIn()
response, err = messages.IPCMessageFromPayload(vaultStatus)

View File

@ -116,7 +116,8 @@ func LoginWithApiKey(ctx context.Context, email string, cfg *config.Config, vaul
func LoginWithMasterpassword(ctx context.Context, email string, cfg *config.Config, vault *vault.Vault) (LoginResponseToken, crypto.MasterKey, string, error) {
var preLogin preLoginResponse
if err := authenticatedHTTPPost(ctx, cfg.ConfigFile.ApiUrl+"/accounts/prelogin", &preLogin, preLoginRequest{
fmt.Println("Posting prelogin")
if err := authenticatedHTTPPost(ctx, cfg.ConfigFile.IdentityUrl+"/accounts/prelogin", &preLogin, preLoginRequest{
Email: email,
}); err != nil {
notify.Notify("Goldwarden", fmt.Sprintf("Could not pre-login: %v", err), "", 0, func() {})
@ -127,12 +128,14 @@ func LoginWithMasterpassword(ctx context.Context, email string, cfg *config.Conf
var masterKey crypto.MasterKey
var hashedPassword string
fmt.Println("Getting password")
password, err := pinentry.GetPassword("Bitwarden Password", "Enter your Bitwarden password")
if err != nil {
notify.Notify("Goldwarden", fmt.Sprintf("Could not get password: %v", err), "", 0, func() {})
return LoginResponseToken{}, crypto.MasterKey{}, "", err
}
fmt.Println("Deriving master key")
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), "", 0, func() {})
@ -142,14 +145,14 @@ func LoginWithMasterpassword(ctx context.Context, email string, cfg *config.Conf
hashedPassword = b64enc.EncodeToString(pbkdf2.Key(masterKey.GetBytes(), []byte(password), 1, 32, sha256.New))
values = urlValues(
"scope", loginScope,
"client_id", "web",
"deviceType", "10",
"deviceIdentifier", cfg.ConfigFile.DeviceUUID,
"deviceName", "firefox",
"grant_type", "password",
"username", email,
"password", string(hashedPassword),
"scope", loginScope,
"client_id", "connector",
"deviceType", deviceType(),
"deviceName", deviceName,
"deviceIdentifier", cfg.ConfigFile.DeviceUUID,
)
var loginResponseToken LoginResponseToken

View File

@ -51,7 +51,7 @@ func authenticatedHTTPPost(ctx context.Context, urlstr string, recv, send interf
}
req.Header.Set("Content-Type", contentType)
if authEmail != "" {
req.Header.Set("Auth-Email", base64.URLEncoding.EncodeToString([]byte(authEmail)))
req.Header.Set("Auth-Email", base64.RawURLEncoding.EncodeToString([]byte(authEmail)))
}
return makeAuthenticatedHTTPRequest(ctx, req, recv)
}
@ -97,7 +97,12 @@ func makeAuthenticatedHTTPRequest(ctx context.Context, req *http.Request, recv i
if token, ok := ctx.Value(AuthToken{}).(string); ok {
req.Header.Set("Authorization", "Bearer "+token)
}
req.Header.Set("device-type", deviceType())
req.Header.Set("Accept", "*/*")
req.Header.Set("Accept-Language", "en-US,en;q=0.5")
req.Header.Set("User-Agent", "Goldwarden (github.com/quexten/goldwarden)")
req.Header.Set("Device-Type", "10")
req.Header.Set("Bitwarden-Client-Name", "goldwarden")
req.Header.Set("Bitwarden-Client-Version", "0.0.0")
res, err := httpClient.Do(req)
if err != nil {

View File

@ -8,74 +8,77 @@ import (
)
type SyncData struct {
Profile Profile
Folders []Folder
Ciphers []Cipher
Profile Profile `json:"profile"`
Folders []Folder `json:"folders"`
Ciphers []Cipher `json:"ciphers"`
}
type Organization struct {
Object string
Id uuid.UUID
Name string
UseGroups bool
UseDirectory bool
UseEvents bool
UseTotp bool
Use2fa bool
UseApi bool
UsersGetPremium bool
SelfHost bool
Seats int
MaxCollections int
MaxStorageGb int
Key string
Status int
Type int
Enabled bool
Object string `json:"object"`
Id uuid.UUID `json:"id"`
Name string `json:"name"`
UseGroups bool `json:"useGroups"`
UseDirectory bool `json:"useDirectory"`
UseEvents bool `json:"useEvents"`
UseTotp bool `json:"useTotp"`
Use2fa bool `json:"use2fa"`
UseApi bool `json:"useApi"`
UsersGetPremium bool `json:"usersGetPremium"`
SelfHost bool `json:"selfHost"`
Seats int `json:"seats"`
MaxCollections int `json:"maxCollections"`
MaxStorageGb int `json:"maxStorageGb"`
Key string `json:"key"`
Status int `json:"status"`
Type int `json:"type"`
Enabled bool `json:"enabled"`
}
type Profile struct {
ID uuid.UUID
Name string
Email string
EmailVerified bool
Premium bool
MasterPasswordHint string
Culture string
TwoFactorEnabled bool
Key crypto.EncString
PrivateKey crypto.EncString
SecurityStamp string
Organizations []Organization
ID uuid.UUID `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
EmailVerified bool `json:"emailVerified"`
Premium bool `json:"premium"`
MasterPasswordHint string `json:"masterPasswordHint"`
Culture string `json:"culture"`
TwoFactorEnabled bool `json:"twoFactorEnabled"`
Key crypto.EncString `json:"key"`
PrivateKey crypto.EncString `json:"privateKey"`
SecurityStamp string `json:"securityStamp"`
Organizations []Organization `json:"organizations"`
}
type Folder struct {
ID uuid.UUID
Name string
RevisionDate time.Time
ID uuid.UUID `json:"id"`
Name string `json:"name"`
RevisionDate time.Time `json:"revisionDate"`
}
type Cipher struct {
Type CipherType
ID *uuid.UUID `json:",omitempty"`
Name crypto.EncString
Edit bool
RevisionDate time.Time
DeletedDate time.Time
Type CipherType `json:"type,omitempty"`
ID *uuid.UUID `json:"id,omitempty"`
Name crypto.EncString `json:"name,omitempty"`
Edit bool `json:"edit,omitempty"`
RevisionDate time.Time `json:"revisionDate,omitempty"`
DeletedDate time.Time `json:"deletedDate,omitempty"`
FolderID *uuid.UUID `json:",omitempty"`
OrganizationID *uuid.UUID `json:",omitempty"`
Favorite bool `json:",omitempty"`
Attachments interface{} `json:",omitempty"`
OrganizationUseTotp bool `json:",omitempty"`
CollectionIDs []string `json:",omitempty"`
Fields []Field `json:",omitempty"`
FolderID *uuid.UUID `json:"folderId,omitempty"`
OrganizationID *uuid.UUID `json:"organizationId,omitempty"`
Favorite bool `json:"favorite,omitempty"`
Attachments interface{} `json:"attachments,omitempty"`
OrganizationUseTotp bool `json:"organizationUseTotp,omitempty"`
CollectionIDs []string `json:"collectionIds,omitempty"`
Fields []Field `json:"fields,omitempty"`
Card *Card `json:",omitempty"`
Identity *Identity `json:",omitempty"`
Login *LoginCipher `json:",omitempty"`
Notes *crypto.EncString `json:",omitempty"`
SecureNote *SecureNoteCipher `json:",omitempty"`
Card *Card `json:"card,omitempty"`
Identity *Identity `json:"identity,omitempty"`
Login *LoginCipher `json:"login,omitempty"`
Notes *crypto.EncString `json:"notes,omitempty"`
SecureNote *SecureNoteCipher `json:"secureNote,omitempty"`
SSHKey *SSHKeyCipher `json:"sshKey,omitempty"`
Key *crypto.EncString `json:"key,omitempty"`
}
type CipherType int
@ -86,59 +89,66 @@ const (
CipherCard = 3
CipherIdentity = 4
CipherNote = 2
CipherSSHKey = 5
)
type SSHKeyCipher struct {
PrivateKey crypto.EncString `json:"privateKey"`
PublicKey crypto.EncString `json:"publicKey"`
KeyFingerprint crypto.EncString `json:"keyFingerprint"`
}
type Card struct {
CardholderName crypto.EncString
Brand crypto.EncString
Number crypto.EncString
ExpMonth crypto.EncString
ExpYear crypto.EncString
Code crypto.EncString
CardholderName crypto.EncString `json:"cardholderName"`
Brand crypto.EncString `json:"brand"`
Number crypto.EncString `json:"number"`
ExpMonth crypto.EncString `json:"expMonth"`
ExpYear crypto.EncString `json:"expYear"`
Code crypto.EncString `json:"code"`
}
type Identity struct {
Title crypto.EncString
FirstName crypto.EncString
MiddleName crypto.EncString
LastName crypto.EncString
Title crypto.EncString `json:"title"`
FirstName crypto.EncString `json:"firstName"`
MiddleName crypto.EncString `json:"middleName"`
LastName crypto.EncString `json:"lastName"`
Username crypto.EncString
Company crypto.EncString
SSN crypto.EncString
PassportNumber crypto.EncString
LicenseNumber crypto.EncString
Username crypto.EncString `json:"username"`
Company crypto.EncString `json:"company"`
SSN crypto.EncString `json:"ssn"`
PassportNumber crypto.EncString `json:"passportNumber"`
LicenseNumber crypto.EncString `json:"licenseNumber"`
Email crypto.EncString
Phone crypto.EncString
Address1 crypto.EncString
Address2 crypto.EncString
Address3 crypto.EncString
City crypto.EncString
State crypto.EncString
PostalCode crypto.EncString
Country crypto.EncString
Email crypto.EncString `json:"email"`
Phone crypto.EncString `json:"phone"`
Address1 crypto.EncString `json:"address1"`
Address2 crypto.EncString `json:"address2"`
Address3 crypto.EncString `json:"address3"`
City crypto.EncString `json:"city"`
State crypto.EncString `json:"state"`
PostalCode crypto.EncString `json:"postalCode"`
Country crypto.EncString `json:"country"`
}
type FieldType int
type Field struct {
Type FieldType
Name crypto.EncString
Value crypto.EncString
Type FieldType `json:"type,omitempty"`
Name crypto.EncString `json:"name,omitempty"`
Value crypto.EncString `json:"value,omitempty"`
}
type LoginCipher struct {
Password crypto.EncString
URI crypto.EncString
URIs []URI
Username crypto.EncString `json:",omitempty"`
Totp crypto.EncString `json:",omitempty"`
Password crypto.EncString `json:"password,omitempty"`
URI crypto.EncString `json:"uri,omitempty"`
URIs []URI `json:"uris,omitempty"`
Username crypto.EncString `json:"username,omitempty"`
Totp crypto.EncString `json:"totp,omitempty"`
}
type URIMatch int
type URI struct {
URI string
Match URIMatch
URI string `json:"uri,omitempty"`
Match URIMatch `json:"match,omitempty"`
}
type SecureNoteType int
@ -147,8 +157,26 @@ type SecureNoteCipher struct {
}
func (cipher Cipher) GetKeyForCipher(keyring crypto.Keyring) (crypto.SymmetricEncryptionKey, error) {
var key1 crypto.SymmetricEncryptionKey = nil
var err error
if cipher.OrganizationID != nil {
return keyring.GetSymmetricKeyForOrganization(cipher.OrganizationID.String())
key1, err = keyring.GetSymmetricKeyForOrganization(cipher.OrganizationID.String())
} else {
key1, err = keyring.GetAccountKey(), nil
}
if err != nil {
return nil, err
}
if cipher.Key == nil {
return key1, nil
} else {
key, err := crypto.DecryptWith(*cipher.Key, key1)
if err != nil {
return nil, err
} else {
return crypto.MemorySymmetricEncryptionKeyFromBytes(key)
}
}
return keyring.GetAccountKey(), nil
}

View File

@ -59,6 +59,8 @@ func DoFullSync(ctx context.Context, vault *vault.Vault, config *config.Config,
vault.AddOrUpdateLogin(cipher)
case models.CipherNote:
vault.AddOrUpdateSecureNote(cipher)
case models.CipherSSHKey:
vault.AddOrUpdateSSHKey(cipher)
}
}

View File

@ -255,12 +255,11 @@ func parseMessageTypeFromMessagePack(messagePack []byte) (int8, string, bool) {
return 0, "", false
}
if len(value) < 5 {
websocketLog.Warn("Invalid message received, length too short")
return 0, "", false
}
value, success := value[4].([]interface{})
if len(value) < 1 || !success {
websocketLog.Warn("Invalid message received, length too short")
websocketLog.Warn("Invalid message received, value length less than 1")
return 0, "", false
}
value1, success := value[0].(map[string]interface{})

View File

@ -89,8 +89,8 @@ func DefaultConfig(useMemguard bool) Config {
useMemguard,
&keyBuffer,
ConfigFile{
IdentityUrl: "https://vault.bitwarden.com/identity",
ApiUrl: "https://vault.bitwarden.com/api",
IdentityUrl: "https://identity.bitwarden.com",
ApiUrl: "https://api.bitwarden.com",
NotificationsUrl: "https://notifications.bitwarden.com",
VaultUrl: "https://vault.bitwarden.com",
EncryptedClientID: "",

View File

@ -12,8 +12,55 @@ import (
"golang.org/x/crypto/ssh"
)
func NewSSHKeyCipher(name string, keyring *crypto.Keyring) (models.Cipher, string) {
// todo refactor to share code
func SSHKeyCipherFromKey(name string, privateKey string, keyring *crypto.Keyring) (models.Cipher, string, error) {
signer, err := ssh.ParsePrivateKey([]byte(privateKey))
if err != nil {
return models.Cipher{}, "", err
}
pubKey := signer.PublicKey()
encryptedName, _ := crypto.EncryptWith([]byte(name), crypto.AesCbc256_HmacSha256_B64, keyring.GetAccountKey())
encryptedPublicKeyKey, _ := crypto.EncryptWith([]byte("public-key"), crypto.AesCbc256_HmacSha256_B64, keyring.GetAccountKey())
encryptedPublicKeyValue, _ := crypto.EncryptWith([]byte(string(ssh.MarshalAuthorizedKey(pubKey))), crypto.AesCbc256_HmacSha256_B64, keyring.GetAccountKey())
encryptedCustomTypeKey, _ := crypto.EncryptWith([]byte("custom-type"), crypto.AesCbc256_HmacSha256_B64, keyring.GetAccountKey())
encryptedCustomTypeValue, _ := crypto.EncryptWith([]byte("ssh-key"), crypto.AesCbc256_HmacSha256_B64, keyring.GetAccountKey())
encryptedPrivateKeyKey, _ := crypto.EncryptWith([]byte("private-key"), crypto.AesCbc256_HmacSha256_B64, keyring.GetAccountKey())
encryptedPrivateKeyValue, _ := crypto.EncryptWith([]byte(privateKey), crypto.AesCbc256_HmacSha256_B64, keyring.GetAccountKey())
cipher := models.Cipher{
Type: models.CipherNote,
Name: encryptedName,
Notes: &encryptedPublicKeyValue,
ID: nil,
Favorite: false,
OrganizationID: nil,
SecureNote: &models.SecureNoteCipher{
Type: 0,
},
Fields: []models.Field{
{
Type: 0,
Name: encryptedCustomTypeKey,
Value: encryptedCustomTypeValue,
},
{
Type: 0,
Name: encryptedPublicKeyKey,
Value: encryptedPublicKeyValue,
},
{
Type: 1,
Name: encryptedPrivateKeyKey,
Value: encryptedPrivateKeyValue,
},
},
}
return cipher, string(ssh.MarshalAuthorizedKey(pubKey)), nil
}
func NewSSHKeyCipher(name string, keyring *crypto.Keyring) (models.Cipher, string, error) {
var reader io.Reader = rand.Reader
pub, priv, err := ed25519.GenerateKey(reader)
@ -72,5 +119,5 @@ func NewSSHKeyCipher(name string, keyring *crypto.Keyring) (models.Cipher, strin
},
}
return cipher, string(ssh.MarshalAuthorizedKey(publicKey))
return cipher, string(ssh.MarshalAuthorizedKey(publicKey)), nil
}

View File

@ -1,16 +1,27 @@
//go:build freebsd || linux
//go:build freebsd || linux || darwin
package pinentry
import (
"errors"
"runtime"
"github.com/twpayne/go-pinentry"
)
func getBinaryClientOption() (clientOption pinentry.ClientOption) {
binaryClientOption := pinentry.WithBinaryNameFromGnuPGAgentConf()
if runtime.GOOS == "darwin" {
binaryClientOption = pinentry.WithBinaryName("pinentry-mac")
}
return binaryClientOption
}
func getPassword(title string, description string) (string, error) {
binaryClientOption := getBinaryClientOption()
client, err := pinentry.NewClient(
pinentry.WithBinaryNameFromGnuPGAgentConf(),
binaryClientOption,
pinentry.WithGPGTTY(),
pinentry.WithTitle(title),
pinentry.WithDesc(description),
@ -43,8 +54,10 @@ func getApproval(title string, description string) (bool, error) {
return true, nil
}
binaryClientOption := getBinaryClientOption()
client, err := pinentry.NewClient(
pinentry.WithBinaryNameFromGnuPGAgentConf(),
binaryClientOption,
pinentry.WithGPGTTY(),
pinentry.WithTitle(title),
pinentry.WithDesc(description),

View File

@ -1,4 +1,4 @@
//go:build windows || darwin
//go:build windows
package pinentry

View File

@ -55,9 +55,12 @@ func (s *SessionStore) CreateSession(pid int, parentpid int, grandparentpid int,
func (s *SessionStore) verifySession(ctx sockets.CallingContext, sessionType SessionType) bool {
for _, session := range s.Store {
if session.ParentPid == ctx.ParentProcessPid && session.GrandParentPid == ctx.GrandParentProcessPid && session.sessionType == sessionType {
if session.Expires.After(time.Now()) {
return true
if session.sessionType == sessionType {
// only check for ancestor if the session is not a ssh session
if sessionType == SSHKey || (session.ParentPid == ctx.ParentProcessPid && session.GrandParentPid == ctx.GrandParentProcessPid) {
if session.Expires.After(time.Now()) {
return true
}
}
}
}

View File

@ -3,6 +3,8 @@ package vault
import (
"errors"
"strings"
"fmt"
"regexp"
"sync"
"github.com/quexten/goldwarden/cli/agent/bitwarden/crypto"
@ -17,10 +19,11 @@ type Vault struct {
Keyring *crypto.Keyring
logins map[string]models.Cipher
secureNotes map[string]models.Cipher
sshKeys map[string]models.Cipher
sshKeyNoteIDs []string
envCredentials map[string]string
lastSynced int64
websockedConnected bool
websocketConnected bool
mu sync.Mutex
}
@ -29,10 +32,11 @@ func NewVault(keyring *crypto.Keyring) *Vault {
Keyring: keyring,
logins: make(map[string]models.Cipher),
secureNotes: make(map[string]models.Cipher),
sshKeys: make(map[string]models.Cipher),
sshKeyNoteIDs: make([]string, 0),
envCredentials: make(map[string]string),
lastSynced: 0,
websockedConnected: false,
websocketConnected: false,
}
}
@ -90,6 +94,12 @@ func (vault *Vault) AddOrUpdateSecureNote(cipher models.Cipher) {
vault.unlockMutex()
}
func (vault *Vault) AddOrUpdateSSHKey(cipher models.Cipher) {
vault.lockMutex()
vault.sshKeys[cipher.ID.String()] = cipher
vault.unlockMutex()
}
func (vault *Vault) isEnv(cipher models.Cipher) (string, bool) {
if cipher.Type != models.CipherNote {
return "", false
@ -174,6 +184,26 @@ type SSHKey struct {
PublicKey string
}
func extractKeyMarker(text, pattern string) (string, string, error) {
re := regexp.MustCompile(pattern)
match := re.FindStringIndex(text)
if match != nil {
// Extract the matched text
extracted := re.FindString(text[match[0]:match[1]])
if match[0] == 0 {
// begin marker
return extracted, text[match[1]:], nil
} else if match[1] == len(strings.TrimRight(text, "\n\r ")) {
// end marker
return extracted, text[:match[0]], nil
}
return "", text, fmt.Errorf("Token found is neither at the beginning nor end: pattern: %s. match idx: %s", pattern, match)
}
return "", text, fmt.Errorf("No match found in pattern %s", pattern)
}
func (vault *Vault) GetSSHKeys() []SSHKey {
vault.lockMutex()
defer vault.unlockMutex()
@ -211,11 +241,19 @@ func (vault *Vault) GetSSHKeys() []SSHKey {
}
}
privateKey = strings.Replace(privateKey, "-----BEGIN OPENSSH PRIVATE KEY-----", "", 1)
privateKey = strings.Replace(privateKey, "-----END OPENSSH PRIVATE KEY-----", "", 1)
beginMarker, privateKey, err := extractKeyMarker(privateKey, `-----\w*BEGIN [a-zA-Z ]+\w*-----`)
if err != nil {
vaultLog.Error("Failed for note %s: %s", vault.secureNotes[id].Name, err.Error())
continue
}
endMarker, privateKey, err := extractKeyMarker(privateKey, `-----\w*END [a-zA-Z ]+\w*-----`)
if err != nil {
vaultLog.Error("Failed for note %s: %s", vault.secureNotes[id].Name, err.Error())
continue
}
pkParts := strings.Join(strings.Split(privateKey, " "), "\n")
privateKeyString := "-----BEGIN OPENSSH PRIVATE KEY-----" + pkParts + "-----END OPENSSH PRIVATE KEY-----"
privateKeyString := beginMarker + pkParts + endMarker
decryptedTitle, err := crypto.DecryptWith(vault.secureNotes[id].Name, key)
if err != nil {
@ -228,6 +266,20 @@ func (vault *Vault) GetSSHKeys() []SSHKey {
PublicKey: string(publicKey),
})
}
for id, _ := range vault.sshKeys {
key, _ := vault.sshKeys[id].GetKeyForCipher(*vault.Keyring)
privKey, _ := crypto.DecryptWith(vault.sshKeys[id].SSHKey.PrivateKey, key)
pubKey, _ := crypto.DecryptWith(vault.sshKeys[id].SSHKey.PublicKey, key)
name, _ := crypto.DecryptWith(vault.sshKeys[id].Name, key)
sshKeys = append(sshKeys, SSHKey{
Name: string(name),
Key: string(privKey),
PublicKey: string(pubKey),
})
}
return sshKeys
}
@ -424,7 +476,7 @@ func (vault *Vault) GetLastSynced() int64 {
func (vault *Vault) SetWebsocketConnected(connected bool) {
vault.lockMutex()
vault.websockedConnected = connected
vault.websocketConnected = connected
vault.unlockMutex()
}
@ -432,5 +484,5 @@ func (vault *Vault) IsWebsocketConnected() bool {
vault.lockMutex()
defer vault.unlockMutex()
return vault.websockedConnected
return vault.websocketConnected
}

View File

@ -1,6 +1,7 @@
package cmd
import (
"bytes"
"fmt"
"os"
@ -18,12 +19,12 @@ var sshCmd = &cobra.Command{
},
}
// runCmd represents the run command
// sshAddCmd represents the ssh add command
var sshAddCmd = &cobra.Command{
Use: "add",
Short: "Runs a command with environment variables from your vault",
Long: `Runs a command with environment variables from your vault.
The variables are stored as a secure note. Consult the documentation for more information.`,
Short: "Creates a new SSH key and adds it to the SSH Agent.",
Long: `Creates a new SSH key and adds it to the SSH Agent.
The key is stored as a secure note. Consult the documentation for more information.`,
Run: func(cmd *cobra.Command, args []string) {
err := loginIfRequired()
if err != nil {
@ -92,6 +93,64 @@ var listSSHCmd = &cobra.Command{
},
}
var importSSHCmd = &cobra.Command{
Use: "import",
Short: "Imports an SSH key into your vault",
Long: `Imports an SSH key into your vault.`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
fmt.Println("Error: No filename for SSH key specified")
return
}
filename := args[0]
fmt.Println("Importing SSH key from " + filename)
name, _ := cmd.Flags().GetString("name")
if name == "" {
name = "Imported SSH Key"
}
if _, err := os.Stat(filename); os.IsNotExist(err) {
fmt.Println("Error: File does not exist")
return
}
file, err := os.Open(filename)
if err != nil {
fmt.Println("Error: " + err.Error())
return
}
buf := new(bytes.Buffer)
buf.ReadFrom(file)
key := buf.String()
result, err := commandClient.SendToAgent(messages.ImportSSHKeyRequest{
Key: key,
Name: name,
})
if err != nil {
handleSendToAgentError(err)
return
}
switch result.(type) {
case messages.ImportSSHKeyResponse:
response := result.(messages.ImportSSHKeyResponse)
if response.Success {
fmt.Println("Success")
} else {
fmt.Println("Error: " + response.ErrorMsg)
}
return
case messages.ActionResponse:
fmt.Println("Error: " + result.(messages.ActionResponse).Message)
return
}
},
}
func init() {
rootCmd.AddCommand(sshCmd)
sshCmd.AddCommand(sshAddCmd)
@ -99,4 +158,6 @@ func init() {
_ = sshAddCmd.MarkFlagRequired("name")
sshAddCmd.PersistentFlags().Bool("clipboard", false, "Copy the public key to the clipboard")
sshCmd.AddCommand(listSSHCmd)
importSSHCmd.PersistentFlags().String("name", "", "")
sshCmd.AddCommand(importSSHCmd)
}

View File

@ -114,7 +114,7 @@ var statusCmd = &cobra.Command{
response["loginEntries"] = status.NumberOfLogins
response["noteEntries"] = status.NumberOfNotes
response["lastSynced"] = time.Unix(status.LastSynced, 0).String()
response["websocketConnected"] = status.WebsockedConnected
response["websocketConnected"] = status.WebsocketConnected
response["pinSet"] = status.PinSet
response["loggedIn"] = status.LoggedIn
responseJSON, _ := json.Marshal(response)

View File

@ -17,6 +17,16 @@ type GetSSHKeysResponse struct {
Keys []string
}
type ImportSSHKeyRequest struct {
Key string
Name string
}
type ImportSSHKeyResponse struct {
Success bool
ErrorMsg string
}
func init() {
registerPayloadParser(func(payload []byte) (interface{}, error) {
var req CreateSSHKeyRequest
@ -53,4 +63,22 @@ func init() {
}
return req, nil
}, GetSSHKeysResponse{})
registerPayloadParser(func(payload []byte) (interface{}, error) {
var req ImportSSHKeyRequest
err := json.Unmarshal(payload, &req)
if err != nil {
panic("Unmarshal: " + err.Error())
}
return req, nil
}, ImportSSHKeyRequest{})
registerPayloadParser(func(payload []byte) (interface{}, error) {
var req ImportSSHKeyResponse
err := json.Unmarshal(payload, &req)
if err != nil {
panic("Unmarshal: " + err.Error())
}
return req, nil
}, ImportSSHKeyResponse{})
}

View File

@ -27,7 +27,7 @@ type VaultStatusResponse struct {
NumberOfLogins int
NumberOfNotes int
LastSynced int64
WebsockedConnected bool
WebsocketConnected bool
}
func init() {

16
go.mod
View File

@ -13,21 +13,21 @@ require (
github.com/gen2brain/beeep v0.0.0-20240112042604-c7bb2cd88fea
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.1
github.com/icza/gox v0.0.0-20230924165045-adcb03233bb5
github.com/gorilla/websocket v1.5.3
github.com/icza/gox v0.2.0
github.com/keybase/client/go v0.0.0-20240424154521-52f30ea26cb1
github.com/lox/go-touchid v0.0.0-20170712105233-619cc8e578d0
github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a
github.com/mitchellh/go-ps v1.0.0
github.com/rymdport/portal v0.2.2
github.com/spf13/cobra v1.8.0
github.com/rymdport/portal v0.2.6
github.com/spf13/cobra v1.8.1
github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4
github.com/tink-crypto/tink-go/v2 v2.1.0
github.com/tink-crypto/tink-go/v2 v2.2.0
github.com/twpayne/go-pinentry v0.3.0
github.com/vmihailenco/msgpack/v5 v5.4.1
golang.org/x/crypto v0.22.0
golang.org/x/crypto v0.28.0
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f
golang.org/x/sys v0.19.0
golang.org/x/sys v0.26.0
)
require (
@ -56,5 +56,3 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
)
replace github.com/rymdport/portal => github.com/quexten/portal v0.0.0-20240429200240-156297fa11c5

38
go.sum
View File

@ -15,7 +15,7 @@ github.com/awnumar/memcall v0.2.0/go.mod h1:S911igBPR9CThzd/hYQQmTc9SWNu3ZHIlCGa
github.com/awnumar/memguard v0.22.5 h1:PH7sbUVERS5DdXh3+mLo8FDcl1eIeVjJVYMnyuYpvuI=
github.com/awnumar/memguard v0.22.5/go.mod h1:+APmZGThMBWjnMlKiSM1X7MVpbIVewen2MTkqWkA/zE=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -32,12 +32,12 @@ github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/icza/gox v0.0.0-20230924165045-adcb03233bb5 h1:K7KEFpKgVcjj98jOu2Z3xMBTtTwfYVT90Zmo3ZuWmbE=
github.com/icza/gox v0.0.0-20230924165045-adcb03233bb5/go.mod h1:VbcN86fRkkUMPX2ufM85Um8zFndLZswoIW1eYtpAcVk=
github.com/icza/gox v0.2.0 h1:+0N8PCt9/QSx+k0dqe/wdlXJNR/haaPsPwrTJTNDeyk=
github.com/icza/gox v0.2.0/go.mod h1:rVecw5Q6POJAWBcXgCZdAtwK/hmoNehxCkAP3sMnOIc=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/keybase/backoff v1.0.1-0.20160517061000-726b63b835ec h1:D6qL2WCnAuxucGbmL+mDW8IKRK1pex+R1fw5rKa9nXc=
@ -76,8 +76,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quexten/portal v0.0.0-20240429200240-156297fa11c5 h1:roVJ7WlvNo3R4NfVLysq3siLrVZgotg/JZkZ1dQEZ5k=
github.com/quexten/portal v0.0.0-20240429200240-156297fa11c5/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
github.com/reiver/go-oi v1.0.0 h1:nvECWD7LF+vOs8leNGV/ww+F2iZKf3EYjYZ527turzM=
github.com/reiver/go-oi v1.0.0/go.mod h1:RrDBct90BAhoDTxB1fenZwfykqeGvhI6LsNfStJoEkI=
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e h1:quuzZLi72kkJjl+f5AQ93FMcadG19WkS7MO6TXFOSas=
@ -86,8 +84,10 @@ github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/rymdport/portal v0.2.6 h1:HWmU3gORu7vWcpr7VSwUS2Xx1HtJXVcUuTqEZcMEsIg=
github.com/rymdport/portal v0.2.6/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -98,16 +98,16 @@ github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG0
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o=
github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4 h1:Gz0rz40FvFVLTBk/K8UNAenb36EbDSnh+q7Z9ldcC8w=
github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4/go.mod h1:phI29ccmHQBc+wvroosENp1IF9195449VDnFDhJ4rJU=
github.com/tink-crypto/tink-go/v2 v2.1.0 h1:QXFBguwMwTIaU17EgZpEJWsUSc60b1BAGTzBIoMdmok=
github.com/tink-crypto/tink-go/v2 v2.1.0/go.mod h1:y1TnYFt1i2eZVfx4OGc+C+EMp4CoKWAw2VSEuoicHHI=
github.com/tink-crypto/tink-go/v2 v2.2.0 h1:L2Da0F2Udh2agtKztdr69mV/KpnY3/lGTkMgLTVIXlA=
github.com/tink-crypto/tink-go/v2 v2.2.0/go.mod h1:JJ6PomeNPF3cJpfWC0lgyTES6zpJILkAX0cJNwlS3xU=
github.com/twpayne/go-pinentry v0.3.0 h1:Rr+fEOZXmeItOb4thjeVaBWJKB9Xa/eojolycyF/26c=
github.com/twpayne/go-pinentry v0.3.0/go.mod h1:iOIZD+9np/2V24OdCGos7Y1/xX90wc6VEAZsgb+r9D4=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY=
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
@ -118,12 +118,12 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

View File

@ -102,7 +102,7 @@ modules:
- cp -R ./gui/* /app/bin
- chmod +x /app/bin/goldwarden_ui_main.py
- install -D ./gui/com.quexten.Goldwarden.desktop /app/share/applications/com.quexten.Goldwarden.desktop
- install -D ./gui/goldwarden.svg /app/share/icons/hicolor/scalable/apps/com.quexten.Goldwarden.svg
- install -D ./gui/com.quexten.Goldwarden.svg /app/share/icons/hicolor/scalable/apps/com.quexten.Goldwarden.svg
- install -Dm644 ./gui/com.quexten.Goldwarden.metainfo.xml -t /app/share/metainfo/
- blueprint-compiler batch-compile /app/bin/src/gui/.templates/ /app/bin/src/gui/ /app/bin/src/gui/*.blp
sources:

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

12
gui/goldwarden_ui_main.py Normal file → Executable file
View File

@ -1,4 +1,12 @@
#!/usr/bin/env python3
import src.linux.main as linux_main
linux_main.main()
import platform
if platform.system() == 'Darwin':
import src.macos.main as macos_main
macos_main.main()
elif platform.system() == 'Linux':
import src.linux.main as linux_main
linux_main.main()
else:
print("Unsupported OS " + platform.system() + "... exiting...")

View File

@ -47,15 +47,45 @@ class GoldwardenLoginApp(Adw.Application):
def on_login(self):
email = self.email_row.get_text()
client_id = self.client_id_row.get_text()
client_secret = self.client_secret_row.get_text()
client_id = self.client_id_row.get_text().strip()
client_secret = self.client_secret_row.get_text().strip()
server = self.server_row.get_text()
print("setting server to", server, "with result", goldwarden.set_server(server))
try:
goldwarden.set_server(server)
except:
print("set server failed")
dialog = Adw.MessageDialog.new(self.window,
"Failed to set server",
"The server you entered is invalid, please try again.",
)
dialog.add_response("ok", "Dismiss")
dialog.present()
return
if client_id != "":
goldwarden.set_client_id(client_id)
if client_secret != "":
goldwarden.set_client_secret(client_secret)
goldwarden.login_with_password(email, "")
try:
goldwarden.login_with_password(email, "")
except Exception as e:
if "errorbadpassword" in str(e):
dialog = Adw.MessageDialog.new(self.window, "Bad Password", "The username or password you entered is incorrect.")
dialog.add_response("ok", "Dismiss")
dialog.present()
return
if "errorcaptcha" in str(e):
dialog = Adw.MessageDialog.new(self.window, "Unusual traffic error", "Traffic is unusual, please set up api client id and client secret.")
dialog.add_response("ok", "Dismiss")
dialog.present()
return
if "errortotp" in str(e):
dialog = Adw.MessageDialog.new(self.window, "TOTP Invalid", "The TOTP code you entered is invalid.")
dialog.add_response("ok", "Dismiss")
dialog.present()
return
self.window.close()
if __name__ == "__main__":

View File

@ -1,10 +1,10 @@
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
gi.require_version('Notify', '0.7')
# gi.require_version('Notify', '0.7')
import gc
import time
from gi.repository import Gtk, Adw, GLib, Notify, Gdk
from gi.repository import Gtk, Adw, GLib, Gdk
from ..services import goldwarden
from ..services.autotype import autotype
from threading import Thread
@ -12,7 +12,6 @@ from .resource_loader import load_template
import sys
import os
from ..services import totp
Notify.init("Goldwarden")
class GoldwardenQuickAccessApp(Adw.Application):
def __init__(self, **kwargs):
@ -115,8 +114,8 @@ class GoldwardenQuickAccessApp(Adw.Application):
def run_autotype(self, text):
def perform_autotype(text):
self.window.hide()
time.sleep(0.1)
GLib.idle_add(self.window.hide)
time.sleep(2)
autotype.autotype(text)
time.sleep(0.1)
os._exit(0)
@ -148,7 +147,7 @@ class GoldwardenQuickAccessApp(Adw.Application):
self.filtered_logins = self.filtered_logins[0:7]
def render_list(self):
if len(self.filtered_logins) > 1:
if len(self.filtered_logins) > 0:
self.results_list.set_visible(True)
while self.results_list.get_first_child() != None:
self.results_list.remove(self.results_list.get_first_child())

View File

@ -110,7 +110,7 @@ Adw.ApplicationWindow window {
icon-name: "emblem-synchronizing-symbolic";
}
Adw.ActionRow websocket_connected_row {
title: "Websocked Connected";
title: "Websocket Connected";
subtitle: "False";
}
Adw.ActionRow logins_row {

View File

@ -101,8 +101,7 @@ class GoldwardenSettingsApp(Adw.Application):
if status == None:
is_daemon_running = goldwarden.is_daemon_running()
if not is_daemon_running:
self.status_row.set_subtitle("Daemon not running")
self.vault_status_icon.set_icon("dialog-error", "error")
print("Daemon not running")
return
logged_in = status["loggedIn"]

View File

@ -7,6 +7,7 @@ gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import GLib, Gio
import sys
from threading import Timer
def set_status(message):
bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
@ -29,9 +30,13 @@ def set_status(message):
sys.exit(0)
except Exception as e:
print(e)
sys.exit(0)
if len(sys.argv) > 1:
set_status(sys.argv[1])
thread = Timer(10, sys.exit, [0])
thread.start()
loop = GLib.MainLoop()
loop.run()

30
gui/src/macos/main.py Normal file
View File

@ -0,0 +1,30 @@
import sys
import subprocess
import os
import secrets
from src.services import goldwarden
from src.services import pinentry
import time
root_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir))
def main():
token = secrets.token_hex(32)
if not os.environ.get("GOLDWARDEN_DAEMON_AUTH_TOKEN") == None:
token = os.environ["GOLDWARDEN_DAEMON_AUTH_TOKEN"]
print("Starting Goldwarden GUI")
goldwarden.run_daemon_background(token)
time.sleep(1)
#pinentry.daemonize()
if not "--hidden" in sys.argv:
p = subprocess.Popen(["python3", "-m", "src.gui.settings"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=root_path, start_new_session=True)
p.stdin.write(f"{token}\n".encode())
p.stdin.flush()
# print stdout
while True:
line = p.stderr.readline()
if not line:
break
print(line.decode().strip())
while True:
time.sleep(60)

View File

@ -1,5 +1,5 @@
from ..goldwarden import autotype
def libportal_autotype(text):
def autotype_libportal(text):
print("autotypeing with libportal")
goldwarden.autotype(text)
autotype(text)

View File

@ -2,4 +2,7 @@ import pyautogui
def autotype_pyautogui(text):
print("autotypeing with pyautogui")
pyautogui.write(text, interval=0.02)
pyautogui.write(text, interval=0.02)
if __name__ == "__main__":
autotype_pyautogui("hello world")

View File

@ -71,7 +71,9 @@ def set_vault_url(url):
send_authenticated_command(f"config set-vault-url {url}")
def set_server(url):
send_authenticated_command(f"config set-server {url}")
result = send_authenticated_command(f"config set-server {url}")
if result.strip() != "Done":
raise Exception("Failed to set server")
def get_environment():
result = send_authenticated_command(f"config get-environment")
@ -81,16 +83,19 @@ def get_environment():
return None
def set_client_id(client_id):
send_authenticated_command(f"config set-client-id \"{client_id}\"")
return send_authenticated_command(f"config set-client-id {client_id}")
def set_client_secret(client_secret):
send_authenticated_command(f"config set-client-secret \"{client_secret}\"")
return send_authenticated_command(f"config set-client-secret {client_secret}")
def login_with_password(email, password):
result = send_authenticated_command(f"vault login --email {email}")
if not "Logged in" in result:
return "badpass"
return "ok"
if "Login failed" in result and "username or password" in result.lower():
raise Exception("errorbadpassword")
if "Login failed" in result and ("error code 7" in result.lower() or "error code 6" in result.lower()):
raise Exception("errorcaptcha")
if "Login failed" in result and "two-factor" in result.lower():
raise Exception("errortotp")
def login_passwordless(email):
send_authenticated_command(f"vault login --email {email} --passwordless")