2
##########################################################################
3
##########################################################################
5
# Barracuda Spam Firewall parser
6
# Written by Hugo van der Kooij <hugo@vanderkooij.org> (HvdK)
7
# Based on existing code of logwatch and the docuemntation on:
8
# http://www.barracudanetworks.com/ns/downloads/BarracudaSyslog.pdf
10
# Revision 0.9 2007/08/27 HvdK
11
# Started the scanner for the logs of Barracuda Spam firewalls.
13
########################################################
14
## Copyright (c) 2008 Hugo van der Kooij <hugo@vanderkooij.org>
15
## Covered under the included MIT/X-Consortium License:
16
## http://www.opensource.org/licenses/mit-license.php
17
## All modifications and contributions by other persons to
18
## this script are assumed to have been donated to the
19
## Logwatch project and thus assume the above copyright
20
## and licensing terms. If you want to make contributions
21
## under your own copyright or a different license this
22
## must be explicitly stated in the contribution an the
23
## Logwatch project reserves the right to not accept such
24
## contributions. If you have made significant
25
## contributions to this script and want to claim
26
## copyright please contact logwatch-devel@logwatch.org.
27
#########################################################
29
my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
30
my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0;
35
my $factor = (10**$digits);
36
my $result = (int( ($input * $factor) + .5) / $factor);
40
# Text messages for the RECV and SCAN action codes:
41
$RSaction[0] = "Allowed Message(s)";
42
$RSaction[1] = "Aborted Message(s)";
43
$RSaction[2] = "Blocked Message(s)";
44
$RSaction[3] = "Quarantined Message(s)";
45
$RSaction[4] = "Tagged Message(s)";
46
$RSaction[5] = "Deferred Message(s)";
47
$RSaction[6] = "Per-User Quarantined Message(s)";
48
$RSaction[7] = "Whitelisted Message(s)";
50
# Text messages for the SEND action codes:
51
$Saction[0] = "UNKNOWN";
52
$Saction[1] = "Delivered Message(s)";
53
$Saction[2] = "Rejected Message(s)";
54
$Saction[3] = "Deferred Message(s)";
55
$Saction[4] = "Expired Message(s)";
57
# Text messages for the reason codes:
58
$Reason[0] = "Allowed";
59
$Reason[1] = "Virus detected";
60
$Reason[2] = "Banned attachment";
61
$Reason[3] = "RBL Match";
62
$Reason[4] = "Rate Control";
63
$Reason[5] = "Too Many Message(s) In Session";
64
$Reason[6] = "Timeout Exceeded";
65
$Reason[7] = "No such Domain";
66
$Reason[8] = "No such User";
67
$Reason[9] = "Subject Filter Match";
68
$Reason[10] = "UNKNOWN (10)";
69
$Reason[11] = "Client IP";
70
$Reason[12] = "Recipient Address Rejected";
71
$Reason[13] = "No valid Recipients";
72
$Reason[14] = "Domain Not Found";
73
$Reason[15] = "Sender Address Rejected";
74
$Reason[16] = "UNKNOWN (16)";
75
$Reason[17] = "Need Fully Qualified Recipient";
76
$Reason[18] = "Need Fully Qualified Sender";
77
$Reason[19] = "Unsupported Command";
78
$Reason[20] = "MAIL FROM Syntax Error";
79
$Reason[21] = "Bad Address Syntax";
80
$Reason[22] = "RCPT TO Syntax Error";
81
$Reason[23] = "Send EHLO/HELO First";
82
$Reason[24] = "Need MAIL Command";
83
$Reason[25] = "Nested MAIL Comand";
84
$Reason[26] = "UNKNOWN (26)";
85
$Reason[27] = "EHLO/HELO Syntax Error";
86
$Reason[28] = "UNKNOWN (28)";
87
$Reason[29] = "UNKNOWN (29)";
88
$Reason[30] = "Mail Protocol Error";
89
$Reason[31] = "Score";
90
$Reason[32] = "UNKNOWN (32)";
91
$Reason[33] = "UNKNOWN (33)";
92
$Reason[34] = "Header Filter Match";
93
$Reason[35] = "Sender Block/Accept";
94
$Reason[36] = "Recipient Block/Accept";
95
$Reason[37] = "Body Filter Match";
96
$Reason[38] = "Message Size Bypass";
97
$Reason[39] = "Intention Analysis Match";
98
$Reason[40] = "SPF/Caller-ID";
99
$Reason[41] = "Client Host Rejected";
100
$Reason[42] = "UNKNOWN (42)";
101
$Reason[43] = "UNKNOWN (43)";
102
$Reason[44] = "Authentication Not Enabed";
103
$Reason[45] = "Allowed Message Size Exceeded";
104
$Reason[46] = "Too Many Recipients";
105
$Reason[47] = "Need RCPT Command";
106
$Reason[48] = "DATA Syntax Error";
107
$Reason[49] = "Internal Error";
108
$Reason[50] = "Too Many Hops";
109
$Reason[51] = "UNKNOWN (51)";
110
$Reason[52] = "UNKNOWN (52)";
111
$Reason[53] = "UNKNOWN (53)";
112
$Reason[54] = "UNKNOWN (54)";
113
$Reason[55] = "Invalid Parameter Syntax";
114
$Reason[56] = "STARTTLS Syntax Error";
115
$Reason[57] = "TLS Allready Active";
116
$Reason[58] = "Too Many Errors";
117
$Reason[59] = "Need STARTTLS First";
118
$Reason[60] = "Spam Fingerprint Found";
120
while (defined($ThisLine = <STDIN>))
122
if ( ($address, $id, $start_time, $end_time, $type, $info) = ($ThisLine =~ /([^\s]+)\s([^\s]+)\s(\d+)\s(\d+)\s(RECV|SCAN|SEND)\s(.*)$/) )
124
($ip) = ($address =~ /\[(.*)\]/);
125
$time = ($end_time - $start_time);
126
if ( $type =~ /RECV/ )
128
if ( ($sender, $recipient, $action, $reason, $reason_extra) = ($info =~ /([^\s]+)\s([^\s]+)\s(\d+)\s(\d+)\s(.*)$/) ) {
129
$RECVaction{$action}++;
130
$RECVreason{$reason}++;
131
$RECVreason_extra{$reason_extra}++;
132
if ( ($reason_extra =~ /^-[| ]$/) or ($reason < 1) ) {
134
$RECVReasons{$reason_extra}++;
135
$RECVReason{$reason_extra} = $reason;
137
$RECVtime_total{$action} = ($RECVtime_total{$action} + $time);
138
$RECVtime_div{$action}++;
139
if ($time < $RECVtime_min{$action}) {
140
$RECVtime_min{$action} = $time;
141
} elsif ($RECVtime_min{$action} eq "") {
142
$RECVtime_min{$action} = $time;
144
if ($time > $RECVtime_max{$action}) {
145
$RECVtime_max{$action} = $time;
146
} elsif ($RECVtime_max{$action} eq "") {
147
$RECVtime_max{$action} = $time;
150
push @OtherList,$ThisLine;
152
} elsif ( $type =~ /SCAN/ ) {
153
if ( ($enc, $sender, $recipient, $score, $action, $reason, $reason_extra, $subject) = ($info =~ /([^\s]+)\s([^\s]+)\s([^\s]+)\s([-\.\d+]+)\s(\d+)\s(\d+)\s(.*)\sSUBJ:(.*)$/) ) {
154
if ( ($size) = ($reason_extra =~ /\sSZ:(\d+)$/) ) {
155
$reason_extra =~ s/\sSZ:(\d+)$//;
156
$SCANsize_total{$action} = ($SCANsize_total{$action} + $size);
157
$SCANsize_div{$action}++;
159
$SCANaction{$action}++;
160
$SCANreason{$reason}++;
161
if ($score =~ /^-$/) {
163
$score_total{$action} = ($score_total{$action} + $score);
164
$score_div{$action}++;
165
if ($score < $score_min{$action}) {
166
$score_min{$action} = $score;
167
} elsif ($score_min{$action} eq "") {
168
$score_min{$action} = $score;
170
if ($score > $score_max{$action}) {
171
$score_max{$action} = $score;
172
} elsif ($score_max{$action} eq "") {
173
$score_max{$action} = $score;
176
if ($reason_extra =~ /^-$/) {
178
$SCANReasons{$reason_extra}++;
179
$SCANReason{$reason_extra} = $reason;
181
$SCANtime_total{$action} = ($SCANtime_total{$action} + $time);
182
$SCANtime_div{$action}++;
183
if ($time < $SCANtime_min{$action}) {
184
$SCANtime_min{$action} = $time;
185
} elsif ($SCANtime_min{$action} eq "") {
186
$SCANtime_min{$action} = $time;
188
if ($time > $SCANtime_max{$action}) {
189
$SCANtime_max{$action} = $time;
190
} elsif ($SCANtime_max{$action} eq "") {
191
$SCANtime_max{$action} = $time;
194
push @OtherList,$ThisLine;
196
} elsif ( $type =~ /SEND/ ) {
197
if ( ($enc, $action, $qid, $response) = ($info =~ /([^\s]+)\s(\d+)\s([^\s]+)\s(.*)$/) ) {
198
$SENDaction{$action}++;
199
if (($delivery) = ($response =~/^(\d+)\s.*/) ) {
200
$SENDresponse{$delivery}++;
203
push @OtherList,$ThisLine;
206
push @OtherList,$ThisLine;
208
} elsif ( $ThisLine =~ /\s[RECV|SCAN|SEND]\s/) {
209
push @OtherList,$ThisLine;
213
##################################################################
215
if ($#OtherList >= 0)
217
print "\n\n**Unmatched Entries**\n\n";
221
if (keys %RECVaction) {
222
print "\nReceive actions:\n";
223
foreach $action (sort {$a cmp $b} keys %RECVaction) {
224
print ' ' . $RSaction[$action] . ": ". $RECVaction{$action} . "\n";
228
if (keys %SCANaction) {
229
print "\nScanning actions:\n";
230
foreach $action (sort {$a cmp $b} keys %SCANaction) {
231
print ' ' . $RSaction[$action] . ": ". $SCANaction{$action} . "\n";
235
if (keys %SENDaction) {
236
print "\nSending actions:\n";
237
foreach $action (sort {$a cmp $b} keys %SENDaction) {
238
print ' ' . $Saction[$action] . ": ". $SENDaction{$action} . "\n";
242
if (keys %RECVreason) {
243
print "\nBlocked incoming messages:\n";
244
foreach $reason (sort {$a cmp $b} keys %RECVreason) {
246
print ' ' . $Reason[$reason] . " : ". $RECVreason{$reason} . "\n";
251
if ( ($Detail >= 10) and (keys %RECVReasons) ) {
252
print "\nDetails of blocked incoming messages :\n";
253
foreach $reason (sort {$a cmp $b} keys %RECVReasons) {
254
print ' ' . $Reason[$RECVReason{$reason}] . " : " . $reason . " : ". $RECVReasons{$reason} . "\n";
258
if (keys %RECVtime_total) {
259
print "\nReceive timing:\n";
260
foreach $action (sort {$a cmp $b} keys %RECVtime_total) {
261
$RECVtime = ($RECVtime_total{$action} / $RECVtime_div{$action});
262
print ' ' . $RSaction[$action] . " :\n";
263
print "\tMinimum : " . $RECVtime_min{$action} . "\n";
264
print "\tAverage : " . Round($RECVtime, 1) . "\n";
265
print "\tMaximum : " . $RECVtime_max{$action} . "\n";
269
if (keys %SCANreason) {
270
print "\nDecisions while scanning:\n";
271
foreach $reason (sort {$a cmp $b} keys %SCANreason) {
272
print ' ' . $Reason[$reason] . " : ". $SCANreason{$reason} . "\n";
276
if ( ($Detail >= 10) and (keys %SCANReasons) ) {
277
print "\nDetails of decisions while scanning:\n";
278
foreach $reason (sort {$a cmp $b} keys %SCANReasons) {
279
print ' ' . $Reason[$SCANReason{$reason}] . " : " . $reason . " : ". $SCANReasons{$reason} . "\n";
283
if (keys %SCANtime_total) {
284
print "\nScan timing:\n";
285
foreach $action (sort {$a cmp $b} keys %SCANtime_total) {
286
$SCANtime = ($SCANtime_total{$action} / $SCANtime_div{$action});
287
print ' ' . $RSaction[$action] . " :\n";
288
print "\tMinimum : " . $SCANtime_min{$action} . "\n";
289
print "\tAverage : " . Round($SCANtime, 1) . "\n";
290
print "\tMaximum : " . $SCANtime_max{$action} . "\n";
294
if (keys %SCANsize_total) {
295
print "\nMessage sizes:\n";
296
foreach $action (sort {$a cmp $b} keys %SCANsize_total) {
297
$SCANsize = ($SCANsize_total{$action} / $SCANsize_div{$action});
298
print ' ' . $RSaction[$action] . " :\n";
299
# print "\tMinimum : " . $SCANsize_min{$action} . "\n";
300
print "\tAverage : " . Round($SCANsize, 0) . "\n";
301
# print "\tMaximum : " . $SCANsize_max{$action} . "\n";
306
if (keys %SENDreason) {
307
print "\nSending reasons:\n";
308
foreach $reason (sort {$a cmp $b} keys %SENDreason) {
309
print ' ' . $Reason[$reason] . " : ". $SENDreason{$reason} . "\n";
313
if (keys %SENDresponse) {
314
print "\nSending responses:\n";
315
foreach $response (sort {$a cmp $b} keys %SENDresponse) {
316
print ' ' . $response . ": ". $SENDresponse{$response} . "\n";
320
if (keys %score_total) {
322
foreach $action (sort {$a cmp $b} keys %score_total) {
323
$score = ($score_total{$action} / $score_div{$action});
324
print ' ' . $RSaction[$action] . " :\n";
325
print "\tMinimum : " . $score_min{$action} . "\n";
326
print "\tAverage : " . Round($score, 3) . "\n";
327
print "\tMaximum : " . $score_max{$action} . "\n";
333
# vi: shiftwidth=3 tabstop=3 syntax=perl et