#!/usr/bin/perl # # Author : Julien Bordet # # 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 => '', $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 () { 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 .= <{'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"; } #### #!/usr/bin/perl -w # # Author : Julien Bordet # # 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 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; }