Reputation: 41
I'm building a tool were a command with a password needs to be entered. I want when I enter this command with the password, the command line replaces each character with "*" or " ", so the command and the password will not be observable !
is there such a command that tells the TCL interpreter "from this point, show each character entered as *", and then switch back to regular mode ?
any other suggestion will be valuable too.
Upvotes: 2
Views: 595
Reputation: 137577
(Assuming Linux.) By far the easiest way to handle passwords in a terminal is to turn off echoing of input but leave the terminal otherwise in cooked mode. It won't show a *
for each entered character, but it does mean that you don't have to handle things like backspace (when a user realises they typed the last couple of characters wrong before hitting Return), etc.
exec /bin/stty -echo <@stdin
set password [gets stdin]
puts ""
exec /bin/stty echo <@stdin
If you've got Tcl 8.6, you can easily make this more robust with this procedure:
proc getPassword {{prompt "Password: "}} {
exec /bin/stty -echo <@stdin
try {
puts -nonewline $prompt
flush stdout
return [gets stdin]
} finally {
puts ""
flush stdout
exec /bin/stty echo <@stdin
}
}
(It's possible to use catch
and some scripting to emulate try…finally
but it's really annoying.)
If you have a GUI and prefer that, you make a password entry box by setting the -show
option to something non-empty (e.g., *
to show an asterisk).
Upvotes: 1
Reputation: 4668
In your case, you shall take "full control" over your terminal and disable its default echoing behavior (In UNIX the likes the terminal should be entered into the so-called raw mode) Then, you can read the characters one-by-one (till max password size or till Enter is pressed) and echo '*' per each pressed character. You got working code examples both on UNIX and Windows how doing so here You may want reading also this link echo-free password entry TCL wiki
proc enableRaw {{channel stdin}} {
exec /bin/stty raw -echo <@$channel
}
proc disableRaw {{channel stdin}} {
exec /bin/stty -raw echo <@$channel
}
enableRaw
set c [read stdin 1]
puts -nonewline $c
disableRaw
package require twapi
proc enableRaw {{channel stdin}} {
set console_handle [twapi::GetStdHandle -10]
set oldmode [twapi::GetConsoleMode $console_handle]
set newmode [expr {$oldmode & ~6}] ;# Turn off the echo and line-editing bits
twapi::SetConsoleMode $console_handle $newmode
}
proc disableRaw {{channel stdin}} {
set console_handle [twapi::GetStdHandle -10]
set oldmode [twapi::GetConsoleMode $console_handle]
set newmode [expr {$oldmode | 6}] ;# Turn on the echo and line-editing bits
twapi::SetConsoleMode $console_handle $newmode
}
enableRaw
set c [read stdin 1]
puts -nonewline $c
disableRaw
Upvotes: 2