[cleanup] Introduce _plot

This commit is contained in:
hellekin 2014-10-23 02:10:24 -03:00 committed by Jaromil
parent 19abe7cf85
commit b91573dde5

318
tomb
View File

@ -72,7 +72,11 @@ typeset -H _UID # Running user identifier
typeset -H _GID # Running user group identifier
typeset -H _TTY # Connected input terminal
typeset -H tomb_file
# Tomb context (see _plot())
typeset -H TOMBPATH # Full path to the tomb
typeset -H TOMBDIR # Directory where the tomb is
typeset -H TOMBFILE # File name of the tomb
typeset -H TOMBNAME # Name of the tomb
typeset -H tomb_key
typeset -H tomb_key_file
@ -100,7 +104,10 @@ endgame() {
while [[ ${#rr} -lt 500 ]]; do
rr+="$RANDOM"; done
# we make sure no info is left in unallocated mem
tomb_file="$rr"; unset tomb_file
TOMBPATH="$rr"; unset TOMBPATH
TOMBDIR="$rr"; unset TOMBDIR
TOMBFILE="$rr"; unset TOMBFILE
TOMBNAME="$rr"; unset TOMBNAME
tomb_key="$rr"; unset tomb_key
tomb_key_file="$rr"; unset tomb_key_file
tomb_secret="$rr"; unset tomb_secret
@ -149,6 +156,35 @@ check_shm() {
return 0
}
# Define sepulture's plot (setup tomb-related arguments)
# Synopsis: _plot "/path/to/the.tomb"
_plot() {
# We set global variables
typeset -g TOMBPATH TOMBDIR TOMBFILE TOMBNAME
TOMBPATH="$1"
_verbose '_plot TOMBPATH = ::1 tomb path::' $TOMBPATH
TOMBDIR=$(dirname $TOMBPATH)
_verbose '_plot TOMBDIR = ::1 tomb dir::' $TOMBDIR
TOMBFILE=$(basename $TOMBPATH)
_verbose '_plot TOMBFILE = ::1 tomb file::' $TOMBFILE
# The tomb name is TOMBFILE without an extension.
# It can start with dots: ..foo.tomb -> ..foo
TOMBNAME="${TOMBFILE%\.[^\.]*}"
_verbose '_plot TOMBNAME = ::1 tomb name::' $TOMBNAME
# Normalize TOMBFILE name
TOMBFILE="${TOMBNAME}.tomb"
_verbose '_plot TOMBFILE = ::1 tomb file:: (normalized)' $TOMBFILE
# Normalize TOMBPATH
TOMBPATH="${TOMBDIR}/${TOMBFILE}"
_verbose '_plot TOMBPATH = ::1 tomb path:: (normalized)' $TOMBPATH
}
# Provide a random filename in shared memory
tmp_create() {
local tfile="${TMPPREFIX}${RANDOM}"
@ -309,7 +345,7 @@ EOF
return 0
}
# check if a filename is a valid tomb
# Check if a filename is a valid tomb
is_valid_tomb() {
_verbose "is_valid_tomb ::1 tomb file::" $1
# argument check
@ -329,13 +365,12 @@ is_valid_tomb() {
file "$1" | grep -i "luks encrypted file" > /dev/null || {
_warning "File is not yet a tomb: ::1 tomb file::" $1}
# check if its already open
tombfile=`basename $1`
tombname=${tombfile%%\.*}
mount -l | grep "${tombfile}.*\[$tombname\]$" > /dev/null
_plot $1 # Set TOMB{PATH,DIR,FILE,NAME}
mount -l | grep "${TOMBFILE}.*\[$TOMBNAME\]$" > /dev/null
{ test $? = 0 } && {
_warning "Tomb is currently in use: ::1 tomb name::" $tombname; return 1 }
_message "Valid tomb file found: ::1 tomb file::" $1
_warning "Tomb is currently in use: ::1 tomb name::" $TOMBNAME; return 1 }
_message "Valid tomb file found: ::1 tomb path::" $TOMBPATH
return 0
}
@ -375,7 +410,8 @@ lo_preserve() {
# eventually used for debugging
dump_secrets() {
_verbose "tomb_file: ::1 tomb file::" $tomb_file
_verbose "TOMBFILE: ::1 tomb file::" $TOMBPATH
_verbose "TOMBFILE: ::1 tomb file::" $TOMBFILE
_verbose "tomb_key: ::1 key:: chars long" ${#tomb_key}
_verbose "tomb_key_file: ::1 key::" $tomb_key_file
_verbose "tomb_secret: ::1 secret:: chars long" ${#tomb_secret}
@ -1122,7 +1158,7 @@ engrave_key() {
# {{{ Create
# This is a new way to create tombs which dissects the whole create_tomb() into 3 clear steps:
# Since version 1.5.3, tomb creation is a three-step process that replaces create_tomb():
#
# * dig a .tomb (the large file) using /dev/urandom (takes some minutes at least)
#
@ -1130,6 +1166,64 @@ engrave_key() {
#
# * lock the .tomb file with the key, binding the key to the tomb (requires dm_crypt format)
# Step one - Dig a tomb
#
# Synopsis: dig_tomb /path/to/tomb -s sizemegabytes
#
# It will create an empty file to be formatted as a loopback
# filesystem. Initially the file is filled with random data taken
# from /dev/urandom to improve overall tomb's security and prevent
# some attacks aiming at detecting how much data is in the tomb, or
# which blocks in the filesystem contain that data.
dig_tomb() {
local tombpath="$1" # Path to tomb
# Require the specification of the size of the tomb (-s) in MB
local -i tombsize=$(option_value -s)
_message "Commanded to dig tomb ::1 tomb path::" $tombpath
[[ -n "$tombpath" ]] || _failure "Missing path to tomb"
[[ -n "$tombsize" ]] || _failure "Size argument missing, use -s"
[[ $tombsize == <-> ]] || _failure "Size must be an integer (megabytes)"
[[ $tombsize -ge 10 ]] || _failure "Tombs can't be smaller than 10 megabytes"
_check_swap # Ensure the available memory is safe to use
_plot $tombpath # Set TOMB{PATH,DIR,FILE,NAME}
[[ -e $TOMBPATH ]] && {
_warning "A tomb exists already. I'm not digging here:"
_warning " $(ls -lh $TOMBPATH)"
return 1
}
_success "Creating a new tomb in ::1 tomb path::" $TOMBPATH
_message "Generating ::1 tomb file:: of ::2 size::MiB" $TOMBFILE $tombsize
# Ensure that file permissions are safe even if interrupted
touch $TOMBPATH
chmod 0600 $TOMBPATH
chown $_UID:$_GID $TOMBPATH
_verbose "Data dump using ::1:: from /dev/urandom" ${DD[1]}
${=DD} if=/dev/urandom bs=1048576 count=$tombsize of=$TOMBPATH
[[ $? == 0 && -e $TOMBPATH ]] && {
_message " $(ls -lh $TOMBPATH)"
} || {
_warning "Error creating the tomb ::1 tomb path::" $TOMBPATH
_failure "Operation aborted."
}
_success "Done digging ::1 tomb name::" $TOMBNAME
_message "Your tomb is not yet ready, you need to forge a key and lock it:"
_message "tomb forge ::1 tomb path::.key" $TOMBPATH
_message "tomb lock ::1 tomb path:: -k ::1 tomb path::.key" $TOMBPATH
return 0
}
forge_key() {
# can be specified both as simple argument or using -k
@ -1213,88 +1307,34 @@ forge_key() {
ls -lh ${tomb_key_file}
}
# Dig a tomb, means that it will create an empty file to be formatted
# as a loopback filesystem. Initially the file is filled with random data
# taken from /dev/urandom which improves the tomb's overall security
dig_tomb() {
_message "Commanded to dig tomb ::1 tomb name::" $1
if [ "$1" = "" ]; then
_warning "No tomb name specified for creation."
return 1
fi
# Step three -- Lock tomb
#
# Synopsis: tomb_lock file.tomb file.tomb.key
#
# Lock the given tomb with the given key file, in fact formatting the
# loopback volume as a LUKS device. it take arguments as the LUKS
# cipher to be used
_check_swap
tombfile=`basename $1`
tombdir=`dirname $1`
# make sure the file has a .tomb extension
tombname=${tombfile%%\.*}
tombfile=${tombname}.tomb
# require the specification of the size of the tomb (-s) in MB
tombsize="`option_value -s`"
[ $tombsize ] || _failure "Size argument missing, use -s"
[[ $tombsize != <-> ]] && _failure "Size argument is not an integer."
[[ $tombsize -lt 10 ]] && _failure "Tombs can't be smaller than 10 megabytes."
if [ -e ${tombdir}/${tombfile} ]; then
_warning "A tomb exists already. I'm not digging here:"
_warning " `ls -lh ${tombdir}/${tombfile}`"
return 1
fi
_success "Creating a new tomb in ::1 tomb dir::/::2 tomb file::" $tombdir $tombfile
_message "Generating ::1 tomb file:: of ::2 size::MiB" $tombfile $tombsize
# we will first touch the file and set permissions: this way, even if interrupted, permissions are right
touch ${tombdir}/${tombfile}
chmod 0600 "${tombdir}/${tombfile}"
chown $_UID:$_GID "${tombdir}/${tombfile}"
_verbose "Data dump using ::1:: from /dev/urandom" ${DD[1]}
${=DD} if=/dev/urandom bs=1048576 count=${tombsize} of=${tombdir}/${tombfile}
if [ $? = 0 -a -e ${tombdir}/${tombfile} ]; then
_message " `ls -lh ${tombdir}/${tombfile}`"
else
_failure "Error creating the tomb ::1 tomb dir::/::2 tomb file::, operation aborted." $tombdir $tombfile
fi
_success "Done digging ::1 tomb name::" $tombname
_message "Your tomb is not yet ready, you need to forge a key and lock it:"
_message "tomb forge ::1 tomb name::.tomb.key" $tombname
_message "tomb lock ::1 tomb name::.tomb -k ::1 tomb name::.tomb.key" $tombname
}
# this function locks a tomb with a key file
# in fact LUKS formatting the loopback volume
# it take arguments as the LUKS cipher to be used
lock_tomb_with_key() {
if ! [ $1 ]; then
local tombpath="$1" # First argument is the path to the tomb
local tombkey="$2" # Second argument is the path to the key file
[[ -n $tombpath ]] || {
_warning "No tomb specified for locking."
_warning "Usage: tomb lock file.tomb file.tomb.key"
return 1
fi
}
tombpath="$1"
tombdir=`dirname "$tombpath"`
tombfile=`basename "$tombpath"`
tombname="${tombfile%%\.*}"
_plot $tombpath
_message "Commanded to lock tomb ::1 tomb file::" $tombfile
_message "Commanded to lock tomb ::1 tomb file::" $TOMBFILE
{ test -f ${tombdir}/${tombfile} } || {
_failure "There is no tomb here. You have to it dig first."
return 1 }
[[ -f $TOMBPATH ]] || {
_failure "There is no tomb here. You have to it dig first." }
_verbose "Tomb found: ::1 tomb dir::/::2 tomb file::" $tombdir $tombfile
_verbose "Tomb found: ::1 tomb path::" $TOMBPATH
lo_mount "${tombdir}/${tombfile}"
lo_mount $TOMBPATH
nstloop=`lo_new`
_verbose "Loop mounted on ::1 mount point::" $nstloop
@ -1337,7 +1377,7 @@ lock_tomb_with_key() {
{ test $? = 0 } || {
_failure "No valid password supplied." }
_success "Locking ::1 tomb file:: with ::2 tomb key::" $tombfile $tomb_key_file
_success "Locking ::1 tomb file:: with ::2 tomb key::" $TOMBFILE $tomb_key_file
_message "Formatting Luks mapped device."
print -n - "$tomb_secret" | \
@ -1358,56 +1398,61 @@ lock_tomb_with_key() {
fi
_message "Formatting your Tomb with Ext3/Ext4 filesystem."
${=MKFS} ${tombname} /dev/mapper/tomb.tmp
${=MKFS} $TOMBNAME /dev/mapper/tomb.tmp
if [ $? != 0 ]; then
_warning "Tomb format returned an error."
_warning "Your tomb ::1 tomb file:: may be corrupted." $tombfile
_warning "Your tomb ::1 tomb file:: may be corrupted." $TOMBFILE
fi
# sync
cryptsetup luksClose tomb.tmp
_message "Done locking ::1 tomb name:: using Luks dm-crypt ::2 cipher::" $tombname $cipher
_success "Your tomb is ready in ::1 tomb dir::/::2 tomb file:: and secured with key ::3 tomb key::" $tombdir $tombfile $tomb_key_file
_message "Done locking ::1 tomb name:: using Luks dm-crypt ::2 cipher::" $TOMBNAME $cipher
_success "Your tomb is ready in ::1 tomb path:: and secured with key ::3 tomb key::" \
$TOMBPATH $tomb_key_file
}
# This function changes the key that locks a tomb
change_tomb_key() {
_message "Commanded to reset key for tomb ::1 tomb name::" $2
local tombkey="$1" # Path to the tomb's key file
local tombpath="$2" # Path to the tomb
_check_swap
_message "Commanded to reset key for tomb ::1 tomb path::" $tombpath
[[ "$2" = "" ]] && {
[[ -z "$tombpath" ]] && {
_warning "Command 'setkey' needs two arguments: the old key file and the tomb."
_warning "I.e: tomb -k new.tomb.key old.tomb.key secret.tomb"
_failure "Execution aborted."
}
lo_mount "$2"
_check_swap
_plot $tombpath
lo_mount $TOMBPATH
nstloop=`lo_new`
cryptsetup isLuks ${nstloop}
# is it a LUKS encrypted nest? we check one more time
{ test $? = 0 } || {
_failure "Not a valid LUKS encrypted volume: ::1 volume::" $2 }
_failure "Not a valid LUKS encrypted volume: ::1 volume::" $TOMBPATH }
load_key "$1"
load_key $tombkey
{ test $? = 0 } || {
_failure "Aborting operations: error loading old key from arguments" }
old_key="$tomb_key"
old_key_file="$tomb_key_file"
# we have everything, prepare to mount
_success "Changing lock on tomb ::1 tomb name::" $tombname
_success "Changing lock on tomb ::1 tomb name::" $TOMBNAME
_message "Old key: ::1 old key::" $old_key
# render the mapper
mapdate=`date +%s`
# save date of mount in minutes since 1970
mapper="tomb.${tombname}.${mapdate}.`basename $nstloop`"
mapper="tomb.$TOMBNAME.$mapdate.$(basename $nstloop)"
# load the old key
if option_is_set --tomb-old-pwd; then
@ -1461,7 +1506,7 @@ change_tomb_key() {
{ test $? = 0 } || {
_failure "Unexpected error in luksClose." }
_success "Succesfully changed key for tomb: ::1 tomb file::" $2
_success "Succesfully changed key for tomb: ::1 tomb file::" $TOMBFILE
_message "The new key is: ::1 new key::" $new_key
unset new_key
@ -1470,6 +1515,7 @@ change_tomb_key() {
}
# backward compatibility
# TODO DEPRECATED remove in 2.0
create_tomb() {
_verbose "create_tomb(): ::1:: ::2::" ${=@} ${=OLDARGS}
[[ "$1" = "" ]] && {
@ -1504,28 +1550,22 @@ create_tomb() {
# $1 = tombfile $2(optional) = mountpoint
mount_tomb() {
local tombpath="$1" # First argument is the path to the tomb
[[ -n "$tombpath" ]] || _failure "No tomb name specified for opening."
_message "Commanded to open tomb ::1 tomb name::" $1
if [ "$1" = "" ]; then
_warning "No tomb name specified for opening."
return 1
fi
_check_swap
_plot $tombpath
# set up variables to be used
# the full path is made with $tombdir/$tombfile
tombfile=`basename ${1}`
tombdir=`dirname ${1}`
# check file type (if its a Luks fs)
file ${tombdir}/${tombfile} | \
grep -i 'luks encrypted file' 2>&1 > /dev/null
if [ $? != 0 ]; then
_warning "::1 tomb file:: is not a valid tomb file, operation aborted." $1
return 1
fi
tombname=${tombfile%%\.*}
_verbose "Tomb found: ::1 tomb dir::/::2 tomb file::" $tombdir $tombfile
file $TOMBPATH | grep -i 'luks encrypted file' 2>&1 > /dev/null
[[ $? == 0 ]] || {
_warning "::1 tomb file:: is not a valid tomb file" $TOMBFILE
_failure "Operation aborted."
}
_verbose "Tomb found: ::1 tomb path::" $TOMBPATH
# load_key called here
load_key
@ -1535,7 +1575,7 @@ mount_tomb() {
_failure "Aborting operations: error loading key ::1 key::" $tombkey }
if [ "$2" = "" ]; then
tombmount=/media/${tombfile}
tombmount=/media/$TOMBFILE
_message "Mountpoint not specified, using default: ::1 mount point::" $tombmount
else
tombmount=$2
@ -1544,21 +1584,21 @@ mount_tomb() {
# check if its already open
mount -l | grep "${tombfile}.*\[$tombname\]$" 2>&1 > /dev/null
if [ $? = 0 ]; then
_warning "::1 tomb name:: is already open." $tombname
_warning "::1 tomb name:: is already open." $TOMBNAME
_message "Here below its status is reported:"
list_tombs ${tombname}
list_tombs $TOMBNAME
return 0
fi
_success "Opening ::1 tomb file:: on ::2 mount point::" $tombfile $tombmount
_success "Opening ::1 tomb file:: on ::2 mount point::" $TOMBFILE $tombmount
lo_mount "${tombdir}/${tombfile}"
lo_mount $TOMBPATH
nstloop=`lo_new`
cryptsetup isLuks ${nstloop}
if [ $? != 0 ]; then
# is it a LUKS encrypted nest? see cryptsetup(1)
_warning "::1 tomb file:: is not a valid Luks encrypted storage file." $tombfile
_warning "::1 tomb file:: is not a valid Luks encrypted storage file." $TOMBFILE
return 1
fi
_message "This tomb is a valid LUKS encrypted device."
@ -1585,7 +1625,7 @@ mount_tomb() {
_verbose "Tomb key: ::1 key::" $tomb_key_file
# take the name only, strip extensions
_verbose "Tomb name: ::1 tomb name:: (to be engraved)" $tombname
_verbose "Tomb name: ::1 tomb name:: (to be engraved)" $TOMBNAME
if option_is_set --tomb-pwd; then
tomb_pwd="`option_value --tomb-pwd`"
@ -1612,13 +1652,13 @@ mount_tomb() {
/cipher:/ {print $2}
/keysize:/ {print $2}
/device:/ {print $2}'`)
_success "Success unlocking tomb ::1 tomb name::" $tombname
_success "Success unlocking tomb ::1 tomb name::" $TOMBNAME
_verbose "Key size is ::1 size:: for cipher ::2 cipher::" $tombstat[2] $tombstat[1]
_message "Checking filesystem via ::1::" $tombstat[3]
fsck -p -C0 /dev/mapper/${mapper}
_verbose "Tomb engraved as ::1 tomb name::" $tombname
tune2fs -L ${tombname} /dev/mapper/${mapper} > /dev/null
_verbose "Tomb engraved as ::1 tomb name::" $TOMBNAME
tune2fs -L $TOMBNAME /dev/mapper/${mapper} > /dev/null
# we need root from here on
mkdir -p $tombmount
@ -1628,7 +1668,7 @@ mount_tomb() {
chown $_UID:$_GID ${tombmount}
chmod 0711 ${tombmount}
_success "Success opening ::1 tomb file:: on ::2 mount point::" $tombfile $tombmount
_success "Success opening ::1 tomb file:: on ::2 mount point::" $TOMBFILE $tombmount
# print out when was opened the last time, by whom and where
{ test -r ${tombmount}/.last } && {
@ -2063,37 +2103,33 @@ search_tombs() {
# resize tomb file size
resize_tomb() {
local tombpath="$1" # First argument is the path to the tomb
_message "Commanded to resize tomb ::1 tomb name:: to ::2 size:: megabytes." $1 $OPTS[-s]
if ! [ $1 ]; then
_failure "No tomb name specified for resizing."
elif ! [ -r "$1" ]; then
_failure "Cannot find ::1::" $1
fi
# $1 is the tomb file path
[[ -z "$tombpath" ]] && _failure "No tomb name specified for resizing."
[[ ! -r $tombpath ]] && _failure "Cannot find ::1::" $tombpath
newtombsize="`option_value -s`"
{ test "$newtombsize" = "" } && {
_failure "Aborting operations: new size was not specified, use -s" }
tombdir=`dirname $1`
tombfile=`basename $1`
tombname=${tombfile%%\.*}
_plot $tombpath # Set TOMB{PATH,DIR,FILE,NAME}
# load key from options or file
load_key
########
local oldtombsize=$(( `stat -c %s "$1" 2>/dev/null` / 1048576 ))
local oldtombsize=$(( `stat -c %s "$TOMBPATH" 2>/dev/null` / 1048576 ))
local mounted_tomb=`mount -l |
awk -vtomb="[$tombname]" '/^\/dev\/mapper\/tomb/ { if($7==tomb) print $1 }'`
awk -vtomb="[$TOMBNAME]" '/^\/dev\/mapper\/tomb/ { if($7==tomb) print $1 }'`
if [ "$mounted_tomb" ]; then
_failure "The tomb ::1 tomb name:: is open, to resize it it needs to be closed." $tombname
_failure "Please close the tomb ::1 tomb name:: before trying to resize it." $TOMBNAME
fi
if ! [ "$newtombsize" ] ; then
_failure "You must specify the new size of ::1 tomb name::" $tombname
_failure "You must specify the new size of ::1 tomb name::" $TOMBNAME
elif [[ $newtombsize != <-> ]]; then
_failure "Size is not an integer."
elif [ "$newtombsize" -le "$oldtombsize" ]; then
@ -2102,10 +2138,10 @@ resize_tomb() {
delta="$(( $newtombsize - $oldtombsize ))"
_message "Generating ::1 tomb file:: of ::2 size::MiB" $tombfile $newtombsize
_message "Generating ::1 tomb file:: of ::2 size::MiB" $TOMBFILE $newtombsize
_verbose "Data dump using ::1:: from /dev/urandom" ${DD[1]}
${=DD} if=/dev/urandom bs=1048576 count=${delta} >> ${tombdir}/${tombfile}
${=DD} if=/dev/urandom bs=1048576 count=${delta} >> $TOMBPATH
{ test $? = 0 } || {
_failure "Error creating the extra resize ::1 size::, operation aborted." $tmp_resize }