瀏覽代碼

r11588@Kushana: nickm | 2006-12-15 02:04:32 -0500
Add a LastRotatedOnionKey variable to the state file, so we can rotate onion keys a week after they change even if we never stay up for a whole week at a time. Should fix bug 368.


svn:r9120

Nick Mathewson 19 年之前
父節點
當前提交
38bd6837db
共有 4 個文件被更改,包括 25 次插入3 次删除
  1. 3 0
      ChangeLog
  2. 1 0
      src/or/config.c
  3. 3 1
      src/or/or.h
  4. 18 2
      src/or/router.c

+ 3 - 0
ChangeLog

@@ -43,6 +43,9 @@ Changes in version 0.1.2.5-xxxx - 200?-??-??
       safe.)
     - When generating bandwidth history, round down to the nearest
       1k. When storing accounting data, round up to the nearest 1k.
+    - When we're running as a server, remember when we last rotated onion
+      keys, so that we will rotate keys once they're a week old even if we
+      never stay up for a week ourselves.  (Bug 368.)
 
   o Controller features:
     - Have GETINFO dir/status/* work on hosts with DirPort disabled.

+ 1 - 0
src/or/config.c

@@ -283,6 +283,7 @@ static config_var_t _state_vars[] = {
 
   VAR("TorVersion",              STRING,      TorVersion,             NULL),
 
+  VAR("LastRotatedOnionKey",     ISOTIME,     LastRotatedOnionKey,    NULL),
   VAR("LastWritten",             ISOTIME,     LastWritten,            NULL),
 
   { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }

+ 3 - 1
src/or/or.h

@@ -1698,6 +1698,9 @@ typedef struct {
   /** Holds any unrecognized values we found in the state file, in the order
    * in which we found them. */
   config_line_t *ExtraLines;
+
+  /** When did we last rotate our onion key?  "0" for 'no idea'. */
+  time_t LastRotatedOnionKey;
 } or_state_t;
 
 /** Change the next_write time of <b>state</b> to <b>when</b>, unless the
@@ -2602,7 +2605,6 @@ int rend_mid_rendezvous(or_circuit_t *circ, const char *request,
 
 /********************************* router.c ***************************/
 
-void set_onion_key(crypto_pk_env_t *k);
 crypto_pk_env_t *get_onion_key(void);
 time_t get_onion_key_set_at(void);
 void set_identity_key(crypto_pk_env_t *k);

+ 18 - 2
src/or/router.c

@@ -35,7 +35,7 @@ static crypto_pk_env_t *identitykey=NULL;
 /** Replace the current onion key with <b>k</b>.  Does not affect lastonionkey;
  * to update onionkey correctly, call rotate_onion_key().
  */
-void
+static void
 set_onion_key(crypto_pk_env_t *k)
 {
   tor_mutex_acquire(key_lock);
@@ -122,6 +122,8 @@ rotate_onion_key(void)
   char fname[512];
   char fname_prev[512];
   crypto_pk_env_t *prkey;
+  or_state_t *state = get_or_state();
+  time_t now;
   tor_snprintf(fname,sizeof(fname),
            "%s/keys/secret_onion_key",get_options()->DataDirectory);
   tor_snprintf(fname_prev,sizeof(fname_prev),
@@ -148,9 +150,11 @@ rotate_onion_key(void)
     crypto_free_pk_env(lastonionkey);
   lastonionkey = onionkey;
   onionkey = prkey;
-  onionkey_set_at = time(NULL);
+  now = time(NULL);
+  state->LastRotatedOnionKey = onionkey_set_at = now;
   tor_mutex_release(key_lock);
   mark_my_descriptor_dirty();
+  or_state_mark_dirty(state, now+600);
   return;
  error:
   log_warn(LD_GENERAL, "Couldn't rotate onion key.");
@@ -247,6 +251,7 @@ init_keys(void)
   crypto_pk_env_t *prkey;
   char digest[20];
   or_options_t *options = get_options();
+  or_state_t *state = get_or_state();
 
   if (!key_lock)
     key_lock = tor_mutex_new();
@@ -293,6 +298,17 @@ init_keys(void)
   prkey = init_key_from_file_name_changed(keydir,keydir2);
   if (!prkey) return -1;
   set_onion_key(prkey);
+  if (state->LastRotatedOnionKey > 100) { /* allow for some parsing slop. */
+    onionkey_set_at = state->LastRotatedOnionKey;
+  } else {
+    /* We have no LastRotatedOnionKey set; either we just created the key
+     * or it's a holdover from 0.1.2.4-alpha-dev or earlier.  In either case,
+     * start the clock ticking now so that we will eventually rotate it even
+     * if we don't stay up for a full MIN_ONION_KEY_LIFETIME. */
+    state->LastRotatedOnionKey = time(NULL);
+    or_state_mark_dirty(state, time(NULL)+600);
+  }
+
   tor_snprintf(keydir,sizeof(keydir),"%s/keys/secret_onion_key.old",datadir);
   if (file_status(keydir) == FN_FILE) {
     prkey = init_key_from_file(keydir);