#/usr/bin/perl -wT
use 5.006;
use strict;
use warnings;
use HTTPD::ADS;
use IO::Socket::UNIX;
use HTTPD::Log::Filter;
use Compress::Zlib;

#do not run this as root, I specifically split root-privileged code into another module.
#you MUST run this as your Postgresql database username
BEGIN {
    use CGI::Carp qw(cluck  carpout);
    my $logfile="/tmp/LogReader.log";
    die "cannot open log file $logfile for write" if (-e $logfile && ! (-w $logfile));
    open(LOG, ">>$logfile") or die "carp could not open log";
    carpout(\*LOG);
}


our $VERSION = '0.02';

#daemon process waits for events to come in, then puts them in database and analyzes and takes action

my $IDSDatabase="wwwads";
my $IDSDataUser="";
my $IDSDataPassword="";
my $line;

my $gz;
my $loopcount;
my $bytesread;
my $rv;
my %args;
my $apacheids = HTTPD::ADS->new (
				 IDSDataUser => $IDSDataUser,
				 IDSDataPassword   => $IDSDataPassword,
				 IDSDatabase => $IDSDatabase,
				 IDSTimeWindowSize => 7801920
				);
my $logfilter= HTTPD::Log::Filter->new(
				       format              => 'ELF',
				       capture => [ qw(
    host
    ident
    authexclude
    date
    request
    status
    referer
)]);
my $linenumber=0;
my $filename;
foreach $loopcount ('33'..'86') {
    $filename = "/var/log/httpd/inside.slavelucy.com-access_log.$loopcount.gz";
    $gz = gzopen($filename, "rb") || die "could not open log file";
 print "$linenumber lines\n";
    print "process $filename\n ";
    for ($bytesread=$gz->gzreadline($line),$linenumber=0; $bytesread > 0; $bytesread=$gz->gzreadline($line),$linenumber++) {
	$rv=$logfilter->filter($line);
	if (!defined $rv) {
	    my $time = scalar localtime;
	    carp "$time: Invalid log format  in $filename at line $linenumber $!  \n";
	    next ;
	}
    
    
	#1st is to put the event in the  database.
	# then can decide what to do  about it.
	# One may think access to protected page w/o specifying username is innocent. Maybe. but it could
	# be that someone trys and then failing to get in launches a brute force attack. So while blank
	# username on its own might be innocent it could be counted with failed login attempts
	# as grounds for killing some asshole
	# or blackholing his ip anyway. But you need data on which to make a decision.
	next unless ($logfilter->status >= 400 && $logfilter->status < 500);
	$apacheids->event_recorder(
				   #				   ip => gethostbyname($logfilter->host),
				   ip => $logfilter->host,
				   request => $logfilter->request,
				   status =>$logfilter->status,
				   referer =>$logfilter->referer,
				   user =>$logfilter->authexclude,
				   time =>$logfilter->date
				  );
	print "$linenumber completed\r";
    }
    ;
}


1;
__END__



=head1 AUTHOR

    Dana Hudes, E<lt>dhudes@networkengineer.bizE<gt>

    =head1 SEE ALSO

    L<perl>.

    =cut
