#!/usr/bin/env python3
"""Password-prompt launcher for LinuxDoors Kernel Config -- same real
pattern as every other root-elevated native LinuxDoors app's own
`-launcher` wrapper: a small unprivileged GUI asks for the root password,
then elevates via a real pty (`su -c`) with DISPLAY/XAUTHORITY explicitly
preserved (a desktop-icon double-click doesn't carry XAUTHORITY, and
`su -c` resets HOME to /root, so a root-owned GUI launched without this
can't reach the X display at all -- the same real bug already found and
fixed for every other root-elevated launcher this session)."""
import os
import pty
import select
import sys

from PySide6.QtWidgets import QApplication, QInputDialog, QLineEdit, QMessageBox

APP = "/usr/local/bin/linuxdoors-kernel-config"


def try_su(password):
    pid, fd = pty.fork()
    if pid == 0:
        x = os.environ.get("XAUTHORITY") or os.path.expanduser("~/.Xauthority")
        d = os.environ.get("DISPLAY", ":0")
        os.execvp("su", ["su", "-c", f"env DISPLAY={d} XAUTHORITY={x} {APP}", "root"])
    sent = False
    auth_failed = False
    buf = b""
    while True:
        try:
            r, _, _ = select.select([fd], [], [], 60)
        except OSError:
            break
        if fd not in r:
            continue
        try:
            chunk = os.read(fd, 4096)
        except OSError:
            break
        if not chunk:
            break
        buf += chunk
        if not sent and b"assword:" in buf:
            os.write(fd, (password + "\n").encode())
            sent = True
            buf = b""
        if b"Authentication failure" in buf or b"su: Authentication" in buf:
            auth_failed = True
    try:
        os.waitpid(pid, 0)
    except ChildProcessError:
        pass
    return sent and not auth_failed


def main():
    app = QApplication(sys.argv)
    pw, ok = QInputDialog.getText(
        None, "LinuxDoors Kernel Config", "Root password:", QLineEdit.Password)
    if not ok:
        return
    if not try_su(pw):
        QMessageBox.critical(None, "LinuxDoors Kernel Config",
                              "Authentication failed.")


if __name__ == "__main__":
    main()
