<?xml version="1.0" encoding="windows-1252"?>
<node id="175289" title="Supervisor" created="2002-06-18 02:18:13" updated="2005-08-15 14:41:57">
<type id="1748">
sourcecode</type>
<author id="31366">
zejames</author>
<data>
<field name="doctext">
&lt;b&gt;supervise&lt;/b&gt;
&lt;br&gt;
&lt;code&gt;
#!/usr/bin/perl
#
# Author : Julien Bordet &lt;zejames@greyhats.org&gt;
#
# check md5 cheksums again those stored in a fingerprint file. When anything 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           =&gt; '',
            $NO_SUCH_FILE       =&gt; 'No such file',
            $MD5_ERROR          =&gt; 'Fingerprints do not correspond');

GetOptions('-f=s'       =&gt;      \$filelist);

$filelist ||= "";

open FILELIST, "&lt; $filelist" or die "Unable to open $filelist : $!\n";
while (&lt;FILELIST&gt;)
{
        next if ( m/^$/ or m/^#/ );
        my ($filename, $md5) = m!^([^:]+):(.*)$!;
        $result{$filename}-&gt;{'expected'} = $md5;
        if (! open FILE, "&lt; $filename") {
                warn "Unable to open $filename\n";
                $result{$filename}-&gt;{'error'} = $NO_SUCH_FILE;
                $result{$filename}-&gt;{'real'} = '';
                next;
        }
        my $ctx = Digest::MD5-&gt;new;
        $ctx-&gt;addfile(*FILE);
        my $digest = encode_base64($ctx-&gt;digest, '');
        $result{$filename}-&gt;{'real'} = $digest;
        if ($digest eq $md5) {
                $result{$filename}-&gt;{'error'} = $NO_ERROR;
        } else {
                $result{$filename}-&gt;{'error'} = $MD5_ERROR;
        }
}
close FILELIST;

foreach my $file (keys %result) {
        if ($result{$file}-&gt;{'error'}) {
                $text .= &lt;&lt;FIN;
Alert on file '$file' : $errors{$result{$file}-&gt;{'error'}}
        Last seen MD5 : $result{$file}-&gt;{'expected'}
        Current MD5   : $result{$file}-&gt;{'real'}

FIN
        }
}

if ($text) {
        my $mailer = new Mail::Send Subject =&gt; "Supervisor alert",
                                    To =&gt; "$adminmail";

        my $fh = $mailer-&gt;open;
        print $fh $text;
        $fh-&gt;close;

        print "Mail send to $adminmail : \n$text";
}
&lt;/code&gt;
&lt;br&gt;
&lt;b&gt;update&lt;/b&gt;
&lt;br&gt;
&lt;code&gt;
#!/usr/bin/perl -w
#
# Author : Julien Bordet &lt;zejames@greyhats.org&gt;
#
# 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'       =&gt;      \$filelist);

if (! -f $filelist) {
        open LIST, "&gt; $filelist" or die "Unable to create $filelist : $!\n";
        close LIST;
}

@filenames = @ARGV;
foreach my $filename (@filenames) {
        $md5{$filename} = '';
        if (open FILE, "&lt; $filename") {
                my $ctx = Digest::MD5-&gt;new;
                $ctx-&gt;addfile(*FILE);
                $md5{$filename} = encode_base64($ctx-&gt;digest, '');
                close FILE;
        }
}

@ARGV = ($filelist);
undef $/;
$^I = ".bak";
while (&lt;&gt;)
{
        foreach my $filename (@filenames) {
                my $digest = $md5{$filename};
                if ( m!\Q$filename\E:! and $digest) {   # File have been changed
                        s/^\Q$filename\E:.*?$/$filename:$digest/m;
                } elsif ($digest) {             # File is being added
                        $_ .= "$filename:$digest\n";
                } else {                        # File is being deleted
                        s/^\Q$filename\E:.*?\n//m;
                }
        }
        print;
}
&lt;/code&gt;

</field>
<field name="codedescription">
Supervisor is a set of 2 script :&lt;br&gt;
&lt;ul&gt;&lt;li&gt;Supervisor, that compares file md5 checksums with the ones stores in a fingerprint file
    &lt;li&gt;update, that updates information about supervised file into the fingerprint file&lt;/ul&gt;</field>
<field name="codecategory">
Cryptography</field>
<field name="codeauthor">
zejames (Julien Bordet &amp;lt;zejames@greyhats.org&amp;gt;)</field>
</data>
</node>
