dotfiles

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

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