mirror of
https://github.com/Llewellynvdm/Tomb.git
synced 2024-09-21 17:29:02 +00:00
Relevant improvements to key password handling
now keys are verified in load_key() honoring commanline args ask_key_password() will challenge user verifying using gnupg drop_key() should be called after key has been used this commit removes quite som duplicate code in password handling.
This commit is contained in:
parent
f37f7dd51d
commit
110ae83cd1
333
tomb
333
tomb
@ -180,7 +180,7 @@ check_bin() {
|
||||
export PATH=/sbin:/usr/sbin:$PATH
|
||||
|
||||
# which dd command to use
|
||||
command -v dcfldd
|
||||
command -v dcfldd > /dev/null
|
||||
{ test $? = 0 } && { DD="dcfldd statusinterval=1" }
|
||||
|
||||
# which wipe command to use
|
||||
@ -249,14 +249,14 @@ safe_dir() {
|
||||
if (( $MKTEMP )); then
|
||||
mktemp -d /dev/shm/$1.$$.XXXXXXX
|
||||
else
|
||||
dir="/dev/shm/$1.$$.$RANDOM$RANDOM"
|
||||
dir="/dev/shm/$1.$$.$RANDOM$RANDOM"
|
||||
mkdir -m 0700 -p "$dir"
|
||||
print "$dir"
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
_warning "WARNING: we cannot ensure we're running in RAM."
|
||||
xxx "Wait a bit before retrying... (attempt $tries)"
|
||||
xxx "Wait a bit before retrying... (attempt $tries)"
|
||||
sync && sleep 0.5
|
||||
fi
|
||||
done
|
||||
@ -827,6 +827,92 @@ dig_tomb() {
|
||||
_message "tomb lock ${tombname}.tomb ${tombname}.tomb.key"
|
||||
}
|
||||
|
||||
# this function retrieves a tomb key specified on commandline
|
||||
# or one implicit if laying nearby the tomb, or from stin
|
||||
# it also runs checks and creates a temporary key in memory
|
||||
# to be dropped at the end of functions using it with drop_key()
|
||||
# on success returns 0 and prints out the full path to the key
|
||||
typeset -h tombkeydir
|
||||
load_key() {
|
||||
# check if the key is set manually then use the one existing
|
||||
local tombdir="$1"
|
||||
local tombname="$2"
|
||||
if option_is_set -k ; then
|
||||
if [[ "`option_value -k`" == "-" ]]; then
|
||||
# take key from stdin
|
||||
local tombkeydir
|
||||
tombkeydir=`safe_dir`
|
||||
cat > ${tombkeydir}/stdin.tmp
|
||||
tombkey=${tombkeydir}/stdin.tmp
|
||||
else
|
||||
# take key from a file
|
||||
tombkey=`option_value -k`
|
||||
fi
|
||||
else
|
||||
# guess key as lying besides the tomb
|
||||
tombkey=${tombdir}/${tombname}.tomb.key
|
||||
fi
|
||||
|
||||
if [ -r "${tombkey}" ]; then
|
||||
_message "We'll use this key:"
|
||||
_message " `ls -lh ${tombkey}`"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
# this does a check on the file header, virtuosism by hellekin
|
||||
# [[ `file =(awk '/^-+BEGIN/,0' $1) -bi` =~ application/pgp ]]
|
||||
if ! is_valid_key ${tombkey}; then
|
||||
_warning "The key seems invalid, the application/pgp header is missing"
|
||||
return 1
|
||||
fi
|
||||
print "$tombkey"
|
||||
return 0
|
||||
}
|
||||
# it asks the user for the password to use the key
|
||||
# it tests it against the return code of gpg
|
||||
# on success returns 0 and prints the password
|
||||
# (to be saved into a temporary variable!)
|
||||
ask_key_password() {
|
||||
tombkey="$1"
|
||||
local keyname=`basename $tombkey`
|
||||
_message "a password is required to use key ${keyname}"
|
||||
local passok=0
|
||||
local tombpass=""
|
||||
if option_is_set --tomb-pwd; then
|
||||
tombpass=`option_value --tomb-pwd`
|
||||
else
|
||||
for c in 1 2 3; do
|
||||
if [ $c = 1 ]; then
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Insert password to use key: $keyname"`
|
||||
else
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Insert password to use key: $keyname (retry $c)"`
|
||||
fi
|
||||
if [[ $? != 0 ]]; then
|
||||
_warning "User aborted password dialog"
|
||||
return 1
|
||||
fi
|
||||
|
||||
get_lukskey "$tombpass" ${tombkey} >/dev/null
|
||||
|
||||
if [ $? = 0 ]; then
|
||||
passok=1; _message "Password OK."
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
{ test "$passok" = "1" } || { return 1 }
|
||||
print "$tombpass"
|
||||
unset $tombpass
|
||||
return 0
|
||||
}
|
||||
drop_key() {
|
||||
{ test "$tombkeydir" = "" } && { return 0 }
|
||||
{ test -r ${tombkeydir}/stdin.tmp } && {
|
||||
${=WIPE} ${tombkeydir}/stdin.tmp; rmdir ${tombkeydir} }
|
||||
}
|
||||
|
||||
# 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
|
||||
@ -858,7 +944,7 @@ lock_tomb_with_key() {
|
||||
xxx "loop mounted on ${nstloop}"
|
||||
|
||||
_message "checking if the tomb is empty (we never step on somebody else's bones)"
|
||||
cryptsetup isLuks ${nstloop}
|
||||
cryptsetup isLuks ${nstloop}
|
||||
if [ $? = 0 ]; then
|
||||
# is it a LUKS encrypted nest? then bail out and avoid reformatting it
|
||||
_warning "The tomb was already locked with another key"
|
||||
@ -868,38 +954,12 @@ lock_tomb_with_key() {
|
||||
_message "fine, this tomb seems empty."
|
||||
fi
|
||||
|
||||
# check if the key is set manually then use the one existing
|
||||
if option_is_set -k ; then
|
||||
if [[ "`option_value -k`" == "-" ]]; then
|
||||
# take key from stdin
|
||||
local tombkeydir
|
||||
tombkeydir=`safe_dir`
|
||||
cat > ${tombkeydir}/stdin.tmp
|
||||
tombkey=${tombkeydir}/stdin.tmp
|
||||
else
|
||||
# take key from a file
|
||||
tombkey=`option_value -k`
|
||||
fi
|
||||
else
|
||||
# guess key as lying besides the tomb
|
||||
tombkey=${tombdir}/${tombname}.tomb.key
|
||||
fi
|
||||
|
||||
if [ -r "${tombkey}" ]; then
|
||||
_message "We'll use this key to lock the tomb:"
|
||||
_message " `ls -lh ${tombkey}`"
|
||||
else
|
||||
losetup -d ${nstloop}
|
||||
die "No key found. Use the option -k to specify a key file."
|
||||
fi
|
||||
|
||||
# this does a check on the file header, virtuosism by hellekin
|
||||
# [[ `file =(awk '/^-+BEGIN/,0' $1) -bi` =~ application/pgp ]]
|
||||
if ! is_valid_key ${tombkey}; then
|
||||
_warning "The key seems invalid, the application/pgp header is missing"
|
||||
losetup -d ${nstloop}
|
||||
die "Operation aborted."
|
||||
fi
|
||||
# load key from options or file
|
||||
tombkey=`load_key ${tombdir} ${tombname}`
|
||||
{ test $? = 0 } || {
|
||||
losetup -d $nstloop
|
||||
die "Aborting operations: error loading key $tombkey" }
|
||||
# make sure to call drop_key later
|
||||
|
||||
# the encryption cipher for a tomb can be set at creation using -o
|
||||
if option_is_set -o; then
|
||||
@ -909,35 +969,11 @@ lock_tomb_with_key() {
|
||||
fi
|
||||
_message "locking using cipher: $cipher"
|
||||
|
||||
keyname=`basename $tombkey | cut -d. -f1`
|
||||
_message "a password is required to use key ${keyname}"
|
||||
local passok=0
|
||||
if option_is_set --tomb-pwd; then
|
||||
tombpass=`option_value --tomb-pwd`
|
||||
else
|
||||
for c in 1 2 3; do
|
||||
if [ $c = 1 ]; then
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Insert password to use key: $keyname"`
|
||||
else
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Insert password to use key: $keyname (retry $c)"`
|
||||
fi
|
||||
if [[ $? != 0 ]]; then
|
||||
losetup -d ${nstloop}
|
||||
die "User aborted"
|
||||
fi
|
||||
|
||||
get_lukskey "${tombpass}" ${tombkey} >/dev/null
|
||||
if [ $? = 0 ]; then
|
||||
passok=1; _message "Password OK."
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [ "$passok" = "0" ]; then
|
||||
_warning "Password incorrect"
|
||||
losetup -d $nstloop
|
||||
die "Operation aborted."
|
||||
fi
|
||||
# get the pass from the user and check it
|
||||
tombpass=`ask_key_password "$tombkey"`
|
||||
{ test $? = 0 } || {
|
||||
losetup -d ${nstloop}
|
||||
die "No valid password supplied" }
|
||||
|
||||
_success "Locking ${tombfile} with ${tombkey}"
|
||||
|
||||
@ -953,8 +989,6 @@ lock_tomb_with_key() {
|
||||
die "Operation aborted."
|
||||
fi
|
||||
|
||||
|
||||
|
||||
get_lukskey "${tombpass}" ${tombkey} | \
|
||||
cryptsetup --key-file - \
|
||||
--cipher ${cipher} luksOpen ${nstloop} tomb.tmp
|
||||
@ -965,7 +999,9 @@ lock_tomb_with_key() {
|
||||
die "Operation aborted."
|
||||
fi
|
||||
|
||||
# cleanup tombs
|
||||
unset tombpass
|
||||
drop_key # make sure all temp files are out
|
||||
|
||||
_message "formatting your Tomb with Ext3/Ext4 filesystem"
|
||||
${=MKFS} ${tombname} /dev/mapper/tomb.tmp
|
||||
@ -1024,7 +1060,7 @@ is_valid_key() {
|
||||
#will output the lukskey
|
||||
get_lukskey() {
|
||||
local tombpass=$1
|
||||
keyfile=$2
|
||||
local keyfile=$2
|
||||
firstline=`head -n1 $keyfile`
|
||||
xxx "get_lukskey XXX $keyfile"
|
||||
if [[ $firstline =~ '^_KDF_' ]]; then
|
||||
@ -1164,33 +1200,14 @@ mount_tomb() {
|
||||
tombname=${tombfile%%\.*}
|
||||
xxx "tomb found: ${tombdir}/${tombfile}"
|
||||
|
||||
if option_is_set -k ; then
|
||||
if [[ "`option_value -k`" == "-" ]]; then
|
||||
# take key from stdin
|
||||
local tombkeydir
|
||||
tombkeydir=`safe_dir`
|
||||
cat > ${tombkeydir}/stdin.tmp
|
||||
tombkey=${tombkeydir}/stdin.tmp
|
||||
else
|
||||
# take key from a file
|
||||
tombkey=`option_value -k`
|
||||
fi
|
||||
else
|
||||
# guess key as lying besides the tomb
|
||||
tombkey=${tombdir}/${tombfile}.key
|
||||
fi
|
||||
if ! [ -r ${tombkey} ]; then
|
||||
_warning "key file not found: ${tombkey}"
|
||||
_warning "operation aborted."
|
||||
return 1
|
||||
fi
|
||||
tombkey=`load_key ${tombdir} ${tombname}`
|
||||
{ test $? = 0 } || {
|
||||
die "Aborting operations: error loading key $tombkey" }
|
||||
|
||||
if ! [ $2 ]; then
|
||||
|
||||
if [ "$2" = "" ]; then
|
||||
tombmount=/media/${tombfile}
|
||||
_message "mountpoint not specified, using default: $tombmount"
|
||||
elif ! [ -x $2 ]; then
|
||||
_warning "mountpoint $2 doesn't exist, operation aborted."
|
||||
return 1
|
||||
else
|
||||
tombmount=$2
|
||||
fi
|
||||
@ -1198,7 +1215,7 @@ mount_tomb() {
|
||||
# check if its already open
|
||||
mount -l | grep "${tombfile}.*\[$tombname\]$" 2>&1 > /dev/null
|
||||
if [ $? = 0 ]; then
|
||||
_warning "$tombname is already open on $tombmount"
|
||||
_warning "$tombname is already open."
|
||||
_message "here below its status is reported:"
|
||||
list_tombs ${tombname}
|
||||
return 1
|
||||
@ -1206,8 +1223,6 @@ mount_tomb() {
|
||||
|
||||
_success "Opening $tombfile on $tombmount"
|
||||
|
||||
# we need root from here on
|
||||
mkdir -p $tombmount
|
||||
|
||||
nstloop=`losetup -f`
|
||||
if [ $? = 255 ]; then
|
||||
@ -1219,7 +1234,6 @@ mount_tomb() {
|
||||
if [ $? != 0 ]; then
|
||||
# is it a LUKS encrypted nest? see cryptsetup(1)
|
||||
_warning "$tombfile is not a valid Luks encrypted storage file"
|
||||
$norm || rmdir $tombmount 2>/dev/null
|
||||
return 1
|
||||
fi
|
||||
say "this tomb is a valid LUKS encrypted device"
|
||||
@ -1241,45 +1255,21 @@ mount_tomb() {
|
||||
# save date of mount in minutes since 1970
|
||||
mapdate=`date +%s`
|
||||
|
||||
|
||||
mapper="tomb.${tombname}.${mapdate}.`basename $nstloop`"
|
||||
keyname=`basename $tombkey | cut -d. -f1`
|
||||
|
||||
_warning "Password is required for key ${keyname}"
|
||||
for c in 1 2 3; do
|
||||
if ! option_is_set --tomb-pwd; then
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Open tomb ${keyname}"`
|
||||
if [[ $? != 0 ]]; then
|
||||
die "User aborted"
|
||||
fi
|
||||
else
|
||||
tombpass=`option_value --tomb-pwd`
|
||||
fi
|
||||
get_lukskey "${tombpass}" ${tombkey} | \
|
||||
cryptsetup --key-file - luksOpen ${nstloop} ${mapper}
|
||||
local ret=$?
|
||||
unset tombpass
|
||||
if [[ $ret != 0 ]]; then
|
||||
if [[ $c = 3 ]] || option_is_set --tomb-pwd; then
|
||||
die "Wrong password: aborting"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
tombpass=`ask_key_password $tombkey`
|
||||
{ test $? = 0 } || {
|
||||
die "No valid password supplied" }
|
||||
|
||||
# if key was from stdin delete temp file and dir
|
||||
if [ $tombkeydir ]; then
|
||||
${=WIPE} ${tombkey}
|
||||
rmdir $tombkeydir
|
||||
fi
|
||||
get_lukskey "${tombpass}" ${tombkey} | \
|
||||
cryptsetup --key-file - luksOpen ${nstloop} ${mapper}
|
||||
|
||||
if [ -r /dev/mapper/${mapper} ]; then
|
||||
break; # password was correct
|
||||
fi
|
||||
done
|
||||
drop_key
|
||||
unset tombpass
|
||||
|
||||
if ! [ -r /dev/mapper/${mapper} ]; then
|
||||
losetup -d ${nstloop}
|
||||
$norm || rmdir ${tombmount} 2>/dev/null
|
||||
die "failure mounting the encrypted file"
|
||||
fi
|
||||
|
||||
@ -1296,6 +1286,9 @@ mount_tomb() {
|
||||
xxx "tomb engraved as $tombname"
|
||||
tune2fs -L ${tombname} /dev/mapper/${mapper} > /dev/null
|
||||
|
||||
# we need root from here on
|
||||
mkdir -p $tombmount
|
||||
|
||||
mount -o $MOUNTOPTS /dev/mapper/${mapper} ${tombmount}
|
||||
|
||||
chown ${_uid}:${_gid} ${tombmount}
|
||||
@ -1364,7 +1357,7 @@ BEGIN { main="" }
|
||||
}
|
||||
'
|
||||
else
|
||||
# list a specific tomb
|
||||
# list a specific tomb
|
||||
mount -l \
|
||||
| awk -vtomb="[$1]" '
|
||||
BEGIN { main="" }
|
||||
@ -1534,9 +1527,9 @@ umount_tomb() {
|
||||
|
||||
# # kill the status tray widget if still present
|
||||
# # this makes the widget disappear when closing tomb from cli
|
||||
# awkmapper=`sed 's:\/:\\\/:g' <<< $mapper`
|
||||
# statustray_pid=`ps ax | awk "/tomb-status $awkmapper/"' {print $1} '`
|
||||
# { test "$statustray_pid" = "" } || { kill ${statustray_pid} }
|
||||
# awkmapper=`sed 's:\/:\\\/:g' <<< $mapper`
|
||||
# statustray_pid=`ps ax | awk "/tomb-status $awkmapper/"' {print $1} '`
|
||||
# { test "$statustray_pid" = "" } || { kill ${statustray_pid} }
|
||||
|
||||
_success "Tomb $tombname closed: your bones will rest in peace."
|
||||
|
||||
@ -1574,23 +1567,14 @@ change_passwd() {
|
||||
lukskey=`safe_filename tombluks`
|
||||
|
||||
_success "Changing password for $keyfile"
|
||||
keyname=`basename $keyfile`
|
||||
if ! option_is_set --tomb-old-pwd; then
|
||||
while true; do
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "Type old password for ${keyname}" "Change tomb key password"`
|
||||
if [[ $? == 1 ]]; then
|
||||
die "User aborted"
|
||||
fi
|
||||
if get_lukskey "${tombpass}" ${keyfile} > ${lukskey}; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
tombpass=`option_value --tomb-old-pwd`
|
||||
if ! get_lukskey "${tombpass}" ${keyfile} > ${lukskey}; then
|
||||
die "Invalid old password"
|
||||
fi
|
||||
fi
|
||||
|
||||
tombpass=`ask_key_password $keyfile`
|
||||
{ test $? = 0 } || {
|
||||
die "No valid password supplied" }
|
||||
|
||||
get_lukskey "${tombpass}" ${keyfile} > ${lukskey};
|
||||
|
||||
drop_key
|
||||
|
||||
{
|
||||
gen_key $lukskey > ${tmpnewkey}
|
||||
@ -1631,25 +1615,11 @@ resize_tomb() {
|
||||
local tombname=${tombfile%%\.*}
|
||||
tombfile=${tombname}.tomb
|
||||
|
||||
if option_is_set -k ; then
|
||||
if [[ "`option_value -k`" == "-" ]]; then
|
||||
# take key from stdin
|
||||
local tombkeydir
|
||||
tombkeydir=`safe_dir`
|
||||
cat > ${tombkeydir}/stdin.tmp
|
||||
tombkey=${tombkeydir}/stdin.tmp
|
||||
else
|
||||
# take key from a file
|
||||
tombkey=`option_value -k`
|
||||
fi
|
||||
else
|
||||
# guess key as lying besides the tomb
|
||||
tombkey=${tombdir}/${tombfile}.key
|
||||
fi
|
||||
|
||||
if ! [ -r ${tombkey} ]; then
|
||||
_failure "key file not found: ${tombkey}"
|
||||
fi
|
||||
# load key from options or file
|
||||
tombkey=`load_key ${tombdir} ${tombname}`
|
||||
{ test $? = 0 } || {
|
||||
die "Aborting operations: error loading key $tombkey" }
|
||||
# make sure to call drop_key later
|
||||
|
||||
local tmp_resize=`safe_filename tmbrsz`
|
||||
local newtombsize=$opts[-s]
|
||||
@ -1688,31 +1658,26 @@ resize_tomb() {
|
||||
cat "${tmp_resize}" >> "$1"
|
||||
${=WIPE} "${tmp_resize}"
|
||||
|
||||
|
||||
tombpass=`ask_key_password $tombkey`
|
||||
{ test $? = 0 } || {
|
||||
die "No valid password supplied" }
|
||||
|
||||
local nstloop=`losetup -f`
|
||||
if [ $? = 255 ]; then
|
||||
_failure "too many tomb opened. Please close any of them to open another tomb"
|
||||
fi
|
||||
|
||||
losetup -f "$1"
|
||||
|
||||
local mapdate=`date +%s`
|
||||
local mapper="tomb.${tombname}.${mapdate}.`basename $nstloop`"
|
||||
|
||||
_message "Password is required for key ${keyname}"
|
||||
for c in 1 2 3; do
|
||||
if [ $c = 1 ]; then
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass ${keyname}`
|
||||
else
|
||||
tombpass=`exec_as_user ${TOMBEXEC} askpass "$keyname (retry $c)"`
|
||||
fi
|
||||
get_lukskey "${tombpass}" ${tombkey} | \
|
||||
cryptsetup --key-file - luksOpen ${nstloop} ${mapper}
|
||||
get_lukskey "${tombpass}" ${tombkey} | \
|
||||
cryptsetup --key-file - luksOpen ${nstloop} ${mapper}
|
||||
|
||||
unset tombpass
|
||||
|
||||
if [ -r /dev/mapper/${mapper} ]; then
|
||||
break; # password was correct
|
||||
fi
|
||||
done
|
||||
unset tombpass
|
||||
drop_key # cleanup after load_key
|
||||
|
||||
if ! [ -r /dev/mapper/${mapper} ]; then
|
||||
losetup -d ${nstloop}
|
||||
@ -1974,7 +1939,7 @@ main() {
|
||||
|
||||
subcommands_opts[create]="f s: -size=s -force k: -key=k -ignore-swap -kdf: -sudo-pwd: -tomb-pwd: -use-urandom"
|
||||
|
||||
subcommands_opts[forge]="f -ignore-swap -kdf: -use-urandom"
|
||||
subcommands_opts[forge]="f -ignore-swap k: -key=k -kdf: -use-urandom"
|
||||
subcommands_opts[dig]="f -ignore-swap s: -size=s"
|
||||
subcommands_opts[lock]="f -force -ignore-swap s: -size=s k: -key=k -sudo-pwd: -tomb-pwd:"
|
||||
|
||||
@ -2146,7 +2111,7 @@ main() {
|
||||
encode_key $PARAM[1] $PARAM[2] ;;
|
||||
exhume)
|
||||
if [ "$STEGHIDE" = 0 ]; then
|
||||
_warning "steghide not installed. Cannot exhume your key"
|
||||
_warning "steghide not installed. Cannot exhume your key"
|
||||
return 1
|
||||
fi
|
||||
decode_key $PARAM[1] $PARAM[2]
|
||||
|
Loading…
Reference in New Issue
Block a user