squeegy/wipe.pl

145 lines
4.9 KiB
Perl
Raw Normal View History

2019-06-12 09:22:28 -06:00
#!/usr/bin/perl -w
use strict;
use warnings;
use Digest::MD5 "md5_base64";
use POSIX;
open (my $drand, "<", "/dev/urandom");
my $clobber;
read($drand, $clobber, 10240000);
close($drand);
my $clobsum = md5_base64($clobber);
my %color = (
"red" => "\e[0;31m",
"green" => "\e[0;32m",
"reset" => "\e[0m"
);
my @failed = ();
my $term = POSIX::Termios->new;
sub anykey {
print shift;
my $key;
my $oldflag = $term->getlflag;
$term->setlflag(ICANON);
system "stty", '-icanon', 'eol', "\001"; #ISNT POSIX compliant
$key = getc(STDIN);
$term->setlflag($oldflag);
system "stty", 'icanon', 'eol', "^@";
return $key
}
sub warning {
print shift;
return 0;
}
sub getdisks {
my $devices = `find /dev/sd*`;
my %listhash = ();
foreach(split("\n",$devices)) {
my $devicepath = $_;
my $serial = `udevadm info --query=all --name=$_ | grep SERIAL_SHORT | sed -e 's/^.*=//'`;
chomp( $serial );
if ( $serial ) {
print $devicepath."\t".$serial."\n";
$listhash{$_}{"path"} = $devicepath;
$listhash{$_}{"serial"} = $serial;
} else { next; }
}
return %listhash;
}
sub wipethemdrives {
my $diskid = shift;
my $disks = shift;
print $disks->{$diskid}{"path"}." - Serial:".$disks->{$diskid}{"serial"}." is being wiped...\n";
open(my $diskw, ">", $disks{$diskid}{"path"}) or return warning("could not open ".$disks{$diskid}{"path"});
# open(my $diskw, ">", "./test") or warning("could not open "."./test");
print $diskw $clobber;
close($diskw);
system("sync");
print "Wipe attempt complete, checking...\n";
open(my $diskr, "<", $disks{$diskid}{"path"}) or return warning("could not open ".$disks{$diskid}{"path"});
# open(my $diskr, "<", "./test") or warning("could not open "."./test");
my $diskdata;
read($diskr, $diskdata, 10240000);
my $disksum = md5_base64($diskdata);
close($diskr);
print "Disk Checksum: ".$disksum."\n";
if ($disksum eq $clobsum) {
print "Checksum ".$color{"green"}."PASSED!!!".$color{"reset"}."\n";
print $disks->{$diskid}{"path"}." is clean.\n";
return 1;
} else {
print "Wipe Checksum: ".$clobsum."\n";
print "Checksum ".$color{"red"}."FAILED!!!".$color{"reset"}."\n";
print $disks->{$diskid}{"path"}." did not take, it could be bad.\n";
return 0;
}
}
sub smartcheck {
# Do our smart disk thing...
my $diskid = shift;
my $disks = shift;
print "Checking S.M.A.R.T. variables...\n";
print 'smartctl '.$disks->{$diskid}{"path"}.' -A -f hex,id | grep "^0x"'."\n";
(my $smartcommand = `smartctl $disks->{$diskid}{"path"} -A -f hex,id | grep "^0x"`) or (print $!."\ncould not check smart data, skipping\n" and return 1);
for (split("\n",$smartcommand)) {
my @smartdata = split(/\s+/,$_);
$disks->{$diskid}{"smart"}{$smartdata[0]}{"id"} = $smartdata[0];
$disks->{$diskid}{"smart"}{$smartdata[0]}{"name"} = $smartdata[1];
$disks->{$diskid}{"smart"}{$smartdata[0]}{"flag"} = $smartdata[2];
$disks->{$diskid}{"smart"}{$smartdata[0]}{"value"} = $smartdata[3];
$disks->{$diskid}{"smart"}{$smartdata[0]}{"worst"} = $smartdata[4];
$disks->{$diskid}{"smart"}{$smartdata[0]}{"thresh"} = $smartdata[5];
$disks->{$diskid}{"smart"}{$smartdata[0]}{"type"} = $smartdata[6];
$disks->{$diskid}{"smart"}{$smartdata[0]}{"updated"} = $smartdata[7];
$disks->{$diskid}{"smart"}{$smartdata[0]}{"when_failed"} = $smartdata[8];
$disks->{$diskid}{"smart"}{$smartdata[0]}{"raw_value"} = $smartdata[9];
}
close( $smartcommand );
for my $smartentry (keys %{$disks->{$diskid}{"smart"}}) {
if ($disks->{$diskid}{"smart"}{$smartentry}{"id"} =~ /0x05|0x07|0xc4|0xc5|0xc6|0xc7/) {
print $disks->{$diskid}{"smart"}{$smartentry}{"id"}." ".$disks->{$diskid}{"smart"}{$smartentry}{"name"}."\t".$disks->{$diskid}{"smart"}{$smartentry}{"raw_value"}."\t";
if ($disks->{$diskid}{"smart"}{$smartentry}{"raw_value"} =~ /0|0\/0/) {
print $color{"green"}."Passed".$color{"reset"}."\n";
}else { print $color{"red"}."Failed".$color{"reset"}."\n"; return 0}
}
}
return 1;
}
while () {
my %disks = getdisks();
my $batchcount = keys %disks;
print "About to wipe ".$batchcount." drives with the following serial numbers:\n";
foreach my $diskid (keys %disks) {
print $disks{$diskid}{"serial"}."\n";
}
anykey("Hit any key to continue...\n");
foreach my $diskid (keys %disks) {
print "\e[J";
print "="x33;
printf '[ %-10s ]', $diskid;
print "="x33;
print "\n";
$disks{$diskid}{"wipe"} = wipethemdrives($diskid,\%disks);
if ($disks{$diskid}{"wipe"} == 1) {
$disks{$diskid}{"smartpass"} = smartcheck($diskid,\%disks);
if ($disks{$diskid}{"smartpass"} == 1) {
print "Smart looks good.\n";
} else { push(@failed, $disks{$diskid}{"serial"}); }
} else { push(@failed, $disks{$diskid}{"serial"}); }
print "="x80;
print "\n"x5;
}
print "The folowing drives did not wipe successfully,\nThey may need another attempt or they may be bad.\n";
print join("\n",@failed);
@failed = ();
print "\nWipe complete, insert more drives.\n";
anykey("Hit any key when ready to continue...\n");
}