sshw (2339B)
1 #!/usr/bin/expect 2 set timeout -1 3 match_max 100000 4 5 if { $argc < 1 } { 6 send_user "No hostname provided\n" 7 exit 1 8 } 9 10 set hosts { 11 } 12 13 set command "ssh" 14 for {set i 0} {$i < $argc} {incr i} { 15 switch -glob [lindex $argv $i] { 16 -h { 17 send_user "Targets: [join [dict keys $hosts] ","]\n" 18 exit 0 19 } 20 -M { 21 lappend command "-M" 22 } 23 sftp { 24 lset command 0 sftp 25 } 26 -J { 27 lappend command "-J" [lindex $argv [expr {$i + 1}]] 28 incr i 29 } 30 -R { 31 lappend command "-R" [lindex $argv [expr {$i + 1}]] 32 incr i 33 } 34 -D { 35 lappend command "-D" [lindex $argv [expr {$i + 1}]] 36 incr i 37 } 38 -L { 39 lappend command "-R" [lindex $argv [expr {$i + 1}]] 40 incr i 41 } 42 -C { 43 lappend command "-C" 44 } 45 default { 46 set host [lindex $argv $i] 47 if {[dict exists $hosts $host]} { 48 set host [dict get $hosts $host] 49 } 50 # TODO: conditionally add -M? 51 lappend command {*}$host 52 } 53 } 54 } 55 send_user "Connecting with $command\n" 56 57 # Define a subroutine to read password 58 proc read_password {} { 59 stty -echo 60 send_user "password: " 61 expect_user -re "(.*)\n" 62 stty echo 63 set pass "$expect_out(1,string)\r" 64 send_user "\n" 65 return $pass 66 } 67 68 # Read password from user 69 set pass [read_password] 70 71 # Define procedure to log in 72 proc login {pass command} { 73 # Variables written in procedures don't change globally, 74 # but spawn_id has to be global for expect to work. 75 global spawn_id 76 77 # Connect 78 eval spawn $command 79 80 expect { 81 # Change password as needed 82 -ex "New password: " { 83 send -- "$pass" 84 expect -exact "Retype new password: " 85 send -- "$pass" 86 expect eof 87 88 # SSH closes the connection, so log in again 89 login $pass $command 90 } 91 # Accept fingerprint as needed 92 -ex "Are you sure you want to continue connecting (yes/no/\[fingerprint\])? " { 93 send -- "yes\r" 94 exp_continue 95 } 96 # On a shell prompt, stop expecting 97 " $" {} 98 # Catch all - we got something we didn't expect 99 default { 100 send_user "Got some unexpected output\n" 101 exit 1 102 } 103 } 104 } 105 106 # Log in 107 login $pass $command 108 109 # Elevate privileges 110 if { [lindex $command 0] == "ssh" } { 111 send -- "sudo su\n" 112 expect -re "password for \[^ \]+: " 113 send -- "$pass" 114 } 115 116 # Yield control 117 interact