[rancid] Re: Understand some regex used in rancid
Lance Vermilion
rancid at gheek.net
Fri Nov 14 15:32:13 UTC 2008
Gregory,
You need to set autoenable for that device inside your ".cloginrc".
The IP puts you in privilege 15 when you login. I am guessing you do
not have that specified so rancid is trying to enable.
2008/11/14 Gregory W Zill <gregoryzill at solutionary.com>:
> I get what appears to be a second user inputted somehow. Have you seen this?
> How might I fix? This is a 4215 IPS.
>
> $ clogin test_cisco_ips6
> test_cisco_ips6
> spawn ssh -c 3des -x -l cisco test_cisco_ips6
>
> Password:
> Last login: Fri Nov 14 09:07:54 2008 from 10.1.1.107
>
> cisco
> test_cisco_ips6# cisco
> ^
> % Invalid input detected at '^' marker
>
>
> BTW, the ipsrancid is great -- thank you
>
> Thx Max and John.
>
> As for making rancid work with IPS modules I have found that the post
> from Jeremy M. Guthrie
> "http://www.shrubbery.net/pipermail/rancid-discuss/2007-May/002209.html"
> does very well and doesn't require making a lot of changes to rancid
> to handle the errors that happen if you run too many commands that are
> invalid commands. I also eliminated the need for his ipslogin. I
> simply just had perl set the TERM to vt100 before it ran clogin and
> then set the TERM back to network after it was finished running
> clogin. I also fixed some typo's he had where it was the work "at"
> instead of "@". I fixed what should be skipped for the ShowVersion as
> it had some extra stuff that can change.
>
> Here is a copy of what I put on my webpage. http://www.gheek.net/?p=78
>
> In order to get rancid to collect the config from an IPS module you
> will need to make sure you have the correct login creds in the rancid
> users ".cloginrc", add the type of ips to "rancid-fe" and you also
> need to create the "ipsrancid" script.
>
> Changes required for "rancid-fe"
> 'ips' => 'ipsrancid',
>
> Create the "ipsrancid" script as "<rancid_home>/bin/ipsrancid". Make
> sure you "chmod 755 <rancid_home>/bin/ipsrancid" and "chown
> <rancid_user>:<rancid_user> <rancid_home>/bin/ipsrancid".
> #! /usr/bin/perl
> ##
> ## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
> ## All rights reserved.
> ##
> ## This software may be freely copied, modified and redistributed
> ## without fee for non-commerical purposes provided that this license
> ## remains intact and unmodified with any RANCID distribution.
> ##
> ## There is no warranty or other guarantee of fitness of this software.
> ## It is provided solely "as is". The author(s) disclaim(s) all
> ## responsibility and liability with respect to this software's usage
> ## or its effect upon hardware, computer systems, other software, or
> ## anything else.
> ##
> ## Except where noted otherwise, rancid was written by and is maintained by
> ## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin
> Schutz.
> ##
> #
> # hacked version of Hank's rancid - this one tries to deal with Hitachi's.
> #
> # Modified again by Lance Vermilion (11/13/08)
> # Modified from htrancid by Jeremy M. Guthrie
> # Created on 5/4/2007
> #
> # This is meant to try handle Cisco's IPS V5.X line and on
> #
> # RANCID - Really Awesome New Cisco confIg Differ
> #
> # usage: ipsrancid [-d] [-l] [-f filename | $host]
> use Getopt::Std;
> getopts('dfl');
> $log = $opt_l;
> $debug = $opt_d;
> $file = $opt_f;
> $host = $ARGV[0];
> $clean_run = 0;
> $found_end = 0;
> $timeo = 90; # clogin timeout in seconds
> my(@commandtable, %commands, @commands);# command lists
> my(%filter_pwds); # password filtering mode
>
> # This routine is used to print out the router configuration
> sub ProcessHistory {
>
> ($new_hist_tag,$new_command,$command_string, @string) = (@_);
> if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
> && defined %history) {
> print eval "$command \%history";
> undef %history;
> }
> if (($new_hist_tag) && ($new_command) && ($command_string)) {
> if ($history{$command_string}) {
> $history{$command_string} = "$history{$command_string}@string";
> } else {
> $history{$command_string} = "@string";
> }
> } elsif (($new_hist_tag) && ($new_command)) {
> $history{++$#history} = "@string";
> } else {
> print "@string";
> }
> $hist_tag = $new_hist_tag;
> $command = $new_command;
> 1;
> }
>
> sub numerically { $a <=> $b; }
>
> # This is a sort routine that will sort numerically on the
> # keys of a hash as if it were a normal array.
> sub keynsort {
> local(%lines) = @_;
> local($i) = 0;
> local(@sorted_lines);
> foreach $key (sort numerically keys(%lines)) {
> $sorted_lines[$i] = $lines{$key};
> $i++;
> }
> @sorted_lines;
> }
>
> # This is a sort routine that will sort on the
> # keys of a hash as if it were a normal array.
> sub keysort {
> local(%lines) = @_;
> local($i) = 0;
> local(@sorted_lines);
> foreach $key (sort keys(%lines)) {
> $sorted_lines[$i] = $lines{$key};
> $i++;
> }
> @sorted_lines;
> }
>
> # This is a sort routine that will sort on the
> # values of a hash as if it were a normal array.
> sub valsort{
> local(%lines) = @_;
> local($i) = 0;
> local(@sorted_lines);
> foreach $key (sort values %lines) {
> $sorted_lines[$i] = $key;
> $i++;
> }
> @sorted_lines;
> }
>
> # This is a numerical sort routine (ascending).
> sub numsort {
> local(%lines) = @_;
> local($i) = 0;
> local(@sorted_lines);
> foreach $num (sort {$a <=> $b} keys %lines) {
> $sorted_lines[$i] = $lines{$num};
> $i++;
> }
> @sorted_lines;
> }
>
> # This is a sort routine that will sort on the
> # ip address when the ip address is anywhere in
> # the strings.
> sub ipsort {
> local(%lines) = @_;
> local($i) = 0;
> local(@sorted_lines);
> foreach $addr (sort sortbyipaddr keys %lines) {
> $sorted_lines[$i] = $lines{$addr};
> $i++;
> }
> @sorted_lines;
> }
>
> # These two routines will sort based upon IP addresses
> sub ipaddrval {
> my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
> $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
> }
> sub sortbyipaddr {
> &ipaddrval($a) <=> &ipaddrval($b);
> }
>
> # This routine parses "show config"
> sub ShowConfig {
> print STDERR " In ShowConfig: $_" if ($debug);
>
> $firstexit=0;
>
> while (<INPUT>) {
> tr/\015//d;
> tr/\020//d;
>
> #strip out the stupid spinning running-config progress thingy
> s/Generating current config: \.*[\|\/\-\\]//gi;
> $skipprocess=0;
>
> #sometimes an 'exit' appears at the top of the config, we
> don't want them
> if ( (/^exit/) && ( ! $firstexit ) ) {
> $firstexit=1;
> $skipprocess=1;
> }
>
> #remove spaces left over from lame spinning progress thingy
> if ( /^\s+! ――――――――――/ ) {
> s/^\s+!/!/g
> }
>
> if (/^(read-only-community) / && $filter_pwds >= 1) {
> ProcessHistory("","","","!$1 <removed>\n"); next;
> }
> if (/^(read-write-community) / && $filter_pwds >= 1) {
> ProcessHistory("","","","!$1 <removed>\n"); next;
> }
> if (/^(trap-community-name) / && $filter_pwds >= 1) {
> ProcessHistory("","","","!$1 <removed>\n"); next;
> }
> if (/^(ntp-keys \d+ md5-key) / && $filter_pwds >= 1) {
> ProcessHistory("","","","!$1 <removed>\n"); next;
> }
> if (/^(password) / && $filter_pwds >= 1) {
> ProcessHistory("","","","!$1 <removed>\n"); next;
> }
>
> last if (/^$prompt/);
> next if (/^(\s*|\s*$cmd\s*)$/);
> if ( ! /^$prompt/) {
> if ( ! $skipprocess ) {
> print STDOUT " ShowConfig Data: $_" if
> ($debug);
> ProcessHistory("","","","$_");
> }
> }
> }
> $clean_run=1;
> print STDERR " Exiting ShowConfig: $_" if ($debug);
> return(0);
> }
>
> # This routine parses single command's that return no required info
> sub ShowVersion {
> print STDERR " In ShowVersion: $_" if ($debug);
> ProcessHistory("","","","!\n!IPS Show Version Start\n");
>
> while (<INPUT>) {
> tr/\015//d;
>
> $skipprocess=0;
>
> if ( /^Sensor up-time/ ) { $skipprocess=1; }
> if ( ( /using.*bytes of available/i ) ) { $skipprocess=1; }
>
> last if (/^$prompt/);
> next if (/^(\s*|\s*$cmd\s*)$/);
> if ( ! /^$prompt/) {
> if ( ! $skipprocess ) {
> print STDOUT " ShowVersion Data: $_" if
> ($debug);
> ProcessHistory("","","","! $_");
> }
> }
> }
> ProcessHistory("","","","!\n!IPS Show Version End\n");
> print STDERR " Exiting ShowVersion: $_" if ($debug);
> return(0)
> }
>
> # This routine parses single command's that return no required info
> sub ShowUsersAll {
> print STDERR " In ShowUsersAll: $_" if ($debug);
> ProcessHistory("","","","!\n!IPS User Database Start\n");
>
> while (<INPUT>) {
> tr/\015//d;
>
> $skipprocess=0;
>
> s/^ CLI ID //g;
> s/^ //g;
> s/^\* +[0-9]+ +//g;
>
> last if (/^$prompt/);
> next if (/^(\s*|\s*$cmd\s*)$/);
> if ( ! /^$prompt/) {
> if ( ! $skipprocess ) {
> print STDOUT " ShowUsersAll Data: $_" if
> ($debug);
> ProcessHistory("","","","!$_");
> }
> }
> }
> ProcessHistory("","","","!\n!IPS User Database End\n!\n!\n");
> print STDERR " Exiting ShowUsersAll: $_" if ($debug);
> return(0)
> }
>
> # dummy function
> sub DoNothing {print STDOUT;}
>
> # Main
> @commandtable = (
> {'show version' => 'ShowVersion'},
> {'show users all' => 'ShowUsersAll'},
> {'show configuration' => 'ShowConfig'}
> );
> # 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.
> @commands = map(keys(%$_), @commandtable);
> %commands = map(%$_, @commandtable);
>
> $cisco_cmds=join(";", at commands);
> $cmds_regexp=join("|", at commands);
>
> open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
> select(OUTPUT);
> # make OUTPUT unbuffered if debugging
> if ($debug) { $| = 1; }
>
> # The IPS doesn't like the TERM of network so we must change it
> if ( $ENV{TERM} eq 'network' ) {
> $ENV{TERM} = 'vt100′;
> }
> if ($file) {
> 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 clogin -t $timeo -c\"$cisco_cmds\"
> $host\n" if ($debug);
> print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\"
> $host\n" if ($log);
> if (defined($ENV{NOPIPE})) {
> system "clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null >
> $host.raw 2>&1" || die "clogin failed for $host: $!\n";
> open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
> } else {
> open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host
> </dev/null |") || die "clogin failed for $host: $!\n";
> }
> }
> # Change the TERM back to network
> if ( $ENV{TERM} eq 'vt100′ ) {
> $ENV{TERM} = 'network';
> }
>
> # determine password filtering mode
> if ($ENV{"FILTER_PWDS"} =~ /no/i) {
> $filter_pwds = 0;
> } elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
> $filter_pwds = 2;
> } else {
> $filter_pwds = 1;
> }
>
> ProcessHistory("","","","!RANCID-CONTENT-TYPE: ipsrancid\n!\n");
> TOP: while(<INPUT>) {
> tr/\015//d;
>
> #strip out the stupid spinning running-config progress thingy
> s/Generating current config: \.*[\|\/\-\\]//gi;
>
> if (/^.*logout$/) {
> $clean_run=1;
> last;
> }
> if (/^Error:/) {
> print STDOUT ("$host clogin error: $_");
> print STDERR ("$host clogin error: $_") if ($debug);
> $clean_run=0;
> last;
> }
> while (/($cmds_regexp)/) {
> $cmd = $1;
> if (!defined($prompt)) {
> $prompt = ($_ =~ /^([^#]+#)/)[0];
> $prompt =~ s/([][}{)(\\])/\\$1/g;
> print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
> }
> print STDERR ("IPS COMMAND:$_") if ($debug);
> if (! defined($commands{$cmd})) {
> print STDERR "$host: found unexpected command - \"$cmd\"\n";
> $clean_run = 0;
> last TOP;
> }
> $rval = &{$commands{$cmd}};
> delete($commands{$cmd});
> if ($rval == -1) {
> $clean_run = 0;
> last TOP;
> }
> }
> }
> print STDOUT "Done $logincmd: $_\n" if ($log);
> # Flush History
> ProcessHistory("","","","");
> # Cleanup
> close(INPUT);
> close(OUTPUT);
>
> if (defined($ENV{NOPIPE})) {
> unlink("$host.raw") if (! $debug);
> }
>
> # check for completeness
> if (scalar(%commands) || !$clean_run ) {
> if (scalar(%commands)) {
> printf(STDOUT "$host: missed cmd(s): %s\n", join(',',
> keys(%commands)));
> printf(STDERR "$host: missed cmd(s): %s\n", join(',',
> keys(%commands))) if ($debug);
> }
> if (!$clean_run ) {
> print STDOUT "$host: End of run not found\n";
> print STDERR "$host: End of run not found\n" if ($debug);
> system("/usr/bin/tail -1 $host.new");
> }
> unlink "$host.new" if (! $debug);
> }
>
> On Wed, Nov 12, 2008 at 11:53 PM, john heasley <heas at shrubbery.net> wrote:
>
>
> Wed, Nov 12, 2008 at 05:36:50PM -0700, Lance Vermilion:
>
>
> I don't understand what this is meaning. i have searched around but
> still can't figure out what the # sign is used for in perl regex like
> it is being used here.
>
> while (/#\s*($cmds_regexp)\s*$/) {
>
>
> the # is a #, the end of the enabled user's prompt.
>
>
>
> If I can figure this out then I will have the IPS module working for
> rancid using the default clogin/rancid with only minor tweaks.
> _______________________________________________
> Rancid-discuss mailing list
> Rancid-discuss at shrubbery.net
> http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
>
>
> _______________________________________________
> Rancid-discuss mailing list
> Rancid-discuss at shrubbery.net
> http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
>
>
> --
>
> Gregory W Zill, MBA, CISSP
> Information Security Engineer
> Phone: 402-361-3066
> Email: gregoryzill at solutionary.com
> Making Security Manageable
> ________________________________
> ActiveGuard(R) and SecurCompass(R) are recognized excellence award winners by SC
> Magazine and InfoSecurity Products Guide.
>
> Confidentiality Notice: The content of this communication, along with any
> attachments, is covered by federal and state law governing electronic
> communications and may contain confidential and legally privileged
> information. If the reader of this message is not the intended recipient,
> you are hereby notified that any dissemination, distribution, use or copying
> of the information contained herein is strictly prohibited. If you have
> received this communication in error, please immediately contact us by
> telephone at 402.361.3000 or e-mail security at solutionary.com. Thank you.
>
> Copyright 2000-2008, Solutionary, Inc. All rights reserved. ActiveGuard,
> SecurCompass, Solutionary and the Solutionary logo are registered marks of
> Solutionary, Inc. SecurComply is a service mark of Solutionary, Inc.
More information about the Rancid-discuss
mailing list