fix(ssh): spawn askpass pinentry off-tree so push doesn't swallow terminal

This commit is contained in:
2026-07-12 16:45:18 +02:00
parent 0851515de0
commit 7205841c4d
+11 -11
View File
@@ -18,11 +18,21 @@ let
# confirm/none informational, e.g. "Confirm user presence" (touch request)
# A FIDO touch can't be faked by software, so those messages need no dialog:
# succeed silently instead of popping a spurious PIN box (the token blinks).
# pinentry runs under `systemd-run --user`, not directly, so it is reparented
# onto the user service manager instead of this askpass shell. ssh spawns the
# askpass from inside the foot terminal, and Hyprland's window swallowing walks
# a new window's parent-PID chain for a `foot` ancestor (swallow_regex) — a
# direct pinentry would match and hide the terminal behind the PIN dialog.
# Detaching breaks that chain (parent becomes systemd), exactly like the
# commit-signing pinentry that gpg-agent already spawns off-tree. --pipe wires
# stdin/stdout through so the Assuan exchange still works; --wait propagates
# the exit status; --collect reaps the transient unit.
sshAskpass = pkgs.writeShellScript "ssh-askpass-pinentry" ''
[ -n "''${SSH_ASKPASS_PROMPT:-}" ] && exit 0
desc=$(printf '%s' "''${1:-Passphrase:}" | sed 's/%/%25/g')
printf 'SETTITLE ssh\nSETPROMPT PIN:\nSETDESC %s\nGETPIN\nBYE\n' "$desc" \
| ${pkgs.pinentry-qt}/bin/pinentry-qt \
| ${pkgs.systemd}/bin/systemd-run --user --pipe --wait --collect --quiet \
${pkgs.pinentry-qt}/bin/pinentry-qt \
| sed -n 's/^D //p'
'';
@@ -516,16 +526,6 @@ in
swallow_regex = "^(foot)$";
};
# Stop the pinentry dialog from swallowing its parent terminal. Commit
# signing pops pinentry from gpg-agent (a daemon, not a foot child) so it
# already floats on top; but an ssh PIN prompt for `git push` is spawned
# via SSH_ASKPASS *inside* the foot shell, so swallow_regex matches and it
# hides the terminal until dismissed. noswallow exempts the dialog itself,
# leaving normal GUI swallowing (zathura/imv from mc) intact.
windowrule = [
"match:class ^(org\\.gnupg\\.pinentry-qt)$ noswallow on"
];
input = {
kb_layout = "de";
follow_mouse = 1;