#!/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 <$BINDIR/cryptsetup <>$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 2>&1 &1 /dev/null 2>&1 &1 /dev/null 2>&1 /dev/null &1 >/dev/null /dev/null) output_stderr=$(echo foobar | $CRYPT --generate '$999$foobar$' 2>&1 >/dev/null) exit_code=$? assertNull "'echo foobar | crypt --generate ' unexpectedly generated something" "$output_stdout" if ! echo "$output_stderr" | grep -q "ERROR:"; then fail "'echo foobar | crypt --generate ' did not print any error message" fi assertEquals "'echo foobar | crypt --generate ' 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 ' did not recreate the original hash" "$output1" "$output3" } testCryptCheckEmptyPassword() { output_stdout=$($CRYPT --check 'h/GdiFWQsXxA.' 2>/dev/null &1 >/dev/null /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 ' printed unexpected output" "$output" assertEquals "'echo foobar | $CRYPT --check ' 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 ' printed unexpected output" "$output" assertEquals "'echo foobar | $CRYPT --check ' 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