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