diff --git a/changes/bug13111-generate-keys-on-empty-file b/changes/bug13111-generate-keys-on-empty-file index 345e87ab75..20c10c7443 100644 --- a/changes/bug13111-generate-keys-on-empty-file +++ b/changes/bug13111-generate-keys-on-empty-file @@ -1,17 +1,23 @@ - o Minor bugfixes + o Minor bugfixes (file handling): - Stop failing when key files are zero-length. Instead, generate new keys, and overwrite the empty key files. - Fixes bug 13111. + Fixes bug 13111. Patch by "teor". - Stop generating a fresh .old RSA key file when the .old file is missing. - Fixed as part of bug 13111. - Avoid overwriting .old key files with empty key files. - Fixed as part of bug 13111. - Stop crashing when a NULL filename is passed to file_status(). - Fixed as part of bug 13111. + Fixed as part of bug 13111. Patches by "teor". - o Minor enhancements: + o Minor enhancements (file handling): - Skip loading zero-length extra info store, router store, stats, state, and key files. - Implemented with bug 13111. - Return FN_ERROR when a zero-length filename is passed to file_status(). - Fixed as part of bug 13111. + Fixed as part of bug 13111. Patches by "teor". + + o Minor enhancements (testing): + - Test that tor does not fail when key files are zero-length. + Check that tor generates new keys, and overwrites the empty key files. + - Test that tor generates new keys when keys are missing (existing + behaviour). + - Test that tor does not overwrite key files that already contain data + (existing behaviour). + Tests bug 13111. Patch by "teor". diff --git a/src/test/include.am b/src/test/include.am index d7a647940b..4518f8fb8f 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -120,9 +120,11 @@ if USEPYTHON ./src/test/test-bt-cl assert | $(PYTHON) $(top_srcdir)/src/test/bt_test.py ./src/test/test-bt-cl crash | $(PYTHON) $(top_srcdir)/src/test/bt_test.py endif + ./src/test/zero_length_keys.sh EXTRA_DIST += \ src/test/bt_test.py \ src/test/ntor_ref.py \ src/test/slownacl_curve25519.py \ - src/test/test_cmdline_args.py + src/test/test_cmdline_args.py \ + src/test/zero_length_keys.sh diff --git a/src/test/zero_length_keys.sh b/src/test/zero_length_keys.sh new file mode 100755 index 0000000000..e7cb900cec --- /dev/null +++ b/src/test/zero_length_keys.sh @@ -0,0 +1,113 @@ +#!/bin/sh +# Check that tor regenerates keys when key files are zero-length +# Test for bug #13111 - Tor fails to start if onion keys are zero length +# +# Usage: +# ./zero_length_keys.sh +# Run all the tests below +# ./zero_length_keys.sh -z +# Check tor will launch and regenerate zero-length keys +# ./zero_length_keys.sh -d +# Check tor regenerates deleted keys (existing behaviour) +# ./zero_length_keys.sh -e +# Check tor does not overwrite existing keys (existing behaviour) +# +# Exit Statuses: +# -2: test failed - tor did not generate the key files on first run +# -1: a command failed - the test could not be completed +# 0: test succeeded - tor regenerated/kept the files +# 1: test failed - tor did not regenerate/keep the files +# + +if [ $# -lt 1 ]; then + echo "Testing that tor correctly handles zero-length keys" + "$0" -z && "$0" -d && "$0" -e + exit $? +fi + +export DATA_DIR=`mktemp -d -t tor_zero_length_keys` +TOR="src/or/tor --hush --DisableNetwork 1 --ShutdownWaitLength 0 --ORPort 12345" + +if [ -s "$DATA_DIR"/keys/secret_id_key -a -s "$DATA_DIR"/keys/secret_onion_key -a -s "$DATA_DIR"/keys/secret_onion_key_ntor ]; then + echo "Failure: Previous tor keys present in tor data directory" + exit -1 +else + echo "Generating initial tor keys" + $TOR --DataDirectory "$DATA_DIR" --PidFile "$DATA_DIR"/pid & + TOR_PID=$! + # generate SIGTERM, hopefully after the keys have been regenerated + sleep 5 + kill $TOR_PID + wait $TOR_PID + + # tor must successfully generate non-zero-length key files + if [ -s "$DATA_DIR"/keys/secret_id_key -a -s "$DATA_DIR"/keys/secret_onion_key -a -s "$DATA_DIR"/keys/secret_onion_key_ntor ]; then + true #echo "tor generated the initial key files" + else + echo "Failure: tor failed to generate the initial key files" + exit -2 + fi +fi + +#ls -lh "$DATA_DIR"/keys/ || exit -1 + +# backup and keep/delete/create zero-length files for the keys + +FILE_DESC="keeps existing" +# make a backup +cp -r "$DATA_DIR"/keys "$DATA_DIR"/keys.old + +# delete keys for -d or -z +if [ "$1" != "-e" ]; then + FILE_DESC="regenerates deleted" + rm "$DATA_DIR"/keys/secret_id_key || exit -1 + rm "$DATA_DIR"/keys/secret_onion_key || exit -1 + rm "$DATA_DIR"/keys/secret_onion_key_ntor || exit -1 +fi + +# create empty files for -z +if [ "$1" == "-z" ]; then + FILE_DESC="regenerates zero-length" + touch "$DATA_DIR"/keys/secret_id_key || exit -1 + touch "$DATA_DIR"/keys/secret_onion_key || exit -1 + touch "$DATA_DIR"/keys/secret_onion_key_ntor || exit -1 +fi + +echo "Running tor again to check if it $FILE_DESC keys" +$TOR --DataDirectory "$DATA_DIR" --PidFile "$DATA_DIR"/pid & +TOR_PID=$! +# generate SIGTERM, hopefully after the keys have been regenerated +sleep 5 +kill $TOR_PID +wait $TOR_PID + +#ls -lh "$DATA_DIR"/keys/ || exit -1 + +# tor must always have non-zero-length key files +if [ -s "$DATA_DIR"/keys/secret_id_key -a -s "$DATA_DIR"/keys/secret_onion_key -a -s "$DATA_DIR"/keys/secret_onion_key_ntor ]; then + # check if the keys are different to the old ones + diff -q -r "$DATA_DIR"/keys "$DATA_DIR"/keys.old > /dev/null + SAME_KEYS=$? + # if we're not testing existing keys, + # the current keys should be different to the old ones + if [ "$1" != "-e" ]; then + if [ $SAME_KEYS -ne 0 ]; then + echo "Success: test that tor $FILE_DESC key files: different keys" + exit 0 + else + echo "Failure: test that tor $FILE_DESC key files: same keys" + exit 1 + fi + else #[ "$1" == "-e" ]; then + if [ $SAME_KEYS -eq 0 ]; then + echo "Success: test that tor $FILE_DESC key files: same keys" + exit 0 + else + echo "Failure: test that tor $FILE_DESC key files: different keys" + exit 1 + fi + fi +else + echo "Failure: test that tor $FILE_DESC key files: no key files" + exit 1 +fi