#!/usr/bin/expect -- # # Original idea and code by noconflic # nocon@darkflame.net # http://nocon.darkflame.net # Wed Mar 12 16:01:47 CST 2003 # # Modified Sat Dec 13 16:04:08 EST 2003 by Ben Okopnik # - Added the "no password" options for "authorized_keys" logins # - Set "hosts" list to read the contents of the "pushlist" file # (this makes it easy to use different sets of hosts) # Set the path to your local scp/ssh commands set sshcmd /usr/bin/ssh set sshcpy /usr/bin/scp set timeout "-1" # Read in the list of hosts if { [catch "open pushlist" FID] == 0 } { set hosts [read $FID] close $FID } proc usage {} { send_user "Usage: sshtool \[option\] \n\n" send_user "Option: (one of the following)\n" send_user " -u execute command on hosts as a normal user.\n" send_user " -U execute command on hosts as a normal user WITHOUT a password.\n" send_user " -r execute command on hosts as root (uses sudo).\n" send_user " -c copy file(s) or directory to hosts.\n" send_user " -C copy file(s) or directory to hosts WITHOUT a password.\n" send_user " -h this help\n\n" send_user " username of login account.\n\n" exit } proc getpass {} { stty -echo send_user "SSH Password: " expect_user -re "(.*)\n" set password(pass) $expect_out(1,string) send_user "\n" stty echo return $password(pass) } proc getcommand {} { send_user "Enter Command: " expect_user -re "(.*)\n" set command(cmd) $expect_out(1,string) return $command(cmd) } proc getfiledir {} { send_user "Local directory or file: " expect_user -re "(.*)\n" set dirfile(dfile) $expect_out(1,string) return $dirfile(dfile) } proc doit {user pass cmmnd files su f} { global hosts sshcmd sshcpy sucmd foreach host [set hosts] { send_user "Connecting to: $host...\n" if {$su == 1} { spawn $sshcmd $user@$host $cmmnd expect "password:" send $pass\r interact } if {$su == 2} { spawn $sshcmd $user@$host $sucmd $cmmnd expect "password:" send $pass\r expect "Password:" send $pass\r interact } if {$f == 1} { spawn $sshcpy -r $files $user@$host:~/ expect "password:" send $pass\r interact } sleep 1 } } proc doit_nopass {user cmmnd files su f} { global hosts sshcmd sshcpy sucmd foreach host [set hosts] { send_user "Connecting to: $host...\n" if {$su == 1} { spawn $sshcmd $user@$host $cmmnd interact } if {$su == 2} { spawn $sshcmd $user@$host $sucmd $cmmnd interact } if {$f == 1} { spawn $sshcpy -r $files $user@$host:~/ interact } sleep 1 } } # Program body if {[llength $argv]!=2} usage set sucmd sudo set user [lindex $argv 1] set su 0 set files 0 set f 0 set cmmnd 0 while {[llength $argv]>0} { set flag [lindex $argv 0] switch -- $flag "-u" { send_user "Running command(s) on hosts as a normal user...\n" set su 1 set pass [getpass] set cmmnd [getcommand] doit $user $pass $cmmnd $files $su $f set argv [lrange $argv 2 end] } "-U" { send_user "Running command(s) on hosts as a normal user WITHOUT a password...\n" set su 1 set cmmnd [getcommand] doit_nopass $user $cmmnd $files $su $f set argv [lrange $argv 2 end] } "-r" { send_user "Running command(s) on hosts as root...\n" set su 2 set pass [getpass] set cmmnd [getcommand] doit $user $pass $cmmnd $files $su $f set argv [lrange $argv 2 end] } "-C" { send_user "Sending file(s) to hosts WITHOUT a password...\n" set f 1 set files [getfiledir] doit_nopass $user $cmmnd $files $su $f set argv [lrange $argv 2 end] } "-c" { send_user "Sending file(s) to hosts...\n" set f 1 set pass [getpass] set files [getfiledir] doit $user $pass $cmmnd $files $su $f set argv [lrange $argv 2 end] } "-h" { usage set argv [lrange $argv 2 end] } default { usage } } send_user "SSHTool Finished.\n" exit