#! /usr/bin/perl -w # # Philip Markwalder # Roland Gafner # use strict; use POSIX; use Net::SSH::Perl; # SSH implementation in pure Perl use Net::SSH::Perl::Constants qw( :msg ); use Getopt::Long qw(GetOptions); # command line parsing ################################################################################### # # Please configure these values! # my $PIX_LG="pix"; # username on pix ( default = pix ) my $PIX_PW="PASSWORD"; # ssh login password my $PIX_PW_ENA="ENABLEPASSORD"; # enable password my $PIX_HOST="PIXFIREWALL"; # Pix firewall ipadress or hostname my $PIX_DEBUG=0; # 1 for debugging informations, 0 for none ################################################################################### my $PIX_CMD="" ; # command will be executed on pix ( will be defined later) my $PIX_HELP=0; my $PIX_BLOCK=0; my $PIX_UNBLOCK=0; my $stdout_buff = ''; use constant STATE_NONE => 0; use constant STATE_ENABLE => 10; use constant STATE_ENABLEPW => 20; use constant STATE_CONFMODE => 30; use constant STATE_SETPAGER => 40; use constant STATE_GETCLOCK => 44; use constant STATE_SETCLOCK => 47; use constant STATE_GETCONFIG => 50; use constant STATE_GETCERT => 60; use constant STATE_GETPUBKEY => 70; use constant STATE_GETVERSION => 80; use constant STATE_CMD => 90; use constant STATE_EXIT => 100; use constant STATE_FINISH => 200; my $state = STATE_NONE; ###################################################################### # Commandline parsing ###################################################################### { my %CmdOptions = ("help!" => \$PIX_HELP, "block:s" => \$PIX_BLOCK, "unblock:s" => \$PIX_UNBLOCK, ); GetOptions(%CmdOptions) } if ( $PIX_BLOCK ) { print "Block Connection \n"; $PIX_CMD="shun $PIX_BLOCK "; }; if ( $PIX_UNBLOCK ) { $PIX_CMD="no shun $PIX_UNBLOCK"; }; if ( length($PIX_CMD)==0 || $PIX_HELP || ( $PIX_BLOCK && $PIX_UNBLOCK ) ) { print "Usage $0 [--block|--unblock] SOURCE_IP \n"; exit 0; }; my $ssh = Net::SSH::Perl->new($PIX_HOST, debug =>$PIX_DEBUG, cipher => 'DES', ); $ssh->login($PIX_LG, $PIX_PW); $ssh->{config}->set('use_pty', 1); $ssh->_setup_connection; my $packet = $ssh->packet_start(SSH_CMSG_EXEC_SHELL); $packet->send; my $s = IO::Select->new; $s->add($ssh->{session}{sock}); my $str = $packet->get_str; CLOOP: while(1) { my @ready = $s->can_read; for my $a (@ready) { if ($a == $ssh->{session}{sock}) { # Got an SSH packet? my $buf; sysread $a, $buf, 8192; # read it and... ($buf) = $buf =~ /(.*)/s; # Untaint data. Anything allowed. $ssh->incoming_data->append($buf); }; }; while (my $packet = Net::SSH::Perl::Packet->read_poll($ssh)) { # Get the next SSH packet (we recieved above) if ($packet->type == SSH_SMSG_STDOUT_DATA) { # normal output from STDOUT on the remote side? my $str = $packet->get_str; # get the output if ("1") { foreach (split (/[\n\r]/, $str)) { printf STDERR "OUT: %s\n", $_ if ( $PIX_DEBUG ); } } $str =~ s/\r//g; $stdout_buff .= $str; if ($state == STATE_NONE) { # Just after connecting if ($stdout_buff =~ m|Type help or.*> $|s) { # Banner after logging in and User-Prompt? send_string ($ssh, "enable \n"); # SEND: enable to enable super-user mode $state = STATE_ENABLE; } } elsif ($state == STATE_ENABLE) { # Waiting for the enable password prompt if ($stdout_buff =~ m|Password:|) { # Got the password prompt? send_string ($ssh, $PIX_PW_ENA . "\n"); # SEND: $state = STATE_ENABLEPW; } }elsif ($state == STATE_ENABLEPW) { # Waiting for success or un-success of enable if ($stdout_buff =~ m|\# $|s) { # Got the Super-User-Prompt? ('# ') print STDERR "* systemname: enabled, entering configuration mode\n" if ( $PIX_DEBUG ); send_string ($ssh, "config terminal\n"); # SEND: config terminal to enter configuration mode $state = STATE_CONFMODE; } elsif ($stdout_buff =~ m|Invalid password|) { # Passwort was wrong? Bad! print STDERR "* systemname: wrong enable password\n" ; $state = STATE_CMD; last CLOOP; # just leave! } } elsif ($state == STATE_CONFMODE) { # Wait to get into configuration mode if ($stdout_buff =~ m|\(config\)\#|) { # got the config-mode-prompt? print STDERR "* systemname: entered configuration mode\n" if ( $PIX_DEBUG ); print STDERR "* systemname: setting pager to 0\n" if ( $PIX_DEBUG ); send_string ($ssh, "pager 0\n"); # SEND: pager 0 to disable paging $state = STATE_SETPAGER; } } elsif ( $state == STATE_SETPAGER) { if ($stdout_buff =~ m|\(config\)\#|) { send_string ($ssh, $PIX_CMD . "\n"); $state = STATE_CMD; }; } elsif ( $state == STATE_CMD) { send_string ($ssh, "exit\n"); send_string ($ssh, "exit\n"); $state = STATE_FINISH ; } elsif ( $state == STATE_FINISH) { if ($stdout_buff =~ m|\*\*|) { last CLOOP; }; }; } elsif ($packet->type == SSH_SMSG_EXITSTATUS) { print $stdout_buff; last CLOOP; # That's it # }; } } }; $packet = $ssh->packet_start(SSH_CMSG_EXIT_CONFIRMATION); # Confirm the SSH session closing $packet->send; $ssh->_disconnect; sub send_string { my ($ssh, $string) = @_; print STDERR "* Send String ", $string if ( $PIX_DEBUG ); $stdout_buff = ''; my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA); $packet->put_str($string); $packet->send; } # send_string