Repository navigation
Conversation
`docker pass set <id>` used to block on STDIN whenever no value was given, echoing whatever the user typed. It now detects an interactive terminal and shows a masked prompt instead, so the value neither lands in shell history nor on screen, and nobody has to pipe it from a file. Pipes and redirects still read STDIN to the end as before. The prompt is a small raw-mode line reader on top of x/term. Raw mode is entered with tcsetattr(TCSAFLUSH), as getpass(3), sudo and readpassphrase do, so input typed before the prompt appeared, which the still-cooked tty echoed in plaintext, is discarded rather than taken as the secret. Printable runes are appended and echoed as '*', Backspace removes the last rune, ctrl+u clears the line, and Enter or a bare LF (ctrl+j) ends it, as with getpass(3). An empty Enter is an error, and so is input ending before Enter: Ctrl-D, or Ctrl-Z on a Windows console, which the console reader in os reports as EOF. Unlike getpass(3), a line that was not entered is never stored. Ctrl-C, which raw mode delivers as a key press rather than a signal, is reported as context.Canceled so the root exits 130 silently. Cancelling the context, as the root does on a signal, ends the read loop so its buffers are zeroed, restores the terminal and returns; the root ends the prompt line when it reports the signal. The blocked read of the tty itself cannot be interrupted and is left to end with the process. Escape sequences are skipped whole, cursor keys, mouse reports and stray terminal replies among them, so they never leak into the value; a control byte inside one ends it, so Enter and Ctrl-C get through regardless. A sequence split after its ESC gets 50 ms to arrive before ESC counts as the Escape key, as in vim and bubbletea. The read buffer and the collected runes are zeroed when the prompt returns. Pastes are taken through bracketed paste mode only; the prompt never reads the clipboard. A pasted trailing newline is trimmed, and a value spanning several lines, or holding control characters other than tab, is rejected with a pointer to STDIN rather than stored mangled. Ctrl-C cancels inside a paste too, the way out should its end marker never arrive. When the terminal does not bracket pastes, a multi-line paste arrives as keystrokes; bytes behind the line end that came in the same read, faster than anyone types, give it away and it is rejected the same way rather than stored as its first line. The terminal is restored and the input still queued in it discarded in one tcsetattr(TCSAFLUSH) ioctl (TIOCSETAF on Darwin, TCSETSF on Linux; SetConsoleMode then FlushConsoleInputBuffer on Windows), as getpass(3) does. Restoring first and flushing second would leave a window on BSD-derived ttys: turning ICANON back on sets PENDIN, and the next byte to arrive has the queued remainder retyped with ECHO on, printing the rest of the paste in plaintext. Pastes larger than the pty input queue can still reach the shell, as they do with sudo and ssh prompts. Cobra hands the subcommands docker's stream wrappers, which hide the terminal file behind File(); unwrapFile reaches it to switch the terminal to raw mode. Signed-off-by: Johannes Großmann <grossmann.johannes@t-online.de>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
docker pass set <id>used to block on STDIN whenever no value was given, echoing whatever the user typed. It now detects an interactive terminal and shows a masked prompt instead, so the value neither lands in shell history nor on screen, and nobody has to pipe it from a file. Pipes and redirects still read STDIN to the end as before.The prompt is a small raw-mode line reader on top of x/term. Printable runes are appended and echoed as '*', Backspace removes the last rune, ctrl+u clears the line, and Enter or a bare LF (ctrl+j) ends it, as with getpass(3). An empty Enter is an error, and so is input ending before Enter: Ctrl-D, or Ctrl-Z on a Windows console, which the console reader in os reports as EOF. Unlike getpass(3), a line that was not entered is never stored. Ctrl-C, which raw mode
delivers as a key press rather than a signal, is reported as context.Canceled so the root exits 130 silently. Cancelling the context, as the root does on a signal, ends the read loop so its buffers are zeroed, restores the terminal and returns; the root ends the prompt line when it reports the signal. The blocked read of the tty itself cannot be interrupted and is left to end with the process. Escape sequences are skipped whole, cursor keys, mouse reports and stray terminal replies among them, so they never leak into the value; a control byte inside one ends it, so Enter and Ctrl-C get through regardless. A sequence split after its ESC gets 50 ms to arrive before ESC counts as the Escape key, as in vim and bubbletea.
The read buffer and the collected runes are zeroed when the prompt returns.
Pastes are taken through bracketed paste mode only; the prompt never reads the clipboard. A pasted trailing newline is trimmed, and a value spanning several lines, or holding control characters other than tab, is rejected with a pointer to STDIN rather than stored mangled. Ctrl-C cancels inside a paste too, the way out should its end marker never arrive. When the terminal does not bracket pastes, a multi-line paste arrives as keystrokes: the value is exactly the first line, and the terminal is restored and the input still queued in it discarded in one tcsetattr(TCSAFLUSH) ioctl (TIOCSETAF on Darwin, TCSETSF on Linux; SetConsoleMode then FlushConsoleInputBuffer on Windows), as getpass(3) does. Restoring first and flushing second would leave a window on BSD-derived ttys: turning ICANON back on sets PENDIN, and the next byte to arrive has the queued remainder retyped with ECHO on, printing the rest of the paste in plaintext. Pastes larger than the pty input queue can still reach the shell, as they do with sudo and ssh prompts.
Cobra hands the subcommands docker's stream wrappers, which hide the terminal file behind File(); unwrapFile reaches it to switch the terminal to raw mode.