"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "tomb" between
Tomb-2.7.tar.gz and Tomb-2.8.tar.gz

About: Tomb is a commandline tool to manage encrypted storage folders.

tomb  (Tomb-2.7):tomb  (Tomb-2.8)
#!/usr/bin/env zsh #!/usr/bin/env zsh
# #
# Tomb, the Crypto Undertaker # Tomb, the Crypto Undertaker
# #
# A commandline tool to easily operate encryption of secret data # A commandline tool to easily operate encryption of secret data
# #
# {{{ License # {{{ License
# Copyright (C) 2007-2019 Dyne.org Foundation # Copyright (C) 2007-2020 Dyne.org Foundation
# #
# Tomb is designed, written and maintained by Denis Roio <jaromil@dyne.org> # Tomb is designed, written and maintained by Denis Roio <jaromil@dyne.org>
# #
# With contributions by Anathema, Boyska, Hellekin O. Wolf and GDrooid # Please refer to the AUTHORS file for more information.
# #
# Gettext internationalization and Spanish translation is contributed by
# GDrooid, French translation by Hellekin, Russian translation by fsLeg,
# German translation by x3nu.
#
# Testing, reviews and documentation are contributed by Dreamer, Shining
# the Translucent, Mancausoft, Asbesto Molesto, Nignux, Vlax, The Grugq,
# Reiven, GDrooid, Alphazo, Brian May, TheJH, fsLeg, JoelMon and the
# Linux Action Show!
#
# Tomb's artwork is contributed by Jordi aka Mon Mort and Logan VanCuren.
#
# Cryptsetup was developed by Christophe Saout and Clemens Fruhwirth.
# This source code is free software; you can redistribute it and/or # This source code is free software; you can redistribute it and/or
# modify it under the terms of the GNU Public License as published by # modify it under the terms of the GNU Public License as published by
# the Free Software Foundation; either version 3 of the License, or # the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This source code is distributed in the hope that it will be useful, # This source code is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please refer # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please refer
# to the GNU Public License for more details. # to the GNU Public License for more details.
# #
# You should have received a copy of the GNU Public License along with # You should have received a copy of the GNU Public License along with
# this source code; if not, write to: Free Software Foundation, Inc., # this source code; if not, , see <https://www.gnu.org/licenses/>.
# 675 Mass Ave, Cambridge, MA 02139, USA.
# }}} - License # }}} - License
# {{{ Global variables # {{{ Global variables
typeset VERSION="2.7" typeset VERSION="2.8"
typeset DATE="Oct/2019" typeset DATE="Nov/2020"
typeset TOMBEXEC=$0 typeset TOMBEXEC=$0
typeset TMPPREFIX=${TMPPREFIX:-/tmp} typeset TMPPREFIX=${TMPPREFIX:-/tmp}
# TODO: configure which tmp dir to use from a cli flag # TODO: configure which tmp dir to use from a cli flag
# Tomb is using some global variables set by the shell: # Tomb is using some global variables set by the shell:
# TMPPREFIX, UID, GID, PATH, TTY, USERNAME # TMPPREFIX, UID, GID, PATH, TTY, USERNAME
# You can grep 'global variable' to see where they are used. # You can grep 'global variable' to see where they are used.
# Keep a reference of the original command line arguments # Keep a reference of the original command line arguments
typeset -a OLDARGS typeset -a OLDARGS
skipping to change at line 98 skipping to change at line 84
unsetopt CASE_MATCH unsetopt CASE_MATCH
typeset -AH OPTS # Command line options (see main()) typeset -AH OPTS # Command line options (see main())
# Command context (see _whoami()) # Command context (see _whoami())
typeset -H _USER # Running username typeset -H _USER # Running username
typeset -Hi _UID # Running user identifier typeset -Hi _UID # Running user identifier
typeset -Hi _GID # Running user group identifier typeset -Hi _GID # Running user group identifier
typeset -H _TTY # Connected input terminal typeset -H _TTY # Connected input terminal
# Tomb context (see _plot()) # Tomb context (see is_valid_tomb())
typeset -H TOMBPATH # Full path to the tomb typeset -H TOMBPATH # Full path to the tomb
typeset -H TOMBDIR # Directory where the tomb is typeset -H TOMBDIR # Directory where the tomb is
typeset -H TOMBFILE # File name of the tomb typeset -H TOMBFILE # File name of the tomb
typeset -H TOMBNAME # Name of the tomb typeset -H TOMBNAME # Name of the tomb
# Tomb secrets # Tomb secrets
typeset -H TOMBKEY # Encrypted key contents (see forge_key (), recover_key()) typeset -H TOMBKEY # Encrypted key contents (see forge_key (), recover_key())
typeset -H TOMBKEYFILE # Key file (ditto) typeset -H TOMBKEYFILE # Key file (ditto)
typeset -H TOMBSECRET # Raw deciphered key (see forge_key(), gpg_ decrypt()) typeset -H TOMBSECRET # Raw deciphered key (see forge_key(), gpg_ decrypt())
typeset -H TOMBPASSWORD # Raw tomb passphrase (see gen_key() , ask_key_password()) typeset -H TOMBPASSWORD # Raw tomb passphrase (see gen_key() , ask_key_password())
skipping to change at line 260 skipping to change at line 246
_verbose "Updating HOME to match user's: ::1 home:: (was ::2 HOME ::)" \ _verbose "Updating HOME to match user's: ::1 home:: (was ::2 HOME ::)" \
$home $HOME $home $HOME
HOME=$home } HOME=$home }
# Get connecting TTY from option -T or the environment # Get connecting TTY from option -T or the environment
option_is_set -T && _TTY=$(option_value -T) option_is_set -T && _TTY=$(option_value -T)
[[ -z $_TTY ]] && _TTY=$TTY [[ -z $_TTY ]] && _TTY=$TTY
} }
# Define sepulture's plot (setup tomb-related arguments)
# Synopsis: _plot /path/to/the.tomb
# Set TOMB{PATH,DIR,FILE,NAME}
_plot() {
# We set global variables
typeset -g TOMBPATH TOMBDIR TOMBFILE TOMBNAME
TOMBPATH="$1"
TOMBDIR=$(dirname $TOMBPATH)
TOMBFILE=$(basename $TOMBPATH)
# The tomb name is TOMBFILE without an extension and underscores instead
of spaces (for mount and cryptsetup)
# It can start with dots: ..foo bar baz.tomb -> ..foo_bar_baz
TOMBNAME=${${TOMBFILE// /_}%.*}
# use the entire filename if the previous transformation returns
# an empty string. This handles the corner case of tomb being
# hidden files (starting with a dot) and have no extension (only
# one dot in string)
TOMBNAME=${TOMBNAME:-${TOMBFILE}}
[[ "$TOMBNAME" = "" ]] &&
_failure "Tomb won't work without a TOMBNAME."
}
# Provide a random filename in shared memory # Provide a random filename in shared memory
_tmp_create() { _tmp_create() {
[[ -d "$TMPPREFIX" ]] || { [[ -d "$TMPPREFIX" ]] || {
# we create the tempdir with the sticky bit on # we create the tempdir with the sticky bit on
_sudo mkdir -m 1777 "$TMPPREFIX" _sudo mkdir -m 1777 "$TMPPREFIX"
[[ $? == 0 ]] || _failure "Fatal error creating the temporary dir ectory: ::1 temp dir::" "$TMPPREFIX" [[ $? == 0 ]] || _failure "Fatal error creating the temporary dir ectory: ::1 temp dir::" "$TMPPREFIX"
} }
# We're going to add one more $RANDOM for each time someone complains # We're going to add one more $RANDOM for each time someone complains
# about this being too weak of a random. # about this being too weak of a random.
skipping to change at line 419 skipping to change at line 378
# Wraps around the pinentry command, from the GnuPG project, as it # Wraps around the pinentry command, from the GnuPG project, as it
# provides better security and conveniently use the right toolkit. # provides better security and conveniently use the right toolkit.
ask_password() { ask_password() {
local description="$1" local description="$1"
local title="${2:-Enter tomb password.}" local title="${2:-Enter tomb password.}"
local output local output
local password local password
local gtkrc local gtkrc
local theme local theme
local pass_asked
# Distributions have broken wrappers for pinentry: they do # Distributions have broken wrappers for pinentry: they do
# implement fallback, but they disrupt the output somehow. We are # implement fallback, but they disrupt the output somehow. We are
# better off relying on less intermediaries, so we implement our # better off relying on less intermediaries, so we implement our
# own fallback mechanisms. Pinentry supported: curses, gtk-2, qt4, qt5 # own fallback mechanisms. Pinentry supported: curses, gtk-2, qt4, qt5
# and x11. # and x11.
# make sure LANG is set, default to C # make sure LANG is set, default to C
LANG=${LANG:-C} LANG=${LANG:-C}
_verbose "asking password with tty=$TTY lc-ctype=$LANG" _verbose "asking password with tty=$TTY lc-ctype=$LANG"
if [[ "$DISPLAY" = "" ]]; then pass_asked=0
if _is_found "pinentry-curses"; then if [[ "$WAYLAND_DISPLAY" ]]; then
_verbose "using pinentry-curses" _verbose "wayland display detected"
output=$(pinentry_assuan_getpass | pinentry-curses) _is_found "pinentry-gnome3" && {
else _verbose "using pinentry-gnome3 on wayland"
_failure "Cannot find pinentry-curses and no DISPLAY dete output=$(pinentry_assuan_getpass | pinentry-gnome3)
cted." pass_asked=1
fi }
fi
else # a DISPLAY is found to be active if [[ "$DISPLAY" ]] && [[ "$pass_asked" == 0 ]]; then
_verbose "X11 display detected"
# customized gtk2 dialog with a skull (if extras are installed)
if _is_found "pinentry-gtk-2"; then if _is_found "pinentry-gtk-2"; then
_verbose "using pinentry-gtk2" _verbose "using pinentry-gtk2"
gtkrc=""
theme=/share/themes/tomb/gtk-2.0-key/gtkrc
for i in /usr/local /usr; do
[[ -r $i/$theme ]] && {
gtkrc="$i/$theme"
break
}
done
[[ "$gtkrc" = "" ]] || {
gtkrc_old="$GTK2_RC_FILES"
export GTK2_RC_FILES="$gtkrc"
}
output=$(pinentry_assuan_getpass | pinentry-gtk-2) output=$(pinentry_assuan_getpass | pinentry-gtk-2)
[[ "$gtkrc" = "" ]] || export GTK2_RC_FILES="$gtkrc_old" pass_asked=1
elif _is_found "pinentry-x11"; then
# TODO QT5 customization of dialog _verbose "using pinentry-x11"
output=$(pinentry_assuan_getpass | pinentry-x11)
pass_asked=1
elif _is_found "pinentry-gnome3"; then
_verbose "using pinentry-gnome3 on X11"
output=$(pinentry_assuan_getpass | pinentry-gnome3)
pass_asked=1
elif _is_found "pinentry-qt5"; then elif _is_found "pinentry-qt5"; then
_verbose "using pinentry-qt5" _verbose "using pinentry-qt5"
output=$(pinentry_assuan_getpass | pinentry-qt5) output=$(pinentry_assuan_getpass | pinentry-qt5)
pass_asked=1
# TODO QT4 customization of dialog
elif _is_found "pinentry-qt4"; then elif _is_found "pinentry-qt4"; then
_verbose "using pinentry-qt4" _verbose "using pinentry-qt4"
output=$(pinentry_assuan_getpass | pinentry-qt4) output=$(pinentry_assuan_getpass | pinentry-qt4)
# TODO X11 customization of dialog pass_asked=1
elif _is_found "pinentry-x11"; then
_verbose "using pinentry-x11"
output=$(pinentry_assuan_getpass | pinentry-x11)
else
if _is_found "pinentry-curses"; then
_verbose "using pinentry-curses"
_warning "Detected DISPLAY, but only pinentry-cur
ses is found."
output=$(pinentry_assuan_getpass | pinentry-curse
s)
else
_failure "Cannot find any pinentry: impossible to
ask for password."
fi
fi fi
fi
if [[ "$pass_asked" == 0 ]]; then
_verbose "no display detected"
_is_found "pinentry-curses" && {
_verbose "using pinentry-curses with no display"
output=$(pinentry_assuan_getpassgetpasspass | pinentry-cu
rses)
pass_asked=1
}
fi
fi # end of DISPLAY block [[ "$pass_asked" == 0 ]] &&
_failure "Cannot find any pinentry-curses and no DISPLAY detected
."
# parse the pinentry output # parse the pinentry output
local pinentry_error
for i in ${(f)output}; do for i in ${(f)output}; do
[[ "$i" =~ "^ERR.*" ]] && { [[ "$i" =~ "^ERR.*" ]] && {
_warning "Pinentry error: ::1 error::" ${i[(w)3]} pinentry_error="${i[(w)3]}"
print "canceled"
return 1
} }
# here the password is found # here the password is found
[[ "$i" =~ "^D .*" ]] && password="${i##D }"; [[ "$i" =~ "^D .*" ]] && password="${i##D }";
done done
[[ ! -z "$pinentry_error" ]] && [[ "$password" = "" ]] && {
_warning "Pinentry error: ::1 error::" ${pinentry_error}
print "canceled"
return 1
}
# if sphinx mode is chosen, use the provided input # if sphinx mode is chosen, use the provided input
# as master password to retrieve the actual password # as master password to retrieve the actual password
if option_is_set --sphx-user || option_is_set --sphx-host; then if option_is_set --sphx-user || option_is_set --sphx-host; then
password=$(sphinx_get_password "$password") password=$(sphinx_get_password "$password")
fi fi
[[ "$password" = "" ]] && { [[ "$password" = "" ]] && {
_warning "Empty password" _warning "Empty password"
print "empty" print "empty"
return 1 return 1
skipping to change at line 582 skipping to change at line 531
rm $errorfile rm $errorfile
_failure "Failed to create password with sphinx" _failure "Failed to create password with sphinx"
fi fi
else else
_failure "Both host and user have to be set to use sphinx" _failure "Both host and user have to be set to use sphinx"
fi fi
} }
# Check if a filename is a valid tomb # Check if a filename is a valid tomb
is_valid_tomb() { is_valid_tomb() {
_verbose "is_valid_tomb ::1 tomb file::" $1 _verbose "is_valid_tomb ::1 tomb file::" $1
# First argument must be the path to a tomb # First argument must be the path to a tomb
[[ -z "$1" ]] && { [[ $1 ]] || _failure "Tomb file is missing from arguments."
_failure "Tomb file is missing from arguments." }
_fail=0 local _fail=0
# Tomb file must be a readable, writable, non-empty regular file. # Tomb file must be a readable, writable, non-empty regular file.
# If passed the "ro" mount option, the writable check is skipped. # If passed the "ro" mount option, the writable check is skipped.
[[ ! -w "$1" ]] && [[ $(option_value -o) != *"ro"* ]] && { [[ ! -w "$1" ]] && [[ $(option_value -o) != *"ro"* ]] && {
_warning "Tomb file is not writable: ::1 tomb file::" $1 _warning "Tomb file is not writable: ::1 tomb file::" $1
_fail=1 _fail=1
} }
_verbose "tomb file is readable" _verbose "tomb file is readable"
[[ ! -f "$1" ]] && { [[ ! -f "$1" ]] && {
_warning "Tomb file is not a regular file: ::1 tomb file::" $1 _warning "Tomb file is not a regular file: ::1 tomb file::" $1
_fail=1 _fail=1
} }
_verbose "tomb file is a regular file" _verbose "tomb file is a regular file"
[[ ! -s "$1" ]] && { [[ ! -s "$1" ]] && {
_warning "Tomb file is empty (zero length): ::1 tomb file::" $1 _warning "Tomb file is empty (zero length): ::1 tomb file::" $1
_fail=1 _fail=1
} }
_verbose "tomb file is not empty" _verbose "tomb file is not empty"
# no more checking on the uid [[ $_fail == 1 ]] && {
# _uid="`zstat +uid $1`"
# [[ "$_uid" = "$UID" ]] || {
# _user="`zstat -s +uid $1`"
# _warning "Tomb file is owned by another user: ::1 tomb owner::"
$_user
# }
# _verbose "tomb is not owned by another user"
[[ $_fail = 1 ]] && {
_failure "Tomb command failed: ::1 command name::" $subcommand _failure "Tomb command failed: ::1 command name::" $subcommand
} }
# TODO: split the rest of that function out.
# We already have a valid tomb, now we're checking
# whether we can alter it.
# Tomb file may be a LUKS FS (or we are creating it) # Tomb file may be a LUKS FS (or we are creating it)
[[ "`file $1`" =~ "luks encrypted file" ]] || { [[ "`file $1`" =~ "luks encrypted file" ]] || {
_warning "File is not yet a tomb: ::1 tomb file::" $1 } _warning "File is not yet a tomb: ::1 tomb file::" $1 }
_plot $1 # Set TOMB{PATH,DIR,FILE,NAME} # We set global variables
typeset -g TOMBPATH TOMBDIR TOMBFILE TOMBNAME TOMBMAPPER
TOMBPATH="$1"
TOMBDIR=$(dirname $TOMBPATH)
TOMBFILE=$(basename $TOMBPATH)
# The tomb name is TOMBFILE without an extension and underscores instead
of spaces (for mount and cryptsetup)
# It can start with dots: ..foo bar baz.tomb -> ..foo_bar_baz
TOMBNAME=${${TOMBFILE// /_}%.*}
# use the entire filename if the previous transformation returns
# an empty string. This handles the corner case of tomb being
# hidden files (starting with a dot) and have no extension (only
# one dot in string)
TOMBNAME=${TOMBNAME:-${TOMBFILE}}
[[ "$TOMBNAME" = "" ]] &&
_failure "Tomb won't work without a TOMBNAME."
# checks if Tomb already mounted (or we cannot alter it)
local maphash=`realpath $TOMBPATH | sha256sum -z`
local nextloop=`losetup -f`
TOMBMAPPER="tomb.$TOMBNAME.${maphash[(w)1]}.`basename $nextloop`"
local mounted_tombs=(`list_tomb_mounts`)
local usedmapper
for t in ${mounted_tombs}; do
usedmapper=`basename "${t[(ws:;:)1]}"`
[[ "${usedmapper%.*}" == "${TOMBMAPPER%.*}" ]] &&
_failure "Tomb file already in use: ::1 tombname::" $TOMB
PATH
done
_verbose "Mapper: ::1 mapper::" $TOMBMAPPER
# Tomb already mounted (or we cannot alter it)
[[ "`_sudo findmnt -rvo SOURCE,TARGET,FSTYPE,OPTIONS,LABEL |
awk -vtomb="[$TOMBNAME]" '
/^\/dev\/mapper\/tomb/ { if($5==tomb) print $1 }'`" = "" ]] || {
_failure "Tomb is currently in use: ::1 tomb name::" $TOMBNAME
}
_verbose "tomb file is not currently in use" _verbose "tomb file is not currently in use"
_message "Valid tomb file found: ::1 tomb path::" $TOMBPATH _message "Valid tomb file found: ::1 tomb path::" $TOMBPATH
return 0 return 0
} }
# $1 is the tomb file to be lomounted # $1 is the tomb file to be lomounted
lo_mount() { lo_mount() {
tpath="$1" tpath="$1"
# check if we have support for loop mounting # check if we have support for loop mounting
_nstloop=`_sudo losetup -f` TOMBLOOP=`_sudo losetup -f`
[[ $? = 0 ]] || { [[ $? = 0 ]] || {
_warning "Loop mount of volumes is not possible on this machine, this error" _warning "Loop mount of volumes is not possible on this machine, this error"
_warning "often occurs on VPS and kernels that don't provide the loop module." _warning "often occurs on VPS and kernels that don't provide the loop module."
_warning "It is impossible to use Tomb on this machine under thes e conditions." _warning "It is impossible to use Tomb on this machine under thes e conditions."
_failure "Operation aborted." _failure "Operation aborted."
} }
_sudo losetup -f "$tpath" # allocates the next loopback for our file _sudo losetup -f "$tpath" # allocates the next loopback for our file
TOMBLOOPDEVS+=("$_nstloop") # add to array of lodevs used TOMBLOOPDEVS+=("$TOMBLOOP") # add to array of lodevs used
return 0 return 0
} }
# print out latest loopback mounted # print out latest loopback mounted
lo_new() { print - "${TOMBLOOPDEVS[${#TOMBLOOPDEVS}]}" } lo_new() { print - "${TOMBLOOPDEVS[${#TOMBLOOPDEVS}]}" }
# $1 is the path to the lodev to be preserved after quit # $1 is the path to the lodev to be preserved after quit
lo_preserve() { lo_preserve() {
_verbose "lo_preserve on ::1 path::" $1 _verbose "lo_preserve on ::1 path::" $1
# remove the lodev from the tomb_lodevs array # remove the lodev from the tomb_lodevs array
skipping to change at line 821 skipping to change at line 781
case "$1" in case "$1" in
inline) inline)
command+=" -n"; pchars=" > "; pcolor="yellow" command+=" -n"; pchars=" > "; pcolor="yellow"
;; ;;
message) message)
pchars=" . "; pcolor="white" pchars=" . "; pcolor="white"
;; ;;
verbose) verbose)
pchars="[D]"; pcolor="blue" pchars="[D]"; pcolor="blue"
fd=2
;; ;;
success) success)
pchars="(*)"; pcolor="green" pchars="(*)"; pcolor="green"
;; ;;
warning) warning)
pchars="[W]"; pcolor="yellow" pchars="[W]"; pcolor="yellow"
;; ;;
failure) failure)
pchars="[E]"; pcolor="red" pchars="[E]"; pcolor="red"
fd=2 fd=2
skipping to change at line 1851 skipping to change at line 1812
# #
# Synopsis: dig_tomb /path/to/tomb -s sizemebibytes # Synopsis: dig_tomb /path/to/tomb -s sizemebibytes
# #
# It will create an empty file to be formatted as a loopback # It will create an empty file to be formatted as a loopback
# filesystem. Initially the file is filled with random data taken # filesystem. Initially the file is filled with random data taken
# from /dev/urandom to improve overall tomb's security and prevent # from /dev/urandom to improve overall tomb's security and prevent
# some attacks aiming at detecting how much data is in the tomb, or # some attacks aiming at detecting how much data is in the tomb, or
# which blocks in the filesystem contain that data. # which blocks in the filesystem contain that data.
dig_tomb() { dig_tomb() {
local tombpath="$1" # Path to tomb # $1 arg is path to tomb
# Require the specification of the size of the tomb (-s) in MiB # Require the specification of the size of the tomb (-s) in MiB
local -i tombsize=$(option_value -s) local -i tombsize=$(option_value -s)
_message "Commanded to dig tomb ::1 tomb path::" $tombpath _message "Commanded to dig tomb ::1 tomb path::" $tombpath
[[ -n "$tombpath" ]] || _failure "Missing path to tomb" [[ $1 ]] || _failure "Missing path to tomb"
[[ -n "$tombsize" ]] || _failure "Size argument missing, use -s" [[ -n "$tombsize" ]] || _failure "Size argument missing, use -s"
[[ $tombsize == <-> ]] || _failure "Size must be an integer (mebibytes)" [[ $tombsize == <-> ]] || _failure "Size must be an integer (mebibytes)"
[[ $tombsize -ge 10 ]] || _failure "Tombs can't be smaller than 10 mebiby tes" [[ $tombsize -ge 10 ]] || _failure "Tombs can't be smaller than 10 mebiby tes"
_plot $tombpath # Set TOMB{PATH,DIR,FILE,NAME} [[ -e $1 ]] && {
[[ -e $TOMBPATH ]] && {
_warning "A tomb exists already. I'm not digging here:" _warning "A tomb exists already. I'm not digging here:"
ls -lh $TOMBPATH ls -lh $1
return 1 return 1
} }
_success "Creating a new tomb in ::1 tomb path::" $TOMBPATH _success "Creating a new tomb in ::1 tomb path::" $1
_message "Generating ::1 tomb file:: of ::2 size::MiB" $1 $tombsize
_message "Generating ::1 tomb file:: of ::2 size::MiB" $TOMBFILE $tombsiz
e
# Ensure that file permissions are safe even if interrupted touch "$1"
touch $TOMBPATH
[[ $? = 0 ]] || { [[ $? = 0 ]] || {
_warning "Error creating the tomb ::1 tomb path::" $TOMBPATH _warning "Error creating the tomb ::1 tomb path::" $1
_failure "Operation aborted." _failure "Operation aborted."
} }
chmod 0600 $TOMBPATH # Ensure that file permissions are safe even if interrupted
_sudo chown ${_UID}:${_GID} "$1"
chmod 0600 $1
_verbose "Data dump using ::1:: from /dev/urandom" ${DD[1]} _verbose "Data dump using ::1:: from /dev/urandom" ${DD[1]}
${=DD} if=/dev/urandom bs=1048576 count=$tombsize of=$TOMBPATH ${=DD} if=/dev/urandom bs=1048576 count=$tombsize of=$1
ls -lh "$1"
[[ $? == 0 && -e $TOMBPATH ]] && {
_sudo chown ${_UID}:${_GID} "$TOMBPATH"
ls -lh "$TOMBPATH"
} || {
_warning "Error creating the tomb ::1 tomb path::" $TOMBPATH
_failure "Operation aborted."
}
_success "Done digging ::1 tomb name::" $TOMBNAME _success "Done digging ::1 tomb name::" $1
_message "Your tomb is not yet ready, you need to forge a key and lock it :" _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 forge ::1 tomb path::.key" $1
_message "tomb lock ::1 tomb path:: -k ::1 tomb path::.key" $TOMBPATH _message "tomb lock ::1 tomb path:: -k ::1 tomb path::.key" $1
return 0 return 0
} }
# Step two -- Create a detached key to lock a tomb with # Step two -- Create a detached key to lock a tomb with
# #
# Synopsis: forge_key [destkey|-k destkey] [-o cipher] [-r|-R gpgid] # Synopsis: forge_key [destkey|-k destkey] [-o cipher] [-r|-R gpgid]
# #
# Arguments: # Arguments:
# -k path to destination keyfile # -k path to destination keyfile
skipping to change at line 1925 skipping to change at line 1877
local algo="AES256" # Default encryption algorithm local algo="AES256" # Default encryption algorithm
[[ -z "$destkey" ]] && { [[ -z "$destkey" ]] && {
_failure "A filename needs to be specified using -k to forge a ne w key." } _failure "A filename needs to be specified using -k to forge a ne w key." }
# _message "Commanded to forge key ::1 key::" $destkey # _message "Commanded to forge key ::1 key::" $destkey
_check_swap # Ensure the available memory is safe to use _check_swap # Ensure the available memory is safe to use
# Ensure GnuPG won't exit with an error before first run # Ensure GnuPG won't exit with an error before first run
[[ -r $HOME/.gnupg/pubring.gpg ]] || { local gpghome=${GNUPGHOME:-$HOME/.gnupg}
mkdir -m 0700 $HOME/.gnupg [[ -r $gpghome/pubring.gpg ]] || {
touch $HOME/.gnupg/pubring.gpg } mkdir -p -m 0700 $gpghome
touch $gpghome/pubring.gpg }
# Do not overwrite any files accidentally # Do not overwrite any files accidentally
[[ -r "$destkey" ]] && { [[ -r "$destkey" ]] && {
ls -lh $destkey ls -lh $destkey
_failure "Forging this key would overwrite an existing file. Oper ation aborted." } _failure "Forging this key would overwrite an existing file. Oper ation aborted." }
touch $destkey touch $destkey
[[ $? == 0 ]] || { [[ $? == 0 ]] || {
_warning "Cannot generate encryption key." _warning "Cannot generate encryption key."
_failure "Operation aborted." } _failure "Operation aborted." }
skipping to change at line 2013 skipping to change at line 1966
_success "Your key is ready:" _success "Your key is ready:"
ls -lh $TOMBKEYFILE ls -lh $TOMBKEYFILE
} }
# Step three -- Lock tomb # Step three -- Lock tomb
# #
# Synopsis: tomb_lock file.tomb file.tomb.key [-o cipher] [-r gpgid] # Synopsis: tomb_lock file.tomb file.tomb.key [-o cipher] [-r gpgid]
# #
# Lock the given tomb with the given key file, in fact formatting the # Lock the given tomb with the given key file, in fact formatting the
# loopback volume as a LUKS device. # loopback volume as a LUKS device.
# Default cipher 'aes-xts-plain64:sha256'can be overridden with -o # Default cipher 'aes-xts-plain64'can be overridden with -o
lock_tomb_with_key() { lock_tomb_with_key() {
# old default was aes-cbc-essiv:sha256 # old default was aes-cbc-essiv:sha256
# Override with -o # Override with -o
# for more alternatives refer to cryptsetup(8) # for more alternatives refer to cryptsetup(8)
local cipher="aes-xts-plain64" local cipher="aes-xts-plain64"
local tombpath="$1" # First argument is the path to the tomb local tombpath="$1" # First argument is the path to the tomb
[[ -n $tombpath ]] || { [[ -n $tombpath ]] || {
_warning "No tomb specified for locking." _warning "No tomb specified for locking."
_warning "Usage: tomb lock file.tomb -k file.tomb.key" _warning "Usage: tomb lock file.tomb -k file.tomb.key"
return 1 return 1
} }
_plot $tombpath is_valid_tomb $tombpath
_message "Commanded to lock tomb ::1 tomb file::" $TOMBFILE _message "Commanded to lock tomb ::1 tomb file::" $TOMBFILE
[[ -f $TOMBPATH ]] || { [[ -f $TOMBPATH ]] || {
_failure "There is no tomb here. You have to dig it first." } _failure "There is no tomb here. You have to dig it first." }
_verbose "Tomb found: ::1 tomb path::" $TOMBPATH _verbose "Tomb found: ::1 tomb path::" $TOMBPATH
lo_mount $TOMBPATH lo_mount $TOMBPATH
nstloop=`lo_new`
_verbose "Loop mounted on ::1 mount point::" $nstloop _verbose "Loop mounted on ::1 mount point::" $TOMBLOOP
_message "Checking if the tomb is empty (we never step on somebody else's bones)." _message "Checking if the tomb is empty (we never step on somebody else's bones)."
_sudo cryptsetup isLuks ${nstloop} _sudo cryptsetup isLuks ${TOMBLOOP}
if [ $? = 0 ]; then if [ $? = 0 ]; then
# is it a LUKS encrypted nest? then bail out and avoid reformatti ng it # is it a LUKS encrypted nest? then bail out and avoid reformatti ng it
_warning "The tomb was already locked with another key." _warning "The tomb was already locked with another key."
_failure "Operation aborted. I cannot lock an already locked tomb . Go dig a new one." _failure "Operation aborted. I cannot lock an already locked tomb . Go dig a new one."
else else
_message "Fine, this tomb seems empty." _message "Fine, this tomb seems empty."
fi fi
_load_key # Try loading key from option -k and set TOMBKEYFILE _load_key # Try loading key from option -k and set TOMBKEYFILE
skipping to change at line 2074 skipping to change at line 2026
else else
ask_key_password ask_key_password
fi fi
[[ $? == 0 ]] || _failure "No valid password supplied." [[ $? == 0 ]] || _failure "No valid password supplied."
_success "Locking ::1 tomb file:: with ::2 tomb key file::" $TOMBFILE $TO MBKEYFILE _success "Locking ::1 tomb file:: with ::2 tomb key file::" $TOMBFILE $TO MBKEYFILE
_message "Formatting Luks mapped device." _message "Formatting Luks mapped device."
_cryptsetup --batch-mode \ _cryptsetup --batch-mode \
--cipher ${cipher} --hash sha512 --key-size 512 - -key-slot 0 \ --cipher ${cipher} --hash sha512 --key-size 512 - -key-slot 0 \
luksFormat ${nstloop} luksFormat ${TOMBLOOP}
[[ $? == 0 ]] || { [[ $? == 0 ]] || {
_warning "cryptsetup luksFormat returned an error." _warning "cryptsetup luksFormat returned an error."
_failure "Operation aborted." } _failure "Operation aborted." }
_cryptsetup --cipher ${cipher} --hash sha512 luksOpen ${nstloop} tomb.tmp _cryptsetup --cipher ${cipher} --hash sha512 luksOpen ${TOMBLOOP} tomb.tm p
[[ $? == 0 ]] || { [[ $? == 0 ]] || {
_warning "cryptsetup luksOpen returned an error." _warning "cryptsetup luksOpen returned an error."
_failure "Operation aborted." } _failure "Operation aborted." }
_message "Formatting your Tomb with Ext3/Ext4 filesystem." _message "Formatting your Tomb with Ext3/Ext4 filesystem."
_sudo mkfs.ext4 -q -F -j -L $TOMBNAME /dev/mapper/tomb.tmp _sudo mkfs.ext4 -q -F -j -L $TOMBNAME /dev/mapper/tomb.tmp
[[ $? == 0 ]] || { [[ $? == 0 ]] || {
_warning "Tomb format returned an error." _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 }
skipping to change at line 2115 skipping to change at line 2067
_message "Commanded to reset key for tomb ::1 tomb path::" $tombpath _message "Commanded to reset key for tomb ::1 tomb path::" $tombpath
[[ -z "$tombpath" ]] && { [[ -z "$tombpath" ]] && {
_warning "Command 'setkey' needs two arguments: the old key file and the tomb." _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" _warning "I.e: tomb -k new.tomb.key old.tomb.key secret.tomb"
_failure "Execution aborted." _failure "Execution aborted."
} }
_check_swap _check_swap
# this also calls _plot()
is_valid_tomb $tombpath is_valid_tomb $tombpath
lo_mount $TOMBPATH lo_mount $TOMBPATH
nstloop=`lo_new`
_sudo cryptsetup isLuks ${nstloop} _sudo cryptsetup isLuks ${TOMBLOOP}
# is it a LUKS encrypted nest? we check one more time # is it a LUKS encrypted nest? we check one more time
[[ $? == 0 ]] || { [[ $? == 0 ]] || {
_failure "Not a valid LUKS encrypted volume: ::1 volume::" $TOMBP ATH } _failure "Not a valid LUKS encrypted volume: ::1 volume::" $TOMBP ATH }
_load_key $tombkey # Try loading given key and set TOMBKEY and _load_key $tombkey # Try loading given key and set TOMBKEY
# TOMBKEYFILE # TOMBKEYFILE
local oldkey=$TOMBKEY local oldkey=$TOMBKEY
local oldkeyfile=$TOMBKEYFILE local oldkeyfile=$TOMBKEYFILE
# we have everything, prepare to mount # 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::" $oldkeyfile _message "Old key: ::1 old key::" $oldkeyfile
# render the mapper
mapdate=`date +%s`
# save date of mount in minutes since 1970
mapper="tomb.$TOMBNAME.$mapdate.$(basename $nstloop)"
# load the old key # load the old key
if option_is_set --tomb-old-pwd; then if option_is_set --tomb-old-pwd; then
tomb_old_pwd="`option_value --tomb-old-pwd`" tomb_old_pwd="`option_value --tomb-old-pwd`"
_verbose "tomb-old-pwd = ::1 old pass::" $tomb_old_pwd _verbose "tomb-old-pwd = ::1 old pass::" $tomb_old_pwd
ask_key_password "$tomb_old_pwd" ask_key_password "$tomb_old_pwd"
else else
ask_key_password ask_key_password
fi fi
[[ $? == 0 ]] || { [[ $? == 0 ]] || {
_failure "No valid password supplied for the old key." } _failure "No valid password supplied for the old key." }
old_secret=$TOMBSECRET old_secret=$TOMBSECRET
# luksOpen the tomb (not really mounting, just on the loopback) # luksOpen the tomb (not really mounting, just on the loopback)
print -R -n - "$old_secret" | _sudo cryptsetup --key-file - \ print -R -n - "$old_secret" | _sudo cryptsetup --key-file - \
l uksOpen ${nstloop} ${mapper} l uksOpen ${TOMBLOOP} ${TOMBMAPPER}
[[ $? == 0 ]] || _failure "Unexpected error in luksOpen." [[ $? == 0 ]] || _failure "Unexpected error in luksOpen."
_load_key # Try loading new key from option -k and set TOMBKEYFILE _load_key # Try loading new key from option -k and set TOMBKEYFILE
_message "New key: ::1 key file::" $TOMBKEYFILE _message "New key: ::1 key file::" $TOMBKEYFILE
if option_is_set --tomb-pwd; then if option_is_set --tomb-pwd; then
tomb_new_pwd="`option_value --tomb-pwd`" tomb_new_pwd="`option_value --tomb-pwd`"
_verbose "tomb-pwd = ::1 tomb pass::" $tomb_new_pwd _verbose "tomb-pwd = ::1 tomb pass::" $tomb_new_pwd
ask_key_password "$tomb_new_pwd" ask_key_password "$tomb_new_pwd"
skipping to change at line 2175 skipping to change at line 2122
ask_key_password ask_key_password
fi fi
[[ $? == 0 ]] || { [[ $? == 0 ]] || {
_failure "No valid password supplied for the new key." } _failure "No valid password supplied for the new key." }
_tmp_create _tmp_create
tmpnewkey=$TOMBTMP tmpnewkey=$TOMBTMP
print -R -n - "$TOMBSECRET" >> $tmpnewkey print -R -n - "$TOMBSECRET" >> $tmpnewkey
print -R -n - "$old_secret" | _sudo cryptsetup --key-file - \ print -R -n - "$old_secret" | _sudo cryptsetup --key-file - \
l uksChangeKey "$nstloop" "$tmpnewkey" l uksChangeKey "$TOMBLOOP" "$tmpnewkey"
[[ $? == 0 ]] || _failure "Unexpected error in luksChangeKey." [[ $? == 0 ]] || _failure "Unexpected error in luksChangeKey."
_sudo cryptsetup luksClose "${mapper}" || _failure "Unexpected error in l uksClose." _sudo cryptsetup luksClose "${TOMBMAPPER}" || _failure "Unexpected error in luksClose."
_success "Succesfully changed key for tomb: ::1 tomb file::" $TOMBFILE _success "Succesfully changed key for tomb: ::1 tomb file::" $TOMBFILE
_message "The new key is: ::1 new key::" $TOMBKEYFILE _message "The new key is: ::1 new key::" $TOMBKEYFILE
return 0 return 0
} }
# }}} - Creation # }}} - Creation
# {{{ Open # {{{ Open
_update_control_file() { _update_control_file() {
# replaces a control file with new contents and gives it user ownership # make sure a control file exists, gives it user ownership
# and replaces it with new contents
# stdin = contents # stdin = contents
# $1 = path to control file # $1 = path to control file
# $2 = contents # $2 = contents
[[ "$2" = "" ]] && return 1 [[ "$2" = "" ]] && return 1
_sudo touch "$1" _sudo touch "$1"
print "$2" > "$1"
_sudo chown ${_UID}:${_GID} "$1" _sudo chown ${_UID}:${_GID} "$1"
print "$2" > "$1"
_verbose "updated control file $1 = $2" _verbose "updated control file $1 = $2"
} }
# $1 = tombfile $2(optional) = mountpoint # $1 = tombfile $2(optional) = mountpoint
mount_tomb() { mount_tomb() {
local tombpath="$1" # First argument is the path to the tomb [[ -n "$1" ]] || _failure "No tomb name specified for opening."
[[ -n "$tombpath" ]] || _failure "No tomb name specified for opening."
_message "Commanded to open tomb ::1 tomb name::" $tombpath _message "Commanded to open tomb ::1 tomb name::" $1
_check_swap _check_swap
# this also calls _plot() is_valid_tomb $1
is_valid_tomb $tombpath
_track_stat "$tombpath" _track_stat "$TOMBPATH"
_load_key # Try loading new key from option -k and set TOMBKEYFILE _load_key # Try loading new key from option -k and set TOMBKEYFILE
tombmount="$2" tombmount="$2"
[[ "$tombmount" = "" ]] && { [[ "$tombmount" = "" ]] && {
tombmount=/media/$TOMBNAME tombmount=/media/$TOMBNAME
[[ -d /media ]] || { # no /media found, adopting /run/media/$USER (udisks2 compat) [[ -d /media ]] || { # no /media found, adopting /run/media/$USER (udisks2 compat)
tombmount=/run/media/$_USER/$TOMBNAME tombmount=/run/media/$_USER/$TOMBNAME
} }
_message "Mountpoint not specified, using default: ::1 mount poin t::" $tombmount _message "Mountpoint not specified, using default: ::1 mount poin t::" $tombmount
} }
_success "Opening ::1 tomb file:: on ::2 mount point::" $TOMBNAME $tombmo
unt
# check if the mountpoint is already used # check if the mountpoint is already used
mounted_tombs=(`list_tomb_mounts`) mounted_tombs=(`list_tomb_mounts`)
for t in ${mounted_tombs}; do for t in ${mounted_tombs}; do
usedmount=${t[(ws:;:)2]} usedmount=${t[(ws:;:)2]}
[[ "$usedmount" == "$tombmount" ]] && [[ "$usedmount" == "$tombmount" ]] &&
_failure "Mountpoint already in use: ::1 mount point::" $ tombmount _failure "Mountpoint already in use: ::1 mount point::" $ tombmount
done done
_success "Opening ::1 tomb file:: on ::2 mount point::" $TOMBNAME $tombmo
unt
lo_mount $TOMBPATH lo_mount $TOMBPATH
nstloop=`lo_new`
_sudo cryptsetup isLuks ${nstloop} || { _sudo cryptsetup isLuks ${TOMBLOOP} || {
# is it a LUKS encrypted nest? see cryptsetup(1) # is it a LUKS encrypted nest? see cryptsetup(1)
_failure "::1 tomb file:: is not a valid Luks encrypted storage f ile." $TOMBFILE } _failure "::1 tomb file:: is not a valid Luks encrypted storage f ile." $TOMBFILE }
_message "This tomb is a valid LUKS encrypted device." _message "This tomb is a valid LUKS encrypted device."
luksdump="`_sudo cryptsetup luksDump ${nstloop}`" luksdump="`_sudo cryptsetup luksDump ${TOMBLOOP}`"
tombdump=(`print $luksdump | awk ' tombdump=(`print $luksdump | awk '
/^Cipher name/ {print $3} /^Cipher name/ {print $3}
/^Cipher mode/ {print $3} /^Cipher mode/ {print $3}
/^Hash spec/ {print $3}'`) /^Hash spec/ {print $3}'`)
_message "Cipher is \"::1 cipher::\" mode \"::2 mode::\" hash \"::3 hash: :\"" $tombdump[1] $tombdump[2] $tombdump[3] _message "Cipher is \"::1 cipher::\" mode \"::2 mode::\" hash \"::3 hash: :\"" $tombdump[1] $tombdump[2] $tombdump[3]
slotwarn=`print $luksdump | awk ' slotwarn=`print $luksdump | awk '
BEGIN { zero=0 } BEGIN { zero=0 }
/^Key slot 0/ { zero=1 } /^Key slot 0/ { zero=1 }
/^Key slot.*ENABLED/ { if(zero==1) print "WARN" }'` /^Key slot.*ENABLED/ { if(zero==1) print "WARN" }'`
[[ "$slotwarn" == "WARN" ]] && { [[ "$slotwarn" == "WARN" ]] && {
_warning "Multiple key slots are enabled on this tomb. Beware: th ere can be a backdoor." } _warning "Multiple key slots are enabled on this tomb. Beware: th ere can be a backdoor." }
# save date of mount in minutes since 1970
mapdate=`date +%s`
mapper="tomb.$TOMBNAME.$mapdate.$(basename $nstloop)"
_verbose "dev mapper device: ::1 mapper::" $mapper
_verbose "Tomb key: ::1 key file::" $TOMBKEYFILE _verbose "Tomb key: ::1 key file::" $TOMBKEYFILE
# take the name only, strip extensions # 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
{ option_is_set --tomb-pwd } && { ! option_is_set -g } && { { option_is_set --tomb-pwd } && { ! option_is_set -g } && {
tomb_pwd="`option_value --tomb-pwd`" tomb_pwd="`option_value --tomb-pwd`"
_verbose "tomb-pwd = ::1 tomb pass::" $tomb_pwd _verbose "tomb-pwd = ::1 tomb pass::" $tomb_pwd
ask_key_password "$tomb_pwd" ask_key_password "$tomb_pwd"
} || { } || {
ask_key_password ask_key_password
} }
[[ $? == 0 ]] || _failure "No valid password supplied." [[ $? == 0 ]] || _failure "No valid password supplied."
_cryptsetup luksOpen ${nstloop} ${mapper} _cryptsetup luksOpen ${TOMBLOOP} ${TOMBMAPPER}
[[ $? = 0 ]] || { [[ $? = 0 ]] || {
_failure "Failure mounting the encrypted file." } _failure "Failure mounting the encrypted file." }
# preserve the loopdev after exit # preserve the loopdev after exit
lo_preserve "$nstloop" lo_preserve "$TOMBLOOP"
# array: [ cipher, keysize, loopdevice ] # array: [ cipher, keysize, loopdevice ]
tombstat=(`_sudo cryptsetup status ${mapper} | awk ' tombstat=(`_sudo cryptsetup status ${TOMBMAPPER} | awk '
/cipher:/ {print $2} /cipher:/ {print $2}
/keysize:/ {print $2} /keysize:/ {print $2}
/device:/ {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] $t ombstat[1] _verbose "Key size is ::1 size:: for cipher ::2 cipher::" $tombstat[2] $t ombstat[1]
_message "Checking filesystem via ::1::" $tombstat[3] _message "Checking filesystem via ::1::" $tombstat[3]
_sudo fsck -p -C0 /dev/mapper/${mapper} _sudo fsck -p -C0 /dev/mapper/${TOMBMAPPER}
_verbose "Tomb engraved as ::1 tomb name::" $TOMBNAME _verbose "Tomb engraved as ::1 tomb name::" $TOMBNAME
_sudo tune2fs -L $TOMBNAME /dev/mapper/${mapper} > /dev/null _sudo tune2fs -L $TOMBNAME /dev/mapper/${TOMBMAPPER} > /dev/null
# we need root from here on # we need root from here on
_sudo mkdir -p $tombmount _sudo mkdir -p $tombmount
# Default mount options are overridden with the -o switch # Default mount options are overridden with the -o switch
{ option_is_set -o } && { { option_is_set -o } && {
local oldmountopts=$MOUNTOPTS local oldmountopts=$MOUNTOPTS
MOUNTOPTS="$(option_value -o)" } MOUNTOPTS="$(option_value -o)" }
# TODO: safety check MOUNTOPTS # TODO: safety check MOUNTOPTS
# safe_mount_options && # safe_mount_options &&
_sudo mount -o $MOUNTOPTS /dev/mapper/${mapper} ${tombmount} _sudo mount -o $MOUNTOPTS /dev/mapper/${TOMBMAPPER} ${tombmount}
# Clean up if the mount failed # Clean up if the mount failed
[[ $? == 0 ]] || { [[ $? == 0 ]] || {
_warning "Error mounting ::1 mapper:: on ::2 tombmount::" $mapper $tombmount _warning "Error mounting ::1 mapper:: on ::2 tombmount::" $TOMBMA PPER $tombmount
[[ $oldmountopts != $MOUNTOPTS ]] && \ [[ $oldmountopts != $MOUNTOPTS ]] && \
_warning "Are mount options '::1 mount options::' valid?" $MOUNTOPTS _warning "Are mount options '::1 mount options::' valid?" $MOUNTOPTS
# TODO: move cleanup to _endgame() # TODO: move cleanup to _endgame()
[[ -d $tombmount ]] && _sudo rmdir $tombmount [[ -d $tombmount ]] && _sudo rmdir $tombmount
[[ -e /dev/mapper/$mapper ]] && _sudo cryptsetup luksClose $mappe r [[ -e /dev/mapper/$TOMBMAPPER ]] && _sudo cryptsetup luksClose $T OMBMAPPER
# The loop is taken care of in _endgame() # The loop is taken care of in _endgame()
_failure "Cannot mount ::1 tomb name::" $TOMBNAME _failure "Cannot mount ::1 tomb name::" $TOMBNAME
} }
_success "Success opening ::1 tomb file:: on ::2 mount point::" $TOMBFILE $tombmount _success "Success opening ::1 tomb file:: on ::2 mount point::" $TOMBFILE $tombmount
local tombtty tombhost tombuid tombuser local tombtty tombhost tombuid tombuser
# print out when it was opened the last time, by whom and where # print out when it was opened the last time, by whom and where
[[ -r ${tombmount}/.last ]] && { [[ -r ${tombmount}/.last ]] && {
skipping to change at line 2458 skipping to change at line 2397
exec_safe_func_hooks() { exec_safe_func_hooks() {
local mnt local mnt
mnt="$2" mnt="$2"
# Only run if post-hooks has the executable bit set # Only run if post-hooks has the executable bit set
[[ -x $mnt/exec-hooks ]] && { [[ -x $mnt/exec-hooks ]] && {
_success "Exec hook: ::1 exec hook:: ::2 action::" \ _success "Exec hook: ::1 exec hook:: ::2 action::" \
"${mnt}/exec-hooks" "$1" "${mnt}/exec-hooks" "$1"
# here call two actions: open or close. Synopsis: # here call two actions: open or close. Synopsis:
# $1 $2 $3 $4 $5 # $1 $2 $3 $4 $5
# open "$tombmount" # open "$tombmount"
# close "$tombmount" "$tombname" "$tombloop" "$mapper" # close "$tombmount" "$tombname" "$tombloop" "$TOMBMAPPER"
$mnt/exec-hooks "$1" "$2" "$3" "$4" "$5" $mnt/exec-hooks "$1" "$2" "$3" "$4" "$5"
return $? return $?
} }
return 0 return 0
} }
# }}} - Tomb open # }}} - Tomb open
# {{{ List # {{{ List
skipping to change at line 2490 skipping to change at line 2429
for t in ${mounted_tombs}; do for t in ${mounted_tombs}; do
mapper=`basename ${t[(ws:;:)1]}` mapper=`basename ${t[(ws:;:)1]}`
tombname=${t[(ws:;:)5]} tombname=${t[(ws:;:)5]}
tombmount=${t[(ws:;:)2]} tombmount=${t[(ws:;:)2]}
tombfs=${t[(ws:;:)3]} tombfs=${t[(ws:;:)3]}
tombfsopts=${t[(ws:;:)4]} tombfsopts=${t[(ws:;:)4]}
tombloop=${mapper[(ws:.:)4]} tombloop=${mapper[(ws:.:)4]}
# calculate tomb size # calculate tomb size
ts=`df -hP /dev/mapper/$mapper | ts=`df -hP /dev/mapper/$TOMBMAPPER |
awk "/mapper/"' { print $2 ";" $3 ";" $4 ";" $5 }'` awk "/mapper/"' { print $2 ";" $3 ";" $4 ";" $5 }'`
tombtot=${ts[(ws:;:)1]} tombtot=${ts[(ws:;:)1]}
tombused=${ts[(ws:;:)2]} tombused=${ts[(ws:;:)2]}
tombavail=${ts[(ws:;:)3]} tombavail=${ts[(ws:;:)3]}
tombpercent=${ts[(ws:;:)4]} tombpercent=${ts[(ws:;:)4]}
tombp=${tombpercent%%%} tombp=${tombpercent%%%}
# obsolete way to get the last open date from /dev/mapper # obsolete way to get the last open date from /dev/mapper
# which doesn't work when tomb filename contain dots # which doesn't work when tomb filename contain dots
# tombsince=`date --date=@${mapper[(ws:.:)3]} +%c` # tombsince=`date --date=@${mapper[(ws:.:)3]} +%c`
skipping to change at line 2790 skipping to change at line 2729
# }}} - Index and search # }}} - Index and search
# {{{ Resize # {{{ Resize
# resize tomb file size # resize tomb file size
resize_tomb() { resize_tomb() {
local tombpath="$1" # First argument is the path to the tomb local tombpath="$1" # First argument is the path to the tomb
_message "Commanded to resize tomb ::1 tomb name:: to ::2 size:: mebibyte s." $1 $OPTS[-s] _message "Commanded to resize tomb ::1 tomb name:: to ::2 size:: mebibyte s." $1 $OPTS[-s]
[[ -z "$tombpath" ]] && _failure "No tomb name specified for resizing." [[ -z "$1" ]] && _failure "No tomb name specified for resizing."
[[ ! -r $tombpath ]] && _failure "Cannot find ::1::" $tombpath [[ ! -r "$1" ]] && _failure "Cannot find ::1::" $1
newtombsize="`option_value -s`" newtombsize="`option_value -s`"
[[ -z "$newtombsize" ]] && { [[ -z "$newtombsize" ]] && {
_failure "Aborting operations: new size was not specified, use -s " } _failure "Aborting operations: new size was not specified, use -s " }
# this also calls _plot()
is_valid_tomb $tombpath is_valid_tomb $tombpath
_load_key # Try loading new key from option -k and set TOMBKEYFILE _load_key # Try loading new key from option -k and set TOMBKEYFILE
if option_is_set --tomb-pwd; then
tomb_pwd="`option_value --tomb-pwd`"
_verbose "tomb-pwd = ::1 tomb pass::" $tomb_pwd
ask_key_password "$tomb_pwd"
else
ask_key_password
fi
[[ $? == 0 ]] || _failure "No valid password supplied."
local oldtombsize=$(( `stat -c %s "$TOMBPATH" 2>/dev/null` / 1048576 )) local oldtombsize=$(( `stat -c %s "$TOMBPATH" 2>/dev/null` / 1048576 ))
local mounted_tomb=`_sudo findmnt -rvo SOURCE,TARGET,FSTYPE,OPTIONS,LABEL
|
awk -vtomb="[$TOMBNAME]" '/^\/dev\/mapper\/tomb/ { if($5==tomb) p
rint $1 }'`
# Tomb must not be open
[[ -z "$mounted_tomb" ]] || {
_failure "Please close the tomb ::1 tomb name:: before trying to
resize it." $TOMBNAME }
# New tomb size must be specified # New tomb size must be specified
[[ -n "$newtombsize" ]] || { [[ -n "$newtombsize" ]] || {
_failure "You must specify the new size of ::1 tomb name::" $TOMB NAME } _failure "You must specify the new size of ::1 tomb name::" $TOMB NAME }
# New tomb size must be an integer # New tomb size must be an integer
[[ $newtombsize == <-> ]] || _failure "Size is not an integer." [[ $newtombsize == <-> ]] || _failure "Size is not an integer."
# Tombs can only grow in size # Tombs can only grow in size
if [[ "$newtombsize" -gt "$oldtombsize" ]]; then if [[ "$newtombsize" -gt "$oldtombsize" ]]; then
delta="$(( $newtombsize - $oldtombsize ))" delta="$(( $newtombsize - $oldtombsize ))"
skipping to change at line 2837 skipping to change at line 2779
# If same size this allows to re-launch resize if pinentry expire s # If same size this allows to re-launch resize if pinentry expire s
# so that it will continue resizing without appending more space. # so that it will continue resizing without appending more space.
# Resizing the partition to the file size cannot harm data anyway . # Resizing the partition to the file size cannot harm data anyway .
elif [[ "$newtombsize" = "$oldtombsize" ]]; then elif [[ "$newtombsize" = "$oldtombsize" ]]; then
_message "Tomb seems resized already, operating filesystem stretc h" _message "Tomb seems resized already, operating filesystem stretc h"
else else
_failure "The new size must be greater then old tomb size." _failure "The new size must be greater then old tomb size."
fi fi
{ option_is_set --tomb-pwd } && {
tomb_pwd="`option_value --tomb-pwd`"
_verbose "tomb-pwd = ::1 tomb pass::" $tomb_pwd
ask_key_password "$tomb_pwd"
} || {
ask_key_password
}
[[ $? == 0 ]] || _failure "No valid password supplied."
lo_mount "$TOMBPATH" lo_mount "$TOMBPATH"
nstloop=`lo_new`
mapdate=`date +%s`
mapper="tomb.$TOMBNAME.$mapdate.$(basename $nstloop)"
_message "opening tomb" _message "opening tomb"
_cryptsetup luksOpen ${nstloop} ${mapper} || { _cryptsetup luksOpen ${TOMBLOOP} ${TOMBMAPPER} || {
_failure "Failure mounting the encrypted file." } _failure "Failure mounting the encrypted file." }
_sudo cryptsetup resize "${mapper}" || { _sudo cryptsetup resize "${TOMBMAPPER}" || {
_failure "cryptsetup failed to resize ::1 mapper::" $mapper } _failure "cryptsetup failed to resize ::1 mapper::" $TOMBMAPPER }
_sudo e2fsck -p -f /dev/mapper/${mapper} || { _sudo e2fsck -p -f /dev/mapper/${TOMBMAPPER} || {
_failure "e2fsck failed to check ::1 mapper::" $mapper } _failure "e2fsck failed to check ::1 mapper::" $TOMBMAPPER }
_sudo resize2fs /dev/mapper/${mapper} || { _sudo resize2fs /dev/mapper/${TOMBMAPPER} || {
_failure "resize2fs failed to resize ::1 mapper::" $mapper } _failure "resize2fs failed to resize ::1 mapper::" $TOMBMAPPER }
# close and free the loop device # close and free the loop device
_sudo cryptsetup luksClose "${mapper}" _sudo cryptsetup luksClose "${TOMBMAPPER}"
return 0 return 0
} }
# }}} # }}}
# {{{ Close # {{{ Close
umount_tomb() { umount_tomb() {
local tombs how_many_tombs local tombs how_many_tombs
 End of changes. 93 change blocks. 
244 lines changed or deleted 167 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)