[rancid] [PATCH] Fortinet RANCID Patches
Daniel G. Epstein
dan at rootlike.com
Wed May 23 00:04:34 UTC 2007
Greetings all,
I recently had a need to get rancid-2.3.2a6 working with a set of
reasonably current Fortinet devices (running FortiOS 2.8 and 3.0). To do
this, I hacked together the attached patches to 'rancid-fe', 'nlogin'
(now 'fnlogin'), and 'fnrancid'. Work was done on a Debian Etch system
with a patched version of expect-5.43 and rancid-2.3.2a6.
Please note that a) I make no claims to be an outstanding programmer,
b) this was my first go with Tk/expect, and c) I have not had (nor will
I have) opportunity for widespread testing of these patches against
Fortinet hardware. If one uses these patches, it is at the user's own
risk. Comments/corrections are more than welcome.
Cheers,
Dan
--
A boast of "I have beens," | Daniel G. Epstein
quoted from foolscap tomes, | Audio Engineer
is a shadow brushed away |
by an acorn from an oak tree | Rootlike Technologies, Inc.
or a salmon in a pool. | http://www.rootlike.com/
GnuPG public keys available from http://pgp.mit.edu/
-------------- next part --------------
--- rancid-fe.orig 2007-05-22 18:09:51.000000000 -0500
+++ rancid-fe 2007-05-22 18:09:51.000000000 -0500
@@ -42,6 +42,7 @@
'extreme' => 'xrancid',
'ezt3' => 'erancid',
'force10' => 'f10rancid',
+ 'fortinet' => 'fnrancid',
'foundry' => 'francid',
'hitachi' => 'htrancid',
'hp' => 'hrancid',
-------------- next part --------------
--- nlogin 2007-05-22 17:46:58.000000000 -0500
+++ fnlogin 2007-05-22 17:46:53.000000000 -0500
@@ -1,7 +1,5 @@
#! /usr/local/bin/expect --
##
-## $Id: nlogin.in,v 1.32 2006/12/05 16:50:52 heas Exp $
-##
## rancid 2.3.2a6
## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
@@ -23,7 +21,10 @@
# The login expect scripts were based on Erik Sherk's gwtn, by permission.
# Netscreen hacks implemented by Stephen Gill <gillsr at yahoo.com>.
#
-# nlogin - netscreen login
+# FortiOS 2.x hacks implemented by Daniel G. Epstein <dan at rootlike.com>.
+# Tue May 22 17:41:04 CDT 2007 - dan at rootlike.com
+#
+# fnlogin - Fortinet login
#
# Most options are intuitive for logging into a netscreen firewall.
#
@@ -386,9 +387,13 @@
global in_proc
set in_proc 1
- send "set console page 0\r"
+ # Disable output paging.
+ send "config system console\r"
+ send "set output standard\r"
+ send "end\r"
expect -re $prompt {}
+
# Is this a multi-command?
if [ string match "*\;*" "$command" ] {
set commands [split $command \;]
@@ -399,7 +404,7 @@
expect {
-re "\[\n\r]+" { exp_continue }
-re "$prompt" {}
- -gl "--- more ---" { send " "
+ -gl "--More--" { send " "
exp_continue
}
}
@@ -409,7 +414,7 @@
expect {
-re "\[\n\r]+" { exp_continue }
-re "$prompt" {}
- -gl "--- more ---" { send " "
+ -gl "--More--" { send " "
exp_continue
}
}
@@ -442,7 +447,9 @@
set firewall [string tolower $firewall]
send_user "$firewall\n"
- set prompt {-> }
+ # FortiOS 2.x prompts can end in either '#' or '$'
+ set prompt "\[#\\$]"
+
# Figure out passwords
if { $do_passwd || $do_enapasswd } {
@@ -496,15 +503,16 @@
continue
}
- # we are logged in, now figure out the full prompt
+ # 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 it has HA (high avail), the prompt will
- # be "something-(.)->"
- regsub -all "\[\]\)\(\[]" $junk {\\&} prompt;
- }
+ if {[$junk = "(^\\$ $)"]} {
+ set prompt $junk;
+ } else {
+ if {[$junk = "(^# $)"]} { set prompt $junk ; }
+ }
}
if { $do_command } {
@@ -512,7 +520,10 @@
continue
}
} elseif { $do_script } {
- send "set console page 0\r"
+ # Disable output paging.
+ send "config system console\r"
+ send "set output standard\r"
+ send "end\r"
expect -re $prompt {}
source $sfile
close
-------------- next part --------------
--- fnrancid.orig 2007-05-22 17:47:15.000000000 -0500
+++ fnrancid 2007-05-22 17:47:07.000000000 -0500
@@ -1,7 +1,5 @@
#! /usr/bin/perl
##
-## $Id: fnrancid.in,v 1.11 2006/10/05 04:27:42 heas Exp $
-##
## rancid 2.3.2a6
## Copyright (C) 1997-2006 by Terrapin Communications, Inc.
## All rights reserved.
@@ -23,10 +21,16 @@
# A library built on Stephen Gill's Netscreen stuff to accomodate
# the Fortinet product line. [d_pfleger at juniper.net]
#
+## Tue May 22 17:39:47 CDT 2007 - dan at rootlike.com
+## - Changed all instances of 'nlogin' to 'fnlogin' as a fork was needed to
+## handle newer FortiOS (>2.0) differences.
+## - Also modified handling of system prompts and commenting of system stats.
+#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: rancid [-dV] [-l] [-f filename | hostname]
#
+#
use Getopt::Std;
getopts('dflV');
if ($opt_V) {
@@ -39,7 +43,7 @@
$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(%filter_pwds); # password filtering mode
@@ -152,7 +156,8 @@
tr/\015//d;
next if /^\s*$/;
last if(/$prompt/);
- ProcessHistory("","","","$_");
+ # - Comment system info in file with '!'.
+ ProcessHistory("","","","!$_");
#print STDOUT "$_";
}
print STDOUT "Vendor: $vendor";
@@ -192,7 +197,7 @@
# Main
@commandtable = (
{'get system status' => 'GetSystem'},
- {'get conf' => 'GetConf'}
+ {'show' => '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.
@@ -220,13 +225,13 @@
print STDERR "opening file $host\n" if ($debug);
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";
- open(INPUT, "< $host.raw") || die "nlogin failed for $host: $!\n";
+ system "fnlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "fnlogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "fnlogin 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 "fnlogin failed for $host: $!\n";
}
}
@@ -243,13 +248,32 @@
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*"; }
+ 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";
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://www.shrubbery.net/pipermail/rancid-discuss/attachments/20070522/c9682866/attachment.bin
More information about the Rancid-discuss
mailing list