sshw (3305B)
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 get { 28 send_user -- [lrange $command 1 end] 29 exit 0 30 } 31 # mount /path/to/local /path/to/remote 32 # You may need to add your own public key to your own ~/.ssh/authorized_keys 33 mount { 34 set fwport 3848 35 set localmount [lindex $argv [expr {$i + 1}]] 36 set remotemount [lindex $argv [expr {$i + 2}]] 37 incr i 3 38 if {$i != $argc} { 39 send_user "`mount` is only usable as a final command\n" 40 exit 1 41 } 42 lappend command "-A" 43 lappend command "-o RequestTTY=yes" 44 lappend command "-R $fwport:localhost:22" 45 lappend command "sshfs -o uid=`id -u`,gid=`id -g` localhost:$localmount $remotemount -o port=$fwport; /bin/bash -li; fusermount -u $remotemount" 46 break 47 } 48 -C - 49 -A - 50 -X - 51 -Y - 52 -M { 53 lappend command $ssharg 54 } 55 -R - 56 -D - 57 -L - 58 -i - 59 -J { 60 lappend command $ssharg [lindex $argv [expr {$i + 1}]] 61 incr i 62 } 63 64 default { 65 set host [lindex $argv $i] 66 if {[dict exists $hosts $host]} { 67 set host [dict get $hosts $host] 68 } 69 lappend command {*}$host 70 } 71 } 72 } 73 send_user "Connecting with $command\n" 74 75 # Define a procedure to read password 76 proc read_password {} { 77 stty -echo 78 send_user "password: " 79 expect_user -re "(.*)\n" 80 stty echo 81 set pass "$expect_out(1,string)\r" 82 send_user "\n" 83 return $pass 84 } 85 86 # Read password from user 87 set pass [read_password] 88 89 # Define procedure to log in 90 proc login {pass command} { 91 # Variables written in procedures don't change globally, 92 # but spawn_id has to be global for expect to work. 93 global spawn_id 94 global spawn_out 95 global current_password 96 97 # Connect 98 eval spawn $command 99 100 # Handle window resizing 101 trap { 102 set rows [stty rows] 103 set cols [stty columns] 104 stty rows $rows columns $cols < $spawn_out(slave,name) 105 } WINCH 106 107 expect { 108 -ex "Current password:" { 109 send -- "${current_password}\r" 110 exp_continue 111 } 112 # Change password as needed 113 -ex "New password: " { 114 send -- "$pass" 115 expect -exact "Retype new password: " 116 send -- "$pass" 117 expect eof 118 119 # SSH closes the connection, so log in again 120 login $pass $command 121 } 122 # Accept fingerprint as needed 123 -ex "Are you sure you want to continue connecting (yes/no/\[fingerprint\])? " { 124 send -- "yes\r" 125 exp_continue 126 } 127 # On a shell prompt, stop expecting 128 "\$ $" {} 129 # Catch all - we got something we didn't expect 130 default { 131 send_user "Got some unexpected output\n" 132 exit 1 133 } 134 } 135 } 136 137 # Log in 138 login $pass $command 139 140 if { [info exists pwonly] } { 141 send -- "exit\r" 142 exit 0 143 } 144 145 # Elevate privileges 146 if { [lindex $command 0] == "ssh" } { 147 send -- "sudo su\n" 148 expect -re "password for \[^ \]+: " 149 send -- "$pass" 150 } 151 152 # Yield control 153 interact