diff options
Diffstat (limited to 'check')
-rwxr-xr-x | check | 266 |
1 files changed, 266 insertions, 0 deletions
@@ -0,0 +1,266 @@ +#!/bin/sh + +CRYPT=${CRYPT:-./crypt} +ASKPASS=${ASKPASS:-./askpass} + +oneTimeSetUp() { + export OUTDIR="$SHUNIT_TMPDIR/out" + export BINDIR="$SHUNIT_TMPDIR/bin" + export PATH="$BINDIR:$PATH" + + # Directory for output data (dropped after each test) + mkdir -p $OUTDIR + + # Test helper scripts + mkdir -p $BINDIR + cat >$BINDIR/askpass <<END +#!/bin/sh +echo -n "\${FAKE_ASKPASS_ANSWER:-foobar}" +END + cat >$BINDIR/cryptsetup <<END +#!/bin/sh +echo "\$@" >>$OUTDIR/cryptsetup +END + chmod 755 $BINDIR/* +} + +setUp() { + # Overrides for askpass + export DIVERTED_ASKPASS="$BINDIR/askpass" + export CRYPT_HELPER="$CRYPT" + export NUKE_PASSWORD_HASH_PATH="$SHUNIT_TMPDIR/password_hash" + export CRYPTTAB_SOURCE="$SHUNIT_TMPDIR/device" + touch $CRYPTTAB_SOURCE + + # Clean up some environment variables that might be set by tests + unset FAKE_ASKPASS_ANSWER +} + +tearDown() { + if [ -d "$OUTDIR" ]; then + rm -f $OUTDIR/* + fi + rm -f $NUKE_PASSWORD_HASH_PATH +} + +testCryptNoArgsOutput() { + output=$($CRYPT 2>&1 </dev/null) + if ! echo "$output" | grep -q "Usage:"; then + fail 'Does not print Usage output without argument' + fi +} +testCryptNoArgsExitCode() { + $CRYPT >/dev/null 2>&1 </dev/null + assertEquals 'Bad exit code when ran without argument' 1 $? +} + +testCryptBadArgOutput() { + output=$($CRYPT --doesnotexist 2>&1 </dev/null) + if ! echo "$output" | grep -q "Usage:"; then + fail 'Does not print Usage output with invalid argument' + fi +} +testCryptBadArgExitCode() { + $CRYPT --doesnotexist >/dev/null 2>&1 </dev/null + assertEquals 'Bad exit code when ran with invalid argument' 1 $? +} + +testCryptHelpOutput() { + output=$($CRYPT --help 2>&1 </dev/null) + if ! echo "$output" | grep -q "Usage:"; then + fail 'Does not print Usage output with --help' + fi +} +testCryptHelpExitCode() { + $CRYPT --help >/dev/null 2>&1 </dev/null + assertEquals 'Bad exit code when ran with --help' 0 $? +} + +testCryptGenerateEmptyPassword() { + output_stdout=$($CRYPT --generate 'h/' 2>/dev/null </dev/null) + output_stderr=$($CRYPT --generate 'h/' 2>&1 >/dev/null </dev/null) + exit_code=$? + assertNull "'crypt --generate </dev/null' unexpectedly generated something" "$output_stdout" + if ! echo "$output_stderr" | grep -q "ERROR:"; then + fail "'crypt --generate </dev/null' did not print any error message" + fi + assertEquals "'crypt --generate </dev/null' has a bad exit code" 1 $exit_code +} + +do_testCryptGenerate() { + output=$(echo "foobar" | $CRYPT --generate $1) + exit_code=$? + assertNotNull "'echo foobar | crypt --generate $1' ($2) provided no output" "$output" + assertEquals "'echo foobar | crypt --generate $1' ($2) returned bad exit code" 0 $exit_code +} + +testCryptGenerateBasic() { + do_testCryptGenerate 'h/' 'DES' +} +testCryptGenerateMD5() { + do_testCryptGenerate '$1$h/$' 'MD5' +} +testCryptGenerateSHA256() { + do_testCryptGenerate '$5$h/$' 'SHA-256' +} +testCryptGenerateSHA512() { + do_testCryptGenerate '$6$h/$' 'SHA-512' +} + +testCryptGenerateBadSalt() { + output_stdout=$(echo foobar | $CRYPT --generate '$999$foobar$' 2>/dev/null) + output_stderr=$(echo foobar | $CRYPT --generate '$999$foobar$' 2>&1 >/dev/null) + exit_code=$? + assertNull "'echo foobar | crypt --generate <bad-salt>' unexpectedly generated something" "$output_stdout" + if ! echo "$output_stderr" | grep -q "ERROR:"; then + fail "'echo foobar | crypt --generate <bad-salt>' did not print any error message" + fi + assertEquals "'echo foobar | crypt --generate <bad-salt>' has a bad exit code" 1 $exit_code +} + +testCryptGenerateNoSaltSupplied() { + output_stdout=$(echo foobar | $CRYPT --generate 2>/dev/null) + output_stderr=$(echo foobar | $CRYPT --generate 2>&1 >/dev/null) + exit_code=$? + assertNull "'echo foobar | crypt --generate' generated noise on stderr" "$output_stderr" + if ! echo "$output_stdout" | grep -q '^\$6\$'; then + fail "'echo foobar | crypt --generate' did not generate a SHA-512 based hash ($output_stdout)" + fi + assertEquals "'echo foobar | crypt --generate' has a bad exit code" 0 $exit_code +} + +testCryptGenerateEmptySaltSupplied() { + output_stdout=$(echo foobar | $CRYPT --generate '' 2>/dev/null) + output_stderr=$(echo foobar | $CRYPT --generate '' 2>&1 >/dev/null) + exit_code=$? + assertNull "'echo foobar | crypt --generate ''' generated noise on stderr" "$output_stderr" + if ! echo "$output_stdout" | grep -q '^\$6\$'; then + fail "'echo foobar | crypt --generate ''' did not generate a SHA-512 based hash ($output_stdout)" + fi + assertEquals "'echo foobar | crypt --generate ''' has a bad exit code" 0 $exit_code +} + +testCryptGenerateNoSaltRandomness() { + output1=$(echo foobar | $CRYPT --generate 2>/dev/null) + output2=$(echo foobar | $CRYPT --generate 2>/dev/null) + salt1="$(echo $output1 | cut -d$ -f1-3)"'$' + salt2="$(echo $output2 | cut -d$ -f1-3)"'$' + assertNotEquals "Two consecutive runs of 'echo foobar | $CRYPT --generate' generated the same salt" "$output1" "$output2" + output3=$(echo foobar | $CRYPT --generate "$salt1") + assertEquals "'echo foobar | $CRYPT --generate <salt>' did not recreate the original hash" "$output1" "$output3" +} + +testCryptCheckEmptyPassword() { + output_stdout=$($CRYPT --check 'h/GdiFWQsXxA.' 2>/dev/null </dev/null) + output_stderr=$($CRYPT --check 'h/GdiFWQsXxA.' 2>&1 >/dev/null </dev/null) + exit_code=$? + assertNull "'crypt --check <hash> </dev/null' unexpectedly generated something" "$output_stdout" + if ! echo "$output_stderr" | grep -q "ERROR:"; then + fail "'crypt --check <hash> </dev/null' did not print any error message" + fi + assertEquals "'crypt --check <hash> </dev/null' has a bad exit code" 1 $exit_code +} + +testCryptCheckNoHashSupplied() { + output_stdout=$(echo "foobar" | $CRYPT --check 2>/dev/null) + output_stderr=$(echo "foobar" | $CRYPT --check 2>&1 >/dev/null) + if ! echo "$output_stderr" | grep -q "ERROR:"; then + fail "'echo foobar | crypt --check' did not print any error message" + fi + assertNull "'echo foobar | crypt --check' unexpectly returned something on stdout" "$output_stdout" +} + +testCryptCheckGoodPassword() { + output=$(echo "foobar" | $CRYPT --check '$6$dkcZzIkv$Ju7XCIc4igWvht3bOu266vvRam6IdnIFxoyonDt.6JZl8NfCaukACeIRYVW7WQtrUtqN2TrWSgEFnXumuTiN41' 2>&1) + exit_code=$? + assertNull "'echo foobar | $CRYPT --check <good-hash>' printed unexpected output" "$output" + assertEquals "'echo foobar | $CRYPT --check <good-hash>' did not exit with" 0 $exit_code +} + +testCryptCheckBadPassword() { + output=$(echo "foobar-bad" | $CRYPT --check '$6$dkcZzIkv$Ju7XCIc4igWvht3bOu266vvRam6IdnIFxoyonDt.6JZl8NfCaukACeIRYVW7WQtrUtqN2TrWSgEFnXumuTiN41' 2>&1) + exit_code=$? + assertNull "'echo foobar | $CRYPT --check <bad-hash>' printed unexpected output" "$output" + assertEquals "'echo foobar | $CRYPT --check <bad-hash>' did not exit with" 1 $exit_code +} + +testCryptGenerateCheckRoundtrip() { + for salt in '' 'h/' '$1$abcd$' '$5$12345678$' '$6$deadbeef$' + do + password="haX0rd3ad" + + password_hash=$(echo $password | $CRYPT --generate "$salt") + exit_code=$? + assertEquals "'echo $password | $CRYPT --generate $salt' did not exit with" 0 $exit_code + + echo $password | $CRYPT --check "$password_hash" + exit_code=$? + assertEquals "'echo $password | $CRYPT --check $password_hash' did not exit with" 0 $exit_code + done +} + +testAskPassWarnsAboutMissingCrypttabSource() { + export CRYPTTAB_SOURCE=/does/not/exist + + $ASKPASS >$OUTDIR/log 2>&1 + + if ! grep -q 'WARNING: $CRYPTTAB_SOURCE' $OUTDIR/log; then + fail "askpass should complain of missing CRYPTTAB_SOURCE" + fi +} + +testAskPassWarnsAboutMissingCryptHelper() { + export CRYPT_HELPER=/does/not/exist + + $ASKPASS >$OUTDIR/log 2>&1 + + if ! grep -q "WARNING: $CRYPT_HELPER" $OUTDIR/log; then + fail "askpass should complain of missing \$CRYPT_HELPER" + fi +} + +testAskPassCallsCryptsetupErase() { + # Setup the password and its matching hash + export FAKE_ASKPASS_ANSWER="foobar" + echo '$6$dkcZzIkv$Ju7XCIc4igWvht3bOu266vvRam6IdnIFxoyonDt.6JZl8NfCaukACeIRYVW7WQtrUtqN2TrWSgEFnXumuTiN41' >$NUKE_PASSWORD_HASH_PATH + + $ASKPASS >$OUTDIR/log 2>&1 + + touch $OUTDIR/cryptsetup + if ! grep -q "erase $CRYPTTAB_SOURCE" $OUTDIR/cryptsetup; then + echo "Output of askpass:" + cat $OUTDIR/log + echo "" + echo "Cryptsetup log:" + cat $OUTDIR/cryptsetup + fail "cryptsetup erase has not been called by askpass" + fi +} + +testAskPassWithoutPasswordHash() { + # No password_hash is created + + $ASKPASS >$OUTDIR/log 2>&1 + + assertFalse 'cryptsetup was unexpectly run' "[ -e $OUTDIR/cryptsetup ]" +} + +testAskPassWithNonMatchingPasswordHash() { + # Setup the password and a non-matching hash + export FAKE_ASKPASS_ANSWER="this-is-not-the-good-password" + echo '$6$dkcZzIkv$Ju7XCIc4igWvht3bOu266vvRam6IdnIFxoyonDt.6JZl8NfCaukACeIRYVW7WQtrUtqN2TrWSgEFnXumuTiN41' >$NUKE_PASSWORD_HASH_PATH + + $ASKPASS >$OUTDIR/log 2>&1 + + assertFalse 'cryptsetup was unexpectly run' "[ -e $OUTDIR/cryptsetup ]" +} + +testAskPassReturnsPassword() { + export FAKE_ASKPASS_ANSWER="my-password" + + OUT=$($ASKPASS 2>/dev/null) + + assertEquals "askpass did not print the password" "$FAKE_ASKPASS_ANSWER" "$OUT" +} + +. shunit2 |