1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 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
|