#!/usr/bin/perl
##########################################################################
# $Id: $
##########################################################################
# $Log:  $
# Revision ?.??  2005/10/19 05:48:39  
#  Written by Yaroslav Halchenko <debian@onerussian.com> for fail2ban
#
# This script is licensed under the same terms as logwatch, ie under
# permissive X11 license (see /usr/share/doc/logwatch/copyright for more
# details)
#
##########################################################################

use strict;
use Logwatch ':all';

my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0;
my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
my $IgnoreHost = $ENV{'sshd_ignore_host'} || "";
my $DebugCounter = 0;

my @OtherList = ();

my %ServicesBans = ();

if ( $Debug >= 5 ) {
	print STDERR "\n\nDEBUG: Inside Fail2Ban Filter \n\n";
	$DebugCounter = 1;
}

while (defined(my $ThisLine = <STDIN>)) {
	if ( $Debug >= 5 ) {
		print STDERR "DEBUG($DebugCounter): $ThisLine";
		$DebugCounter++;
	}
	chomp($ThisLine);
	if ( ($ThisLine =~ /..,... DEBUG: /) or
		 ($ThisLine =~ /..,... INFO: (Fail2Ban v.* is running|Exiting|Enabled sections:)/) or
		 ($ThisLine =~ /..,... WARNING: Verbose level is /) or
		 ($ThisLine =~ /..,... WARNING: Restoring firewall rules/)
		 )
	{
		if ( $Debug >= 6 ) {
			print STDERR "DEBUG($DebugCounter): line ignored\n";
		}
	} elsif ( my ($Service,$Action,$Host) = ($ThisLine =~ m/WARNING:\s(.*):\s(Ban|Unban)[^\.]* (\S+)/)) {
		if ( $Debug >= 6 ) {
			print STDERR "DEBUG($DebugCounter): Found $Action for $Service from $Host\n";
		}
		$ServicesBans{$Service}{$Host}{$Action}++;
		$ServicesBans{$Service}{"(all)"}{$Action}++;
	} elsif ( my ($Service,$Host,$NumFailures) = ($ThisLine =~ m/INFO: (\S+): (.+) has (\d+) login failure\(s\). Banned./)) {
	   if ($Debug >= 4) {
		   print STDERR "DEBUG: Found host $Host trying to access $Service - failed $NumFailures times\n";
	   }
	   push @{$ServicesBans{$Service}{$Host}{'Failures'}}, $NumFailures;
   } else
   {
	   # Report any unmatched entries...
	   push @OtherList, "$ThisLine\n";
   }
}

###########################################################


if (keys %ServicesBans) {
   printf("\nBanned services with Fail2Ban:                             Bans:Unbans\n");
   foreach my $service (sort {$a cmp $b} keys %ServicesBans) {
      printf("   %-55s [%3d:%-3d]\n", "$service:",
			 $ServicesBans{$service}{'(all)'}{'Ban'},
			 $ServicesBans{$service}{'(all)'}{'Unban'});
	  delete $ServicesBans{$service}{'(all)'};
      my $totalSort = TotalCountOrder(%{$ServicesBans{$service}}, \&SortIP);
	  if ($Detail >= 5) {
		  foreach my $ip (sort $totalSort keys %{$ServicesBans{$service}}) {
			  my $name = LookupIP($ip);
			  printf("      %-53s %3d:%-3d\n",
					 $name,
					 $ServicesBans{$service}{$ip}{'Ban'},
					 $ServicesBans{$service}{$ip}{'Unban'});
			  if (($Detail >= 10) and ($ServicesBans{$service}{$ip}{'Failures'}>0)) {
				  print "        Failed ";
				  foreach my $fails (@{$ServicesBans{$service}{$ip}{'Failures'}}) {
					  print " $fails";
				  }
				  print " times";
				  print "\n";
			  }
		  }
	  }
  }
}

if ($Detail>0 and $#OtherList >= 0) {
   print "\n**Unmatched Entries**\n";
   print @OtherList;
}

exit(0);

# vi: shiftwidth=3 tabstop=3 syntax=perl et
