user3514268
user3514268

Reputation: 41

using TCL command line, is there a way to stop showing characters?

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

Answers (2)

Donal Fellows
Donal Fellows

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

Shmil The Cat
Shmil The Cat

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

Related Questions