commit b91573dde5003e06ac31e896adc80528241d88f5
parent 19abe7cf8573a33e855ea6c7de9d138527df9c91
Author: hellekin <hellekin@cepheide.org>
Date: Thu, 23 Oct 2014 02:10:24 -0300
[cleanup] Introduce _plot
Diffstat:
M | tomb | | | 318 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
1 file changed, 177 insertions(+), 141 deletions(-)
diff --git a/tomb b/tomb
@@ -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
-
- _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
-}
-
+# 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
-# 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 }