Spectrum users,

I know I have a seen a lot of requests for Perl scripts to allow the use
of SSH to pull down the configs from ASA and Pix's. I'm not done yet,
but I have a functional module for capture startup configs. I've
attached that to this email for everyone to see how I went about it..

Me and a few of the other students here are working on getting the other
scripts working using SSH and making sure they fail gracefully and give
the right error codes etc. I'll provide those as we have them working.
This script may also receive revisions, but hopefully it's enough to get
some people started on config captures for these devices.

Let me know if anyone has any questions for the time being. I'm sure
once we have these done that Christian will throw them up on the Wiki too.
-- 
Brett Davis, CCNA, GSEC
IT Security Engineer
Purdue University
YONG 602
Phone (765) 49-62304
[email protected]
#!/opt/Spectrum/bin/perl -w

# This script will capture the startup configuration of a
# Cisco PIX OS device and print it to STDOUT.
#
# Error Codes:
#   0   = Success
#   255 = Usage error
#   254 = Invalid timeout value
#   252 = Connection error
#   251 = Login error
#   249 = Enable error
#   244 = Error retrieving configuration
#   253 = Unexpected output
#

use strict;
use warnings;
use Net::SSH::Expect;

### Main ###
if( $#ARGV != 4 && $#ARGV != 5 )
{
    print "Usage: capture_startup.pl <device IP> <user> <pass> <enable_pass> 
<login_timeout_in_seconds> <capture_timeout_in_seconds>\n";
    print STDERR "Usage:  capture_startup.pl <deviceIP> <user> <pass> 
<enable_pass> <login_timeout_in_seconds> <capture_timeout_in_seconds>\n";
    exit 255;
}
elsif( $ARGV[4] < 1 || $ARGV[4] > 600 )
{
    print "$ARGV[4] is the login timeout and must be an int between 1 and 600 
seconds\n";
    print STDERR "$ARGV[4] is the login timeout and must be an int between 1 
and 600 seconds\n";
    exit 254;
}
elsif( $#ARGV == 5 && ( $ARGV[5] < 1 || $ARGV[5] > 600 ) )
{
    print "$ARGV[5] is the capture timeout and must be an int between 1 and 600 
seconds\n";
    print STDERR "$ARGV[5] is the capture timeout and must be an int between 1 
and 600 seconds\n";
    exit 254;
}
else
{
    my $capture_timeout = $ARGV[4];
    if( $ARGV[5] )
    {
       $capture_timeout = $ARGV[5];
    }

    my $errorCode = 1;
    my @data;
    my $errorString = "\nHost $ARGV[0]:  \n";

    ($errorCode,@data) = GetConfig( $ARGV[0], $ARGV[1], $ARGV[2], $ARGV[3],
                                    $ARGV[4], $capture_timeout );

    if( $errorCode == 0 )
    {
        # Success.  The startup configuration
        # content is in the data variable

        for( @data ) { print }; # print the configuration to STDOUT
        exit 0;
    }
    else
    {
        print STDERR $errorString;

        if( $errorCode == 253 )
        {
            print STDERR join " ", @data, "\nEnable password may be invalid\n";
        }
        else
        {
            print STDERR join " ", @data, "\n";
        }

        exit $errorCode;
    }
}

exit 0;


sub GetConfig
{
    my $deviceIP=shift;
    my $user=shift;
    my $pass=shift;
    my $epass=shift;
    my $login_timeout=shift;
    my $capture_timeout=shift;
    my @config;
    my $msg;
        my $cmd_output;
    
    my $ssh = Net::SSH::Expect->new(
        host => $deviceIP,
        password => $pass,
        user => $user,
        raw_pty => 1,
        timeout => 5);
        
    eval {
                $msg = $ssh->login(1);
    };
    if ($@) {
        $ssh->close();
        return (252, "Error connecting to device: ".$@);
    }
    
    $cmd_output = $ssh->exec("enable");

    if ($cmd_output !~ m/#/)
    {
        #print "Didn't match auto-enable...did it prompt for password? \n";
        if ($cmd_output =~ m/password/i)
        {
                        $cmd_output = $ssh->exec($epass);
        }
    }

    # disabe paging
    # different commands for different devices, if they don't
    # work then we will get messages about problems later
    # specifically the "No prompt after 'sh start'" error
    # errmsg doesn't get set when these error and if we use print
    # and getlines to read for errors it causes problems with print "sh start"
    # later.
    $ssh->exec("term pager 0");
    $ssh->exec("term length 0");
        
    $ssh->send( "sh start" );
    while( my $line = $ssh->read_line() )
    {
        # get configuration content

        if( $line !~
            /sh start|Building configuration|Current configuration|^\s*$/ )
        {
            push @config, $line;
        }
    }

    if( @config <= 0 )
    {
        $msg = "No data retrieved, the capture timeout may be too low.";
        $ssh->close();
        return( 244, $msg );
    }

    if( scalar grep {$_ =~ /^%/} @_ )
    {
        # Ensure show start actually returned the config and not an error 
message containing '%'
        $ssh->close();
        return( 253, @config);
    }
        $ssh->close();
    return( 0, @config); # everything was okay, return the captured data
}

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to