Tomb/extras/test/runtests
Alexandre Pujol 6f89dbd2fe Add '--shared' in order to activate sharing support.
Sharing feature is a very sensitive action, the user needs to trust the
GPG public key it is going to share its tomb. This is why this feature
needs to be explicitly activated using in more the flag --shared
on the key encryption commands.
2017-02-03 23:57:52 +00:00

532 lines
15 KiB
Bash
Executable File

#!/usr/bin/env zsh
#
# Copyright (C) 2007-2016 Dyne.org Foundation
#
# Tomb test units by Denis Roio <jaromil@dyne.org>
#
# 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
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This source code is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please refer
# to the GNU Public License for more details.
#
# You should have received a copy of the GNU Public License along with
# this source code; if not, write to: Free Software Foundation, Inc.,
# 675 Mass Ave, Cambridge, MA 02139, USA.
T="../../tomb"
source ${T} source
dummypass=test
dummypassnew=changetest
GLOBAL_RESULT=0
notice() { print; _message "${@}"; print; }
error() { _warning " ${@}"; }
tt() {
start_loops=(`sudo losetup -a |cut -d: -f1`)
start_temps=(`find /dev/shm -name 'tomb*'`)
${T} -D ${=@}
res=$?
loops=(`sudo losetup -a |cut -d: -f1`)
temps=(`find /dev/shm -name 'tomb*'`)
{ test "${#start_loops}" = "${#loops}" } || {
error "loop device usage change to ${#loops}" }
{ test "${#start_temps}" = "${#temps}" } || {
error "temp files usage change to ${#temps}" }
print " Tomb command returns $res"
return $res
}
# check for auxiliary programs
KDF=1
STEGHIDE=1
RESIZER=1
command -v steghide > /dev/null || STEGHIDE=0
command -v e2fsck resize2fs > /dev/null || RESIZER=0
command -v tomb-kdb-pbkdf2 > /dev/null || KDF=0
command -v qrencode > /dev/null || QRENCODE=0
typeset -A results
tests=(dig forge lock badpass open close passwd chksum bind setkey recip-dig
recip-forge recip-lock recip-open recip-close recip-passwd recip-resize
recip-setkey shared shared-passwd shared-setkey)
{ test $RESIZER = 1 } && { tests+=(resize) }
{ test $KDF = 1 } && { tests+=(kdforge kdfpass kdflock kdfopen) }
{ test $STEGHIDE = 1 } && { tests+=(stgin stgout stgopen stgpipe stgimpl
recip-stgin recip-stgout recip-stgopen recip-stgimpl) }
{ test $QRENCODE = 1 } && { tests+=(qrenc) }
# GnuPG Conf.
# Note: the assumption is the test keys are unencrypted.
export GNUPGHOME="gnupg/"
chmod 700 "$GNUPGHOME"
gpgid_1="A4857CD176B31435F9709D25F0E573B8289439CD"
gpgid_2="0B2235E660753AB0475FB3E23DC836481F44B31E"
notice "Loading test suite"
# functions that can be called singularly
test-tomb-create() {
notice "wiping all test.tomb* in /tmp"
sudo rm -f /tmp/test.tomb{,.key,.new.key}
notice "Testing creation: dig"
tt dig -s 20 /tmp/test.tomb
{ test $? = 0 } && { results+=(dig SUCCESS) }
notice "Testing creation: forge"
tt forge /tmp/test.tomb.key \
--ignore-swap --unsafe --tomb-pwd ${dummypass} --use-urandom
{ test $? = 0 } && {
results+=(forge SUCCESS)
#
notice "Dump of clear key contents to examine them:"
print ${dummypass} \
| gpg --batch --passphrase-fd 0 --no-tty --no-options -d /tmp/test.tomb.key \
| hexdump -C
echo --
}
notice "Testing creation: lock"
tt lock /tmp/test.tomb -k /tmp/test.tomb.key \
--ignore-swap --unsafe --tomb-pwd ${dummypass}
{ test $? = 0 } && { results+=(lock SUCCESS) }
}
test-tomb-recip() {
notice "wiping all recip.tomb* in /tmp"
local tomb=/tmp/recip.tomb
local tomb_key=/tmp/recip.tomb.key
sudo rm -f "$tomb" "$tomb_key"
notice "Testing tomb with recipient creation: dig"
tt dig -s 20 $tomb
{ test $? = 0 } && { results+=(recip-dig SUCCESS) }
notice "Testing tomb with recipient creation: forge"
tt forge $tomb_key -r $gpgid_1 --ignore-swap --unsafe --use-urandom
{ test $? = 0 } && { results+=(recip-forge SUCCESS) }
notice "Testing tomb with recipient creation: lock"
tt lock $tomb -k $tomb_key -r $gpgid_1 --ignore-swap --unsafe
{ test $? = 0 } && { results+=(recip-lock SUCCESS) }
notice "Testing tomb with recipient opening: open"
tt open $tomb -k $tomb_key -r $gpgid_1
{ test $? = 0 } && { results+=(recip-open SUCCESS) }
notice "Testing tomb with recipient closing: close"
tt close recip
{ test $? = 0 } && { results+=(recip-close SUCCESS) }
{ test $STEGHIDE = 1 } && {
notice "Testing tomb with recipient steganographic hiding of keys"
cp -f arditi.jpg /tmp/recip.jpg
sudo rm -f /tmp/recip.steg.key
tt --unsafe --tomb-pwd ${dummypass} bury -k /tmp/recip.tomb.key \
/tmp/recip.jpg -r "$gpgid_1"
{ test $? = 0 } && { results+=(recip-stgin SUCCESS) }
tt --unsafe --tomb-pwd ${dummypass} exhume -k /tmp/recip.steg.key \
/tmp/recip.jpg
{ test $? = 0 } && { results+=(recip-stgout SUCCESS) }
tt --unsafe --tomb-pwd ${dummypass} open -k /tmp/recip.steg.key \
/tmp/recip.tomb -r "$gpgid_1"
{ test $? = 0 } && { results+=(recip-stgopen SUCCESS) }
${T} close recip
notice "test using open -k image.jpeg"
tt --unsafe --tomb-pwd ${dummypass} open -k /tmp/recip.jpg \
/tmp/recip.tomb -r "$gpgid_1"
{ test $? = 0 } && { results+=(recip-stgimpl SUCCESS) }
tt close recip
}
notice "Testing tomb with recipient changing gpg key: passwd"
res=0
tt passwd -k $tomb_key -r $gpgid_1 -R $gpgid_2
{ test $? = 0 } || { res=1 }
tt open $tomb -k $tomb_key -r $gpgid_2
{ test $? = 0 } || { res=1 }
tt close recip
{ test $? = 0 } || { res=1 }
{ test $res = 0 } && { results+=(recip-passwd SUCCESS) }
notice "Testing tomb with recipient resizing a tomb: resize"
tt resize -s 30 $tomb -k $tomb_key -r $gpgid_2
{ test $? = 0 } && { results+=(recip-resize SUCCESS) }
notice "Testing tomb with recipient setting a new key: setkey"
sudo rm -f /tmp/new.recip.tomb.key
res=0
tt forge /tmp/new.recip.tomb.key -r $gpgid_2 \
--ignore-swap --unsafe --use-urandom
{ test $? = 0 } || { res=1 }
tt setkey -k /tmp/new.recip.tomb.key $tomb_key $tomb -r $gpgid_2
{ test $? = 0 } || { res=1 }
tt open -k /tmp/new.recip.tomb.key $tomb -r $gpgid_2
{ test $? = 0 } || { res=1 }
{ test $res = 0 } && { results+=(recip-setkey SUCCESS) }
tt close recip
}
test-tomb-shared() {
notice "wiping all shared.tomb* in /tmp"
rm -f /tmp/shared.tomb /tmp/shared.tomb.key
notice "Testing sharing a tomb"
res=0
tt dig -s 20 /tmp/shared.tomb
{ test $? = 0 } || { res=1 }
tt forge /tmp/shared.tomb.key -r $gpgid_1,$gpgid_2 --shared \
--ignore-swap --unsafe --use-urandom
{ test $? = 0 } || { res=1 }
tt lock /tmp/shared.tomb -k /tmp/shared.tomb.key \
--ignore-swap --unsafe -r $gpgid_1
{ test $? = 0 } || { res=1 }
tt open /tmp/shared.tomb -k /tmp/shared.tomb.key -r $gpgid_1
{ test $? = 0 } || { res=1 }
tt close shared
{ test $? = 0 } || { res=1 }
{ test $res = 0 } && { results+=(shared SUCCESS) }
notice "Testing changing recipients on a shared Tomb"
tt passwd -k /tmp/shared.tomb.key -r $gpgid_1,$gpgid_2 \
-R $gpgid_2,$gpgid_1 --shared
{ test $? = 0 } && { results+=(shared-passwd SUCCESS) }
notice "Testing setkey on a shared Tomb"
rm -f /tmp/new.shared.tomb.key
res=0
tt forge /tmp/new.shared.tomb.key -r $gpgid_1,$gpgid_2 --shared\
--ignore-swap --unsafe --use-urandom
{ test $? = 0 } || { res=1 }
tt setkey -k /tmp/new.shared.tomb.key /tmp/shared.tomb.key /tmp/shared.tomb \
-r $gpgid_2,$gpgid_1 --shared
{ test $? = 0 } || { res=1 }
{ test $res = 0 } && { results+=(shared-setkey SUCCESS) }
}
test-bind-hooks() {
notice "Testing bind hooks"
tt --ignore-swap --unsafe --tomb-pwd ${dummypass} \
open /tmp/test.tomb -k /tmp/test.tomb.key
rnd=$RANDOM
bindtest="dyne-tomb-bind-test-$rnd"
echo $rnd > /media/test/$bindtest
rm -f /media/test/bind-hooks
echo "$bindtest $bindtest" > /media/test/bind-hooks
touch $HOME/$bindtest
tt close test
tt -k /tmp/test.tomb.key --unsafe --tomb-pwd ${dummypass} open /tmp/test.tomb
rnd2=`cat $HOME/$bindtest`
if [ "$rnd" = "$rnd2" ]; then
notice "Bind hook on file matches"
results+=(bind SUCCESS)
tt list test
else
error "Bind hook on file reports incongruence"
fi
tt close test
}
test-set-key() {
notice "Testing set key"
sudo rm -f /tmp/test.tomb.new.key
tt forge -k /tmp/test.tomb.new.key --force --unsafe --tomb-pwd ${dummypass} --use-urandom
tt setkey -k /tmp/test.tomb.new.key --unsafe --tomb-pwd ${dummypass} --tomb-old-pwd ${dummypass} /tmp/test.tomb.key /tmp/test.tomb
tt open -k /tmp/test.tomb.new.key --unsafe --tomb-pwd ${dummypass} /tmp/test.tomb
[[ $? = 0 ]] && {
notice "Setkey succesfully swapped tomb key"
results+=(setkey SUCCESS)
notice "Dump of clear key contents to examine them:"
print ${dummypass} \
| gpg --batch --passphrase-fd 0 --no-tty --no-options -d /tmp/test.tomb.new.key \
| hexdump -C
echo --
mv /tmp/test.tomb.new.key /tmp/test.tomb.key
tt close test
}
}
test-regression() {
url=${1:-https://files.dyne.org/tomb/old-releases/Tomb-2.2.tar.gz}
notice "Regression tests using $url"
curl $url > /tmp/tomb-regression.tar.gz
mkdir -p /tmp/tomb-regression
tar xfz /tmp/tomb-regression.tar.gz \
--strip-components 1 -C /tmp/tomb-regression
OLDT="/tmp/tomb-regression/tomb"
version=`${OLDT} -v |& awk 'NR==1 {print $3}'`
_message "tomb version: $version"
tests+=(oldnew-$version newold-$version)
sudo rm -f /tmp/regression-test.tomb{,.key}
${OLDT} -D dig -s 10 /tmp/regression-test.tomb
${OLDT} -D forge /tmp/regression-test.tomb.key \
--ignore-swap --unsafe --tomb-pwd ${dummypass} --use-urandom
${OLDT} -D lock /tmp/regression-test.tomb -k /tmp/regression-test.tomb.key \
--ignore-swap --unsafe --tomb-pwd ${dummypass}
notice "opening old tomb and key using the new tomb"
tt -k /tmp/regression-test.tomb.key --unsafe \
--tomb-pwd ${dummypass} open /tmp/regression-test.tomb
[[ $? = 0 ]] && results+=(oldnew-$version SUCCESS)
tt close regression-test
notice "opening new tomb and key using the old tomb"
${OLDT} -D -k /tmp/test.tomb.key --unsafe \
--tomb-pwd ${dummypass} open /tmp/test.tomb
[[ $? = 0 ]] && results+=(newold-$version SUCCESS)
${OLDT} close test
}
startloops=(`sudo losetup -a |cut -d: -f1`)
[[ $1 = "source" ]] && { return 0 }
[[ $1 = "" ]] || {
tt ${=@}
return $?
}
# isolated function (also called with source)
test-tomb-create
test-tomb-recip
test-tomb-shared
notice "Testing open with wrong password"
tt -k /tmp/test.tomb.key --unsafe --tomb-pwd wrongpassword open /tmp/test.tomb
{ test $? = 0 } || { results+=(badpass SUCCESS) }
notice "Testing open with good password"
tt -k /tmp/test.tomb.key --unsafe --tomb-pwd ${dummypass} open /tmp/test.tomb
{ test $? = 0 } && { results+=(open SUCCESS) }
tt close test
{ test $? = 0 } && { results+=(close SUCCESS) }
notice "Testing changing tomb password"
tt passwd /tmp/test.tomb \
-k /tmp/test.tomb.key --unsafe --tomb-old-pwd ${dummypass} --tomb-pwd ${dummypassnew}
tt passwd /tmp/test.tomb \
-k /tmp/test.tomb.key --unsafe --tomb-old-pwd ${dummypassnew} --tomb-pwd ${dummypass}
{ test $? = 0 } && { results+=(passwd SUCCESS) }
notice "Generating content for file integrity test"
tt -k /tmp/test.tomb.key --unsafe --tomb-pwd ${dummypass} open /tmp/test.tomb
tt dig -s 10 /media/test/datacheck.raw
crc="sha256 /media/test/datacheck.raw"
echo "$crc" > /media/test/datacheck.sha
tt --unsafe close test
{ test $RESIZER = 1 } && {
notice "Testing resize to 30 MiB"
tt --unsafe --tomb-pwd ${dummypass} -k /tmp/test.tomb.key resize /tmp/test.tomb -s 30
{ test $? = 0 } && { results+=(resize SUCCESS) }
}
notice "Testing contents integrity"
tt -k /tmp/test.tomb.key --unsafe --tomb-pwd ${dummypass} open /tmp/test.tomb
{ test $? = 0 } && {
crc2="sha256 /media/test/datacheck.raw"
{ test "$crc" = "$crc2" } && { results+=(chksum SUCCESS) }
tt close test
}
# regression tests with previous stable versions
test-regression https://files.dyne.org/tomb/old-releases/Tomb-2.2.tar.gz
test-regression https://files.dyne.org/tomb/old-releases/Tomb-2.1.1.tar.gz
test-regression https://files.dyne.org/tomb/old-releases/Tomb-2.0.1.tar.gz
# isolated function
test-bind-hooks
# iso func
test-set-key
{ test $KDF = 1 } && {
notice "Testing KDF key"
sudo rm -f /tmp/test.tomb.kdf /tmp/kdf.tomb
tt --unsafe --tomb-pwd ${dummypass} --use-urandom --kdf 1 forge -k /tmp/test.tomb.kdf
{ test $? = 0 } && { results+=(kdforge SUCCESS) }
tt passwd --unsafe --tomb-old-pwd ${dummypass} --tomb-pwd ${dummypassnew} --kdf 1 -k /tmp/test.tomb.kdf
{ test $? = 0 } && { results+=(kdfpass SUCCESS) }
tt dig -s 10 /tmp/kdf.tomb
tt lock /tmp/kdf.tomb -k /tmp/test.tomb.kdf \
--ignore-swap --unsafe --tomb-pwd ${dummypassnew} --kdf 1
{ test $? = 0 } && { results+=(kdflock SUCCESS) }
tt open /tmp/kdf.tomb -k /tmp/test.tomb.kdf \
--ignore-swap --unsafe --tomb-pwd ${dummypassnew} --kdf 1
{ test $? = 0 } && { results+=(kdfopen SUCCESS) }
${T} close kdf
}
{ test $STEGHIDE = 1 } && {
notice "Testing steganographic hiding of keys"
cp -f arditi.jpg /tmp/tomb.jpg
sudo rm -f /tmp/test.steg.key
tt --unsafe --tomb-pwd ${dummypass} bury -k /tmp/test.tomb.key /tmp/tomb.jpg
{ test $? = 0 } && { results+=(stgin SUCCESS) }
rm -f /tmp/test.steg.key
tt --unsafe --tomb-pwd ${dummypass} exhume -k /tmp/test.steg.key /tmp/tomb.jpg
{ test $? = 0 } && { results+=(stgout SUCCESS) }
tt --unsafe --tomb-pwd ${dummypass} open -k /tmp/test.steg.key /tmp/test.tomb
{ test $? = 0 } && { results+=(stgopen SUCCESS) }
${T} close test
# test piping keys using -k -
tkey=`tt --unsafe --tomb-pwd ${dummypass} exhume /tmp/tomb.jpg`
print "$tkey" | tt --unsafe --tomb-pwd ${dummypass} open -k - /tmp/test.tomb
{ test $? = 0 } && { results+=(stgpipe SUCCESS) }
${T} close test
notice "test using open -k image.jpeg"
tt --unsafe --tomb-pwd ${dummypass} open -k /tmp/tomb.jpg /tmp/test.tomb
{ test $? = 0 } && { results+=(stgimpl SUCCESS) }
tt close test
}
{ test $QRENCODE = 1 } && {
notice "test rendering a QR printable key backup"
tt engrave -k /tmp/test.tomb.key
{ test $? = 0 } && { results+=(qrenc SUCCESS) }
}
# rm /tmp/test.tomb{,.key} -f || exit 1
endloops=(`sudo losetup -a |cut -d: -f1`)
notice "Test results summary"
print "${#startloops} loop devices busy at start"
for t in $tests; do
res=${results[$t]:-FAIL}
[[ "$res" == "SUCCESS" ]] || GLOBAL_RESULT=1
echo "$t\t$res"
done
print "${#endloops} loop devices busy at end"
print "Done. You can remove temporary leftovers from /tmp :"
for i in `find /tmp -name '*tomb*' 2>/dev/null`; do ls -lh $i; done
return $GLOBAL_RESULT