Imported Upstream version 2.5.11
[libapache-mod-security.git] / apache2 / mlogc-src / mlogc-batch-load.pl.in
1 #!@PERL@
2 #
3 # ModSecurity for Apache 2.x, http://www.modsecurity.org/
4 # Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
5 #
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.
9 #
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
13 # distribution.
14 #
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.
18 #
19
20 use strict;
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);
25
26 my $ROOTDIR = $ARGV[0] || '';
27 my $MLOGC = $ARGV[1] || '';
28 my $MLOGCCONF = $ARGV[2] || '';
29 my @AUDIT = ();
30
31 if ($ROOTDIR eq '' or ! -e $MLOGC or ! -e $MLOGCCONF) {
32         printf STDERR "\nUsage: $0 <rootdir> </path/to/mlogc> <mlogc_config>\n\n";
33         exit 1;
34 }
35
36 open(MLOGC, "|$MLOGC -f $MLOGCCONF") or die "ERROR: could not open '$MLOGC' - $!\n";
37
38 find(
39         {
40                 wanted => sub {
41                         my($fn,$dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size);
42
43                         (($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size) = stat($_)) &&
44                         -f _ &&
45                         /^\d{8}-\d+-\w{24}$/s
46                         && (($fn = $File::Find::name) =~ s/^\Q$ROOTDIR\E//)
47                         && push(@AUDIT, [$fn, $size]);
48                 },
49                 follow => 1,
50         },
51         $ROOTDIR
52 );
53
54 for my $audit (@AUDIT) {
55         my $fn = $audit->[0];
56         my $line = "";
57         my $err = 0;
58         my $ln = 0;
59         my $sln = 0;
60         my $sect = "";
61         my $data = "";
62         my %data = (
63                 hostname => hostname(),
64                 remote_addr => "-",
65                 remote_user => "-",
66                 local_user  => "-",
67                 logtime => "-",
68                 request => "-",
69                 response_status => "-",
70                 bytes_sent => "-",
71                 referer => "-",
72                 user_agent => "-",
73                 uniqueid => "-",
74                 sessionid => "-",
75                 audit_file => $fn,
76                 extra => "0",
77                 audit_size => $audit->[1],
78                 md5 => "-",
79         );
80
81         ### Parse the audit file in an attempt to recreate the original log line
82         open (AUDIT, "<".catfile($ROOTDIR,$fn)) or $err = 1;
83         if ($err == 1) {
84                 print STDERR "ERROR: could not open '$fn' - $!\n";
85                 next;
86         }
87
88         while($line = <AUDIT>) {
89                 $data .= $line;
90                 chop $line;
91                 $ln++;
92                 $sln++;
93                 if ($line =~ m%^--[0-9A-Fa-f]{8}-([A-Z])--$%) {
94                         $sect = $1;
95                         $sln = 0;
96                         next;
97                 };
98                 if ($sect eq 'A') {
99                         if ($line =~ m%^(\[[-\d/: a-zA-Z]{27}\]) (\S+) (\S+) (\d+) (\S+) (\d+)%) { 
100                                 $data{logtime} = $1;
101                                 $data{uniqueid} = $2;
102                                 $data{remote_addr} = $3;
103                         }
104                         next;
105                 }
106                 elsif ($sect eq 'B') {
107                         if ($sln == 1) {
108                                 $data{request} = $line;
109                         }
110                         elsif ($line =~ m%^User=Agent: (.*)%i) {
111                                 $data{user_agent} = $1;
112                         }
113                         elsif ($line =~ m%^Referer: (.*)%i) {
114                                 $data{referer} = $1;
115                         }
116                         next;
117                 }
118                 elsif ($sect eq 'F') {
119                         if ($sln == 1 and $line =~ m%^\S+ (\d{3})\D?.*%) {
120                                 $data{response_status} = $1;
121                         }
122                         elsif ($line =~ m%^Content-Length: (\d+)%i) {
123                                 $data{bytes_sent} = $1;
124                         }
125                         next;
126                 }
127         }
128         $data{md5} = md5_hex($data);
129
130         printf MLOGC (
131                 "%s %s %s %s %s \"%s\" %s %s \"%s\" \"%s\" %s \"%s\" %s %s %s md5:%s\n",
132                 $data{hostname},
133                 $data{remote_addr},
134                 $data{remote_user},
135                 $data{local_user},
136                 $data{logtime},
137                 $data{request},
138                 $data{response_status},
139                 $data{bytes_sent},
140                 $data{referer},
141                 $data{user_agent},
142                 $data{uniqueid},
143                 $data{sessionid},
144                 $data{audit_file},
145                 $data{extra},
146                 $data{audit_size},
147                 $data{md5},
148         );
149        
150 }
151