From ce7fd6e160e2e3acb824b29e29afe15cd5e7bf4f Mon Sep 17 00:00:00 2001 From: teor Date: Sat, 8 Nov 2014 20:03:21 +1100 Subject: [PATCH 1/4] Stop crashing when a NULL filename is passed to file_status() Stop crashing when a NULL filename is passed to file_status(), instead, return FN_ERROR. Also return FN_ERROR when a zero-length filename is passed to file_status(). Fixed as part of bug 13111. --- changes/bug13111-generate-keys-on-empty-file | 7 +++++++ src/common/util.c | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 changes/bug13111-generate-keys-on-empty-file diff --git a/changes/bug13111-generate-keys-on-empty-file b/changes/bug13111-generate-keys-on-empty-file new file mode 100644 index 0000000000..f6a56effbb --- /dev/null +++ b/changes/bug13111-generate-keys-on-empty-file @@ -0,0 +1,7 @@ + o Minor bugfixes + - Stop crashing when a NULL filename is passed to file_status(). + Fixed as part of bug 13111. + + o Minor enhancements: + - Return FN_ERROR when a zero-length filename is passed to file_status(). + Fixed as part of bug 13111. diff --git a/src/common/util.c b/src/common/util.c index 2371ad3649..e850b14a16 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1888,7 +1888,8 @@ clean_name_for_stat(char *name) #endif } -/** Return FN_ERROR if filename can't be read, FN_NOENT if it doesn't +/** Return FN_ERROR if filename can't be read, or is NULL or zero-length, + * FN_NOENT if it doesn't * exist, FN_FILE if it is a regular file, or FN_DIR if it's a * directory. On FN_ERROR, sets errno. */ file_status_t @@ -1897,6 +1898,9 @@ file_status(const char *fname) struct stat st; char *f; int r; + if (!fname || strlen(fname) == 0) { + return FN_ERROR; + } f = tor_strdup(fname); clean_name_for_stat(f); log_debug(LD_FS, "stat()ing %s", f); From fd7e9e9030cee9d8e863cea3f3f90226ae66fdfe Mon Sep 17 00:00:00 2001 From: teor Date: Sun, 19 Oct 2014 17:48:07 +1100 Subject: [PATCH 2/4] Stop failing when key files are zero-length Instead, generate new keys, and overwrite the empty key files. Adds FN_EMPTY to file_status_t and file_status. Fixes bug 13111. Related changes due to review of FN_FILE usage: Stop generating a fresh .old RSA key file when the .old file is missing. Avoid overwriting .old key files with empty key files. Skip loading zero-length extra info store, router store, stats, state, and key files. --- changes/bug13111-generate-keys-on-empty-file | 10 ++++++ src/common/compat.c | 1 + src/common/util.c | 30 +++++++++++----- src/common/util.h | 2 +- src/or/config.c | 22 ++++++++---- src/or/router.c | 36 ++++++++++++++------ src/or/routerlist.c | 1 + src/or/statefile.c | 3 ++ 8 files changed, 79 insertions(+), 26 deletions(-) diff --git a/changes/bug13111-generate-keys-on-empty-file b/changes/bug13111-generate-keys-on-empty-file index f6a56effbb..345e87ab75 100644 --- a/changes/bug13111-generate-keys-on-empty-file +++ b/changes/bug13111-generate-keys-on-empty-file @@ -1,7 +1,17 @@ o Minor bugfixes + - Stop failing when key files are zero-length. Instead, generate new + keys, and overwrite the empty key files. + Fixes bug 13111. + - 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. o Minor enhancements: + - 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. diff --git a/src/common/compat.c b/src/common/compat.c index e4758aaf88..b28790f0e4 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -823,6 +823,7 @@ replace_file(const char *from, const char *to) case FN_NOENT: break; case FN_FILE: + case FN_EMPTY: if (unlink(to)) return -1; break; case FN_ERROR: diff --git a/src/common/util.c b/src/common/util.c index e850b14a16..1c35338eef 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1888,10 +1888,15 @@ clean_name_for_stat(char *name) #endif } -/** Return FN_ERROR if filename can't be read, or is NULL or zero-length, - * FN_NOENT if it doesn't - * exist, FN_FILE if it is a regular file, or FN_DIR if it's a - * directory. On FN_ERROR, sets errno. */ +/** Return: + * FN_ERROR if filename can't be read, is NULL, or is zero-length, + * FN_NOENT if it doesn't exist, + * FN_FILE if it is a non-empty regular file, or a FIFO on unix-like systems, + * FN_EMPTY for zero-byte regular files, + * FN_DIR if it's a directory, and + * FN_ERROR for any other file type. + * On FN_ERROR and FN_NOENT, sets errno. (errno is not set when FN_ERROR + * is returned due to an unhandled file type.) */ file_status_t file_status(const char *fname) { @@ -1912,16 +1917,23 @@ file_status(const char *fname) } return FN_ERROR; } - if (st.st_mode & S_IFDIR) + if (st.st_mode & S_IFDIR) { return FN_DIR; - else if (st.st_mode & S_IFREG) - return FN_FILE; + } else if (st.st_mode & S_IFREG) { + if (st.st_size > 0) { + return FN_FILE; + } else if (st.st_size == 0) { + return FN_EMPTY; + } else { + return FN_ERROR; + } #ifndef _WIN32 - else if (st.st_mode & S_IFIFO) + } else if (st.st_mode & S_IFIFO) { return FN_FILE; #endif - else + } else { return FN_ERROR; + } } /** Check whether dirname exists and is private. If yes return 0. If diff --git a/src/common/util.h b/src/common/util.h index d7feb6e925..c5471ff9f2 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -334,7 +334,7 @@ enum stream_status get_string_from_pipe(FILE *stream, char *buf, size_t count); /** Return values from file_status(); see that function's documentation * for details. */ -typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR } file_status_t; +typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR, FN_EMPTY } file_status_t; file_status_t file_status(const char *filename); /** Possible behaviors for check_private_dir() on encountering a nonexistent diff --git a/src/or/config.c b/src/or/config.c index 3f31e876dd..3e7a73f612 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -4017,17 +4017,24 @@ find_torrc_filename(config_line_t *cmd_arg, if (*using_default_fname) { /* didn't find one, try CONFDIR */ const char *dflt = get_default_conf_file(defaults_file); - if (dflt && file_status(dflt) == FN_FILE) { + file_status_t st = file_status(dflt); + if (dflt && (st == FN_FILE || st == FN_EMPTY)) { fname = tor_strdup(dflt); } else { #ifndef _WIN32 char *fn = NULL; - if (!defaults_file) + if (!defaults_file) { fn = expand_filename("~/.torrc"); - if (fn && file_status(fn) == FN_FILE) { - fname = fn; + } + if (fn) { + file_status_t hmst = file_status(fn); + if (hmst == FN_FILE || hmst == FN_EMPTY) { + fname = fn; + } else { + tor_free(fn); + fname = tor_strdup(dflt); + } } else { - tor_free(fn); fname = tor_strdup(dflt); } #else @@ -4063,7 +4070,8 @@ load_torrc_from_disk(config_line_t *cmd_arg, int defaults_file) *fname_var = fname; /* Open config file */ - if (file_status(fname) != FN_FILE || + file_status_t st = file_status(fname); + if (!(st == FN_FILE || st == FN_EMPTY) || !(cf = read_file_to_str(fname,0,NULL))) { if (using_default_torrc == 1 || ignore_missing_torrc) { if (!defaults_file) @@ -6413,7 +6421,9 @@ write_configuration_file(const char *fname, const or_options_t *options) tor_assert(fname); switch (file_status(fname)) { + /* create backups of old config files, even if they're empty */ case FN_FILE: + case FN_EMPTY: old_val = read_file_to_str(fname, 0, NULL); if (!old_val || strcmpstart(old_val, GENERATED_FILE_PREFIX)) { rename_old = 1; diff --git a/src/or/router.c b/src/or/router.c index 01838b4b3e..94ae2e78c4 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -313,6 +313,7 @@ rotate_onion_key(void) time_t now; fname = get_datadir_fname2("keys", "secret_onion_key"); fname_prev = get_datadir_fname2("keys", "secret_onion_key.old"); + /* There isn't much point replacing an old key with an empty file */ if (file_status(fname) == FN_FILE) { if (replace_file(fname, fname_prev)) goto error; @@ -335,6 +336,7 @@ rotate_onion_key(void) fname_prev = get_datadir_fname2("keys", "secret_onion_key_ntor.old"); if (curve25519_keypair_generate(&new_curve25519_keypair, 1) < 0) goto error; + /* There isn't much point replacing an old key with an empty file */ if (file_status(fname) == FN_FILE) { if (replace_file(fname, fname_prev)) goto error; @@ -389,9 +391,9 @@ log_new_relay_greeting(void) already_logged = 1; } -/** Try to read an RSA key from fname. If fname doesn't exist - * and generate is true, create a new RSA key and save it in - * fname. Return the read/created key, or NULL on error. Log all +/** Try to read an RSA key from fname. If fname doesn't exist, + * or is empty, and generate is true, create a new RSA key and save it + * in fname. Return the read/created key, or NULL on error. Log all * errors at level severity. */ crypto_pk_t * @@ -409,7 +411,11 @@ init_key_from_file(const char *fname, int generate, int severity) case FN_ERROR: tor_log(severity, LD_FS,"Can't read key from \"%s\"", fname); goto error; + /* treat empty key files as if the file doesn't exist, and, + * if generate is set, replace the empty file in + * crypto_pk_write_private_key_to_filename() */ case FN_NOENT: + case FN_EMPTY: if (generate) { if (!have_lockfile()) { if (try_locking(get_options(), 0)<0) { @@ -460,10 +466,10 @@ init_key_from_file(const char *fname, int generate, int severity) } /** Load a curve25519 keypair from the file fname, writing it into - * keys_out. If the file isn't found and generate is true, - * create a new keypair and write it into the file. If there are errors, log - * them at level severity. Generate files using tag in their - * ASCII wrapper. */ + * keys_out. If the file isn't found, or is empty, and generate + * is true, create a new keypair and write it into the file. If there are + * errors, log them at level severity. Generate files using tag + * in their ASCII wrapper. */ static int init_curve25519_keypair_from_file(curve25519_keypair_t *keys_out, const char *fname, @@ -476,7 +482,10 @@ init_curve25519_keypair_from_file(curve25519_keypair_t *keys_out, case FN_ERROR: tor_log(severity, LD_FS,"Can't read key from \"%s\"", fname); goto error; + /* treat empty key files as if the file doesn't exist, and, if generate + * is set, replace the empty file in curve25519_keypair_write_to_file() */ case FN_NOENT: + case FN_EMPTY: if (generate) { if (!have_lockfile()) { if (try_locking(get_options(), 0)<0) { @@ -876,7 +885,9 @@ init_keys(void) keydir = get_datadir_fname2("keys", "secret_onion_key.old"); if (!lastonionkey && file_status(keydir) == FN_FILE) { - prkey = init_key_from_file(keydir, 1, LOG_ERR); /* XXXX Why 1? */ + /* Load keys from non-empty files only. + * Missing old keys won't be replaced with freshly generated keys. */ + prkey = init_key_from_file(keydir, 0, LOG_ERR); if (prkey) lastonionkey = prkey; } @@ -897,6 +908,8 @@ init_keys(void) last_curve25519_onion_key.pubkey.public_key, CURVE25519_PUBKEY_LEN) && file_status(keydir) == FN_FILE) { + /* Load keys from non-empty files only. + * Missing old keys won't be replaced with freshly generated keys. */ init_curve25519_keypair_from_file(&last_curve25519_onion_key, keydir, 0, LOG_ERR, "onion"); } @@ -2562,8 +2575,9 @@ router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport) * end_line, ensure that its timestamp is not more than 25 hours in * the past or more than 1 hour in the future with respect to now, * and write the file contents starting with that line to *out. - * Return 1 for success, 0 if the file does not exist, or -1 if the file - * does not contain a line matching these criteria or other failure. */ + * Return 1 for success, 0 if the file does not exist or is empty, or -1 + * if the file does not contain a line matching these criteria or other + * failure. */ static int load_stats_file(const char *filename, const char *end_line, time_t now, char **out) @@ -2597,7 +2611,9 @@ load_stats_file(const char *filename, const char *end_line, time_t now, notfound: tor_free(contents); break; + /* treat empty stats files as if the file doesn't exist */ case FN_NOENT: + case FN_EMPTY: r = 0; break; case FN_ERROR: diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 00994863f0..5c08f5990f 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1204,6 +1204,7 @@ router_reload_router_list_impl(desc_store_t *store) tor_free(fname); fname = get_datadir_fname_suffix(store->fname_base, ".new"); + /* don't load empty files - we wouldn't get any data, even if we tried */ if (file_status(fname) == FN_FILE) contents = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st); if (contents) { diff --git a/src/or/statefile.c b/src/or/statefile.c index 2ce53fdfca..6640aed7d0 100644 --- a/src/or/statefile.c +++ b/src/or/statefile.c @@ -323,7 +323,10 @@ or_state_load(void) goto done; } break; + /* treat empty state files as if the file doesn't exist, and generate + * a new state file, overwriting the empty file in or_state_save() */ case FN_NOENT: + case FN_EMPTY: break; case FN_ERROR: case FN_DIR: From 6a9cae2e1dafb756b30fda541e8b5d68cfd45f89 Mon Sep 17 00:00:00 2001 From: teor Date: Sat, 20 Dec 2014 22:20:54 +1100 Subject: [PATCH 3/4] Fix clang warning, IPv6 address comment, buffer size typo The address of an array in the middle of a structure will always be non-NULL. clang recognises this and complains. Disable the tautologous and redundant check to silence this warning. A comment about an IPv6 address string incorrectly refers to an IPv4 address format. A log buffer is sized 10024 rather than 10240. Fixes bug 14001. --- changes/bug14001-clang-warning | 6 ++++++ src/common/address.c | 3 ++- src/common/log.c | 2 +- src/or/connection_edge.c | 11 ++++++++++- 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 changes/bug14001-clang-warning diff --git a/changes/bug14001-clang-warning b/changes/bug14001-clang-warning new file mode 100644 index 0000000000..b932af6ab7 --- /dev/null +++ b/changes/bug14001-clang-warning @@ -0,0 +1,6 @@ + o Minor bugfixes: + - The address of an array in the middle of a structure will + always be non-NULL. clang recognises this and complains. + Disable the tautologous and redundant check to silence + this warning. + Fixes bug 14001. diff --git a/src/common/address.c b/src/common/address.c index a3b5df66bc..0b475fc9fd 100644 --- a/src/common/address.c +++ b/src/common/address.c @@ -1119,7 +1119,8 @@ fmt_addr32(uint32_t addr) int tor_addr_parse(tor_addr_t *addr, const char *src) { - char *tmp = NULL; /* Holds substring if we got a dotted quad. */ + /* Holds substring of IPv6 address after removing square brackets */ + char *tmp = NULL; int result; struct in_addr in_tmp; struct in6_addr in6_tmp; diff --git a/src/common/log.c b/src/common/log.c index ad0da7da6b..0a21ffbd44 100644 --- a/src/common/log.c +++ b/src/common/log.c @@ -451,7 +451,7 @@ MOCK_IMPL(STATIC void, logv,(int severity, log_domain_mask_t domain, const char *funcname, const char *suffix, const char *format, va_list ap)) { - char buf[10024]; + char buf[10240]; size_t msg_len = 0; int formatted = 0; logfile_t *lf; diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 9ace375d74..9859cc26ea 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -744,8 +744,17 @@ connection_ap_fail_onehop(const char *failed_digest, /* we don't know the digest; have to compare addr:port */ tor_addr_t addr; if (!build_state || !build_state->chosen_exit || - !entry_conn->socks_request || !entry_conn->socks_request->address) + !entry_conn->socks_request) { + /* clang thinks that an array midway through a structure + * will never have a NULL address, under either: + * -Wpointer-bool-conversion if using !, or + * -Wtautological-pointer-compare if using == or != + * It's probably right (unless pointers overflow and wrap), + * so we just skip this check + || !entry_conn->socks_request->address + */ continue; + } if (tor_addr_parse(&addr, entry_conn->socks_request->address)<0 || !tor_addr_eq(&build_state->chosen_exit->addr, &addr) || build_state->chosen_exit->port != entry_conn->socks_request->port) From debd7862bb6d641c13fe4ee019da633c683d740e Mon Sep 17 00:00:00 2001 From: teor Date: Sat, 10 Jan 2015 17:14:29 +1100 Subject: [PATCH 4/4] Test that tor correctly handles zero-length keys 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 fixes to bug 13111. --- changes/bug13111-generate-keys-on-empty-file | 22 ++-- src/test/include.am | 4 +- src/test/zero_length_keys.sh | 113 +++++++++++++++++++ 3 files changed, 130 insertions(+), 9 deletions(-) create mode 100755 src/test/zero_length_keys.sh 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