3 # ModSecurity for Apache 2.x, http://www.modsecurity.org/
4 # Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
6 # This product is released under the terms of the General Public Licence,
7 # version 2 (GPLv2). Please refer to the file LICENSE (included with this
8 # distribution) which contains the complete text of the licence.
10 # There are special exceptions to the terms and conditions of the GPL
11 # as it is applied to this software. View the full text of the exception in
12 # file MODSECURITY_LICENSING_EXCEPTION in the directory of this software
15 # If any of the files related to licensing are missing or if you have any
16 # other questions related to licensing please contact Breach Security, Inc.
17 # directly using the email address support@breach.com.
21 use File::Find qw(find);
22 use File::Spec::Functions qw(catfile);
23 use Sys::Hostname qw(hostname);
24 use Digest::MD5 qw(md5_hex);
26 my $ROOTDIR = $ARGV[0] || '';
27 my $MLOGC = $ARGV[1] || '';
28 my $MLOGCCONF = $ARGV[2] || '';
31 if ($ROOTDIR eq '' or ! -e $MLOGC or ! -e $MLOGCCONF) {
32 printf STDERR "\nUsage: $0 <rootdir> </path/to/mlogc> <mlogc_config>\n\n";
36 open(MLOGC, "|$MLOGC -f $MLOGCCONF") or die "ERROR: could not open '$MLOGC' - $!\n";
41 my($fn,$dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size);
43 (($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size) = stat($_)) &&
46 && (($fn = $File::Find::name) =~ s/^\Q$ROOTDIR\E//)
47 && push(@AUDIT, [$fn, $size]);
54 for my $audit (@AUDIT) {
63 hostname => hostname(),
69 response_status => "-",
77 audit_size => $audit->[1],
81 ### Parse the audit file in an attempt to recreate the original log line
82 open (AUDIT, "<".catfile($ROOTDIR,$fn)) or $err = 1;
84 print STDERR "ERROR: could not open '$fn' - $!\n";
88 while($line = <AUDIT>) {
93 if ($line =~ m%^--[0-9A-Fa-f]{8}-([A-Z])--$%) {
99 if ($line =~ m%^(\[[-\d/: a-zA-Z]{27}\]) (\S+) (\S+) (\d+) (\S+) (\d+)%) {
101 $data{uniqueid} = $2;
102 $data{remote_addr} = $3;
106 elsif ($sect eq 'B') {
108 $data{request} = $line;
110 elsif ($line =~ m%^User=Agent: (.*)%i) {
111 $data{user_agent} = $1;
113 elsif ($line =~ m%^Referer: (.*)%i) {
118 elsif ($sect eq 'F') {
119 if ($sln == 1 and $line =~ m%^\S+ (\d{3})\D?.*%) {
120 $data{response_status} = $1;
122 elsif ($line =~ m%^Content-Length: (\d+)%i) {
123 $data{bytes_sent} = $1;
128 $data{md5} = md5_hex($data);
131 "%s %s %s %s %s \"%s\" %s %s \"%s\" \"%s\" %s \"%s\" %s %s %s md5:%s\n",
138 $data{response_status},