mirror of
https://github.com/quexten/goldwarden.git
synced 2024-09-11 19:17:33 +03:00
Compare commits
17 Commits
ac0e84a46f
...
2e42a798e3
Author | SHA1 | Date | |
---|---|---|---|
|
2e42a798e3 | ||
|
8d257c265e | ||
|
a6d3a1026d | ||
|
563ad6fa45 | ||
|
4a3e8ca819 | ||
|
8a41543601 | ||
|
ed6060eae4 | ||
|
417567f549 | ||
|
200bce7d7e | ||
|
53989ebaa3 | ||
|
39d1ec6980 | ||
|
75982ad322 | ||
|
219a8cb849 | ||
|
14618b3d07 | ||
|
ef276a0019 | ||
|
5805931c00 | ||
|
069afeae27 |
@ -33,29 +33,29 @@ func SetExternalPinentry(pinentry Pinentry) error {
|
||||
}
|
||||
|
||||
func GetPassword(title string, description string) (string, error) {
|
||||
// password, err := getPassword(title, description)
|
||||
// if err == nil {
|
||||
// return password, nil
|
||||
// }
|
||||
password, err := getPassword(title, description)
|
||||
if err == nil {
|
||||
return password, nil
|
||||
}
|
||||
|
||||
if externalPinentry.GetPassword != nil {
|
||||
return externalPinentry.GetPassword(title, description)
|
||||
}
|
||||
|
||||
return "", errors.New("Not implemented")
|
||||
// return password, nil
|
||||
// return "", errors.New("Not implemented")
|
||||
return password, nil
|
||||
}
|
||||
|
||||
func GetApproval(title string, description string) (bool, error) {
|
||||
// approval, err := getApproval(title, description)
|
||||
// if err == nil {
|
||||
// return approval, nil
|
||||
// }
|
||||
approval, err := getApproval(title, description)
|
||||
if err == nil {
|
||||
return approval, nil
|
||||
}
|
||||
|
||||
if externalPinentry.GetApproval != nil {
|
||||
return externalPinentry.GetApproval(title, description)
|
||||
}
|
||||
|
||||
// return approval, nil
|
||||
return true, errors.New("Not implemented")
|
||||
// return true, errors.New("Not implemented")
|
||||
return approval, nil
|
||||
}
|
||||
|
@ -139,6 +139,8 @@ func serveAgentSession(c net.Conn, vault *vault.Vault, cfg *config.Config) {
|
||||
payload := messages.PinentryRegistrationResponse{
|
||||
Success: pinnentrySetError == nil,
|
||||
}
|
||||
log.Info("Pinentry registration success: %t", payload.Success)
|
||||
|
||||
responsePayload, err := messages.IPCMessageFromPayload(payload)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
@ -208,6 +210,50 @@ func serveAgentSession(c net.Conn, vault *vault.Vault, cfg *config.Config) {
|
||||
err error
|
||||
}{getPasswordResponse.Pin, nil}
|
||||
}
|
||||
case getApprovalRequest := <-getApprovalChan:
|
||||
log.Info("Received getApproval request")
|
||||
payload := messages.PinentryApprovalRequest{
|
||||
Message: getApprovalRequest.description,
|
||||
}
|
||||
payloadPayload, err := messages.IPCMessageFromPayload(payload)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
continue
|
||||
}
|
||||
|
||||
payloadBytes, err := json.Marshal(payloadPayload)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = c.Write(payloadBytes)
|
||||
if err != nil {
|
||||
log.Error("Failed writing to socket " + err.Error())
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024*1024)
|
||||
nr, err := c.Read(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data := buf[0:nr]
|
||||
|
||||
var msg messages.IPCMessage
|
||||
err = json.Unmarshal(data, &msg)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if msg.Type == messages.MessageTypeForEmptyPayload(messages.PinentryApprovalResponse{}) {
|
||||
getApprovalResponse := messages.ParsePayload(msg).(messages.PinentryApprovalResponse)
|
||||
getApprovalReturnChan <- struct {
|
||||
approved bool
|
||||
err error
|
||||
}{getApprovalResponse.Approved, nil}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,17 +69,12 @@ func (conn UnixSocketConnection) SendCommand(request interface{}) (interface{},
|
||||
|
||||
func (conn UnixSocketConnection) ReadMessage() interface{} {
|
||||
result := Reader(conn.conn)
|
||||
// fmt.Println("ReadMessag")
|
||||
// fmt.Println(result)
|
||||
payload := messages.ParsePayload(result.(messages.IPCMessage))
|
||||
// fmt.Println(payload)
|
||||
return payload
|
||||
}
|
||||
|
||||
func (conn UnixSocketConnection) WriteMessage(message interface{}) error {
|
||||
// fmt.Println("WriteMessage")
|
||||
messagePacket, err := messages.IPCMessageFromPayload(message)
|
||||
// fmt.Println(messagePacket)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -87,7 +82,6 @@ func (conn UnixSocketConnection) WriteMessage(message interface{}) error {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// fmt.Println(messageJson)
|
||||
_, err = conn.conn.Write(messageJson)
|
||||
return err
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ id: com.quexten.Goldwarden
|
||||
runtime: org.gnome.Platform
|
||||
runtime-version: '45'
|
||||
sdk: org.gnome.Sdk
|
||||
command: main.py
|
||||
command: goldwarden_ui_main.py
|
||||
finish-args:
|
||||
# Allow network access for sync
|
||||
- --share=network
|
||||
@ -28,7 +28,7 @@ finish-args:
|
||||
# biometric / user password auth
|
||||
- --system-talk-name=org.freedesktop.PolicyKit1
|
||||
modules:
|
||||
- ./ui/python3-requirements.json
|
||||
- ./gui/python3-requirements.json
|
||||
- name: wl-clipboard
|
||||
buildsystem: meson
|
||||
config-opts:
|
||||
@ -40,18 +40,18 @@ modules:
|
||||
- name: goldwarden-python-ui
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- cp -R ./ui/* /app/bin
|
||||
- chmod +x /app/bin/main.py
|
||||
- install -D ./ui/com.quexten.Goldwarden.desktop /app/share/applications/com.quexten.Goldwarden.desktop
|
||||
- install -D ./ui/goldwarden.svg /app/share/icons/hicolor/scalable/apps/com.quexten.Goldwarden.svg
|
||||
- install -Dm644 ./ui/com.quexten.Goldwarden.metainfo.xml -t /app/share/metainfo/
|
||||
- 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 -Dm644 ./gui/com.quexten.Goldwarden.metainfo.xml -t /app/share/metainfo/
|
||||
sources:
|
||||
- type: dir
|
||||
path: ./
|
||||
- name: goldwarden-core-daemon
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- install -D goldwarden /app/bin/goldwarden
|
||||
- install -D goldwarden /app/bin/src/goldwarden
|
||||
sources:
|
||||
- type: file
|
||||
path: ./goldwarden
|
@ -2,7 +2,7 @@
|
||||
Name=Goldwarden
|
||||
Comment=A Bitwarden compatible desktop password manager
|
||||
Keywords=password;ssh;auto-type;keys;
|
||||
Exec=main.py
|
||||
Exec=goldwarden_ui_main.py
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=com.quexten.Goldwarden
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
4
gui/goldwarden_ui_main.py
Normal file
4
gui/goldwarden_ui_main.py
Normal file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
import src.linux.main as linux_main
|
||||
|
||||
linux_main.main()
|
14
gui/python3-requirements.json
Normal file
14
gui/python3-requirements.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "python3-tendo",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"tendo==0.3.0\" --no-build-isolation"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/ce/3f/761077d55732b0b1a673b15d4fdaa947a7c1eb5c9a23b7142df557019823/tendo-0.3.0-py3-none-any.whl",
|
||||
"sha256": "026b70b355ea4c9da7c2123fa2d5c280c8983c1b34e329ff49260e2e78b93be7"
|
||||
}
|
||||
]
|
||||
}
|
1
gui/requirements.txt
Normal file
1
gui/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
tendo==0.3.0
|
@ -47,13 +47,17 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
# Cancel button
|
||||
cancel_button = Gtk.Button(label="Cancel")
|
||||
cancel_button.set_hexpand(True) # Make the button expand horizontally
|
||||
def on_cancel_button_clicked(button):
|
||||
print("", flush=True)
|
||||
os._exit(0)
|
||||
cancel_button.connect("clicked", on_cancel_button_clicked)
|
||||
button_box.append(cancel_button)
|
||||
|
||||
# Approve button
|
||||
approve_button = Gtk.Button(label="Approve")
|
||||
approve_button.set_hexpand(True) # Make the button expand horizontally
|
||||
def on_approve_button_clicked(button):
|
||||
print(self.password_entry.get_text())
|
||||
print(self.password_entry.get_text(), flush=True)
|
||||
os._exit(0)
|
||||
approve_button.connect("clicked", on_approve_button_clicked)
|
||||
button_box.append(approve_button)
|
@ -42,7 +42,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
cancel_button = Gtk.Button(label="Cancel")
|
||||
cancel_button.set_hexpand(True) # Make the button expand horizontally
|
||||
def on_cancel_button_clicked(button):
|
||||
print("false")
|
||||
print("false", flush=True)
|
||||
os._exit(0)
|
||||
cancel_button.connect("clicked", on_cancel_button_clicked)
|
||||
button_box.append(cancel_button)
|
||||
@ -51,7 +51,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
approve_button = Gtk.Button(label="Approve")
|
||||
approve_button.set_hexpand(True) # Make the button expand horizontally
|
||||
def on_approve_button_clicked(button):
|
||||
print("true")
|
||||
print("true", flush=True)
|
||||
os._exit(0)
|
||||
approve_button.connect("clicked", on_approve_button_clicked)
|
||||
button_box.append(approve_button)
|
@ -51,7 +51,7 @@ class SettingsWinvdow(Gtk.ApplicationWindow):
|
||||
self.autotype_button.set_label("Quick Access")
|
||||
self.autotype_button.set_margin_top(10)
|
||||
def quickaccess_button_clicked():
|
||||
p = subprocess.Popen(["python3", "-m", "src.ui.quickaccess"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p = subprocess.Popen(["python3", "-m", "src.gui.quickaccess"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p.stdin.write(f"{token}\n".encode())
|
||||
p.stdin.flush()
|
||||
self.autotype_button.connect("clicked", lambda button: quickaccess_button_clicked())
|
@ -5,7 +5,8 @@ from tendo import singleton
|
||||
from .monitors import dbus_autofill_monitor
|
||||
from .monitors import dbus_monitor
|
||||
import sys
|
||||
from services import goldwarden
|
||||
from src.services import goldwarden
|
||||
from src.services import pinentry
|
||||
from threading import Thread
|
||||
import os
|
||||
import secrets
|
||||
@ -27,17 +28,19 @@ def main():
|
||||
import dbus
|
||||
|
||||
bus = dbus.SessionBus()
|
||||
the_object = bus.get_objeect("com.quexten.Goldwarden.dbus", "/com/quexten/Goldwarden")
|
||||
the_interface = dbus.Interface(the_object, "com.quexten.Goldwarden.Settings")
|
||||
the_object = bus.get_object("com.quexten.Goldwarden.gui", "/com/quexten/Goldwarden/gui")
|
||||
the_interface = dbus.Interface(the_object, "com.quexten.Goldwarden.gui.actions")
|
||||
reply = the_interface.settings()
|
||||
exit()
|
||||
|
||||
goldwarden.run_daemon_background(token)
|
||||
# start daemons
|
||||
dbus_autofill_monitor.run_daemon(token) # todo: remove after migration
|
||||
dbus_monitor.run_daemon(token)
|
||||
pinentry.daemonize()
|
||||
|
||||
if not "--hidden" in sys.argv:
|
||||
p = subprocess.Popen(["python3", "-m", "src.ui.settings"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p = subprocess.Popen(["python3", "-m", "src.gui.settings"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p.stdin.write(f"{token}\n".encode())
|
||||
p.stdin.flush()
|
||||
|
@ -1,6 +1,9 @@
|
||||
#Python DBUS Test Server
|
||||
#runs until the Quit() method is called via DBUS
|
||||
|
||||
from gi import require_version
|
||||
require_version('Gtk', '4.0')
|
||||
require_version('Adw', '1')
|
||||
from gi.repository import Gtk
|
||||
import dbus
|
||||
import dbus.service
|
||||
@ -16,7 +19,7 @@ class GoldwardenDBUSService(dbus.service.Object):
|
||||
|
||||
@dbus.service.method('com.quexten.Goldwarden.Autofill')
|
||||
def autofill(self):
|
||||
p = subprocess.Popen(["python3", "-m", "src.ui.quickaccess"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p = subprocess.Popen(["python3", "-m", "src.gui.quickaccess"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p.stdin.write(f"{daemon_token}\n".encode())
|
||||
p.stdin.flush()
|
||||
return ""
|
@ -11,19 +11,19 @@ daemon_token = None
|
||||
|
||||
class GoldwardenDBUSService(dbus.service.Object):
|
||||
def __init__(self):
|
||||
bus_name = dbus.service.BusName('com.quexten.Goldwarden.ui', bus=dbus.SessionBus())
|
||||
dbus.service.Object.__init__(self, bus_name, '/com/quexten/Goldwarden/ui')
|
||||
bus_name = dbus.service.BusName('com.quexten.Goldwarden.gui', bus=dbus.SessionBus())
|
||||
dbus.service.Object.__init__(self, bus_name, '/com/quexten/Goldwarden/gui')
|
||||
|
||||
@dbus.service.method('com.quexten.Goldwarden.ui.QuickAccess')
|
||||
@dbus.service.method('com.quexten.Goldwarden.gui.actions')
|
||||
def quickaccess(self):
|
||||
p = subprocess.Popen(["python3", "-m", "src.ui.quickaccess"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p = subprocess.Popen(["python3", "-m", "src.gui.quickaccess"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p.stdin.write(f"{daemon_token}\n".encode())
|
||||
p.stdin.flush()
|
||||
return ""
|
||||
|
||||
@dbus.service.method('com.quexten.Goldwarden.ui.Settings')
|
||||
@dbus.service.method('com.quexten.Goldwarden.gui.actions')
|
||||
def settings(self):
|
||||
subprocess.Popen(["python3", "-m", "src.ui.settings"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p = subprocess.Popen(["python3", "-m", "src.gui.settings"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p.stdin.write(f"{daemon_token}\n".encode())
|
||||
p.stdin.flush()
|
||||
return ""
|
@ -2,6 +2,13 @@ import subprocess
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from threading import Thread
|
||||
|
||||
is_flatpak = os.path.exists("/.flatpak-info")
|
||||
log_directory = str(Path.home()) + "/.local/share/goldwarden"
|
||||
if is_flatpak:
|
||||
log_directory = str(Path.home()) + "/.var/app/com.quexten.goldwarden/data/goldwarden"
|
||||
os.makedirs(log_directory, exist_ok=True)
|
||||
|
||||
BINARY_PATHS = [
|
||||
"/app/bin/goldwarden",
|
||||
@ -10,18 +17,17 @@ BINARY_PATHS = [
|
||||
]
|
||||
|
||||
BINARY_PATH = ""
|
||||
BINARY_PATH = None
|
||||
for path in BINARY_PATHS:
|
||||
if os.path.exists(path):
|
||||
BINARY_PATH = path
|
||||
break
|
||||
if BINARY_PATH == None:
|
||||
raise Exception("Could not find goldwarden binary")
|
||||
authenticated_connection = None
|
||||
|
||||
def create_authenticated_connection(token):
|
||||
global authenticated_connection
|
||||
global BINARY_PATH
|
||||
BINARY_PATH = None
|
||||
for path in BINARY_PATHS:
|
||||
if os.path.exists(path):
|
||||
BINARY_PATH = path
|
||||
break
|
||||
if BINARY_PATH == None:
|
||||
raise Exception("Could not find goldwarden binary")
|
||||
authenticated_connection = subprocess.Popen([f"{BINARY_PATH}", "session"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
if not token == None:
|
||||
authenticated_connection.stdin.write("authenticate-session " + token + "\n")
|
||||
@ -141,14 +147,50 @@ def is_daemon_running():
|
||||
daemon_not_running = ("daemon running" in result)
|
||||
return not daemon_not_running
|
||||
|
||||
# def run_daemon():
|
||||
# restic_cmd = f"daemonize"
|
||||
# # print while running
|
||||
# result = subprocess.Popen(restic_cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
# if result.returncode != 0:
|
||||
# print("Failed err", result.stderr)
|
||||
# for line in result.stdout:
|
||||
# print(line.decode("utf-8"))
|
||||
# result.wait()
|
||||
# print("quitting goldwarden daemon")
|
||||
# return result.returncode
|
||||
def listen_for_pinentry(on_pinentry, on_pin_approval):
|
||||
print("listening for pinentry", BINARY_PATH)
|
||||
pinentry_process = subprocess.Popen([f"{BINARY_PATH}", "pinentry"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
while True:
|
||||
line = pinentry_process.stdout.readline()
|
||||
# starts with pin-request
|
||||
if line.startswith("pin-request"):
|
||||
text = line.split(",")[1].strip()
|
||||
pin = on_pinentry(text)
|
||||
if pin == None:
|
||||
pin = ""
|
||||
pinentry_process.stdin.write(pin + "\n")
|
||||
pinentry_process.stdin.flush()
|
||||
if line.startswith("approval-request"):
|
||||
text = line.split(",")[1].strip()
|
||||
approval = on_pin_approval(text)
|
||||
if approval:
|
||||
pinentry_process.stdin.write("true\n")
|
||||
pinentry_process.stdin.flush()
|
||||
else:
|
||||
pinentry_process.stdin.write("false\n")
|
||||
pinentry_process.stdin.flush()
|
||||
|
||||
def run_daemon(token):
|
||||
#todo replace with stdin
|
||||
daemon_env = os.environ.copy()
|
||||
daemon_env["GOLDWARDEN_DAEMON_AUTH_TOKEN"] = token
|
||||
|
||||
print("starting goldwarden daemon", BINARY_PATH)
|
||||
|
||||
# print while running
|
||||
result = subprocess.Popen([f"{BINARY_PATH}", "daemonize"], stdout=subprocess.PIPE, text=True, env=daemon_env)
|
||||
|
||||
# write log to file until process exits
|
||||
log_file = open(f"{log_directory}/daemon.log", "w")
|
||||
while result.poll() == None:
|
||||
# read stdout and stder
|
||||
stdout = result.stdout.readline()
|
||||
log_file.write(stdout)
|
||||
log_file.flush()
|
||||
log_file.close()
|
||||
print("quitting goldwarden daemon")
|
||||
return result.returncode
|
||||
|
||||
def run_daemon_background(token):
|
||||
thread = Thread(target=lambda: run_daemon(token))
|
||||
thread.start()
|
34
gui/src/services/pinentry.py
Normal file
34
gui/src/services/pinentry.py
Normal file
@ -0,0 +1,34 @@
|
||||
import subprocess
|
||||
import os
|
||||
from src.services import goldwarden
|
||||
from threading import Thread
|
||||
import time
|
||||
|
||||
root_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir))
|
||||
|
||||
def get_pin(message):
|
||||
p = subprocess.Popen(["python3", "-m", "src.gui.pinentry"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p.stdin.write(f"{message}\n".encode())
|
||||
p.stdin.flush()
|
||||
pin = p.stdout.readline().decode().strip()
|
||||
if pin == "":
|
||||
return None
|
||||
return pin
|
||||
|
||||
def get_approval(message):
|
||||
p = subprocess.Popen(["python3", "-m", "src.gui.pinentry_approval"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
p.stdin.write(f"{message}\n".encode())
|
||||
p.stdin.flush()
|
||||
result = p.stdout.readline().decode().strip()
|
||||
if result == "true":
|
||||
return True
|
||||
return False
|
||||
|
||||
def daemon():
|
||||
goldwarden.listen_for_pinentry(get_pin, get_approval)
|
||||
|
||||
def daemonize():
|
||||
#todo fix this
|
||||
time.sleep(3)
|
||||
thread = Thread(target=daemon)
|
||||
thread.start()
|
2
main.go
2
main.go
@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@ -64,7 +63,6 @@ func main() {
|
||||
userHome, _ := os.UserHomeDir()
|
||||
runtimeConfig.ConfigDirectory = userHome + "/.var/app/com.quexten.Goldwarden/config/goldwarden.json"
|
||||
runtimeConfig.ConfigDirectory = strings.ReplaceAll(runtimeConfig.ConfigDirectory, "~", userHome)
|
||||
fmt.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"
|
||||
}
|
||||
|
190
ui/goldwarden.py
Normal file
190
ui/goldwarden.py
Normal file
@ -0,0 +1,190 @@
|
||||
import subprocess
|
||||
import json
|
||||
from shutil import which
|
||||
import os
|
||||
import sys
|
||||
|
||||
# if flatpak
|
||||
if os.path.exists("/app/bin/goldwarden"):
|
||||
BINARY_PATH = "/app/bin/goldwarden"
|
||||
else:
|
||||
BINARY_PATH = which('goldwarden')
|
||||
if isinstance(BINARY_PATH,str):
|
||||
BINARY_PATH = BINARY_PATH.strip()
|
||||
else:
|
||||
print("goldwarden executable not found")
|
||||
sys.exit()
|
||||
|
||||
def set_api_url(url):
|
||||
restic_cmd = f"{BINARY_PATH} config set-api-url {url}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def set_identity_url(url):
|
||||
restic_cmd = f"{BINARY_PATH} config set-identity-url {url}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def set_notification_url(url):
|
||||
restic_cmd = f"{BINARY_PATH} config set-notifications-url {url}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def set_vault_url(url):
|
||||
restic_cmd = f"{BINARY_PATH} config set-vault-url {url}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed err", result.stderr)
|
||||
|
||||
def set_url(url):
|
||||
restic_cmd = f"{BINARY_PATH} config set-url {url}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed err", result.stderr)
|
||||
|
||||
def get_environment():
|
||||
restic_cmd = f"{BINARY_PATH} config get-environment"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
return None
|
||||
try:
|
||||
result_text = result.stdout
|
||||
print(result_text)
|
||||
return json.loads(result_text)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def set_client_id(client_id):
|
||||
restic_cmd = f"{BINARY_PATH} config set-client-id \"{client_id}\""
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed err", result.stderr)
|
||||
|
||||
def set_client_secret(client_secret):
|
||||
restic_cmd = f"{BINARY_PATH} config set-client-secret \"{client_secret}\""
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed err", result.stderr)
|
||||
|
||||
def login_with_password(email, password):
|
||||
restic_cmd = f"{BINARY_PATH} vault login --email {email}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
if len(result.stderr.strip()) > 0:
|
||||
print(result.stderr)
|
||||
if "password" in result.stderr:
|
||||
return "badpass"
|
||||
else:
|
||||
if "Logged in" in result.stderr:
|
||||
print("ok")
|
||||
return "ok"
|
||||
return "error"
|
||||
print("ok")
|
||||
return "ok"
|
||||
|
||||
def login_passwordless(email):
|
||||
restic_cmd = f"{BINARY_PATH} vault login --email {email} --passwordless"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def is_pin_enabled():
|
||||
restic_cmd = f"{BINARY_PATH} vault pin status"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
# check if contains enabled
|
||||
return "enabled" in result.stderr
|
||||
|
||||
def enable_pin():
|
||||
restic_cmd = f"{BINARY_PATH} vault pin set"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def unlock():
|
||||
restic_cmd = f"{BINARY_PATH} vault unlock"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def lock():
|
||||
restic_cmd = f"{BINARY_PATH} vault lock"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def purge():
|
||||
restic_cmd = f"{BINARY_PATH} vault purge"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def get_vault_status():
|
||||
restic_cmd = f"{BINARY_PATH} vault status"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
try:
|
||||
return json.loads(result.stdout)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def get_vault_logins():
|
||||
restic_cmd = f"{BINARY_PATH} logins list"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
try:
|
||||
return json.loads(result.stdout)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
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):
|
||||
# environment
|
||||
env = os.environ.copy()
|
||||
env["PASSWORD"] = password
|
||||
restic_cmd = f"{BINARY_PATH} autotype --username {username}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True, env=env)
|
||||
print(result.stderr)
|
||||
print(result.stdout)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def is_daemon_running():
|
||||
restic_cmd = f"{BINARY_PATH} vault status"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
return False
|
||||
daemon_not_running = ("daemon running?" in result.stderr or "daemon running" in result.stderr)
|
||||
return not daemon_not_running
|
||||
|
||||
def run_daemon():
|
||||
restic_cmd = f"{BINARY_PATH} daemonize"
|
||||
# print while running
|
||||
result = subprocess.Popen(restic_cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
print("Failed err", result.stderr)
|
||||
for line in result.stdout:
|
||||
print(line.decode("utf-8"))
|
||||
result.wait()
|
||||
print("quitting goldwarden daemon")
|
||||
return result.returncode
|
@ -1,49 +0,0 @@
|
||||
{
|
||||
"name": "python3-requirements",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [],
|
||||
"modules": [
|
||||
{
|
||||
"name": "python3-ChaCha20",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"ChaCha20==1.1.1\" --no-build-isolation"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/7d/93/2c5c7203bcb1ece177a49d14b32f0e0511f7d4eaf8446c15f7d64af082ad/ChaCha20-1.1.1.tar.gz",
|
||||
"sha256": "6d6b1ef373058540369c14d2369ab14ee4ffaeae4dc53d8a18b5b617bd06c6bb"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "python3-chacha20poly1305",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"chacha20poly1305==0.0.3\" --no-build-isolation"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/38/2c/5b4eb73c5cb30ded3082af025e76f529764971c57c02b101e842ff998f63/chacha20poly1305-0.0.3.tar.gz",
|
||||
"sha256": "f2f005c7cf4638ffa4ff06c02c78748068b642916795c6d16c7cc5e355e70edf"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "python3-tendo",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"tendo==0.3.0\" --no-build-isolation"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/ce/3f/761077d55732b0b1a673b15d4fdaa947a7c1eb5c9a23b7142df557019823/tendo-0.3.0-py3-none-any.whl",
|
||||
"sha256": "026b70b355ea4c9da7c2123fa2d5c280c8983c1b34e329ff49260e2e78b93be7"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
ChaCha20==1.1.1
|
||||
chacha20poly1305==0.0.3
|
||||
tendo==0.3.0
|
@ -1,3 +0,0 @@
|
||||
import linux.main as linux_main
|
||||
|
||||
linux_main.main()
|
Loading…
Reference in New Issue
Block a user