tomb

the crypto undertaker
git clone git://parazyd.org/tomb.git
Log | Files | Refs | README | LICENSE

runtests (17305B)


      1 #!/usr/bin/env zsh
      2 #
      3 # Copyright (C) 2007-2016 Dyne.org Foundation
      4 #
      5 # Tomb test units by Denis Roio <jaromil@dyne.org>
      6 #
      7 # This source code is free software; you can redistribute it and/or
      8 # modify it under the terms of the GNU Public License as published by
      9 # the Free Software Foundation; either version 3 of the License, or
     10 # (at your option) any later version.
     11 #
     12 # This source code is distributed in the hope that it will be useful,
     13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  Please refer
     15 # to the GNU Public License for more details.
     16 #
     17 # You should have received a copy of the GNU Public License along with
     18 # this source code; if not, write to: Free Software Foundation, Inc.,
     19 # 675 Mass Ave, Cambridge, MA 02139, USA.
     20 
     21 
     22 T="../../tomb"
     23 
     24 source ${T} source
     25 dummypass=test
     26 dummypassnew=changetest
     27 
     28 GLOBAL_RESULT=0
     29 
     30 notice() { print; _message "${@}"; print; }
     31 error() { _warning "     ${@}"; }
     32 tt() {
     33 	start_loops=(`sudo losetup -a |cut -d: -f1`)
     34 	start_temps=(`find /dev/shm -name 'tomb*'`)
     35 	${T} -D ${=@}
     36 	res=$?
     37 	loops=(`sudo losetup -a |cut -d: -f1`)
     38 	temps=(`find /dev/shm -name 'tomb*'`)
     39 
     40 	{ test "${#start_loops}" = "${#loops}" } || {
     41 	    error "loop device usage change to ${#loops}" }
     42 	{ test "${#start_temps}" = "${#temps}" } || {
     43 	    error "temp files usage change to ${#temps}" }
     44 	print "     Tomb command returns $res"
     45 	return $res
     46 }
     47 
     48 # check for auxiliary programs
     49 KDF=1
     50 STEGHIDE=1
     51 RESIZER=1
     52 command -v steghide > /dev/null || STEGHIDE=0
     53 command -v e2fsck resize2fs > /dev/null || RESIZER=0
     54 command -v tomb-kdb-pbkdf2 > /dev/null || KDF=0
     55 command -v qrencode > /dev/null || QRENCODE=0
     56 
     57 
     58 typeset -A results
     59 
     60 tests=(dig forge lock badpass open close passwd chksum bind setkey recip-dig 
     61 		recip-forge recip-lock recip-open recip-close recip-passwd recip-resize 
     62 		recip-setkey recip-default recip-hidden shared shared-passwd shared-setkey)
     63 
     64 { test $RESIZER = 1 } && { tests+=(resize) }
     65 { test $KDF = 1 } && { tests+=(kdforge kdfpass kdflock kdfopen) }
     66 { test $STEGHIDE = 1 } && { tests+=(stgin stgout stgopen stgpipe stgimpl
     67 recip-stgin recip-stgout recip-stgopen recip-stgimpl) }
     68 { test $QRENCODE = 1 } && { tests+=(qrenc) }
     69 
     70 # GnuPG Conf.
     71 # Note: the assumption is the test keys are unencrypted.
     72 export GNUPGHOME="gnupg/"
     73 chmod 700 "$GNUPGHOME"
     74 gpgid_1="A4857CD176B31435F9709D25F0E573B8289439CD"
     75 gpgid_2="0B2235E660753AB0475FB3E23DC836481F44B31E"
     76 
     77 notice "Loading test suite"
     78 
     79 # functions that can be called singularly
     80 
     81 test-tomb-create() {
     82 
     83     notice "wiping all test.tomb* in /tmp"
     84     sudo rm -f /tmp/test.tomb{,.key,.new.key}
     85 
     86     notice "Testing creation: dig"
     87 
     88     tt dig -s 20 /tmp/test.tomb
     89 
     90     { test $? = 0 } && { results+=(dig SUCCESS) }
     91 
     92     notice "Testing creation: forge"
     93 
     94     tt forge /tmp/test.tomb.key \
     95         --ignore-swap --unsafe --tomb-pwd ${dummypass} --use-urandom 
     96 
     97     { test $? = 0 } && { 
     98         results+=(forge SUCCESS)
     99         # 
    100         notice "Dump of clear key contents to examine them:"
    101         print ${dummypass} \
    102 	        | gpg --batch --passphrase-fd 0 --no-tty --no-options -d /tmp/test.tomb.key \
    103 	        | hexdump -C
    104         echo --
    105     }
    106 
    107     notice "Testing creation: lock"
    108 
    109     tt lock /tmp/test.tomb -k /tmp/test.tomb.key \
    110         --ignore-swap --unsafe --tomb-pwd ${dummypass} 
    111 
    112     { test $? = 0 } && { results+=(lock SUCCESS) }
    113 }
    114 
    115 test-tomb-recip() {
    116 
    117     notice "wiping all recip.tomb* in /tmp"
    118     local tomb=/tmp/recip.tomb
    119     local tomb_key=/tmp/recip.tomb.key
    120     sudo rm -f "$tomb" "$tomb_key"
    121 
    122     notice "Testing tomb with recipient creation: dig"
    123     tt dig -s 20 $tomb
    124     { test $? = 0 } && { results+=(recip-dig SUCCESS) }
    125     
    126     notice "Testing tomb with recipient creation: forge"
    127     tt forge $tomb_key -g -r $gpgid_1 --ignore-swap --unsafe --use-urandom
    128     { test $? = 0 } && { results+=(recip-forge SUCCESS) } 
    129     
    130     notice "Testing tomb with recipient creation: lock"
    131     tt lock $tomb -k $tomb_key -g -r $gpgid_1 --ignore-swap --unsafe
    132     { test $? = 0 } && { results+=(recip-lock SUCCESS) }
    133     
    134     notice "Testing tomb with recipient opening: open"
    135     tt open $tomb -k $tomb_key -g
    136     { test $? = 0 } && { results+=(recip-open SUCCESS) }
    137     
    138     notice "Testing tomb with recipient closing: close"
    139     tt close recip
    140     { test $? = 0 } && { results+=(recip-close SUCCESS) }
    141     
    142     { test $STEGHIDE = 1 } && {
    143         notice "Testing tomb with recipient steganographic hiding of keys"
    144         
    145         cp -f arditi.jpg /tmp/recip.jpg
    146         sudo rm -f /tmp/recip.steg.key
    147     	
    148         tt --unsafe --tomb-pwd ${dummypass} bury -k /tmp/recip.tomb.key \
    149             /tmp/recip.jpg -g -r "$gpgid_1"
    150         { test $? = 0 } && { results+=(recip-stgin SUCCESS) }
    151 
    152         tt --unsafe --tomb-pwd ${dummypass} exhume -k /tmp/recip.steg.key \
    153             /tmp/recip.jpg
    154         { test $? = 0 } && { results+=(recip-stgout SUCCESS) }
    155 
    156         tt --unsafe --tomb-pwd ${dummypass} open -k /tmp/recip.steg.key \
    157             /tmp/recip.tomb -g
    158         { test $? = 0 } && { results+=(recip-stgopen SUCCESS) }
    159         ${T} close recip
    160 
    161         notice "test using open -k image.jpeg"
    162         tt --unsafe --tomb-pwd ${dummypass} open -k /tmp/recip.jpg \
    163             /tmp/recip.tomb -g
    164         { test $? = 0 } && { results+=(recip-stgimpl SUCCESS) }
    165         tt close recip
    166     }
    167     
    168 	notice "Testing tomb with recipient changing gpg key: passwd"
    169 	res=0
    170 	tt passwd -k $tomb_key -g -r $gpgid_2
    171 	{ test $? = 0 } || { res=1 }
    172 	tt open $tomb -k $tomb_key -g
    173 	{ test $? = 0 } || { res=1 }
    174 	tt close recip
    175 	{ test $? = 0 } || { res=1 }
    176 	{ test $res = 0 } && { results+=(recip-passwd SUCCESS) }
    177 	
    178 	notice "Testing tomb with recipient resizing a tomb: resize"
    179     tt resize -s 30 $tomb -k $tomb_key -g -r $gpgid_2
    180     { test $? = 0 } && { results+=(recip-resize SUCCESS) }
    181     
    182     notice "Testing tomb with recipient setting a new key: setkey"
    183     sudo rm -f /tmp/new.recip.tomb.key
    184     res=0
    185     tt forge /tmp/new.recip.tomb.key -g -r $gpgid_2 \
    186         --ignore-swap --unsafe --use-urandom
    187     { test $? = 0 } || { res=1 }
    188     tt setkey -k /tmp/new.recip.tomb.key $tomb_key $tomb -g -r $gpgid_2
    189     { test $? = 0 } || { res=1 }
    190     tt open -k /tmp/new.recip.tomb.key $tomb -g
    191     { test $? = 0 } || { res=1 }
    192     { test $res = 0 } && { results+=(recip-setkey SUCCESS) }
    193     tt close recip
    194 }
    195 
    196 test-tomb-recip-default() {
    197 
    198 	notice "wiping all default.tomb* in /tmp"
    199 	rm -f /tmp/default.tomb /tmp/default.tomb.key /tmp/default.tmp 
    200 	
    201 	notice "Testing tomb with the default recipient"
    202 	res=0
    203     tt dig -s 20 /tmp/default.tomb
    204     { test $? = 0 } || { res=1 }
    205     tt forge /tmp/default.tomb.key -g --ignore-swap --unsafe --use-urandom
    206     { test $? = 0 } || { res=1 }
    207 	tt lock /tmp/default.tomb -k /tmp/default.tomb.key \
    208         --ignore-swap --unsafe -g
    209     { test $? = 0 } || { res=1 }
    210     gpg -d --status-fd 2 /tmp/default.tomb.key 1> /dev/null 2> /tmp/default.tmp 
    211     [[ -z "$(grep 'Tomb Test 2' /tmp/default.tmp)" ]] && { res=1 }
    212     { test $res = 0 } && { results+=(recip-default SUCCESS) }
    213 }
    214 
    215 test-tomb-recip-hidden() {
    216 
    217 	notice "wiping all hidden.tomb* in /tmp"
    218 	rm -f /tmp/hidden.tomb /tmp/hidden.tomb.key
    219 	
    220 	notice "Testing tomb with hidden recipient"
    221 	res=0
    222     tt dig -s 20 /tmp/hidden.tomb
    223     { test $? = 0 } || { res=1 }
    224     tt forge /tmp/hidden.tomb.key -g -R $gpgid_1 --ignore-swap --unsafe --use-urandom
    225     { test $? = 0 } || { res=1 }
    226 	tt lock /tmp/hidden.tomb -k /tmp/hidden.tomb.key \
    227         --ignore-swap --unsafe -g -R $gpgid_1
    228     { test $? = 0 } || { res=1 }
    229     { test $res = 0 } && { results+=(recip-hidden SUCCESS) }
    230 }
    231 
    232 test-tomb-shared() {
    233 
    234 	notice "wiping all shared.tomb* in /tmp"
    235     rm -f /tmp/shared.tomb /tmp/shared.tomb.key
    236     
    237     notice "Testing sharing a tomb"
    238     res=0
    239     tt dig -s 20 /tmp/shared.tomb
    240     { test $? = 0 } || { res=1 }
    241     tt forge /tmp/shared.tomb.key -g -r $gpgid_1,$gpgid_2 \
    242         --ignore-swap --unsafe --use-urandom 
    243     { test $? = 0 } || { res=1 }
    244     tt lock /tmp/shared.tomb -k /tmp/shared.tomb.key \
    245         --ignore-swap --unsafe -g -r $gpgid_1
    246     { test $? = 0 } || { res=1 }
    247     tt open /tmp/shared.tomb -k /tmp/shared.tomb.key -g
    248     { test $? = 0 } || { res=1 }
    249     tt close shared
    250     { test $? = 0 } || { res=1 }
    251     { test $res = 0 } && { results+=(shared SUCCESS) }
    252     
    253     notice "Testing changing recipients on a shared Tomb"
    254     tt passwd -k /tmp/shared.tomb.key -g -r $gpgid_2,$gpgid_1
    255     { test $? = 0 } && { results+=(shared-passwd SUCCESS) }
    256     
    257     notice "Testing setkey on a shared Tomb"
    258     rm -f /tmp/new.shared.tomb.key
    259     res=0
    260     tt forge /tmp/new.shared.tomb.key -g -r $gpgid_1,$gpgid_2 \
    261         --ignore-swap --unsafe --use-urandom
    262     { test $? = 0 } || { res=1 }
    263     tt setkey -k /tmp/new.shared.tomb.key /tmp/shared.tomb.key /tmp/shared.tomb \
    264         -g -r $gpgid_2,$gpgid_1
    265     { test $? = 0 } || { res=1 }
    266     { test $res = 0 } && { results+=(shared-setkey SUCCESS) }
    267 }
    268 
    269 test-bind-hooks() {
    270     notice "Testing bind hooks"
    271 
    272     tt --ignore-swap --unsafe --tomb-pwd ${dummypass} \
    273         open /tmp/test.tomb -k /tmp/test.tomb.key
    274 
    275     rnd=$RANDOM
    276     bindtest="dyne-tomb-bind-test-$rnd"
    277     echo $rnd > /media/test/$bindtest
    278     rm -f /media/test/bind-hooks
    279     echo "$bindtest $bindtest" > /media/test/bind-hooks
    280     touch $HOME/$bindtest
    281     tt close test
    282     tt -k /tmp/test.tomb.key --unsafe --tomb-pwd ${dummypass} open /tmp/test.tomb
    283     rnd2=`cat $HOME/$bindtest`
    284     if [ "$rnd" = "$rnd2" ]; then
    285 	    notice "Bind hook on file matches"
    286 	    results+=(bind SUCCESS)
    287 	    tt list test
    288     else
    289 	    error "Bind hook on file reports incongruence"
    290     fi
    291     tt close test
    292 }
    293 
    294 test-set-key() {
    295 
    296     notice "Testing set key"
    297 
    298     sudo rm -f /tmp/test.tomb.new.key
    299 
    300     tt forge -k /tmp/test.tomb.new.key --force --unsafe --tomb-pwd ${dummypass} --use-urandom
    301 
    302     tt setkey -k /tmp/test.tomb.new.key --unsafe --tomb-pwd ${dummypass} --tomb-old-pwd ${dummypass} /tmp/test.tomb.key /tmp/test.tomb
    303 
    304     tt open -k /tmp/test.tomb.new.key --unsafe --tomb-pwd ${dummypass} /tmp/test.tomb
    305 
    306     [[ $? = 0 ]] && {
    307         notice "Setkey succesfully swapped tomb key"
    308         results+=(setkey SUCCESS)
    309         notice "Dump of clear key contents to examine them:"
    310         print ${dummypass} \
    311 	        | gpg --batch --passphrase-fd 0 --no-tty --no-options -d /tmp/test.tomb.new.key \
    312 	        | hexdump -C
    313         echo --
    314         mv /tmp/test.tomb.new.key /tmp/test.tomb.key
    315         tt close test
    316     }
    317 }
    318 
    319 
    320 test-regression() {
    321 
    322 	url=${1:-https://files.dyne.org/tomb/old-releases/Tomb-2.2.tar.gz}
    323 	notice "Regression tests using $url"
    324 
    325 	curl $url > /tmp/tomb-regression.tar.gz
    326 	mkdir -p /tmp/tomb-regression
    327 	tar xfz /tmp/tomb-regression.tar.gz \
    328 		--strip-components 1 -C /tmp/tomb-regression
    329 
    330 	OLDT="/tmp/tomb-regression/tomb"
    331 	version=`${OLDT} -v |& awk 'NR==1 {print $3}'`
    332 	_message "tomb version: $version"
    333 	tests+=(oldnew-$version newold-$version)
    334 
    335 	sudo rm -f /tmp/regression-test.tomb{,.key}
    336 
    337 	${OLDT} -D dig -s 10 /tmp/regression-test.tomb
    338 	${OLDT} -D forge /tmp/regression-test.tomb.key \
    339 			--ignore-swap --unsafe --tomb-pwd ${dummypass} --use-urandom
    340 	${OLDT} -D lock /tmp/regression-test.tomb -k /tmp/regression-test.tomb.key \
    341 			--ignore-swap --unsafe --tomb-pwd ${dummypass}
    342 
    343 	notice "opening old tomb and key using the new tomb"
    344 
    345 	tt -k /tmp/regression-test.tomb.key --unsafe \
    346 	   --tomb-pwd ${dummypass} open /tmp/regression-test.tomb
    347 
    348 	[[ $? = 0 ]] && results+=(oldnew-$version SUCCESS)
    349 
    350 	tt close regression-test
    351 
    352 	notice "opening new tomb and key using the old tomb"
    353 
    354 	${OLDT} -D -k /tmp/test.tomb.key --unsafe \
    355 			--tomb-pwd ${dummypass} open /tmp/test.tomb
    356 
    357 	[[ $? = 0 ]] && results+=(newold-$version SUCCESS)
    358 
    359 	${OLDT} close test
    360 }
    361 
    362 
    363 test-open-read-only() {
    364 
    365     notice "wiping all testro.tomb* in /tmp"
    366     sudo rm -f /tmp/testro.tomb{,.key,.new.key}
    367 
    368     # Create new
    369     tt dig -s 20 /tmp/testro.tomb
    370     tt forge /tmp/testro.tomb.key \
    371         --ignore-swap --unsafe --tomb-pwd ${dummypass} --use-urandom
    372     tt lock /tmp/testro.tomb -k /tmp/testro.tomb.key \
    373         --ignore-swap --unsafe --tomb-pwd ${dummypass} 
    374 
    375     notice "Testing open read only"
    376 
    377     # Remove write privilege on test.tomb
    378     chmod -w /tmp/testro.tomb
    379 
    380     # Attempt to open the unwritable tomb with the read-only mount option
    381     tt open /tmp/testro.tomb -k /tmp/testro.tomb.key \
    382         --ignore-swap --unsafe --tomb-pwd ${dummypass} -o ro,noatime,nodev
    383 
    384     { test $? = 0 } && {
    385         results+=(openro SUCCESS)
    386         tt close testro
    387     }
    388 }
    389 
    390 
    391 startloops=(`sudo losetup -a |cut -d: -f1`)
    392 
    393 [[ $1 = "source" ]] && { return 0 }
    394 
    395 [[ $1 = "" ]] || {
    396     tt ${=@}
    397     return $?
    398 }
    399 
    400 # isolated function (also called with source)
    401 test-tomb-create
    402 test-tomb-recip
    403 test-tomb-recip-default
    404 test-tomb-recip-hidden
    405 test-tomb-shared
    406 
    407 notice "Testing open with wrong password"
    408 
    409 tt -k /tmp/test.tomb.key --unsafe --tomb-pwd wrongpassword open /tmp/test.tomb
    410 
    411 { test $? = 0 } || { results+=(badpass SUCCESS) }
    412 
    413 
    414 
    415 notice "Testing open with good password"
    416 
    417 tt -k /tmp/test.tomb.key --unsafe --tomb-pwd ${dummypass} open /tmp/test.tomb
    418 
    419 { test $? = 0 } && { results+=(open SUCCESS) }
    420 
    421 tt close test
    422 
    423 { test $? = 0 } && { results+=(close SUCCESS) }
    424 
    425 # isolated function
    426 test-open-read-only
    427 
    428 
    429 notice "Testing changing tomb password"
    430 
    431 tt passwd /tmp/test.tomb \
    432     -k /tmp/test.tomb.key --unsafe --tomb-old-pwd ${dummypass} --tomb-pwd ${dummypassnew}
    433 
    434 tt passwd /tmp/test.tomb \
    435     -k /tmp/test.tomb.key --unsafe --tomb-old-pwd ${dummypassnew} --tomb-pwd ${dummypass}
    436 
    437 { test $? = 0 } && { results+=(passwd SUCCESS) }
    438 
    439 
    440 
    441 
    442 
    443 notice "Generating content for file integrity test"
    444 
    445 tt -k /tmp/test.tomb.key --unsafe --tomb-pwd ${dummypass} open /tmp/test.tomb
    446 
    447 tt dig -s 10 /media/test/datacheck.raw
    448 
    449 crc="sha256 /media/test/datacheck.raw"
    450 echo "$crc" > /media/test/datacheck.sha
    451 
    452 tt --unsafe close test
    453 
    454 { test $RESIZER = 1 } && {
    455     notice "Testing resize to 30 MiB"
    456     
    457     tt --unsafe --tomb-pwd ${dummypass} -k /tmp/test.tomb.key resize /tmp/test.tomb -s 30
    458     
    459     { test $? = 0 } && { results+=(resize SUCCESS) }
    460 
    461 }
    462 
    463 notice "Testing contents integrity"
    464 
    465 tt -k /tmp/test.tomb.key --unsafe --tomb-pwd ${dummypass} open /tmp/test.tomb
    466 
    467 { test $? = 0 } && {
    468     
    469     crc2="sha256 /media/test/datacheck.raw"
    470     
    471     { test "$crc" = "$crc2" } && { results+=(chksum SUCCESS) }
    472 
    473     tt close test
    474 }
    475 
    476 
    477 # regression tests with previous stable versions
    478 test-regression https://files.dyne.org/tomb/old-releases/Tomb-2.2.tar.gz
    479 test-regression https://files.dyne.org/tomb/old-releases/Tomb-2.1.1.tar.gz
    480 test-regression https://files.dyne.org/tomb/old-releases/Tomb-2.0.1.tar.gz
    481 
    482 
    483 # isolated function
    484 test-bind-hooks
    485 
    486 
    487 
    488 
    489 
    490 
    491 
    492 
    493 
    494 # iso func
    495 test-set-key
    496 
    497 
    498 
    499 
    500 { test $KDF = 1 } && { 
    501     
    502     notice "Testing KDF key"
    503     sudo rm -f /tmp/test.tomb.kdf /tmp/kdf.tomb
    504     
    505     tt --unsafe --tomb-pwd ${dummypass} --use-urandom --kdf 1 forge -k /tmp/test.tomb.kdf
    506     
    507     { test $? = 0 } && { results+=(kdforge SUCCESS) }
    508     
    509     tt passwd --unsafe --tomb-old-pwd ${dummypass} --tomb-pwd ${dummypassnew} --kdf 1 -k /tmp/test.tomb.kdf
    510     
    511     { test $? = 0 } && { results+=(kdfpass SUCCESS) }
    512     
    513     tt dig -s 10 /tmp/kdf.tomb
    514     
    515     tt lock /tmp/kdf.tomb -k /tmp/test.tomb.kdf \
    516         --ignore-swap --unsafe --tomb-pwd ${dummypassnew} --kdf 1
    517     
    518     { test $? = 0 } && { results+=(kdflock SUCCESS) }
    519     
    520     tt open /tmp/kdf.tomb -k /tmp/test.tomb.kdf \
    521         --ignore-swap --unsafe --tomb-pwd ${dummypassnew} --kdf 1
    522     
    523     { test $? = 0 } && { results+=(kdfopen SUCCESS) }
    524     
    525     ${T} close kdf
    526     
    527 }
    528 
    529 { test $STEGHIDE = 1 } && {
    530 
    531     notice "Testing steganographic hiding of keys"
    532 
    533     cp -f arditi.jpg /tmp/tomb.jpg
    534     sudo rm -f /tmp/test.steg.key
    535     
    536     tt --unsafe --tomb-pwd ${dummypass} bury -k /tmp/test.tomb.key /tmp/tomb.jpg
    537 
    538     { test $? = 0 } && { results+=(stgin SUCCESS) }
    539 
    540     rm -f /tmp/test.steg.key
    541 
    542     tt --unsafe --tomb-pwd ${dummypass} exhume -k /tmp/test.steg.key /tmp/tomb.jpg
    543 
    544     { test $? = 0 } && { results+=(stgout SUCCESS) }
    545 
    546     tt --unsafe --tomb-pwd ${dummypass} open -k /tmp/test.steg.key /tmp/test.tomb
    547 
    548     { test $? = 0 } && { results+=(stgopen SUCCESS) }
    549 
    550     ${T} close test
    551 
    552     # test piping keys using -k -
    553     tkey=`tt --unsafe --tomb-pwd ${dummypass} exhume /tmp/tomb.jpg`
    554     print "$tkey" | tt --unsafe --tomb-pwd ${dummypass} open -k - /tmp/test.tomb
    555     { test $? = 0 } && { results+=(stgpipe SUCCESS) }
    556 
    557     ${T} close test
    558 
    559 
    560     notice "test using open -k image.jpeg"
    561 
    562     tt --unsafe --tomb-pwd ${dummypass} open -k /tmp/tomb.jpg /tmp/test.tomb 
    563     { test $? = 0 } && { results+=(stgimpl SUCCESS) }
    564 
    565     tt close test
    566 }
    567 
    568 { test $QRENCODE = 1 } && {
    569 
    570     notice "test rendering a QR printable key backup"
    571 
    572     tt engrave -k /tmp/test.tomb.key
    573 
    574     { test $? = 0 } && { results+=(qrenc SUCCESS) }
    575 
    576 }
    577 
    578 # rm /tmp/test.tomb{,.key} -f || exit 1
    579     
    580 endloops=(`sudo losetup -a |cut -d: -f1`)
    581 
    582 notice "Test results summary"
    583 
    584 print "${#startloops} loop devices busy at start"
    585 
    586 for t in $tests; do
    587     res=${results[$t]:-FAIL}
    588     [[ "$res" == "SUCCESS" ]] || GLOBAL_RESULT=1
    589     echo "$t\t$res"
    590 done
    591 
    592 print "${#endloops} loop devices busy at end"
    593 print "Done. You can remove temporary leftovers from /tmp :"
    594 for i in `find /tmp -name '*tomb*' 2>/dev/null`; do ls -lh $i; done
    595 return $GLOBAL_RESULT