#!/usr/bin/perl
# cpanel12 - modsecparse.pl                  Copyright(c) 2004-2006 cPanel, Inc.
#                                                           All Rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

BEGIN {
    unshift( @INC, '/usr/local/cpanel' );
    @INC = grep( !/(^\.|\.\.|\/\.+)/, @INC );
    @INC = grep( /^(\/usr\/lib\d*\/perl|\/usr\/local\/lib\d*\/perl|\/usr\/local\/cpanel)/, @INC );
}

use strict;
use DBI;

my $dbhost     = '__MYSQLHOST__';
my $dbuser     = 'modsec';
my $dbpassword = '__DBPASSWORD__';
my $dbname     = 'modsec';
my $tblname    = 'modsec';

my @MS        = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' );
my $i         = 0;
my %MONTHLIST = map { $i++; $_ => $i; } @MS;

my $dsn       = "DBI:mysql:$dbname:$dbhost";
my $dbh       = DBI->connect( $dsn, $dbuser, $dbpassword ) || die 'Unable to connect to mysql database';
my $audit_log = '/usr/local/apache/logs/audit_log';

exit if !-e $audit_log || -z _;

my %REQUEST;
if ( open my $al_fh, '+<', $audit_log ) {
    while ( readline($al_fh) ) {
        chomp();
        if (/^\=\=([^\=]+)\=+$/) {
            delete @REQUEST{ keys %REQUEST };
            $REQUEST{'id'} = $1;
        }
        elsif ( !defined $REQUEST{'ip'} && /^Request:\s*\S+\s*([\d\.]+)[^\[]+\[([^\]\s]+)/ ) {
            $REQUEST{'ip'} = $1;
            ( $REQUEST{'date'}, $REQUEST{'time'} ) = split( /:/, $2, 2 );
            mysql_date( \$REQUEST{'date'} );
        }
        elsif ( !defined $REQUEST{'handler'} && /^Handler:\s*(.*)/ ) {
            $REQUEST{'handler'} = $1;
        }
        elsif ( !defined $REQUEST{'get'} && /^(?:POST|PUT|GET|HEAD)\s*(.*)/ ) {
            $REQUEST{'get'} = $1;
        }
        elsif ( !defined $REQUEST{'host'} && /^Host:\s*(.*)/ ) {
            $REQUEST{'host'} = $1;
        }
        elsif ( !defined $REQUEST{'mod_security_message'} && /^mod_security[\-\_]message:\s*(.*)/ ) {
            $REQUEST{'mod_security_message'} = $1;
        }
        elsif ( !defined $REQUEST{'mod_security_action'} && /^mod_security[\-\_]action:\s*(.*)/ ) {
            $REQUEST{'mod_security_action'} = $1;
        }
        elsif ( defined $REQUEST{'id'} && /^\-\-$REQUEST{'id'}\-+$/ ) {
            my @NAMES  = qw(ip date time handler get host mod_security_message mod_security_action);
            my @VALUES = map { $REQUEST{$_}; } @NAMES;
            my $q      = "INSERT INTO $tblname " . '(' . join( ',', @NAMES ) . ') VALUES(' . join( ',', map { '?'; } @NAMES ) . ');' . "\n";
            my $mq     = $dbh->prepare($q);
            $mq->execute(@VALUES);
            delete @REQUEST{ keys %REQUEST };
        }
    }
    truncate( $al_fh, 0 );
    close($al_fh);
}
else {
    die "Unable to read $audit_log: $!";
}

sub mysql_date {
    my $dateref = shift;
    $$dateref =~ /([^\/]+)\/([^\/]+)\/([^\/]+)/;
    $$dateref = join( '-', $3, sprintf( '%02d', $MONTHLIST{$2} ), $1 );
}
