]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Make the guard lifetime configurable and adjustable via the consensus
authorNick Mathewson <nickm@torproject.org>
Fri, 15 Feb 2013 22:24:13 +0000 (17:24 -0500)
committerNick Mathewson <nickm@torproject.org>
Tue, 19 Mar 2013 20:02:19 +0000 (16:02 -0400)
Fixes 8240.

(Don't actually increase the default guard lifetime. It seems likely to
break too many things if done precipitiously.)

changes/ticket8240 [new file with mode: 0644]
doc/tor.1.txt
src/common/util.h
src/or/circuitbuild.c
src/or/config.c
src/or/or.h

diff --git a/changes/ticket8240 b/changes/ticket8240
new file mode 100644 (file)
index 0000000..91e6f8c
--- /dev/null
@@ -0,0 +1,4 @@
+  o Major security fixes:
+    - Make the default guard lifetime controllable via a new
+      GuardLifetime torrc option and a GuardLifetime consensus
+      parameter. Start of a fix for bug 8240; bugfix on 0.1.1.11-alpha.
index 773fccf53674a50052aec73c7bfd09fe66e6be04..5cf5a718c0ae006b8fb677761c036c29f45259e9 100644 (file)
@@ -959,6 +959,12 @@ The following options are useful only for clients (that is, if
     If UseEntryGuards is set to 1, we will try to pick a total of NUM routers
     as long-term entries for our circuits. (Default: 3)
 
+**HeartbeatPeriod**  __N__ **days**|**weeks**|**months**::
+    If nonzero, and UseEntryGuards is set, minimum time to keep a guard before
+    picking a new one. If zero, we use the GuardLifetime parameter from the
+    consensus directory.  No value here may  be less than 2 months or greater
+    than 5 years; out-of-range values are clamped. (Default: 0)
+
 **SafeSocks** **0**|**1**::
     When this option is enabled, Tor will reject application connections that
     use unsafe variants of the socks protocol -- ones that only provide an IP
index 8977d273c50f5aa6b407dc0b3fa2a32262f47244..4642e40584922a5d60b123872d0808a945f2ce58 100644 (file)
@@ -173,6 +173,17 @@ int n_bits_set_u8(uint8_t v);
  * overflow. */
 #define CEIL_DIV(a,b) (((a)+(b)-1)/(b))
 
+/* Return <b>v</b> if it's between <b>min</b> and <b>max</b>.  Otherwise
+ * return <b>min</b> if <b>v</b> is smaller than <b>min</b>, or <b>max</b> if
+ * <b>b</b> is larger than <b>max</b>.
+ *
+ * Requires that <b>min</b> is no more than <b>max</b>. May evaluate any of
+ * its arguments more than once! */
+#define CLAMP(min,v,max)                        \
+  ( ((v) < (min)) ? (min) :                     \
+    ((v) > (max)) ? (max) :                     \
+    (v) )
+
 /* String manipulation */
 
 /** Allowable characters in a hexadecimal string. */
index f8521c5cff2b67032dfa83d270cae538b8850232..f07d428829832a813b4d336ab76afbea5e88215a 100644 (file)
@@ -4203,6 +4203,9 @@ control_event_guard_deferred(void)
 #endif
 }
 
+/** Largest amount that we'll backdate chosen_on_date */
+#define CHOSEN_ON_DATE_SLOP (30*86400)
+
 /** Add a new (preferably stable and fast) router to our
  * entry_guards list. Return a pointer to the router if we succeed,
  * or NULL if we can't find any more suitable entries.
@@ -4241,7 +4244,7 @@ add_an_entry_guard(const node_t *chosen, int reset_status, int prepend)
    * don't all select them on the same day, and b) avoid leaving a
    * precise timestamp in the state file about when we first picked
    * this guard. For details, see the Jan 2010 or-dev thread. */
-  entry->chosen_on_date = time(NULL) - crypto_rand_int(3600*24*30);
+  entry->chosen_on_date = time(NULL) - crypto_rand_int(CHOSEN_ON_DATE_SLOP);
   entry->chosen_by_version = tor_strdup(VERSION);
   if (prepend)
     smartlist_insert(entry_guards, 0, entry);
@@ -4285,15 +4288,40 @@ entry_guard_free(entry_guard_t *e)
   tor_free(e);
 }
 
+/**
+ * Return the minimum lifetime of working entry guard, in seconds,
+ * as given in the consensus networkstatus.
+ */
+static int32_t
+guards_get_lifetime(void)
+{
+  const or_options_t *options = get_options();
+#define DFLT_GUARD_LIFETIME (86400 * 60)   /* Two months. */
+#define MIN_GUARD_LIFETIME  (86400 * 60)   /* Two months. */
+#define MAX_GUARD_LIFETIME  (86400 * 1826) /* Five years. */
+
+  if (options->GuardLifetime >= 1) {
+    return CLAMP(MIN_GUARD_LIFETIME,
+                 options->GuardLifetime,
+                 MAX_GUARD_LIFETIME) + CHOSEN_ON_DATE_SLOP;
+  }
+
+  return networkstatus_get_param(NULL, "GuardLifetime",
+                                 DFLT_GUARD_LIFETIME,
+                                 MIN_GUARD_LIFETIME,
+                                 MAX_GUARD_LIFETIME) + CHOSEN_ON_DATE_SLOP;
+}
+
 /** Remove any entry guard which was selected by an unknown version of Tor,
  * or which was selected by a version of Tor that's known to select
- * entry guards badly, or which was selected more 2 months ago. */
+ * entry guards badly, or which was selected a long time ago */
 /* XXXX The "obsolete guards" and "chosen long ago guards" things should
  * probably be different functions. */
 static int
 remove_obsolete_entry_guards(time_t now)
 {
   int changed = 0, i;
+  int32_t guard_lifetime = guards_get_lifetime();
 
   for (i = 0; i < smartlist_len(entry_guards); ++i) {
     entry_guard_t *entry = smartlist_get(entry_guards, i);
@@ -4324,8 +4352,8 @@ remove_obsolete_entry_guards(time_t now)
       }
       tor_free(tor_ver);
     }
-    if (!version_is_bad && entry->chosen_on_date + 3600*24*60 < now) {
-      /* It's been 2 months since the date listed in our state file. */
+    if (!version_is_bad && entry->chosen_on_date + guard_lifetime < now) {
+      /* It's been too long since the date listed in our state file. */
       msg = "was selected several months ago";
       date_is_bad = 1;
     }
index 90a5dfbda1c00399b141ef765470be6aeca42ad9..6ccd65a57aa03800614c1b80ae43b98362fa5cd5 100644 (file)
@@ -302,6 +302,7 @@ static config_var_t _option_vars[] = {
 #endif
   OBSOLETE("GiveGuardFlagTo_CVE_2011_2768_VulnerableRelays"),
   OBSOLETE("Group"),
+  V(GuardLifetime,               INTERVAL, "0 minutes"),
   V(HardwareAccel,               BOOL,     "0"),
   V(HeartbeatPeriod,             INTERVAL, "6 hours"),
   V(AccelName,                   STRING,   NULL),
index 51c23d305d1d0bffb0cc227fccc715d26431ec91..b54834de32aa0013e3c8550048ae8752dbe47d55 100644 (file)
@@ -3605,6 +3605,9 @@ typedef struct {
   int PathBiasScaleFactor;
   /** @} */
 
+  /** How long (seconds) do we keep a guard before picking a new one? */
+  int GuardLifetime;
+
 } or_options_t;
 
 /** Persistent state for an onion router, as saved to disk. */