dotfiles

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

sshw (2349B)


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