|
The script "dodwipe_k93" will perform a DoD style disk wipe of a file,
logical volume, or disk partition. It performs 3 passes, first pass
fills the space with zero's using an octal 0 character, second pass
fills the space with one's using an octal 377 character, and the third
pass fills the space with random bits.
#!/usr/bin/ksh93
################################################################
function usagemsg_dodwipe_k93 {
print "
Program: dodwipe_k93
This script will perform a DoD style disk wipe of a file, logical
volume, or disk partition. It performs 3 passes, first pass fills the
space with zero's using an octal 0 character, second pass fills the
space with one's using an octal 377 character, and the third pass fills
the space with random bits.
Usage: ${1##*/} [-?vV] [-w] [-1|-2|-3] -f fileName | -l lvName | -p pvName
Where:
-f fileName = full path file name of a file to wipe clean (/home/username/filename)
-l lvName = full path file name of a logical volume to wipe clean (/dev/vgName/lvName)
-p pvName = full path file name of a physical volume to wipe clean (/dev/rdsk/sdx#)
-w = turn off warning message and confirmation prompt
-1 = Do NOT perform Pass 1: Do NOT overwrite space with zero's (0)
-2 = Do NOT perform Pass 2: Do NOT overwrite space with one's (1)
-3 = Do NOT perform Pass 3: Do NOT overwrite space with random bits
-v = Verbose mode - displays dodwipe_k93 function info
-V = Very Verbose Mode - debug output displayed
-? = Help - display this message
Author: Dana French (dfrench@mtxia.com)
Copyright 2014, All Rights Reserved
\"AutoContent\" enabled
"
}
################################################################
####
#### Description:
####
#### This script will perform a DoD style disk wipe of a file, logical
#### volume, or disk partition. It performs 3 passes, first pass fills the
#### space with zero's using an octal 0 character, second pass fills the
#### space with one's using an octal 377 character, and the third pass fills
#### the space with random bits.
####
#### Assumptions:
####
#### This script assumes the existance of /dev/zero to generate continuous
#### stream of 0's. If /dev/zero does not exist, this script will generate
#### it's own continuous stream of zero's or one's, but it takes much longer
#### to run.
####
#### Dependencies:
####
#### This script is dependent upon the Unix utility "dd" and uses it to
#### overwrite logical volumes and physical volumes.
####
#### Products:
####
#### The product of this shell script are wiped clean and overwritten files,
#### logical volumes and physical volumes. The result is NOT a newly
#### initialize file, logical volume, or physical volume. The result is a
#### file, LV, or PV where every bit has been overwritten multiple times,
#### then every byte is overwritten with a random set of bits.
####
#### Configured Usage:
####
#### This shell script can be executed as a standalone script, or included in
#### a function library to be referenced and used by other shell scripts.
####
#### Details:
####
################################################################
configure_dodwipe_k93()
{
####
#### Notice this function is a POSIX function so that it can see local
#### and global variables from calling functions and scripts.
####
#### Configuration parameters can be stored in a file and
#### this script can be dynamically reconfigured by sending
#### the running script a HUP signal using the kill command.
####
#### Configuration variables can be defined in the configuration file using
#### the same syntax as defining a shell variable, e.g.: VARIABLE="value"
CFILE=~/.dodwipe_k93.conf
(( VERBOSE == TRUE )) && print -- "# Configuration File: ${CFILE}"
if [[ -f ${CFILE} ]]
then
(( VERBOSE == TRUE )) && cat ${CFILE}
. ${CFILE}
fi
return 0
}
################################################################
function dodwipe_k93 {
typeset VERSION="1.0"
typeset TRUE="1"
typeset FALSE="0"
typeset VERBOSE="${FALSE}"
typeset VERYVERB="${FALSE}"
typeset FILETOGGLE="${FALSE}"
typeset FINAME=""
typeset LVTOGGLE="${FALSE}"
typeset LVNAME=""
typeset PVTOGGLE="${FALSE}"
typeset PVNAME=""
typeset WARNTOGGLE="${TRUE}"
typeset P1TOGGLE="${TRUE}"
typeset P2TOGGLE="${TRUE}"
typeset P3TOGGLE="${TRUE}"
typeset BSIZE="1024"
typeset CFILE
typeset TFILE
typeset BLOCK
typeset SKIP
typeset BCNT
typeset ANS
typeset LV
typeset PV
typeset OF
typeset R
typeset i
####
#### Set up a trap of the HUP signal to cause this script
#### to dynamically configure or reconfigure itself upon
#### receipt of the HUP signal.
trap "configure_dodwipe_k93 ${0}" HUP
#### Read the configuration file and initialize variables by
#### sending this script a HUP signal
kill -HUP ${$}
#### Process the command line options and arguments.
while getopts ":vVw123f:l:p:" OPTION
do
case "${OPTION}" in
'f') FITOGGLE="${TRUE}"
FINAME="${OPTARG}";;
'l') LVTOGGLE="${TRUE}"
LVNAME="${OPTARG}";;
'p') PVTOGGLE="${TRUE}"
PVNAME="${OPTARG}";;
'w') WARNTOGGLE="${FALSE}";;
'1') P1TOGGLE="${FALSE}"
P2TOGGLE="${FALSE}"
P3TOGGLE="${FALSE}";;
'2') P2TOGGLE="${FALSE}"
P3TOGGLE="${FALSE}";;
'3') P3TOGGLE="${FALSE}";;
'v') VERBOSE="${TRUE}";;
'V') VERYVERB="${TRUE}";;
'?') usagemsg_dodwipe_k93 "${0}" && return 1 ;;
':') usagemsg_dodwipe_k93 "${0}" && return 1 ;;
'#') usagemsg_dodwipe_k93 "${0}" && return 1 ;;
esac
done
shift $(( ${OPTIND} - 1 ))
(( VERYVERB == TRUE )) && set -x
(( VERYVERB == TRUE )) && VERBOSE="${TRUE}"
(( VERBOSE == TRUE )) && print -u 2 "# Program Name...: ${0}"
(( VERBOSE == TRUE )) && print -u 2 "# Version........: ${VERSION}"
(( VERBOSE == TRUE )) && print -u 2 "# Block Size.....: ${BSIZE}"
(( VERBOSE == TRUE )) && (( P1TOGGLE == TRUE )) && print -u 2 "# PASS 1 Request.: TRUE"
(( VERBOSE == TRUE )) && (( P2TOGGLE == TRUE )) && print -u 2 "# PASS 2 Request.: TRUE"
(( VERBOSE == TRUE )) && (( P3TOGGLE == TRUE )) && print -u 2 "# PASS 3 Request.: TRUE"
(( VERBOSE == TRUE )) && (( P1TOGGLE == FALSE )) && print -u 2 "# PASS 1 Request.: FALSE"
(( VERBOSE == TRUE )) && (( P2TOGGLE == FALSE )) && print -u 2 "# PASS 2 Request.: FALSE"
(( VERBOSE == TRUE )) && (( P3TOGGLE == FALSE )) && print -u 2 "# PASS 3 Request.: FALSE"
################################################################
####
#### Check the command line options and arguments and verify that required
#### information has been provided, and that it is of the correct type, and
#### that it makes sense. If anything is incorrect, then return from this
#### function and display the usage message by trapping the exit.
trap "usagemsg_dodwipe_k93 ${0}" EXIT
####
#### Check the file name, logical volume, and physical volume toggle
#### variables. If they are all set to FALSE, issue an error message and
#### return from the script. Tell the user they must specify at least one of
#### these.
if (( FITOGGLE == FALSE )) &&
(( LVTOGGLE == FALSE )) &&
(( PVTOGGLE == FALSE ))
then
print -u 2 -- "# SYNTAX ERROR: You must specify a file, logical volume, or physical partition."
return 10
fi
####
#### If the user specified a filename to wipe on the command line, check to see if
#### it is a regular file. If not, issue an error message and return from the script.
if (( FITOGGLE == TRUE ))
then
OF="${FINAME}"
if [[ ! -f "${FINAME}" ]]
then
print -u 2 -- "# $( ls -l ${FINAME} )"
print -u 2 -- "# ERROR: The file name specified \"${FINAME}\" is not a regular file."
return 11
fi
(( VERBOSE == TRUE )) && print -u 2 "# File Name......: ${FINAME}"
fi
####
#### If the user specified a logical volume to wipe on the command line, check to see if
#### it is a block device file. If not, issue an error message and return from the script.
if (( LVTOGGLE == TRUE )) && OF="${LVNAME}"
then
OF="${LVNAME}"
if [[ ! -b "${LVNAME}" ]]
then
print -u 2 -- "# $( ls -l ${LVNAME} )"
print -u 2 -- "# ERROR: The Logical Volume name specified \"${LVNAME}\" is not a block device."
return 12
fi
(( VERBOSE == TRUE )) && print -u 2 "# Logical Volume.: ${LVNAME}"
fi
####
#### If the user specified a logical volume to wipe on the command line, check to see if
#### it is a block device file. If not, issue an error message and return from the script.
if (( PVTOGGLE == TRUE )) && OF="${PVNAME}"
then
OF="${PVNAME}"
if [[ ! -c "${PVNAME}" ]]
then
print -u 2 -- "# $( ls -l ${PVNAME} )"
print -u 2 -- "# ERROR: The Physical Volume name specified \"${PVNAME}\" is not a character device."
return 13
fi
(( VERBOSE == TRUE )) && print -u 2 "# Physical Volume: ${PVNAME}"
fi
####
#### Check the data wipe PASS toggles selected on the command line. If the
#### first data wipe pass is turned off, then return from the function and
#### inform the user that all data wipe passes are disabled. The first pass
#### is a requirement before other passes can be executed.
if (( P1TOGGLE == FALSE ))
then
print -u 2 -- "# All data wipe passes are disabled."
return 10
fi
####
#### Check the data wipe PASS toggles selected on the command line. If the
#### second data wipe pass is false, but the third is true, then some sort of
#### error has occurred. Each pass must be executed in order, so it is not
#### allowed to run pass 1, and pass 3, but NOT pass 2.
if (( P2TOGGLE == FALSE )) &&
(( P3TOGGLE == TRUE ))
then
print -u 2 -- "# ERROR: You must first execute PASS 2 before you can execute PASS 3"
return 10
fi
if [[ ! -c /dev/zero ]]
then
print -u 2 -- "# ERROR: The ZERO device /dev/zero must exist as a character device"
return 15
fi
trap "-" EXIT
################################################################
####
#### Warn the user that they are about to wipe clean whatever storage device
#### they specified, ask them to verify they really want to do this. If the
#### user specified the "-w" command line option, do not ask, just do it.
if (( WARNTOGGLE == TRUE ))
then
print -- "# The storage area \"${OF}\" is about to be wiped clean and overwritten."
print -n -- "# Are you sure you want to wipe clean/overwrite \"${OF}\" (y/N)? "
read ANS
if [[ "_${ANS}" != _[Yy] ]]
then
print "# You did not answer \"Y\" or \"y\", exiting program."
return 99
fi
fi
################################################################
#### Pass 1: fill the space with zero's (\0)
if (( P1TOGGLE == TRUE ))
then
if (( FITOGGLE == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 -- "# $( ls -l ${FINAME} )"
(( VERBOSE == TRUE )) && print -u 2 -- "# Pass 1 (0's)...: Overwritting every bit with zero's"
TFILE="/tmp/tmp${$}.out"
if cp "${FINAME}" "${TFILE}"
then
tr '[[:print:][:cntrl:][:xdigit:][:space:]]' '\0' < "${TFILE}" > "${FINAME}"
fi
[[ -f "${TFILE}" ]] && rm -f "${TFILE}"
fi
####
#### Check to see if the /dev/zero device exists, if so use it to generate a
#### continuous stream of zeros to overwrite all the bits of the targeted
#### storage space.
if [[ -c /dev/zero ]]
then
if (( LVTOGGLE == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 "# Pass 1 (0's)...: /dev/zero"
dd bs=${BSIZE} of="${LVNAME}" if=/dev/zero
fi
if (( PVTOGGLE == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 "# Pass 1 (0's)...: /dev/zero"
dd bs=${BSIZE} of="${PVNAME}" if=/dev/zero
fi
else
####
#### This "else" code is not currently active because /dev/zero is required to exist
(( VERBOSE == TRUE )) && print -u 2 "# ZERO Device....: none"
if (( LVTOGGLE == TRUE )) ||
(( PVTOGGLE == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 "# Pass 1 (0's)...: while looping"
BLOCK=""
for (( i=0; i<${BSIZE}; ++i ))
do
R=$'\0'
BLOCK="${BLOCK}${R}"
done
# SKIP=0
# while print -- "${BLOCK}" | dd bs=${BSIZE} of="${OF}" count=1 skip=${SKIP}
# do
# (( ++SKIP ))
# done
fi
fi
fi
################################################################
#### Pass 2: fill the space with one's (\377)
if (( P2TOGGLE == TRUE ))
then
if (( FITOGGLE == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 -- "# Pass 2 (1's)...: Overwritting every bit with one's"
TFILE="/tmp/tmp${$}.out"
if cp "${FINAME}" "${TFILE}"
then
tr '\0' '\377' < "${TFILE}" > "${FINAME}"
fi
[[ -f "${TFILE}" ]] && rm -f "${TFILE}"
fi
####
#### Check to see if the /dev/zero device exists, if so use it to generate a
#### continuous stream of zeros, then translate those zeros to one's and
#### overwrite all the bits of the targeted storage space.
if [[ -c /dev/zero ]]
then
if (( LVTOGGLE == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 "# Pass 2 (1's)...: tr conv < /dev/zero"
tr '\0' '\377' < /dev/zero | dd bs=${BSIZE} of="${LV}"
fi
if (( PVTOGGLE == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 "# Pass 2 (1's)...: tr conv < /dev/zero"
tr '\0' '\377' < /dev/zero | dd bs=${BSIZE} of="${PV}"
fi
else
####
#### This "else" code is not currently active because /dev/zero is required to exist
(( VERBOSE == TRUE )) && print -u 2 "# ZERO Device....: none"
if (( LVTOGGLE == TRUE )) ||
(( PVTOGGLE == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 "# Pass 2 (1's)...: while looping"
BLOCK=""
for (( i=0; i<${BSIZE}; ++i ))
do
R=$'\377'
BLOCK="${BLOCK}${R}"
done
# SKIP=0
# while print -- "${BLOCK}" | dd bs=${BSIZE} of="${OF}" count=1 skip=${SKIP}
# do
# (( ++SKIP ))
# done
fi
fi
fi
################################################################
#### Pass 3: fill the space with random bits (( RANDOM % 377 ))
if (( P3TOGGLE == TRUE ))
then
if (( FITOGGLE == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 "# Pass 3 (random): Overwritting every byte with random bits"
TFILE="/tmp/tmp${$}.out"
if cp "${FINAME}" "${TFILE}"
then
BCNT=0
> "${FINAME}"
tr '\377' '\n' < "${TFILE}" | while read -- C
do
R=$( printf "%o" $(( ${RANDOM} % 377 )) )
print -n -- "\\0${R}" >> "${FINAME}"
(( ++BCNT ))
if (( VERBOSE == TRUE ))
then
if (( BCNT >= BSIZE ))
then
print -u 2 -n -- "."
BCNT=0
fi
fi
done
(( VERBOSE == TRUE )) && print -u 2 -- "."
fi
[[ -f "${TFILE}" ]] && rm -f "${TFILE}"
(( VERBOSE == TRUE )) && print -u 2 -- "# $( ls -l ${FINAME} )"
fi
if (( LVTOGGLE == TRUE )) ||
(( PVTOGGLE == TRUE ))
then
(( VERBOSE == TRUE )) && print -u 2 "# Pass 3 (random): while looping"
SKIP=0
while :;
do
BLOCK=""
for (( i=0; i<${BSIZE}; ++i ))
do
R=$( printf "%o" $(( ${RANDOM} % 377 )) )
BLOCK="${BLOCK}\\0${R}"
done
if ! print -- "${BLOCK}" | dd bs=${BSIZE} of="${OF}" count=1 skip=${SKIP}
then
break
fi
(( ++SKIP ))
done
fi
fi
trap "-" HUP
return 0
}
################################################################
dodwipe_k93 "${@}"
|
|
|