Implement totp copy and url launch

This commit is contained in:
Bernd Schoolmann 2024-01-20 17:34:42 +01:00
parent ce17426063
commit 25b72e4c43
No known key found for this signature in database
5 changed files with 60 additions and 7 deletions

View file

@ -3,10 +3,7 @@ package actions
import (
"fmt"
"runtime/debug"
"strings"
"time"
"github.com/pquerna/otp/totp"
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
"github.com/quexten/goldwarden/agent/config"
"github.com/quexten/goldwarden/agent/sockets"
@ -72,9 +69,8 @@ func handleGetLoginCipher(request messages.IPCMessage, cfg *config.Config, vault
if !login.Login.Totp.IsNull() {
decryptedTotp, err := crypto.DecryptWith(login.Login.Totp, cipherKey)
if err == nil {
code, err := totp.GenerateCode(string(strings.ReplaceAll(string(decryptedTotp), " ", "")), time.Now())
if err == nil {
decryptedLogin.TwoFactorCode = code
decryptedLogin.TOTPSeed = string(decryptedTotp)
} else {
fmt.Println(err)
}
@ -101,7 +97,7 @@ func handleGetLoginCipher(request messages.IPCMessage, cfg *config.Config, vault
}
func handleListLoginsRequest(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) {
if approved, err := pinentry.GetApproval("Approve List Credentials", fmt.Sprintf("%s on %s>%s>%s is trying access all credentials", ctx.UserName, ctx.GrandParentProcessName, ctx.ParentProcessName, ctx.ProcessName)); err != nil || !approved {
if approved, err := pinentry.GetApproval("Access Vault", fmt.Sprintf("%s on %s>%s>%s is trying access ALL CREDENTIALS", ctx.UserName, ctx.GrandParentProcessName, ctx.ParentProcessName, ctx.ProcessName)); err != nil || !approved {
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
Success: false,
Message: "not approved",
@ -124,6 +120,8 @@ func handleListLoginsRequest(request messages.IPCMessage, cfg *config.Config, va
var decryptedName []byte = []byte{}
var decryptedUsername []byte = []byte{}
var decryptedPassword []byte = []byte{}
var decryptedTotp []byte = []byte{}
var decryptedURL []byte = []byte{}
if !login.Name.IsNull() {
decryptedName, err = crypto.DecryptWith(login.Name, key)
@ -149,11 +147,29 @@ func handleListLoginsRequest(request messages.IPCMessage, cfg *config.Config, va
}
}
if !login.Login.Totp.IsNull() {
decryptedTotp, err = crypto.DecryptWith(login.Login.Totp, key)
if err != nil {
actionsLog.Warn("Could not decrypt login:" + err.Error())
continue
}
}
if !login.Login.URI.IsNull() {
decryptedURL, err = crypto.DecryptWith(login.Login.URI, key)
if err != nil {
actionsLog.Warn("Could not decrypt login:" + err.Error())
continue
}
}
decryptedLoginCiphers = append(decryptedLoginCiphers, messages.DecryptedLoginCipher{
Name: string(decryptedName),
Username: string(decryptedUsername),
UUID: login.ID.String(),
Password: string(decryptedPassword),
TOTPSeed: string(decryptedTotp),
URI: string(decryptedURL),
})
// prevent deadlock from enclaves

View file

@ -79,6 +79,8 @@ var listLoginsCmd = &cobra.Command{
"uuid": stringsx.Clean(login.UUID),
"username": stringsx.Clean(login.Username),
"password": stringsx.Clean(strings.ReplaceAll(login.Password, "\"", "\\\"")),
"totp": stringsx.Clean(login.TOTPSeed),
"uri": stringsx.Clean(login.URI),
}
jsonString, err := json.Marshal(data)
if err != nil {

View file

@ -28,7 +28,8 @@ type DecryptedLoginCipher struct {
UUID string
OrgaizationID string
Notes string
TwoFactorCode string
TOTPSeed string
URI string
}
type AddLoginRequest struct {

View file

@ -9,6 +9,7 @@ import clipboard
from threading import Thread
import sys
import os
import totp
Notify.init("Goldwarden")
class MyApp(Adw.Application):
@ -66,6 +67,8 @@ class MainWindow(Gtk.ApplicationWindow):
action_row.password = i["password"]
action_row.username = i["username"]
action_row.uuid = i["uuid"]
action_row.uri = i["uri"]
action_row.totp = i["totp"]
self.history_list.append(action_row)
self.starts_with_logins = None
self.other_logins = None
@ -109,6 +112,17 @@ class MainWindow(Gtk.ApplicationWindow):
return
item_uri = environment["vault"] + "#/vault?itemId=" + self.history_list.get_selected_row().uuid
Gtk.show_uri(None, item_uri, Gdk.CURRENT_TIME)
elif keyval == 108:
print("launch")
print(self.history_list.get_selected_row().uri)
Gtk.show_uri(None, self.history_list.get_selected_row().uri, Gdk.CURRENT_TIME)
elif keyval == 116:
print("copy totp")
totp_code = totp.totp(self.history_list.get_selected_row().totp)
clipboard.write(totp_code)
notification=Notify.Notification.new("Goldwarden", "Totp Copied", "dialog-information")
notification.set_timeout(5)
notification.show()
keycont.connect('key-pressed', handle_keypress, self)
self.add_controller(keycont)

20
ui/totp.py Normal file
View file

@ -0,0 +1,20 @@
# https://github.com/susam/mintotp
#!/usr/bin/env python3
import base64
import hmac
import struct
import sys
import time
def hotp(key, counter, digits=6, digest='sha1'):
key = base64.b32decode(key.upper() + '=' * ((8 - len(key)) % 8))
counter = struct.pack('>Q', counter)
mac = hmac.new(key, counter, digest).digest()
offset = mac[-1] & 0x0f
binary = struct.unpack('>L', mac[offset:offset+4])[0] & 0x7fffffff
return str(binary)[-digits:].zfill(digits)
def totp(key, time_step=30, digits=6, digest='sha1'):
return hotp(key, int(time.time() / time_step), digits, digest)