#!/usr/bin/perl
##########################################################################
# $Id: proftpd-messages,v 1.10 2002/10/15 13:50:10 kirk Exp $
##########################################################################

########################################################
# This was written and is maintained by:
#    Simon Liddington <sjl96v@ecs.soton.ac.uk>
#
# for use with Logwatch
#
# Logwatch was written and is maintained by:
#    Kirk Bauer <kirk@kaybee.org>
########################################################

$Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'};
$IgnoreUnmatched = $ENV{'ftpd_ignore_unmatched'};

while (defined($ThisLine = <STDIN>)) {
   if ( ( $ThisLine =~ /^FTP session closed./ ) or
         ( $ThisLine =~ /^(ANONYMOUS )?FTP login as \'.*\' from [^ ]+ \[.*\] to .*/ ) or
         ( $ThisLine =~ /^FTP no transfer time out, disconnected\./ ) or
         ( $ThisLine =~ /PAM\(.*\): Authentication failure/ ) or
         ( $ThisLine =~ /^data_sendfile/ ) or
         ( $ThisLine =~ / - FTP session opened/ ) or
         ( $ThisLine =~ / - FTP session closed/ ) or
         ( $ThisLine =~ / - No certificate files found/ ) or
         ( $ThisLine =~ /FTP no transfer timeout, disconnected\./ ) or
         ( $ThisLine =~ /FTP login timed out, disconnected\./ )   ) {
      # We don't care about these
   }        			 
   elsif ( ($Host,$IP,$Email,) = ( $ThisLine =~ /^FTP session opened: ftp\/ftp (.*)\[(.*)\] (.*)$/ ) ) {
      $Temp = "   " . $Host . " (" . $IP . "): " . $Email . " - ";
      $AnonLogins{$Temp}++;
   }
   elsif ( ($Host, $IP) = ( $ThisLine =~ /\((.*)\[(.*)\]\) - ANON .+: Login successful\./ ) ) {
      $Temp = "   " . $Host . " (" . $IP . ")";
      $AnonLogins{$Temp}++;
   }
   elsif ( ($User,$Host,$IP) = ( $ThisLine =~ /^FTP session opened: (.*\/.*) (.*)\[(.*)\] (.*)$/ ) ) {
      $Temp = "   " . $Host .  ": " . $User . " - ";
      $UserLogins{$Temp}++;
   }
   elsif ( ($Host,$IP,$User) = ( $ThisLine =~ /\((.*)\[(.*)\]\) - USER (.+): Login successful/ ) ) {
      $Temp = "   " . $Host . ": " . $User . " - ";
      $UserLogins{$Temp}++;
   }
   elsif ( ($User) = ( $ThisLine =~ /^failed login, can\'t find user \'(.*)\' $/ ) ) {
      $Temp = "   " . "Unknown" . " (" . "Unknown.IP" . "): " . $User . " - ";
      $BadUsers{$Temp}++;
   }
   elsif ( ($User,$Host,$IP) = ( $ThisLine =~ /USER (.*): no such user found from (.*) \[(.*)\] to/ ) ) {
      $Temp = "   " . $Host . ": " . $User . " - ";
      $BadUsers{$Temp}++;
   }
   elsif ( ($Host,$IP,$User) = ( $ThisLine =~ /\((.*)\[(.*)\]\) - no such user '(.*)'$/ ) ) {
      $Temp = "   " . $Host . ": " . $User . " - ";
      $BadUsers{$Temp}++;
   }
   elsif ( ($Host,$User) = ( $ThisLine =~ /\[(.*)\]\) - USER (.*) \(Login failed\): Incorrect password/ ) ) {
      $Temp = "   " . $Host . ": " . $User . " - ";
      $BadPasswds{$Temp}++;
   }
   elsif ( ($Host,$User) = ( $ThisLine =~ /\[(.*)\]\) - USER (.*) \(Login failed\): Invalid shell/ ) ) {
      $Temp = "   " . $Host . ": " . $User . " - ";
      $BadShell{$Temp}++;
   }
   elsif ( ($Host,$Reason) = ( $ThisLine =~ /\[(.*)\]\) - Refused PORT [0123456789,]+ \((.*)\)/ ) ) {
      $Temp = "   " . $Host . ": " . $Reason . " - ";
      $RefusedPorts{$Temp}++;
   }
   else {
      # Report any unmatched entries...
      push @OtherList,$ThisLine;
   }
}

if ( (keys %AnonLogins) and ($Detail >= 5) ) {
   print "\nAnonymous FTP Logins:\n";
   foreach $ThisOne (keys %AnonLogins) {
      print $ThisOne . $AnonLogins{$ThisOne} . " Time(s)\n";
   }
}

if ( (keys %DeletedFiles) and ($Detail >= 10) ) {
   print "\nFiles deleted through FTP:\n";
   foreach $ThisOne (keys %DeletedFiles) {
      print $ThisOne;
      print @{$DeletedFiles{$ThisOne}};
   }
}

if (keys %UserLogins) {
   print "\nUser FTP Logins:\n";
   foreach $ThisOne (keys %UserLogins) {
      print $ThisOne . $UserLogins{$ThisOne} . " Time(s)\n";
   }
}

if ( ( (keys %BadUsers) or (keys %BadPasswds) ) and ($Detail >= 5) ) {
   print "\nFailed FTP Logins:\n";

   if ( (keys %BadUsers) and ($Detail >= 5) ) {
      print "\n  Invalid Username:\n";
      foreach $ThisOne (keys %BadUsers) {
         print $ThisOne . $BadUsers{$ThisOne} . " Time(s)\n";
      }
   }

   if ( (keys %BadPasswds) and ($Detail >= 5) ) {
      print "\n  Incorrect Password:\n";
      foreach $ThisOne (keys %BadPasswds) {
         print $ThisOne . $BadPasswds{$ThisOne} . " Time(s)\n";
      }
   }
   if ( (keys %BadPasswds) and ($Detail >= 5) ) {
      print "\n  Invalid Shell:\n";
      foreach $ThisOne (keys %BadShell) {
         print $ThisOne . $BadShell{$ThisOne} . " Time(s)\n";
      }
   }

}

if ( (keys %RefusedPorts) and ($Detail >= 5) ) {
   print "\nRefused PORTs:\n";
   foreach $ThisOne (keys %RefusedPorts) {
      print $ThisOne . $RefusedPorts{$ThisOne} . " Time(s)\n";
   }
}

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

exit(0);

