commit e75831439a52eab9a011d3eb038139d43787e1d9 Author: bluesaxman Date: Wed Jun 12 09:22:28 2019 -0600 initial git commit for squeegy diff --git a/README.md b/README.md new file mode 100644 index 0000000..a25da94 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +Squeegy is designed to perform quick file table wipes and smart disk checks on many drives at once. +It is designed to be quick and to accuratly and clearly provide feedback to the user in order to separate out bad and good drives, +and to determin if a drive has actually been properly wiped. diff --git a/wipe.pl b/wipe.pl new file mode 100755 index 0000000..519a274 --- /dev/null +++ b/wipe.pl @@ -0,0 +1,144 @@ +#!/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"); +}