RJ 1/16/04: (I work in a NOC - this was a BIG problem for us) suggests an approach to avoiding embedded passwords in Expect scripts. Feel free to format this for wiki-reaper friendly and improve/fix. Works on Sun/Solaris 8, TCL 8.x and most UNIX flavors. (Don Libes: Thank you sooo much for Expect - you have no idea how many man-hours you save those who log into 30-100 routers, switches and servers per day.)
[Q: What's a NOC? A: Network Operations Center. The people that keep ISPs running.]
todo: Somebody adapt for Windows (maybe exec'ing PGP?)
PT: tcllib includes md5crypt which generates MD5 based password hashes (as used in Apache and modern Unices). This would be simpler than fiddling with PGP. It also doesn't suffer the password length limitations of standard crypt.
RJ 2/16/04: Thanks PT. Ok, I have installed tcllib and tried md5crypt, but I'm confused on how it works:
tclsh> md5crypt::md5crypt rickrick baconbac $1$baconbac$P/Ffd5hoRpvGbNK8SU9st0
There you have it. It seems to dump the key with the encrypted data. Also, how would you decrypt this in an application? I appreciate the help - it would be great to have a pure tcl encryption mechanism for this and md5 128bit would be much stronger than DES. Just not sure how to use it and there is no man page for md5crypt with the tcllib dist.
The basic idea
Procedure to prompt for key - shameless pilfer from Mr. Libes' "Exploring Expect"
proc getpass pwprompt { set oldmode [stty -echo -raw] send_user "\n $pwprompt" set timeout -1 expect_user -re "(.*)\n" send_user "\n" eval stty $oldmode return $expect_out(1,string) }
Procedure to encrypt device passwords
proc utility_encrypt {pd filename} { global key HOME catch [exec echo "$pd" | des -e -k $key -b > $HOME/pwdir/$filename] return }
Procedure to decrypt device passwords
proc utility_decrypt filename { global key HOME catch {exec cat $HOME/pwdir/$filename | des -d -b -k $key} dpd return $dpd }
You can use utility_encrypt in a setup program, and provide functionality that allows new passwords to be added to the encrypted files as they are implemented.
Lets assume the encrypted password files are organized by device type and separated with "\n". Then the mechanics of the program look something like this:
SAMPLE login proc
proc foo_login_proc {device_name} { global key sid set spawn_id $sid($device_name) set decrypted_all [utility_decrypt foo_passwords.enc] for {set i 0} {$i <= [llength $decrypted_all]} {incr i} { set foo_pws($i) [lindex $decrypted_all $i] } ... #loop through foo_pws array using exp_send/expect until login successful... set i 0 set pw $foo_pws($i) expect { "password for foo: " { exp_send "$pw\n" exp_continue } "login successful" { interact { "invalid password" { incr i set pw $foo_pws($i) exp_continue { "other stuff" { ... } ;#eof, timeout, errors from device, etc. } ... exit }
SAMPLE Main
#user launches program to log into a Foo systems Bar device ''device_name'': ... set user [exec whoami] set key [getpass "Enter password for $user: "] spawn -noecho telnet $device_name set sid($device_name) $spawn_id detect_device_prompt ;# an Expect proc that detects this is a foo type device # from it's prompt and launches the foo_login proc ...
- RJ 1/17/04
[Start by looking at source protection.]
[Follow up by locating information about writing secure Tcl scripts]
Finally, consider using interactive prompting rather than hard coding passwords ...
[See [L1 ].]