[rancid] fortinet problem
john heasley
heas at shrubbery.net
Sat Oct 2 14:38:10 UTC 2010
Sat, Oct 02, 2010 at 08:39:40AM +0200, F?rtbauer Wolfgang:
> Dear John,
>
> I finally found the patch:
> http://www.shrubbery.net/pipermail/rancid-discuss/2009-June/004005.html
> and applied it (manually) against my rancid-2.3.4.
> It's working! Thanks a lot Diego!
>
> Probalby this patch could be added to the main code?!
>
> to answer your question John: the prompt ends with a '#' for readonly-users
> and a '$' for read-write users
Thanks. When did this change from '->'? is there a need to support the
old prompt?
> BR
> Wolfgang
>
>
>
> Wolfgang F?rtbauer
> Leitung IT
>
> ASAMER Holding AG
> Unterthalham Strasse 2
> 4694 Ohlsdorf
> AUSTRIA
> tel +43 50 799 - 2500
> fax +43 7612 799 - 9526
> mobile +43 664 8332326
> w.fuertbauer at asamer.at
> www.asamer.at
>
>
> This message is confidential. It may not be disclosed to, or used by, anyone other than the addressee. If you receive this
> message by mistake, please advise the sender.
>
>
>
> -----Urspr?ngliche Nachricht-----
> Von: john heasley [mailto:heas at shrubbery.net]
> Gesendet: Fr 01.10.2010 17:56
> An: F?rtbauer Wolfgang
> Cc: john heasley; rancid-discuss at shrubbery.net
> Betreff: Re: [rancid] fortinet problem
>
> Fri, Oct 01, 2010 at 09:34:15AM +0200, F?rtbauer Wolfgang:
> > Dear John,
> >
> > Output of nlogin is:
> >
> > rancid at aohmonitoring01:~> nlogin <fortinet>
> > <fortinet>
> > spawn ssh -c 3des -x -l monitoring <fortinet>
> > monitoring@<fortinet>'s password:
> > FGT50A3906508751 #
> > FGT50A3906508751 # Timeout
>
> wie geht es. nlogin looks for the prompt to end with "-> "; why is it "#"
> here? ISTR someone saying that the format had changed and trying to
> understand when and under what circumstances, but not being able to verify.
>
Content-Description: rancid-2.3.4_fortigate_2x-3x.patch
> --- rancid-2.3.4/bin/Makefile.in 2010-10-02 08:31:22.000000000 +0200
> +++ rancid-patch/bin/Makefile.in 2010-10-02 08:29:48.000000000 +0200
> @@ -54,7 +54,7 @@
> $(srcdir)/hlogin.in $(srcdir)/hrancid.in $(srcdir)/htlogin.in \
> $(srcdir)/htrancid.in $(srcdir)/jerancid.in \
> $(srcdir)/jlogin.in $(srcdir)/jrancid.in $(srcdir)/mrancid.in \
> - $(srcdir)/mrvlogin.in $(srcdir)/mrvrancid.in \
> + $(srcdir)/mrvlogin.in $(srcdir)/mrvrancid.in $(srcdir)/fnlogin.in \
> $(srcdir)/nlogin.in $(srcdir)/nrancid.in $(srcdir)/nslogin.in \
> $(srcdir)/nsrancid.in $(srcdir)/nxrancid.in $(srcdir)/par.in \
> $(srcdir)/prancid.in $(srcdir)/rancid-fe.in \
> @@ -75,7 +75,7 @@
> arancid arrancid avologin avorancid blogin brancid cat5rancid \
> clogin rancid cssrancid elogin erancid f5rancid f10rancid \
> flogin francid fnrancid hlogin hrancid htlogin htrancid jlogin \
> - jrancid jerancid mrancid mrvlogin mrvrancid nlogin nrancid \
> + jrancid jerancid mrancid mrvlogin mrvrancid fnlogin nlogin nrancid \
> nslogin nsrancid nxrancid prancid rivlogin rivrancid rrancid \
> srancid tlogin tntlogin tntrancid trancid xrancid xrrancid \
> zrancid
> @@ -247,7 +247,7 @@
> blogin brancid cat5rancid clogin control_rancid cssrancid \
> elogin erancid f5rancid f10rancid flogin fnrancid francid \
> hlogin hrancid htlogin htrancid jerancid jlogin jrancid \
> - mrancid mrvlogin mrvrancid nlogin nrancid nslogin nsrancid \
> + mrancid mrvlogin mrvrancid fnlogin nlogin nrancid nslogin nsrancid \
> nxrancid par prancid rancid-fe rancid rivlogin rivrancid \
> rrancid srancid tlogin tntlogin tntrancid trancid xrancid \
> xrrancid zrancid lg.cgi lgform.cgi rancid-cvs rancid-run
> @@ -383,6 +383,8 @@
> cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
> mrvrancid: $(top_builddir)/config.status $(srcdir)/mrvrancid.in
> cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
> +fnlogin: $(top_builddir)/config.status $(srcdir)/fnlogin.in
> + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
> nlogin: $(top_builddir)/config.status $(srcdir)/nlogin.in
> cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
> nrancid: $(top_builddir)/config.status $(srcdir)/nrancid.in
> --- rancid-2.3.4/bin/fnlogin.in 1970-01-01 01:00:00.000000000 +0100
> +++ rancid-patch/bin/fnlogin.in 2010-10-02 08:29:48.000000000 +0200
> @@ -0,0 +1,591 @@
> +#! @EXPECT_PATH@ --
> +##
> +## $Id: fnlogin.in,v 1.51 2009/04/16 21:22:58 heas Exp $
> +## patched to accomplish fortinet from nlogin
> +## by: Daniel G. Epstein <dan at rootlike.com>
> +## adapted by: Diego Ercolani <diego.ercolani at ssis.sm>
> +##
> +## @PACKAGE@ @VERSION@
> +## Copyright (c) 1997-2009 by Terrapin Communications, Inc.
> +## All rights reserved.
> +##
> +## This code is derived from software contributed to and maintained by
> +## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan,
> +## Pete Whiting, Austin Schutz, and Andrew Fort.
> +##
> +## Redistribution and use in source and binary forms, with or without
> +## modification, are permitted provided that the following conditions
> +## are met:
> +## 1. Redistributions of source code must retain the above copyright
> +## notice, this list of conditions and the following disclaimer.
> +## 2. Redistributions in binary form must reproduce the above copyright
> +## notice, this list of conditions and the following disclaimer in the
> +## documentation and/or other materials provided with the distribution.
> +## 3. All advertising materials mentioning features or use of this software
> +## must display the following acknowledgement:
> +## This product includes software developed by Terrapin Communications,
> +## Inc. and its contributors for RANCID.
> +## 4. Neither the name of Terrapin Communications, Inc. nor the names of its
> +## contributors may be used to endorse or promote products derived from
> +## this software without specific prior written permission.
> +## 5. It is requested that non-binding fixes and modifications be contributed
> +## back to Terrapin Communications, Inc.
> +##
> +## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS
> +## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
> +## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> +## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS
> +## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> +## POSSIBILITY OF SUCH DAMAGE.
> +#
> +# The expect login scripts were based on Erik Sherk's gwtn, by permission.
> +#
> +# Netscreen hacks implemented by Stephen Gill <gillsr at yahoo.com>.
> +# Fortinet hacks by Daniel G. Epstein <dan at rootlike.com>
> +#
> +# fnlogin - fortinet login
> +#
> +# Most options are intuitive for logging into a netscreen firewall.
> +#
> +# Misc notes
> +# netscreen does not have the concept of "enable", once logged in, a
> +# users permissions can not change.
> +
> +# Usage line
> +set usage "Usage: $argv0 \[-dSV\] \[-c command\] \[-Evar=x\] \
> +\[-f cloginrc-file\] \[-p user-password\] \
> +\[-s script-file\] \[-t timeout\] \[-u username\] \
> +\[-v vty-password\] \[-x command-file\] \
> +\[-y ssh_cypher_type\] router \[router...\]\n"
> +
> +# env(CLOGIN) may contain:
> +# x == do not set xterm banner or name
> +
> +# Password file
> +set password_file $env(HOME)/.cloginrc
> +# Default is to login to the firewall
> +set do_command 0
> +set do_script 0
> +# The default is to look in the password file to find the passwords. This
> +# tracks if we receive them on the command line.
> +set do_passwd 1
> +set do_enapasswd 1
> +# Save config, if prompted
> +set do_saveconfig 0
> +
> +# Find the user in the ENV, or use the unix userid.
> +if {[ info exists env(CISCO_USER) ]} {
> + set default_user $env(CISCO_USER)
> +} elseif {[ info exists env(USER) ]} {
> + set default_user $env(USER)
> +} elseif {[ info exists env(LOGNAME) ]} {
> + set default_user $env(LOGNAME)
> +} else {
> + # This uses "id" which I think is portable. At least it has existed
> + # (without options) on all machines/OSes I've been on recently -
> + # unlike whoami or id -nu.
> + if [ catch {exec id} reason ] {
> + send_error "\nError: could not exec id: $reason\n"
> + exit 1
> + }
> + regexp {\(([^)]*)} "$reason" junk default_user
> +}
> +if {[ info exists env(CLOGINRC) ]} {
> + set password_file $env(CLOGINRC)
> +}
> +
> +# Sometimes firewall take awhile to answer (the default is 10 sec)
> +set timeout 45
> +
> +# Process the command line
> +for {set i 0} {$i < $argc} {incr i} {
> + set arg [lindex $argv $i]
> +
> + switch -glob -- $arg {
> + # Expect debug mode
> + -d* {
> + exp_internal 1
> + # Username
> + } -u* {
> + if {! [ regexp .\[uU\](.+) $arg ignore user]} {
> + incr i
> + set username [ lindex $argv $i ]
> + }
> + # VTY Password
> + } -p* {
> + if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} {
> + incr i
> + set userpasswd [ lindex $argv $i ]
> + }
> + set do_passwd 0
> + # Environment variable to pass to -s scripts
> + } -E* {
> + if {[ regexp .\[E\](.+)=(.+) $arg ignore varname varvalue]} {
> + set E$varname $varvalue
> + } else {
> + send_user "\nError: invalid format for -E in $arg\n"
> + exit 1
> + }
> + # Command to run.
> + } -c* {
> + if {! [ regexp .\[cC\](.+) $arg ignore command]} {
> + incr i
> + set command [ lindex $argv $i ]
> + }
> + set do_command 1
> + # Expect script to run.
> + } -s* {
> + if {! [ regexp .\[sS\](.+) $arg ignore sfile]} {
> + incr i
> + set sfile [ lindex $argv $i ]
> + }
> + if { ! [ file readable $sfile ] } {
> + send_user "\nError: Can't read $sfile\n"
> + exit 1
> + }
> + set do_script 1
> + # save config on exit
> + } -S* {
> + set do_saveconfig 1
> + # cypher type
> + } -y* {
> + if {! [ regexp .\[eE\](.+) $arg ignore cypher]} {
> + incr i
> + set cypher [ lindex $argv $i ]
> + }
> + # alternate cloginrc file
> + } -f* {
> + if {! [ regexp .\[fF\](.+) $arg ignore password_file]} {
> + incr i
> + set password_file [ lindex $argv $i ]
> + }
> + } -t* {
> + incr i
> + set timeout [ lindex $argv $i ]
> + } -x* {
> + if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} {
> + incr i
> + set cmd_file [ lindex $argv $i ]
> + }
> + if [ catch {set cmd_fd [open $cmd_file r]} reason ] {
> + send_user "\nError: $reason\n"
> + exit 1
> + }
> + set cmd_text [read $cmd_fd]
> + close $cmd_fd
> + set command [join [split $cmd_text \n] \;]
> + set do_command 1
> + # Version string
> + } -V* {
> + send_user "@PACKAGE@ @VERSION@\n"
> + exit 0
> + # Does tacacs automatically enable us?
> + } -autoenable {
> + # ignore autoenable
> + } -* {
> + send_user "\nError: Unknown argument! $arg\n"
> + send_user $usage
> + exit 1
> + } default {
> + break
> + }
> + }
> +}
> +# Process firewalls...no firewalls listed is an error.
> +if { $i == $argc } {
> + send_user "\nError: $usage"
> +}
> +
> +# Only be quiet if we are running a script (it can log its output
> +# on its own)
> +if { $do_script } {
> + log_user 0
> +} else {
> + log_user 1
> +}
> +
> +#
> +# Done configuration/variable setting. Now run with it...
> +#
> +
> +# Sets Xterm title if interactive...if its an xterm and the user cares
> +proc label { host } {
> + global env
> + # if CLOGIN has an 'x' in it, don't set the xterm name/banner
> + if [info exists env(CLOGIN)] {
> + if {[string first "x" $env(CLOGIN)] != -1} { return }
> + }
> + # take host from ENV(TERM)
> + if [info exists env(TERM)] {
> + if [regexp \^(xterm|vs) $env(TERM) ignore ] {
> + send_user "\033]1;[lindex [split $host "."] 0]\a"
> + send_user "\033]2;$host\a"
> + }
> + }
> +}
> +
> +# This is a helper function to make the password file easier to
> +# maintain. Using this the password file has the form:
> +# add password sl* pete cow
> +# add password at* steve
> +# add password * hanky-pie
> +proc add {var args} { global int_$var ; lappend int_$var $args}
> +proc include {args} {
> + global env
> + regsub -all "(^{|}$)" $args {} args
> + if { [ regexp "^/" $args ignore ] == 0 } {
> + set args $env(HOME)/$args
> + }
> + source_password_file $args
> +}
> +
> +proc find {var router} {
> + upvar int_$var list
> + if { [info exists list] } {
> + foreach line $list {
> + if { [string match [lindex $line 0] $router ] } {
> + return [lrange $line 1 end]
> + }
> + }
> + }
> + return {}
> +}
> +
> +# Loads the password file. Note that as this file is tcl, and that
> +# it is sourced, the user better know what to put in there, as it
> +# could install more than just password info... I will assume however,
> +# that a "bad guy" could just as easy put such code in the clogin
> +# script, so I will leave .cloginrc as just an extention of that script
> +proc source_password_file { password_file } {
> + global env
> + if { ! [file exists $password_file] } {
> + send_user "\nError: password file ($password_file) does not exist\n"
> + exit 1
> + }
> + file stat $password_file fileinfo
> + if { [expr ($fileinfo(mode) & 007)] != 0000 } {
> + send_user "\nError: $password_file must not be world readable/writable\n"
> + exit 1
> + }
> + if [ catch {source $password_file} reason ] {
> + send_user "\nError: $reason\n"
> + exit 1
> + }
> +}
> +
> +# Log into the firewall.
> +# returns: 0 on success, 1 on failure
> +proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
> + global spawn_id in_proc do_command do_script sshcmd
> + set in_proc 1
> + set uprompt_seen 0
> +
> + # Telnet to the firewall & try to login.
> + set progs [llength $cmethod]
> + foreach prog [lrange $cmethod 0 end] {
> + incr progs -1
> + if [string match "telnet*" $prog] {
> + regexp {telnet(:([^[:space:]]+))*} $prog command suffix port
> + if {"$port" == ""} {
> + set retval [ catch {spawn telnet $router} reason ]
> + } else {
> + set retval [ catch {spawn telnet $router $port} reason ]
> + }
> + if { $retval } {
> + send_user "\nError: telnet failed: $reason\n"
> + return 1
> + }
> + } elseif [string match "ssh*" $prog] {
> + regexp {ssh(:([^[:space:]]+))*} $prog methcmd suffix port
> + if {"$port" == ""} {
> + set cmd [join [lindex $sshcmd 0] " "]
> + set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user $router" { }]} reason ]
> + } else {
> + set cmd [join [lindex $sshcmd 0] " "]
> + set retval [ catch {eval spawn [split "$cmd -c $cyphertype -x -l $user -p $port $router" { }]} reason ]
> + }
> + if { $retval } {
> + send_user "\nError: $sshcmd failed: $reason\n"
> + return 1
> + }
> + } elseif ![string compare $prog "rsh"] {
> + send_error "\nError: unsupported method: rsh\n"
> + if { $progs == 0 } {
> + return 1
> + }
> + continue;
> + } else {
> + send_user "\nError: unknown connection method: $prog\n"
> + return 1
> + }
> +
> + sleep 0.3
> +
> + # This helps cleanup each expect clause.
> + expect_after {
> + timeout {
> + send_user "\nError: TIMEOUT reached\n"
> + catch {close}; catch {wait};
> + if { $in_proc} {
> + return 1
> + } else {
> + continue
> + }
> + } eof {
> + send_user "\nError: EOF received\n"
> + catch {close}; catch {wait};
> + if { $in_proc} {
> + return 1
> + } else {
> + continue
> + }
> + }
> + }
> +
> + # Here we get a little tricky. There are several possibilities:
> + # the firewall can ask for a username and passwd and then
> + # talk to the TACACS server to authenticate you, or if the
> + # TACACS server is not working, then it will use the enable
> + # passwd. Or, the firewall might not have TACACS turned on,
> + # then it will just send the passwd.
> + # if telnet fails with connection refused, try ssh
> + expect {
> + -re "(Connection refused|Secure connection \[^\n\r]+ refused)" {
> + catch {close}; catch {wait};
> + if !$progs {
> + send_user "\nError: Connection Refused ($prog): $router\n"
> + return 1
> + }
> + }
> + -re "(Connection closed by|Connection to \[^\n\r]+ closed)" {
> + catch {close}; catch {wait};
> + if !$progs {
> + send_user "\nError: Connection closed ($prog): $router\n"
> + return 1
> + }
> + }
> + eof { send_user "\nError: Couldn't login: $router\n"; wait; return 1 }
> + -nocase "unknown host\r" {
> + send_user "\nError: Unknown host $router\n";
> + catch {close}; catch {wait};
> + return 1
> + }
> + "Host is unreachable" {
> + send_user "\nError: Host Unreachable: $router\n";
> + catch {close}; catch {wait};
> + return 1
> + }
> + "No address associated with name" {
> + send_user "\nError: Unknown host $router\n";
> + catch {close}; catch {wait};
> + return 1
> + }
> + -re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
> + send "yes\r"
> + send_user "\nHost $router added to the list of known hosts.\n"
> + exp_continue }
> + -re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?" {
> + send "no\r"
> + send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n"
> + catch {close}; catch {wait};
> + return 1
> + }
> + -re "Offending key for .* \(yes\/no\)\?" {
> + send "no\r"
> + send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n"
> + catch {close}; catch {wait};
> + return 1
> + }
> + -re "(denied|Sorry)" {
> + send_user "\nError: Check your passwd for $router\n"
> + catch {close}; catch {wait}; return 1
> + }
> + "Login failed" {
> + send_user "\nError: Check your passwd for $router\n";
> + catch {close}; catch {wait}; return 1
> + }
> + -re "(login:)" {
> + sleep 1;
> + send -- "$user\r"
> + set uprompt_seen 1
> + exp_continue
> + }
> + -re "@\[^\r\n]+\[Pp]assword:" {
> + # ssh pwd prompt
> + sleep 1
> + send -- "$userpswd\r"
> + exp_continue
> + }
> + "\[Pp]assword:" {
> + sleep 1;
> + if {$uprompt_seen == 1} {
> + send -- "$userpswd\r"
> + } else {
> + send -- "$passwd\r"
> + }
> + exp_continue
> + }
> + -- "$prompt" { break; }
> + }
> + }
> + set in_proc 0
> + return 0
> +}
> +
> +# Run commands given on the command line.
> +proc run_commands { prompt command } {
> + global in_proc
> + set in_proc 1
> +
> + # Disable output paging.
> + send -- "config system console\r"
> + expect -re $prompt; send -- "set output standard\r"
> + expect -re $prompt; send -- "end\r"
> + expect -re $prompt;
> +
> + set commands [split $command \;]
> + set num_commands [llength $commands]
> + for {set i 0} {$i < $num_commands} { incr i} {
> + send -- "[subst [lindex $commands $i]]\r"
> +# send_user "**************** [subst [lindex $commands $i]] ************\n"
> + expect {
> + -re "$prompt" { send "\r"
> + sleep 0.5
> + }
> + -gl "--More--" { send " "
> + exp_continue
> + -re "\[\n\r]+" { exp_continue }
> + }
> + }
> + }
> +# send_user "******* fuori da ciclo for *******\n"
> + expect {
> + -re "$prompt$" {
> + send "exit\r"
> + sleep 0.5
> + exp_continue
> + }
> + -re "\[\n\r]+" { exp_continue }
> + -gl "Configuration modified, save?" {
> + send "n\r"
> + exp_continue
> + }
> + timeout { catch {close}; catch {wait};
> + return 0
> + }
> + eof { return 0 }
> + }
> + set in_proc 0
> +}
> +
> +#
> +# For each firewall... (this is main loop)
> +#
> +source_password_file $password_file
> +set in_proc 0
> +set exitval 0
> +foreach router [lrange $argv $i end] {
> + set router [string tolower $router]
> + send_user "$router\n"
> +
> + # FortiOS 2.x prompts can end in either '#' or '$'
> + set prompt "\[#\\$] "
> +
> + # Figure out passwords
> + if { $do_passwd || $do_enapasswd } {
> + set pswd [find password $router]
> + if { [llength $pswd] == 0 } {
> + send_user "\nError: no password for $router in $password_file.\n"
> + continue
> + }
> + set passwd [join [lindex $pswd 0] ""]
> + set enapasswd [join [lindex $pswd 1] ""]
> + } else {
> + set passwd $userpasswd
> + set enapasswd $enapasswd
> + }
> +
> + # Figure out username
> + if {[info exists username]} {
> + # command line username
> + set ruser $username
> + } else {
> + set ruser [join [find user $router] ""]
> + if { "$ruser" == "" } { set ruser $default_user }
> + }
> +
> + # Figure out username's password (if different from the vty password)
> + if {[info exists userpasswd]} {
> + # command line username
> + set userpswd $userpasswd
> + } else {
> + set userpswd [join [find userpassword $router] ""]
> + if { "$userpswd" == "" } { set userpswd $passwd }
> + }
> +
> +
> + # Figure out cypher type
> + if {[info exists cypher]} {
> + # command line cypher type
> + set cyphertype $cypher
> + } else {
> + set cyphertype [find cyphertype $router]
> + if { "$cyphertype" == "" } { set cyphertype "3des" }
> + }
> +
> + # Figure out connection method
> + set cmethod [find method $router]
> + if { "$cmethod" == "" } { set cmethod {{telnet} {ssh}} }
> +
> + # Figure out the SSH executable name
> + set sshcmd [find sshcmd $router]
> + if { "$sshcmd" == "" } { set sshcmd {ssh} }
> +
> + # Login to the router
> + if {[login $router $ruser $userpswd $passwd $enapasswd $prompt $cmethod $cyphertype]} {
> + incr exitval
> + continue
> + }
> +
> + # we are logged in, now figure out the full prompt based on what the device sends us.
> + send "\r"
> + expect {
> + -re "\[\r\n]+" { exp_continue; }
> + -re "^(.+$prompt)" { set junk $expect_out(0,string); }
> + if {[$junk = "(^\\$ $)"]} {
> + set prompt $junk;
> + } else {
> + if {[$junk = "(^# $)"]} { set prompt $junk ; }
> + };
> + }
> +
> + if { $do_command } {
> + if {[run_commands $prompt $command]} {
> + incr exitval
> + continue
> + }
> + } elseif { $do_script } {
> + # Disable output paging.
> + send "config system console\r"
> + send "set output standard\r"
> + send "end\r"
> + expect -re $prompt {}
> + source $sfile
> + catch {close};
> + } else {
> + label $router
> + log_user 1
> + interact
> + }
> +
> + # End of for each firewall
> + catch {wait};
> + sleep 0.3
> +}
> +exit $exitval
> +
> --- rancid-2.3.4/bin/fnrancid.in 2010-10-02 08:31:34.000000000 +0200
> +++ rancid-patch/bin/fnrancid.in 2010-10-02 08:29:48.000000000 +0200
> @@ -48,6 +48,7 @@
> # usage: rancid [-dV] [-l] [-f filename | hostname]
> #
> use Getopt::Std;
> +use Data::Dumper;
> getopts('dflV');
> if ($opt_V) {
> print "@PACKAGE@ @VERSION@\n";
> @@ -59,10 +60,11 @@
> $file = $opt_f;
> $host = $ARGV[0];
> $found_end = 0;
> -$timeo = 90; # nlogin timeout in seconds
> +$timeo = 90; # fnlogin timeout in seconds
>
> my(@commandtable, %commands, @commands);# command lists
> my($aclsort) = ("ipsort"); # ACL sorting mode
> +$aclsort = ""; # disable sort
> my($filter_commstr); # SNMP community string filtering
> my($filter_pwds); # password filtering mode
>
> @@ -174,10 +176,35 @@
> tr/\015//d;
> next if /^\s*$/;
> last if (/$prompt/);
> -
> next if (/^System Time:/);
> next if (/^FortiClient application signature package:/);
> - ProcessHistory("","","","$_");
> + if(/^\s*(System time:) (.*)/) {
> + ProcessHistory("System time","","","$1 ****removed****");
> + #print STDERR "!$1 ****removed****\n";
> + next;
> + }
> + if(/^\s*(Virus-DB:) (.*)/) {
> + ProcessHistory("$1","","","$1 ****removed****\n");
> + #print STDERR "!$1 ****removed****\n";
> + next;
> + }
> + if(/^\s*(Extended DB:) (.*)/) {
> + ProcessHistory("$1","","","$1 ****removed****\n");
> + #print STDERR "!$1 ****removed****\n";
> + next;
> + }
> + if(/^\s*(IPS-DB:) (.*)/) {
> + ProcessHistory("$1","","","$1 ****removed****\n");
> + #print STDERR "!$1 ****removed****\n";
> + next;
> + }
> + if(/^get system status/) {
> + # sometimes compare on the console so filter out
> + next;
> + }
> + # - Comment system info in file with '!'.
> + ProcessHistory("","","","!$_");
> +
> }
> ProcessHistory("SYSTEM","","","\n");
> return(0);
> @@ -197,11 +224,22 @@
> while (<INPUT>) {
> tr/\015//d;
> next if /^\s*$/;
> + next if(/^\s*!System time:/); # System time is fortigate extraction time so remove it
> + # remove occurrances of conf_file_ver
> + if ( /^\s*(#conf_file_ver=)([0-9]+)(.*)/i && $filter_pwds >0 ) {
> + #print STDERR "removed serial number -->!$1$2$3\n";
> + ProcessHistory("conf_file_ver","","","!$1**removed**$3\n");
> + next;
> + }
> last if (/$prompt/);
>
> next if (/^conf_file_ver=/);
> - if (/(^set.*)('Enc .*')(.*)/) {
> - ProcessHistory("ENC","","","!$1 'Enc **encoding removed**' $3\n");
> + # Remove all the variability from the configuration versions
> + # if filter_pwds is enabled, filter out also variabilities between configurations
> + # password encription is different between extraction so filtering out encoding
> + if ( /^\s*(set [^\s]*)\s(Enc\s[^\s]+)(.*)/i && $filter_pwds >0 ) {
> + # print STDERR "removed password-->!$1 ENC **encoding removed** $3\n";
> + ProcessHistory("ENC","","","!$1 ENC **encoding removed**' $3\n");
> next;
> }
> ProcessHistory("","","","$_");
> @@ -216,7 +254,7 @@
> # Main
> @commandtable = (
> {'get system status' => 'GetSystem'},
> - {'get conf' => 'GetConf'}
> + {'show full-configuration' => 'GetConf'}
> );
> # Use an array to preserve the order of the commands and a hash for mapping
> # commands to the subroutine and track commands that have been completed.
> @@ -245,13 +283,13 @@
> print STDOUT "opening file $host\n" if ($log);
> open(INPUT,"<$host") || die "open failed for $host: $!\n";
> } else {
> - print STDERR "executing nlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
> - print STDOUT "executing nlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
> + print STDERR "executing fnlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
> + print STDOUT "executing fnlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
> if (defined($ENV{NOPIPE})) {
> - system "nlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "nlogin failed for $host: $!\n";
> + system "fnlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "nlogin failed for $host: $!\n";
> open(INPUT, "< $host.raw") || die "nlogin failed for $host: $!\n";
> } else {
> - open(INPUT,"nlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "nlogin failed for $host: $!\n";
> + open(INPUT,"fnlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "nlogin failed for $host: $!\n";
> }
> }
>
> @@ -279,14 +317,34 @@
> TOP: while(<INPUT>) {
> tr/\015//d;
> if (/^Error:/) {
> - print STDOUT ("$host nlogin error: $_");
> - print STDERR ("$host nlogin error: $_") if ($debug);
> + print STDOUT ("$host fnlogin error: $_");
> + print STDERR ("$host fnlogin error: $_") if ($debug);
> last;
> }
> - while (/>\s*($cmds_regexp)\s*$/) {
> - $cmd = $1;
> - if (!defined($prompt)) { $prompt = " >\s*"; }
> - print STDERR ("HIT COMMAND:$_") if ($debug);
> + while (/^.+(#|\$)\s*($cmds_regexp)\s*$/) {
> + $cmd = $2;
> + # - FortiGate prompts end with either '#' or '$'. Further, they may
> + # be prepended with a '~' if the hostname is too long. Therefore,
> + # we need to figure out what our prompt really is.
> + if (!defined($prompt)) {
> + if ( $_ =~ m/^.+\~\$/ ) {
> + $prompt = '\~\$ .*' ;
> + } else {
> + if ( $_ =~ m/^.+\$/ ) {
> + $prompt = ' \$ .*' ;
> + } else {
> + if ( $_ =~ m/^.+\~#/ ) {
> + $prompt = '\~# .*' ;
> + } else {
> + if ( $_ =~ m/^.+#/ ) {
> + $prompt = ' # .*' ;
> + }
> + }
> + }
> + }
> + }
> + print STDERR ("HIT COMMAND:$_") if ($debug);
> +
> if (!defined($commands{$cmd})) {
> print STDERR "$host: found unexpected command - \"$cmd\"\n";
> last TOP;
> --- rancid-2.3.4/configure 2010-10-02 08:31:58.000000000 +0200
> +++ rancid-patch/configure 2010-10-02 08:29:49.000000000 +0200
> @@ -6042,7 +6042,7 @@
>
> ac_config_files="$ac_config_files bin/flogin bin/francid"
>
> -ac_config_files="$ac_config_files bin/fnrancid"
> +ac_config_files="$ac_config_files bin/fnlogin bin/fnrancid"
>
> ac_config_files="$ac_config_files bin/hlogin bin/hrancid"
>
More information about the Rancid-discuss
mailing list