#!/usr/bin/perl
##########################################################################
# $Id: secure,v 1.12 2000/09/22 15:59:05 kirk Exp $
##########################################################################
# $Log: secure,v $
# Revision 1.12  2000/09/22 15:59:05  kirk
# Prepping for Version 2.0.1
#
# Revision 1.11  2000/09/22 14:47:04  kirk
# *** empty log message ***
#
# Revision 1.10  1999/02/23 14:55:13  kirk
# Prepping for Version 1.6.6
#
# Revision 1.9  1999/02/23 01:24:31  kirk
# Improved LookupIP in named/secure.
# Applied ftp-messages patch from Simon Liddington <sjl96v@ecs.soton.ac.uk>.
#
# Revision 1.8  1999/02/23 00:39:54  kirk
# Added code written by Fabrizio Zeno Cornelli <zeno@filibusta.crema.unimi.it>.
#
# Revision 1.7  1998/09/08 13:08:21  kirk
# Applied patches submitted by Simon Liddington <sjl96v@ecs.soton.ac.uk>.
# Thanks!
#
# Revision 1.6  1998/07/30 19:44:49  kirk
# Prepping for Version 1.4.2
#
# Revision 1.5  1998/06/11 16:37:36  kirk
# Prepping for Version 1.4.1
#
# Revision 1.4  1998/06/01 20:39:55  kirk
# Applied patch submitted by Simon Liddington <sjl96v@ecs.soton.ac.uk>...
#
# Revision 1.3  1998/05/11 13:03:31  kirk
# Applied some wonderful patches sent in by
# Luuk de Boer <luuk_de_boer@pi.net>.
#
# Revision 1.2  1998/04/08 18:32:03  kirk
# Applied changes submitted by Luuk de Boer <luuk_de_boer@pi.net>.. Thanks!
#
# Revision 1.1  1998/03/19 06:43:14  kirk
# Added support for /var/log/secure
#
##########################################################################

########################################################
# This was written and is maintained by:
#    Kirk Bauer <kirk@kaybee.org>
#
# Please send all comments, suggestions, bug reports,
#    etc, to kirk@kaybee.org.
#
########################################################

#$Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'};
$DoLookup = $ENV{'secure_ip_lookup'};
$Ignore = $ENV{'ignore_services'};

sub LookupIP {
   my ($name, $a1, $a2,$a3,$a4,$PackedAddr,$Addr);
   $Addr = $_[0];
   ($a1,$a2,$a3,$a4) = split /\./,$Addr;
   $PackedAddr = pack('C4',$a1,$a2,$a3,$a4);
   if ($DoLookup) {
      if ($name = gethostbyaddr ($PackedAddr,2)) {
         return ($name . " (" . $Addr . ")");
      } else {
         return ($Addr);
      }
   }
   else {
      return ($Addr);
   }
}

