[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