#!/usr/bin/perl -w
##########################################################################
# $Id: sshd,v 1.7 1998/06/01 20:42:46 kirk Exp $
##########################################################################
# $Log: sshd,v $
# Revision 1.7  1998/06/01 20:42:46  kirk
# Fixed bug found by Brian Aljian <brian@aljian.com>...
#
# Revision 1.6  1998/06/01 20:33:26  kirk
# Applied changes submitted by Bert de Bruijn <bob@ace.ulyssis.student.kuleuven.ac.be>...
#
# Revision 1.5  1998/03/19 03:12:54  kirk
# Fixed a few problems
#
# Revision 1.4  1998/02/26 08:47:17  kirk
# Added a fun 'fortune' module...
# Applied SSHD patch from Jonathan Stanton <jonathan@cs.jhu.edu>
#
# Revision 1.3  1998/02/23 01:17:00  kirk
# Getting ready for a first distribution
#
# Revision 1.2  1998/02/22 22:36:31  kirk
# Created named...
#
# Revision 1.1  1998/02/22 03:07:54  kirk
# Re-organization
#
# Revision 1.3  1998/02/12 06:07:22  kirk
# Fixed a few things...
#
# Revision 1.2  1998/02/12 02:23:24  kirk
# Finished the sshd filter...
#
# Revision 1.1  1998/01/25 04:07:48  kirk
# 'sshd' module started.
#
##########################################################################

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

$Debug = $ENV{'LOGWATCH_DEBUG'};
$Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'};

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 ($name = gethostbyaddr ($PackedAddr,2)) {
      return ($name . " (" . $Addr . ")");
   } else {
      return ($Addr);
   }
}

# No sense in running if 'sshd' doesn't even exist on this system...
unless (( -f "/usr/sbin/sshd" ) or ( -f "/usr/local/sbin/sshd")) {
    exit (0);
}

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

