Listing 5: PIX authentication log parsing script

#!/usr/bin/perl

use Socket;
use DBI;
use POSIX;
use IO::Select;
use Getopt::Std;
use Sys::Syslog;

#------- Configurable constants ------------------
$database='fwlog';
$dbusername='username';
$host='dbserver';
$pw='password';
$logpipe="/usr/local/fwlog/fwlog.fifo";
#-------------------------------------------------

# get commandline options
my %option= ();
getopts("dv?h:", \%option);

printusage() if $option{h} or $option{'?'};

if ($option{d}) {
        # go into daemon mode
        # fork once, let the parent exit
        my $pid = fork;
        exit if $pid;
        die "Couldn't fork: $!" unless defined($pid);

        # disassociated from our controlling terminal
        POSIX::setsid() or die "Can't start a new session: $!";
}


# open database
$dbh=DBI->connect("DBI:Pg:dbname=$database;host=$host",$dbusername,$pw);
fatalerror("Unable to connect: $DBI::errstr\n") unless (defined $dbh);

my $sth = $dbh->prepare("INSERT INTO auth (datetime,username,sourceip) VALUES (?,?,?)");

# open named pipe in non-blocking mode.   If we're unable to keep up, we
# don't want to block syslog-ng
sysopen(LOGFILE, $logpipe, O_RDONLY | O_NONBLOCK) or fatalerror("Unable to open named pipe $logpipe:$!\n");


#Read each record
while (1) {
	# sleep until there is something to read
	my $select = IO::Select->new(\*LOGFILE);
	$select->can_read;

	# read next line
	$_ = <LOGFILE>;

	# reads syslog messages of the format "Feb 10 00:17:08 pixfw1 Feb 10 2003 00:17:08: %PIX-6-109007: Authorization permitted for user 'testuser' from 10.1.1.102/1159 to 10.2.1.1/80 on interface inside"
	# inserts datetime, username, and sourceip into database
	if ($_ =~ /.*Authorization\spermitted.*/) {
		my ($month, $day, $year, $time, $username, $sourceip) = (split)[4,5,6,7,13,15];
		chop $time;
		$username =~ s/'//g;
		$username = lc($username);
		$sourceip =~ s#^(.*?)/.*#$1#;

		$datetime = "$year-$month-$day $time";


		$results = $sth->execute($datetime, $username, $sourceip);
		fatalerror("Unable to perform INSERT:$DBI::errstr\n") unless (defined $results);

	}
}
close (logfile);


sub printusage {
        print <<"END";

$0: Reads pix authentication log messages from a fifo and inserts them into a database
Usage: $0 [OPTION]... [DEVICENAME]

Options:
        -d              Became a daemon (run in the background) 
        -h or -?        Command line help (this screen)


END
}

sub fatalerror {
        my $message = shift;
        openlog($0, "nowait", "daemon");
        syslog("warning", "%s\n",$message);
        closelog();
        die;
}

