|
@@ -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:
|