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