$ThisLine = <STDIN>;
while (defined($ThisLine)) {
    if ( $Debug >= 5 ) {
	print STDERR "DEBUG: Line Number " . $DebugCounter . ":\n";
	print STDERR "DEBUG: " . $ThisLine;
    }
    $NeedNextLine = 1;
    if ( ($ThisLine =~ m/^log: Connection from/) and (not $ThisLine =~ m/not allowed/) ) {
	# Connected from host...
	$ThisLine =~ s/^log: Connection from ([1234567890]*\.[1234567890]*\.[1234567890]*\.[1234567890]*) port [0123456789]*$/$1/ ;
	chomp($ThisLine);
	$ThisLine = LookupIP ($ThisLine);
	$ConnectFrom{$ThisLine}++;
	if ( $Debug >= 5 ) {
	    print STDERR "DEBUG: Found -Connection From- Line (" . $ThisLine . ") -- Reading another line\n";
	    $DebugCounter++;
        }
	while (($NeedNextLine == 1) && (defined($NextLine = <STDIN>))) {
	    if ( $Debug >= 5 ) {
		print STDERR "DEBUG: Line Number " . $DebugCounter . ":\n";
		print STDERR "DEBUG: " . $NextLine;
	    }
	    if ( $NextLine =~ s/^log: RSA authentication for ([^ ]*) accepted\./$1/ ) {
		chomp($NextLine);
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: Found -RSA Auth Accepted- line (" . $NextLine . ")\n";
		}
		$NextLine = "   " . $NextLine . " logged in from " . $ThisLine . "\n";
		$Users{$NextLine}++;;
	    }
	    elsif ( $NextLine =~ s/^log: Rhosts with RSA host authentication accepted for ([^ ,]*), ([^ ]*) on (.*)\./$2 as ($1)/ ) {
		chomp($NextLine);
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: Found -Rhosts RSA host Auth Accepted- line (" . $NextLine . ")\n";
		}
		$NextLine = "   " . $NextLine . " logged in from " . $ThisLine . "\n";
		$Users{$NextLine}++;;
	    }
	    elsif ( $NextLine =~ s/^log: Password authentication for ([^ ]*) accepted\./$1/ ) {
		chomp($NextLine);
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: Found -Password Auth Accepted- line (" . $NextLine . ")\n";
		}
		$NextLine = "   " . $NextLine . " logged in from " . $ThisLine . "\n";
		$Users{$NextLine}++;;
	    }
	    elsif ( $NextLine =~ s/^log: Rhosts authentication refused for ([^ ]*) (.*)/$1 refused because: $2/ ) {
		chomp($NextLine);
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: Found -Rhosts Auth Refused- line (" . $NextLine . ")\n";
		}
		$NextLine = "   " . $NextLine . ".  Attempt from " . $ThisLine . "\n";
		$Users{$NextLine}++;;
	    }
	    elsif ( $NextLine =~ s/^log: ROOT LOGIN as ([^ ]*) from ([^ ]*)/$1/ ) {
		chomp($NextLine);
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: Found -ROOT LOGIN- line (" . $NextLine . ")\n";
		}
		$NextLine = "   " . $NextLine . " logged in as ROOT from " . $ThisLine . "\n";
		$Users{$NextLine}++;;
	    }
	    elsif ( $NextLine =~ s/^log: executing remote command as (user)* ([^ ]*)/$2/ ) {
		chomp($NextLine);
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: Found -Remote Command Executed- line (" . $NextLine . ")\n";
		}
		$NextLine = "   " . $NextLine . " executed a command from " . $ThisLine . "\n";
		$Users{$NextLine}++;;
	    }
	    elsif ( $NextLine =~ s/^log: executing remote command as root: (.*)/$1/ ) {
		chomp($NextLine);
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: Found -Remote Root Command Executed- line (" . $NextLine . ")\n";
		}
		$NextLine = "   " . "root executed: " . $NextLine . ", from " . $ThisLine . "\n";
		$Users{$NextLine}++;;
	    }
	    elsif ( $NextLine =~ m/^fatal: Did not receive ident string\./ ) {
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: Found -Did not receive ident- line\n";
		}
		push @NoIdent,$ThisLine;
	    }
	    else {
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: No matches... keeping current line.\n";
		}
		$ThisLine = $NextLine;
		$NeedNextLine = 0;
	    }
	}
    }
    elsif ( $ThisLine =~ m/^log: Closing connection to/ ) {
	# Don't care about this...
	if ( $Debug >= 5 ) {
	    print STDERR "DEBUG: Found -Closing Connection- line\n";
	}
    }
    elsif ( $ThisLine =~ m/^fatal: Connection closed by remote host\./ ) {
	# Don't care about this...
	if ( $Debug >= 5 ) {
	    print STDERR "DEBUG: Found -Connection Closed by Remote Host- line\n";
	}
    }
    elsif ( $ThisLine =~ m/^log: Received signal 15; terminating\./ ) {
	# Don't care about this...
	if ( $Debug >= 5 ) {
	    print STDERR "DEBUG: Found -Signal 15 Terminating- line\n";
	}
    }
    elsif ( $ThisLine =~ m/^log: Server listening on port 22\./ ) {
	# Don't care about this...
	if ( $Debug >= 5 ) {
	    print STDERR "DEBUG: Found -Listening on port 22- line\n";
	}
    }
    elsif ( $ThisLine =~ m/^log: Generating .* RSA key\./ ) {
	# Don't care about this...
	if ( $Debug >= 5 ) {
	    print STDERR "DEBUG: Found -Generating RSA key- line\n";
	}
    }
    elsif ( $ThisLine =~ m/^log: RSA key generation complete\./ ) {
	# Don't care about this...
	if ( $Debug >= 5 ) {
	    print STDERR "DEBUG: Found -Keygen complete- line\n";
	}
    }
    elsif ( $ThisLine =~ m/^log: Could not reverse map address/ ) {
       	$ThisLine =~ s/^log: Could not reverse map address ([1234567890]*\.[1234567890]*\.[1234567890]*\.[1234567890]*)\.$/$1/ ;
	chomp($ThisLine);
	if ( $Debug >= 5 ) {
	    print STDERR "DEBUG: Found -Could Not Reverse Map- line (" . $ThisLine . ") -- Reading next line\n";
	    $DebugCounter++;
	}
	push @NoRevMap,$ThisLine;
	if (defined($NextLine = <STDIN>)) {
	    if ( $Debug >= 5 ) {
		print STDERR "DEBUG: Line Number " . $DebugCounter . ":\n";
		print STDERR "DEBUG: " . $NextLine;
	    }
	    if ( $NextLine =~ m/^fatal: Did not receive ident string\./ ) {
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: Found -Did not receive ident- line\n";
		}
		push @NoIdent,$ThisLine;
	    }
	    else {
		if ( $Debug >= 5 ) {
		    print STDERR "DEBUG: No matches... keeping current line.\n";
		}
		$ThisLine = $NextLine;
		$NeedNextLine = 0;
	    }
	}
    }
    else {
	# Report any unmatched entries...
   unless ($ThisLine =~ /fwd X11 connect/) {
	   push @OtherList,$ThisLine;
   }
    }
    if ($NeedNextLine == 1) {
	if ( $Debug >= 5 ) {
	    $DebugCounter++;
	}
	$ThisLine = <STDIN>;
    }
}

if ( ( ($Detail >= 5) and (keys %ConnectFrom) ) or
     ( ($Detail >= 10) and (@NoRevMap) ) or
     ( ($Detail >= 10) and (@NoIdent) ) or
     ( keys %Users ) or
     ( @OtherList ) 
     ) {

    print "\n\n --------------------- SSHD Begin ------------------------ \n";
    
    if ( ( $Detail >= 5 ) or (keys %ConnectFrom) ) {
	print "\nConnections:\n";
	foreach $ThisOne (keys %ConnectFrom) {
	    print "   " . $ThisOne . ": " . $ConnectFrom{$ThisOne} . " Connection(s)\n";
	}
    }
    
    if ( $Detail >= 10 ) {
	if ($#NoRevMap >= 0) {
	    print "\nCouldn't resolve these IPs:\n";
	    foreach $ThisOne (@NoRevMap) {
		print "   " . $ThisOne . "\n";
	    }
	}
	if ($#NoIdent >= 0) {
	    print "\nDid not get an ident string from these:\n";
	    foreach $ThisOne (@NoIdent) {
		print "   " . $ThisOne . "\n";
	    }
	}
    }
    
    if (keys %Users) {
	print "\nUsers logging in through sshd:\n";
	foreach $ThisOne (keys %Users) {
	    print "   " . $ThisOne . ": " . $Users{$ThisOne} . " Times(s)\n";
	}
    }
    
    if ($#OtherList >= 0) {
	print "\n**Unmatched Entries**\n";
	print @OtherList;
    }
    
    print "\n\n ---------------------- SSHD End ------------------------- \n\n";

}
    
exit(0);
    


