Posted by mazet on 14 Nov 2009 in Programmation, Tcl/Tk
Script Tcl/expect permettant de se connecter à une machine avec plusieurs rebonds
Code
# -*- tcl -*- | |
# the next line restarts using expect \ | |
exec expect "$0" -- ${1+"$@"} | |
| |
# autoconnect.tcl - an expect script to connect a machine beyond multiple hops | |
# Copyright (C) 2001 Laurent Mazet | |
| |
# This program is free software; you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation; either version 2, or (at your option) | |
# any later version. | |
| |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
| |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, write to the Free Software Foundation, | |
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
| |
# Changelog: | |
# - 1.0.0 | |
# * add default configuration files generation | |
# - 0.9.0 | |
# * initial release | |
| |
# set to 1 to force conservative mode even if script wasn't run | |
# conservatively originally | |
set force_conservative 0 | |
| |
if {$force_conservative} { | |
set send_slow {1 .1} | |
proc send {ignore arg} { | |
sleep .1 | |
exp_send -s -- $arg | |
} | |
} | |
| |
proc test_exec {} { | |
| |
send "exec\r" | |
expect { | |
" not " { | |
set cmd "" | |
} | |
"\r" { | |
set cmd "exec " | |
} | |
} | |
| |
return $cmd | |
} | |
| |
proc cross_gateway {gateway netlogin netpassword} { | |
| |
send "open $gateway\r" | |
| |
expect { | |
"OneIT Username: " { | |
send -- "$netlogin\r" | |
} | |
timeout { | |
send_user "connection to $host timed out\n" | |
exit 1 | |
} | |
} | |
| |
expect { | |
"OneIT Password: " { | |
send -- "$netpassword\r" | |
} | |
timeout { | |
send_user "connection to $host timed out\n" | |
exit 1 | |
} | |
} | |
| |
expect { | |
"tngate0>" { | |
return | |
} | |
"failed" { | |
send_user "\nincorrect netlogin or netpassword for $gateway\n" | |
exit 1 | |
} | |
timeout { | |
send_user "connection to $host timed out\n" | |
exit 1 | |
} | |
} | |
| |
return | |
} | |
| |
proc telnet {host login password prompt} { | |
| |
set prefix [test_exec] | |
| |
send -- "${prefix}telnet $host\r" | |
| |
expect { | |
"ogin:" { | |
send -- "$login\r" | |
} | |
timeout { | |
send_user "connection to $host timed out\n" | |
exit 1 | |
} | |
} | |
| |
expect { | |
"assword:" { | |
send -- "$password\r" | |
} | |
timeout { | |
send_user "connection to $host timed out\n" | |
exit 1 | |
} | |
} | |
| |
expect { | |
"$prompt" { | |
return | |
} | |
"incorrect" { | |
send_user "incorrect login or password on $host\n" | |
exit 1 | |
} | |
timeout { | |
send_user "connection to $host timed out\n" | |
exit 1 | |
} | |
} | |
| |
return | |
} | |
| |
proc ssh {login_host arg1 {arg2 ""}} { | |
| |
if {$arg2 == ""} { | |
set password "" | |
set prompt "$arg1" | |
} else { | |
set password "$arg1" | |
set prompt "$arg2" | |
} | |
| |
set prefix [test_exec] | |
| |
send -- "${prefix}ssh $login_host\r" | |
| |
if {$password != ""} { | |
expect { | |
"assword:" { | |
send -- "$password\r" | |
} | |
"refused" { | |
send_user "Connection refused by $login_host\n" | |
exit 1 | |
} | |
timeout { | |
send_user "connection to $login_host timed out\n" | |
exit 1 | |
} | |
} | |
} | |
| |
expect { | |
"$prompt" { | |
return | |
} | |
"refused" { | |
send_user "Connection refused by $login_host\n" | |
exit 1 | |
} | |
"incorrect" { | |
send_user "incorrect login or password on $login_host\n" | |
exit 1 | |
} | |
timeout { | |
send_user "connection to $login_host timed out\n" | |
exit 1 | |
} | |
} | |
| |
return | |
} | |
| |
set timeout 30 | |
match_max 100000 | |
| |
set hook [lindex $argv 0] | |
set nargs [llength $argv] | |
if {$nargs != 1} { | |
set hook "-h" | |
} | |
| |
switch $tcl_platform(platform) { | |
windows { | |
set basercfile "_autoconnect.rc" | |
} | |
default { | |
set basercfile ".autoconnectrc" | |
} | |
} | |
| |
if {[info exists env(AUTOCONNECTRC)]} { | |
set rcfile $env(AUTOCONNECTRC) | |
if {[file isdirectory $rcfile]} { | |
set rcfile [file join $rcfile $basercfile] | |
} | |
} elseif {[info exists env(HOME)]} { | |
set rcfile [file join $env(HOME) $basercfile] | |
} else { | |
set rcfile [file join "/" $basercfile] | |
} | |
| |
if {[file exists $rcfile]} { | |
if {[catch {source $rcfile} error]} { | |
puts "Error(s) in your resource file ($rcfile)" | |
exit 1 | |
} | |
} else { | |
puts "No resource file." | |
set f [open $rcfile "w"] | |
if {$f == 0} { | |
puts "Can't create a skeleton" | |
exit 2 | |
} else { | |
puts "Create a skeleton" | |
} | |
puts $f "# Resource file for autoconnect" | |
puts $f "" | |
puts $f "# Gateway setting" | |
puts $f "#set gateway \"tngate0.mot.com\"" | |
puts $f "#set gwlogin \"my_gateway_login\"" | |
puts $f "#set gwpasswd \"my_gateway_passwd\"" | |
puts $f "" | |
puts $f "# Exemple of host connections" | |
puts $f "#set conn(hook1) {telnet \"foo_host\" \"my_login\" \"my_passwd\" \"my_prompt\"}" | |
puts $f "#set conn(hook2) {telnet \"foo_host\" \"my_login\" \"my_passwd\" \"my_prompt\";" | |
puts $f "# telnet \"bar_host\" \"my_login\" \"my_passwd\" \"my_prompt\"}" | |
puts $f "#set conn(hook3) {telnet \"foo_host\" \"my_login\" \"my_passwd\" \"my_prompt\";" | |
puts $f "# ssh \"my_login@bar_host\" \"my_passwd\" \"my_prompt\"}" | |
puts $f "#set conn(hook4) {telnet \"foo_host\" \"my_login\" \"my_passwd\" \"my_prompt\";" | |
puts $f "# ssh \"my_login@bar_host\" \"my_prompt\"}" | |
close $f | |
puts "Don't forget to protect it: chmod 0600 $rcfile" | |
exit 0 | |
} | |
| |
if {$hook == "-h"} { | |
puts "Usage: autoconnect \[-h\] <hook>" | |
exit 3 | |
} | |
| |
if {"$conn($hook)" == ""} { | |
puts "Unknown hook `$hook'" | |
exit 4 | |
} | |
| |
spawn telnet | |
expect "telnet>" | |
cross_gateway $gateway $gwlogin $gwpasswd | |
eval $conn($hook) | |
| |
interact |