while (defined($ThisLine = <STDIN>)) {
   if ( ($Host,$User) = ($ThisLine =~ /^... .. ..:..:.. [^ ]+ login: FAILED LOGIN [0123456789]+ FROM ([^ ]+) FOR ([^,]+),/ ) ) {
      $FailedLogins->{$User}->{$Host}++;
   }
   elsif ( ($Service,$IP) = ($ThisLine =~ /^... .. ..:..:.. [^ ]+ ([^ ]+)\[[0123456789]+\]: connect from ([0123456789]+\.[0123456789]+\.[0123456789]+\.[0123456789]+)$/) ) {
      $Name = LookupIP ($IP);
      $Connections->{$Service}->{$Name}++;
   }
   elsif ( ($Service,$IP) = ($ThisLine =~ /^... .. ..:..:.. [^ ]+ ([^ ]+)\[[0123456789]+\]: refused connect from ([0123456789]+\.[0123456789]+\.[0123456789]+\.[0123456789]+)$/) ) {
      $Name = LookupIP ($IP);
      $Refused->{$Service}->{$Name}++;
   }
   elsif ( ($Service,$Name) = ($ThisLine =~ /^... .. ..:..:.. [^ ]+ ([^ ]+)\[[0123456789]+\]: refused connect from (.*)$/) ) {
      $Refused->{$Service}->{$Name}++;
   }
   elsif ( ($Service,$Name) = ($ThisLine =~ /^... .. ..:..:.. [^ ]+ ([^ ]+)\[[0123456789]+\]: connect from ([^ \n]+)$/) ) {
      $Connections->{$Service}->{$Name}++;
   }
   elsif ( ($Service,$Name) = ($ThisLine =~ /^... .. ..:..:.. [^ ]+ xinetd\[[0123456789]+\]: START: ([^ ]+) pid=[0123456789]+ from=([^ \n]+)$/) ) {
      $Connections->{$Service}->{$Name}++;
   }
   elsif ( ($Service) = ($ThisLine =~ /^... .. ..:..:.. [^ ]+ xinetd\[[0123456789]+\]: EXIT: ([^ ]+) pid=[0123456789]+/) ) {
      #ignore...
   }
   elsif ( $ThisLine =~ s/^... .. ..:..:.. [^ ]+ ([^ ]+)\[[0123456789]+\]: warning: can\'t get client address: No route to host$/$1/ ) {
      chomp ($ThisLine);
      $NoIP->{$ThisLine}++;
   }
   elsif ( $ThisLine =~ m/^... .. ..:..:.. [^ ]+ [^ ]+\[[0123456789]+\]: connect from localhost$/ ) {
      #ignore...
   }
   elsif ( $ThisLine =~ s/^... .. ..:..:.. [^ ]+ ([^ ]+)\[[0123456789]+\]: warning: can\'t get client address: Network is unreachable$/$1/ ) {
      chomp ($ThisLine);
      $NoIP->{$ThisLine}++;
   }
   elsif ( $ThisLine =~ s/^... .. ..:..:.. [^ ]+ ([^ ]+)\[[0123456789]+\]: warning: can\'t get client address: Connection reset by peer$/$1/ ) {
      chomp ($ThisLine);
      $NoIP->{$ThisLine}++;
   }
   elsif ( $ThisLine =~ s/^... .. ..:..:.. [^ ]+ ([^ ]+)\[[0123456789]+\]: warning: can\'t get client address: Connection timed out$/$1/ ) {
      chomp ($ThisLine);
      $NoIP->{$ThisLine}++;
   }
   elsif ( $ThisLine =~ s/^... .. ..:..:.. [^ ]+ ([^ ]+)\[[0123456789]+\]: connect from unknown$/$1/ ) {
      chomp ($ThisLine);
      $NoIP->{$ThisLine}++;
   }
   elsif ( ($Service,$Err) = ($ThisLine =~ /^... .. ..:..:.. [^ ]+ ([^ ]+)\[[0123456789]+\]: error: (.+)$/) ) {
      chomp($Err);
      $Error{$Service}{$Err}++;
   }
   elsif ( ($Service,$Err) = ($ThisLine =~ /^... .. ..:..:.. [^ ]+ ([^ ]+): (FAILED LOGIN SESSION FROM [^ ]+ FOR , .*)$/ ) ) {
      chomp($Err);
      $Error{$Service}{$Err}++;
   }
   elsif ( $ThisLine =~ /warning: can.t get client address: Connection refused/) {
      # Nothing
   }
   elsif ( $ThisLine =~ /^... .. ..:..:.. [^ ]+ login: ROOT LOGIN ON tty[0-9]+/) {
      $RootLoginTTY++
   }
   else {
      # Unmatched entries...
      push @OtherList,$ThisLine;
   }
}

if ( (keys %{$Connections}) or
      (keys %{$Refused}) or
      (keys %{$FailedLogins}) or
      (keys %{$NoIP}) or 
      (keys %{Error}) or
      ($RootLoginTTY) or
      ($#OtherList >= 0)
   ) {

   print "\n\n ---------------- Connections (secure-log) Begin ------------------- \n";

   if (keys %{$Connections}) {
      print "\nConnections:\n";
      foreach $ThisOne (keys %{$Connections}) {
         unless ($Ignore =~ /$ThisOne/) { 
            print "   Service " . $ThisOne . ":\n";
            foreach $OtherOne (keys %{$Connections->{$ThisOne}}) {
               print "      " . $OtherOne . ": " . $Connections->{$ThisOne}->{$OtherOne} . " Time(s)\n";
            }
         }
      }
   }

   if (keys %{$Refused}) {
      print "\nRefused Connections:\n";
      foreach $ThisOne (keys %{$Refused}) {
         print "   Service " . $ThisOne . ":\n";
         foreach $OtherOne (keys %{$Refused->{$ThisOne}}) {
            print "      " . $OtherOne . ": " . $Refused->{$ThisOne}->{$OtherOne} . " Time(s)\n";
         }
      }
   }

   if (keys %{$FailedLogins}) {
      print "\nFailed logins:\n";
      foreach $ThisOne (keys %{$FailedLogins}) {
         print "   User " . $ThisOne . ":\n";
         foreach $OtherOne (keys %{$FailedLogins->{$ThisOne}}) {
            print "      " . $OtherOne . ": " . $FailedLogins->{$ThisOne}->{$OtherOne} . " Time(s)\n";
         }
      }
   }

   if (keys %{$NoIP}) {
      print "\nCouldn't get client IPs for connections to:\n";
      foreach $ThisOne (keys %{$NoIP}) {
         print "   " . $ThisOne . ": " . $NoIP->{$ThisOne} . " Time(s)\n";
      }
   }

   if (keys %{Error}) {
      print "\nErrors:\n";
      foreach $Service (sort {$a cmp $b} keys %{Error}) {
         print "   Service " . $Service . ":\n";
         foreach $Err (sort {$a cmp $b} keys %{$Error{$Service}}) {
            print "      " . $Err . ": " . $Error{$Service}{$Err} . " Time(s)\n";
         }
      }
   }

   if ($RootLoginTTY) {
      print "\nRoot logins on tty\'s: $RootLoginTTY Time(s).\n";
   }

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

   print "\n\n ----------------- Connections (secure-log) End -------------------- \n\n";

}

exit(0);



