dotfiles

My personal shell configs and stuff
git clone git://git.alex.balgavy.eu/dotfiles.git
Log | Files | Refs | Submodules | README | LICENSE

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