Implement totp copy and url launch
This commit is contained in:
parent
ce17426063
commit
25b72e4c43
5 changed files with 60 additions and 7 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ type DecryptedLoginCipher struct {
|
|||
UUID string
|
||||
OrgaizationID string
|
||||
Notes string
|
||||
TwoFactorCode string
|
||||
TOTPSeed string
|
||||
URI string
|
||||
}
|
||||
|
||||
type AddLoginRequest struct {
|
||||
|
|
|
|||
|
|
@ -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
20
ui/totp.py
Normal 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)
|
||||
Loading…
Reference in a new issue