http://qs321.pair.com?node_id=175289
Category: Cryptography
Author/Contact Info zejames (Julien Bordet <zejames@greyhats.org>)
Description: Supervisor is a set of 2 script :
  • Supervisor, that compares file md5 checksums with the ones stores in a fingerprint file
  • update, that updates information about supervised file into the fingerprint file
supervise
#!/usr/bin/perl
#
# Author : Julien Bordet <zejames@greyhats.org>
#
# check md5 cheksums again those stored in a fingerprint file. When an
+ything has
# changed, send an alert email.
#
# fingerprint file should be passed with the -f switch
#

use strict;
use Getopt::Long;
use Digest::MD5;
use Mail::Send;
use MIME::Base64;

use vars qw (   $NO_ERROR $NO_SUCH_FILE $MD5_ERROR
                %errors  %result $adminmail $filelist $text
            );

$adminmail = 'julien';

$NO_ERROR     = 0;
$NO_SUCH_FILE = 1;
$MD5_ERROR    = 2;

%errors = ( $NO_ERROR           => '',
            $NO_SUCH_FILE       => 'No such file',
            $MD5_ERROR          => 'Fingerprints do not correspond');

GetOptions('-f=s'       =>      \$filelist);

$filelist ||= "";

open FILELIST, "< $filelist" or die "Unable to open $filelist : $!\n";
while (<FILELIST>)
{
        next if ( m/^$/ or m/^#/ );
        my ($filename, $md5) = m!^([^:]+):(.*)$!;
        $result{$filename}->{'expected'} = $md5;
        if (! open FILE, "< $filename") {
                warn "Unable to open $filename\n";
                $result{$filename}->{'error'} = $NO_SUCH_FILE;
                $result{$filename}->{'real'} = '';
                next;
        }
        my $ctx = Digest::MD5->new;
        $ctx->addfile(*FILE);
        my $digest = encode_base64($ctx->digest, '');
        $result{$filename}->{'real'} = $digest;
        if ($digest eq $md5) {
                $result{$filename}->{'error'} = $NO_ERROR;
        } else {
                $result{$filename}->{'error'} = $MD5_ERROR;
        }
}
close FILELIST;

foreach my $file (keys %result) {
        if ($result{$file}->{'error'}) {
                $text .= <<FIN;
Alert on file '$file' : $errors{$result{$file}->{'error'}}
        Last seen MD5 : $result{$file}->{'expected'}
        Current MD5   : $result{$file}->{'real'}

FIN
        }
}

if ($text) {
        my $mailer = new Mail::Send Subject => "Supervisor alert",
                                    To => "$adminmail";

        my $fh = $mailer->open;
        print $fh $text;
        $fh->close;

        print "Mail send to $adminmail : \n$text";
}

update
#!/usr/bin/perl -w
#
# Author : Julien Bordet <zejames@greyhats.org>
#
# Update a md5 fingerprint file. Supervised file name should be passed
+ as
# parameters : if they changed, their md5 is updated. If they are new,
+ they are
# added. If they do not exist anylonger, their entry is deleted in the
+ fingerprint
# file
#
# fingerprint file should be passed with the -f switch
#

use strict;
use Getopt::Long;
use Digest::MD5;
use MIME::Base64;

use vars qw ( @filenames %md5 $filelist );

my $filename = "";

GetOptions('-f=s'       =>      \$filelist);

if (! -f $filelist) {
        open LIST, "> $filelist" or die "Unable to create $filelist : 
+$!\n";
        close LIST;
}

@filenames = @ARGV;
foreach my $filename (@filenames) {
        $md5{$filename} = '';
        if (open FILE, "< $filename") {
                my $ctx = Digest::MD5->new;
                $ctx->addfile(*FILE);
                $md5{$filename} = encode_base64($ctx->digest, '');
                close FILE;
        }
}

@ARGV = ($filelist);
undef $/;
$^I = ".bak";
while (<>)
{
        foreach my $filename (@filenames) {
                my $digest = $md5{$filename};
                if ( m!\Q$filename\E:! and $digest) {   # File have be
+en changed
                        s/^\Q$filename\E:.*?$/$filename:$digest/m;
                } elsif ($digest) {             # File is being added
                        $_ .= "$filename:$digest\n";
                } else {                        # File is being delete
+d
                        s/^\Q$filename\E:.*?\n//m;
                }
        }
        print;
}