Implement pinentry integration for ui

This commit is contained in:
Bernd Schoolmann 2024-02-09 14:03:27 +01:00
parent ac0e84a46f
commit 069afeae27
No known key found for this signature in database
5 changed files with 109 additions and 11 deletions

View File

@ -208,6 +208,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}
}
}
}

View File

@ -10,18 +10,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,6 +140,29 @@ def is_daemon_running():
daemon_not_running = ("daemon running" in result)
return not daemon_not_running
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():
# restic_cmd = f"daemonize"
# # print while running

View File

@ -0,0 +1,28 @@
import subprocess
import os
from src.services import goldwarden
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.ui.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.ui.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)
daemon()

View File

@ -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)

View File

@ -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)