diff options
author | teor <teor2345@gmail.com> | 2014-10-19 17:48:07 +1100 |
---|---|---|
committer | teor <teor2345@gmail.com> | 2014-11-08 20:31:20 +1100 |
commit | fd7e9e9030cee9d8e863cea3f3f90226ae66fdfe (patch) | |
tree | a9ca33e658ff76b7a4bf4a7d5f9dd3a4936da575 /src/or | |
parent | ce7fd6e160e2e3acb824b29e29afe15cd5e7bf4f (diff) | |
download | tor-fd7e9e9030cee9d8e863cea3f3f90226ae66fdfe.tar.gz tor-fd7e9e9030cee9d8e863cea3f3f90226ae66fdfe.zip |
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.
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/config.c | 22 | ||||
-rw-r--r-- | src/or/router.c | 36 | ||||
-rw-r--r-- | src/or/routerlist.c | 1 | ||||
-rw-r--r-- | src/or/statefile.c | 3 |
4 files changed, 46 insertions, 16 deletions
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 <b>fname</b>. If <b>fname</b> doesn't exist - * and <b>generate</b> is true, create a new RSA key and save it in - * <b>fname</b>. Return the read/created key, or NULL on error. Log all +/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist, + * or is empty, and <b>generate</b> is true, create a new RSA key and save it + * in <b>fname</b>. Return the read/created key, or NULL on error. Log all * errors at level <b>severity</b>. */ 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 <b>fname</b>, writing it into - * <b>keys_out</b>. If the file isn't found and <b>generate</b> is true, - * create a new keypair and write it into the file. If there are errors, log - * them at level <b>severity</b>. Generate files using <b>tag</b> in their - * ASCII wrapper. */ + * <b>keys_out</b>. If the file isn't found, or is empty, and <b>generate</b> + * is true, create a new keypair and write it into the file. If there are + * errors, log them at level <b>severity</b>. Generate files using <b>tag</b> + * 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) * <b>end_line</b>, ensure that its timestamp is not more than 25 hours in * the past or more than 1 hour in the future with respect to <b>now</b>, * and write the file contents starting with that line to *<b>out</b>. - * 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: |