SSH_ASKPASS_PROMPT is a new behavior introduced in OpenSSH 8.2 for prompting U2F touch. - When unset/empty, this is used to input passphrase as before. - When set to "confirm", allows the user to OK or Cancel. - When set to "none", only shows a message. Signed-off-by: Likai Liu <liulk@xxxxxxxxx> --- git-gui/git-gui--askpass | 70 +++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/git-gui/git-gui--askpass b/git-gui/git-gui--askpass index 71a536d232..7d4bda8f31 100755 --- a/git-gui/git-gui--askpass +++ b/git-gui/git-gui--askpass @@ -4,6 +4,21 @@ exec wish "$0" -- "$@" # This is a trivial implementation of an SSH_ASKPASS handler. # Git-gui uses this script if none are already configured. +# +# When SSH_ASKPASS_PROMPT is unset or empty, we show a message +# promot, a text input, an option to show the input, and the OK and +# Cancel buttons. If the prompt explicitly asks for (yes/no) as the +# answer, the input will be checked to be either "yes" or "no". +# +# When SSH_ASKPASS_PROMPT=confirm, we only show the message and the OK +# and Cancel buttons without the text input. +# +# When SSH_ASKPASS_PROMPT=none, we only show the message. This is +# typically to prompt for U2F touch, which cannot be dismissed. We +# will get SIGTERM once touched. The exit status is inconsequential. +# +# See: https://www.openssh.com/txt/release-8.2 +# See also: notify_start() and notify_complete() in readpass.c package require Tk @@ -11,10 +26,22 @@ set answer {} set yesno 0 set rc 255 +if {[info exists ::env(SSH_ASKPASS_PROMPT)]} { + set mode $::env(SSH_ASKPASS_PROMPT) +} else { + set mode {} +} +switch $mode { + confirm {} + none {} + default {set mode {}} +} if {$argc < 1} { set prompt "Enter your OpenSSH passphrase:" } else { set prompt [join $argv " "] +} +if {$mode eq {}} { if {[regexp -nocase {\(yes\/no\)\?\s*$} $prompt]} { set yesno 1 } @@ -23,9 +50,6 @@ if {$argc < 1} { message .m -text $prompt -justify center -aspect 4000 pack .m -side top -fill x -padx 20 -pady 20 -expand 1 -entry .e -textvariable answer -width 50 -pack .e -side top -fill x -padx 10 -pady 10 - proc on_show_input_changed {args} { global show_input if {$show_input} { @@ -34,27 +58,37 @@ proc on_show_input_changed {args} { .e configure -show "*" } } -trace add variable show_input write "on_show_input_changed" -set show_input 0 +if {$mode eq {}} { + entry .e -textvariable answer -width 50 + pack .e -side top -fill x -padx 10 -pady 10 -if {!$yesno} { - checkbutton .cb_show -text "Show input" -variable show_input - pack .cb_show -side top -anchor nw + trace add variable show_input write "on_show_input_changed" + + set show_input $yesno + + if {!$yesno} { + checkbutton .cb_show -text "Show input" -variable show_input + pack .cb_show -side top -anchor nw + } } -frame .b -button .b.ok -text OK -command finish -button .b.cancel -text Cancel -command cancel +if {$mode ne {none}} { + frame .b + button .b.ok -text OK -command finish + button .b.cancel -text Cancel -command cancel -pack .b.ok -side left -expand 1 -pack .b.cancel -side right -expand 1 -pack .b -side bottom -fill x -padx 10 -pady 10 + pack .b.ok -side left -expand 1 + pack .b.cancel -side right -expand 1 + pack .b -side bottom -fill x -padx 10 -pady 10 -bind . <Visibility> {focus -force .e} -bind . <Key-Return> [list .b.ok invoke] -bind . <Key-Escape> [list .b.cancel invoke] -bind . <Destroy> {set rc $rc} + if {$mode eq {}} { + bind . <Visibility> {focus -force .e} + } + bind . <Key-Return> [list .b.ok invoke] + bind . <Key-Escape> [list .b.cancel invoke] +} +bind . <Destroy> {set rc $rc} proc cancel {} { set ::rc 255 -- 2.30.1 (Apple Git-130)