Skip to content

Detect password prompts and answer via read-passwd#241

Merged
dakra merged 1 commit into
mainfrom
feat/password-prompt-detection
May 8, 2026
Merged

Detect password prompts and answer via read-passwd#241
dakra merged 1 commit into
mainfrom
feat/password-prompt-detection

Conversation

@dakra
Copy link
Copy Markdown
Owner

@dakra dakra commented May 8, 2026

Summary

  • Detects password prompts (sudo, ssh, gpg, passwd, …) and answers them via read-passwd instead of streaming through Emacs's key pipeline (where they'd land in view-lossage and the recent-keys ring).
  • New Zig binding ghostel--pty-password-input-p mirrors libghostty's canonical && !echo heuristic from ghostty/src/termio/Exec.zig. Regex fallback on the cursor row covers remote ssh / programs that don't toggle echo.
  • ghostel-password-prompt-functions is a chain of (ROW) -> string-or-nil sources, tried via run-hook-with-args-until-success. Default reads with read-passwd; users prepend their own (auth-source, 1Password, pass, …) and the default acts as the fallback. Docstring includes a TRAMP-aware auth-source-pick-first-password example.
  • The freshly allocated (concat pwd "\r") wire copy is clear-string'd after sending so the password doesn't sit in the heap until the next GC. The source's return value is deliberately not cleared (could be a shared auth-source cache entry).
  • ghostty_feature_requests/06-password-input-setter.md drafts an upstream proposal to add a setter for libghostty's password_input flag — currently the public C-API has only a getter, so libghostty-vt embedders can't round-trip through it.

Test plan

  • make -j4 all clean: build + lint + 60 elisp + 137 native + 316 evil tests, no unexpected failures
  • Live sudo -K; sudo true in a ghostel buffer — read-passwd minibuffer pops up, password accepted on first try, mode-line shows 🔒Password while open, view-lossage does not contain the password
  • Wrong-password retry re-prompts automatically (cursor moves to "Sorry, try again." row, suppression auto-clears)
  • No double-prompt after submission (regression test ghostel-test-detect-suppresses-while-on-handled-row)
  • Wire copy is zeroed after send (regression test ghostel-test-prompt-password-clears-wire-copy)
  • Hook chain semantics: first non-nil source wins (ghostel-test-prompt-password-tries-sources-in-order)
  • auth-source extension example (manual smoke test on a real ~/.authinfo.gpg entry — recommended before merging)

Mirrors libghostty's canonical+!echo heuristic (see
ghostty/src/termio/Exec.zig) so password input from sudo/ssh/gpg goes
through read-passwd instead of Emacs's key handling, where it would
land in view-lossage and the recent-keys ring.

The Zig binding ghostel--pty-password-input-p opens the slave path
and runs tcgetattr.  Falls back to a regex on the cursor row when
echo state can't be observed (remote ssh, programs that don't toggle
echo).  Post-submission re-fires are suppressed while the cursor
stays on the row, to bridge the brief window where sudo holds the
tty in canonical+!echo before restoring; cursor moving off the row
(wrong-password retry, next program) re-arms naturally.

ghostel-password-prompt-functions is a chain of
(ROW) -> string-or-nil sources, tried via
run-hook-with-args-until-success.  Default reads with read-passwd;
users prepend their own (auth-source, 1Password, pass, ...) and the
default acts as the fallback.
@dakra dakra force-pushed the feat/password-prompt-detection branch 7 times, most recently from c7eb0f1 to c0d7f8e Compare May 8, 2026 15:47
@dakra dakra merged commit c0d7f8e into main May 8, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant