Spawn goldwarden daemon automatically on boot; fix biometrics

This commit is contained in:
Bernd Schoolmann 2023-12-23 13:24:46 +01:00
parent f79aac1792
commit b9be947d94
No known key found for this signature in database
7 changed files with 79 additions and 16 deletions

View File

@ -3,6 +3,7 @@ package sockets
import ( import (
"net" "net"
"os/user" "os/user"
"time"
gops "github.com/mitchellh/go-ps" gops "github.com/mitchellh/go-ps"
"inet.af/peercred" "inet.af/peercred"
@ -20,11 +21,26 @@ type CallingContext struct {
func GetCallingContext(connection net.Conn) CallingContext { func GetCallingContext(connection net.Conn) CallingContext {
creds, err := peercred.Get(connection) creds, err := peercred.Get(connection)
errorContext := CallingContext{
UserName: "unknown user",
ProcessName: "unknown process",
ParentProcessName: "unknown parent",
GrandParentProcessName: "unknown grandparent",
ProcessPid: time.Now().UTC().Nanosecond(),
ParentProcessPid: time.Now().UTC().Nanosecond(),
GrandParentProcessPid: time.Now().UTC().Nanosecond(),
}
if err != nil { if err != nil {
panic(err) return errorContext
} }
pid, _ := creds.PID() pid, _ := creds.PID()
process, err := gops.FindProcess(pid) process, err := gops.FindProcess(pid)
if err != nil {
return errorContext
}
if process == nil {
return errorContext
}
// git is epheremal and spawns ssh-keygen and ssh so we need to anchor to git // git is epheremal and spawns ssh-keygen and ssh so we need to anchor to git
if process.Executable() == "ssh-keygen" || process.Executable() == "ssh" { if process.Executable() == "ssh-keygen" || process.Executable() == "ssh" {
@ -38,22 +54,22 @@ func GetCallingContext(connection net.Conn) CallingContext {
uid, _ := creds.UserID() uid, _ := creds.UserID()
ppid := process.PPid() ppid := process.PPid()
if err != nil { if err != nil {
panic(err) return errorContext
} }
parentProcess, err := gops.FindProcess(ppid) parentProcess, err := gops.FindProcess(ppid)
if err != nil { if err != nil {
panic(err) return errorContext
} }
parentParentProcess, err := gops.FindProcess(parentProcess.PPid()) parentParentProcess, err := gops.FindProcess(parentProcess.PPid())
if err != nil { if err != nil {
panic(err) return errorContext
} }
username, err := user.LookupId(uid) username, err := user.LookupId(uid)
if err != nil { if err != nil {
panic(err) return errorContext
} }
return CallingContext{ return CallingContext{

View File

@ -78,15 +78,18 @@ func BiometricsWorking() bool {
authority, err := polkit.NewAuthority() authority, err := polkit.NewAuthority()
if err != nil { if err != nil {
log.Warn("Failed to create polkit authority: %s", err.Error())
return false return false
} }
result, err := authority.EnumerateActions("en") result, err := authority.EnumerateActions("en")
if err != nil { if err != nil {
log.Warn("Failed to enumerate polkit actions: %s", err.Error())
return false return false
} }
if len(result) == 0 { if len(result) == 0 {
log.Warn("No polkit actions found")
return false return false
} }

View File

@ -87,6 +87,7 @@ func GetPermission(sessionType SessionType, ctx sockets.CallingContext, config *
return false, nil return false, nil
} }
} else { } else {
log.Warn("Biometrics is not available, asking for pin")
pin, err := pinentry.GetPassword("Enter PIN", "Biometrics is not available. Enter your pin to authorize this action. "+message) pin, err := pinentry.GetPassword("Enter PIN", "Biometrics is not available. Enter your pin to authorize this action. "+message)
if err != nil { if err != nil {
return false, err return false, err

View File

@ -8,9 +8,12 @@ finish-args:
- --share=network - --share=network
- --socket=wayland - --socket=wayland
- --socket=fallback-x11 - --socket=fallback-x11
- --filesystem=home - --device=dri
# todo remove this # - --filesystem=home
- --filesystem=host
# polkit & locking.. should filter this later on
- --socket=session-bus - --socket=session-bus
- --socket=system-bus
modules: modules:
- name: goldwarden - name: goldwarden
buildsystem: simple buildsystem: simple

View File

@ -107,3 +107,23 @@ def autotype(username, password):
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True, env=env) result = subprocess.run(restic_cmd.split(), capture_output=True, text=True, env=env)
if result.returncode != 0: if result.returncode != 0:
raise Exception("Failed to initialize repository, err", result.stderr) 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

View File

@ -4,6 +4,8 @@ import subprocess
from tendo import singleton from tendo import singleton
import monitors.dbus_autofill_monitor import monitors.dbus_autofill_monitor
import sys import sys
import goldwarden
from threading import Thread
try: try:
subprocess.Popen(["python3", "/app/bin/background.py"], start_new_session=True) subprocess.Popen(["python3", "/app/bin/background.py"], start_new_session=True)
@ -21,6 +23,19 @@ try:
except: except:
exit() exit()
def run_daemon():
# todo: do a proper check
time.sleep(20)
if not goldwarden.is_daemon_running():
goldwarden.run_daemon()
if not goldwarden.is_daemon_running():
print("daemon not running.. autostarting")
daemonThread = Thread(target=run_daemon)
daemonThread.start()
print("starting autofill monitor")
def on_autofill(): def on_autofill():
subprocess.Popen(["python3", "/app/bin/autofill.py"], start_new_session=True) subprocess.Popen(["python3", "/app/bin/autofill.py"], start_new_session=True)
monitors.dbus_autofill_monitor.on_autofill = on_autofill monitors.dbus_autofill_monitor.on_autofill = on_autofill

View File

@ -123,6 +123,7 @@ class SettingsWinvdow(Gtk.ApplicationWindow):
def update_labels(): def update_labels():
pin_set = goldwarden.is_pin_enabled() pin_set = goldwarden.is_pin_enabled()
status = goldwarden.get_vault_status() status = goldwarden.get_vault_status()
if status != None:
locked = status["locked"] locked = status["locked"]
self.login_button.set_sensitive(pin_set and not locked) self.login_button.set_sensitive(pin_set and not locked)
self.set_pin_button.set_sensitive(not pin_set or not locked) self.set_pin_button.set_sensitive(not pin_set or not locked)
@ -131,6 +132,10 @@ class SettingsWinvdow(Gtk.ApplicationWindow):
self.notes_row.set_subtitle(str(status["noteEntries"])) self.notes_row.set_subtitle(str(status["noteEntries"]))
self.unlock_button.set_sensitive(True) self.unlock_button.set_sensitive(True)
self.unlock_button.set_label("Unlock" if locked else "Lock") self.unlock_button.set_label("Unlock" if locked else "Lock")
else:
is_daemon_running = goldwarden.is_daemon_running()
if not is_daemon_running:
self.status_row.set_subtitle("Daemon not running")
GLib.timeout_add(1000, update_labels) GLib.timeout_add(1000, update_labels)
GLib.timeout_add(1000, update_labels) GLib.timeout_add(1000, update_labels)