#! /usr/bin/perl # # This tool will help extract the XML log file produced by Samhain # Put it into a more readable format that can then be run by CRON # and e-mailed to a user. # # Created: Ben # # # Updates: # JUL 05 ver 1.1: - Updata to add in checkpint subroutine, this checks # the scalar length # that is return from the log file if is is a good size # the program gets the value, if not value is returned it will not print it # to the report. # # JUL 07 ver 1.2: - Update to the Code to handle reporting selection # from the command line. # Users are able to pass in [ReadOnly][LogFiles][Attributes]. # Better support for date # # Version: 1.2 use strict; use XML::Simple; use Tie::File; use POSIX qw(strftime); my $date=strftime("%a %b %d %H:%M:%S %Y", localtime()); my $tdate = `date +'%m%d%y'`; # Just to time stamp the files my $hostname = `hostname`; chomp($hostname); my $policy = $ARGV[1]; &main(); sub main { unless (@ARGV == 2) { printf("Usage: $0 Samhain_report.xml \n"); exit(0); } printf("## Reporting Starting\n"); &eatfile(); &extractdata($policy); printf("## Report completed\n"); printf("## Your new report file has been created : Samhain-report-$hostname.$tdate\n"); } # This routine will pull the data from the XML file, and sort through it # and look for the policy for [ReadOnly], once it has bfound that it will detected all the changes # within the policy # sub extractdata { my $xmlfile = $ARGV[0]; my $config = XMLin($xmlfile); # Create new report file open(RP, ">fmre_report-$hostname.$tdate") || die ("Unable to open new report file, $!\n"); printf RP ("Samhain CRITICAL REPORT FOR $hostname\n"); printf RP ("\n"); printf RP ("This report was created on : $date\n"); printf RP ("Samhain Reporting Tool version 1.0\n"); printf RP ("Created: Ben Cuthbert \n"); printf RP ("\n"); printf RP ("Report for !! $_[0] Policy !!\n"); printf RP ("\n"); # STart getting all of the data from xml file foreach my $alert (@{$config->{'LOG'}}) { if($alert->{msg} =~ /POLICY \[$_[0]]/) { # Check we are on the correct policy print RP ("File Changed: $alert->{path}\n"); &checkprint("$alert->{mtime_new}","Time Changed Old: $alert->{mtime_new}"); &checkprint("$alert->{mtime_new}","Time Changed New: $alert->{mtime_old}"); &checkprint("$alert->{mode_old}","Mode Old: $alert->{mode_old}"); &checkprint("$alert->{mode_new}","Mode New: $alert->{mode_new}"); &checkprint("$alert->{chksum_old}","CheckSum Old: $alert->{chksum_old}"); &checkprint("$alert->{chksum_new}","CheckSum New: $alert->{chksum_new}"); &checkprint("$alert->{size_new}","Size New: $alert->{size_new}"); &checkprint("$alert->{size_old}","Size Old: $alert->{size_old}"); printf RP ("\n"); } } printf RP ("Created Using: Samhain XML Reporting tool.\n"); printf RP ("Created By: Ben Cuthbert ben\@deephouse.co.za.\n"); close(RP); } # This helps with logs that do not have Entires for Certain modes ie --rwx # Get the scalar back, check the lenght then print out if the lenght is # bigger than 1 sub checkprint { chomp; my $l = length($_[0]); if($l gt 1) { printf RP ("$_[1]\n"); } } # We need to change the structure of the HRML file from FMRE # so that we have the following tree structure. #VAR1 = { # 'LOG' => [ # { # 'msg' = 'value' # # The reason for this is it makes extraction better. # # So we open XML file and enter the following details. # please at top of file # place at bottom of file # remove trails, as we do not require them as # log files are rotated every day. # reports will only run on the day. sub eatfile { # Search and reaplce log with LOG, makes it easy open(FH, "$ARGV[0]") || die ("Unable to ammend file \n"); open(FW, ">tmp.xml") || die ("Unable to ammend file \n"); while () { $_ =~ s/^---*//g; $_ =~ s/log/LOG/g; $_ =~ s///g; $_ =~ s/<\/trail>//g; $_ =~ s/Log file printed//g; printf FW $_; } close(FW); close(FH); system("mv tmp.xml $ARGV[0]"); # Put in & at top and bottom open(FH, ">>$ARGV[0]") || die ("Unable to ammend file \n"); seek FH,0,2; printf FH ""; close(FH); ## Star the insert at the top and bottom, close the config tie(my @FH1, 'Tie::File', $ARGV[0]) or die("Unable to read file, $!\n"); unshift @FH1, ''; untie @FH1; printf ("Xml file has been modified to run with this program \n"); }