[tor-commits] [tor/master] Actually check for missing protocols and exit as appropriate.

nickm at torproject.org nickm at torproject.org
Mon Sep 26 18:03:40 UTC 2016


commit 7f718c46f355e194fb6ae8c8aabb72d2492c4d3f
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Aug 19 17:45:08 2016 -0400

    Actually check for missing protocols and exit as appropriate.
---
 src/or/networkstatus.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 2eb3cd8..6c92773 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -1552,6 +1552,31 @@ networkstatus_set_current_consensus_from_ns(networkstatus_t *c,
 }
 #endif //TOR_UNIT_TESTS
 
+/** Called when we have received a networkstatus <b>c</b>. If there are
+ * any _required_ protocols we are missing, log an error and exit
+ * immediately. If there are any _recommended_ protocols we are missing,
+ * warn. */
+static void
+handle_missing_protocol_warning(const networkstatus_t *c,
+                                const or_options_t *options)
+{
+  char *protocol_warning = NULL;
+  int should_exit = networkstatus_check_required_protocols(c,
+                                                   !server_mode(options),
+                                                   &protocol_warning);
+  if (protocol_warning) {
+    tor_log(should_exit ? LOG_ERR : LOG_WARN,
+            LD_GENERAL,
+            "%s", protocol_warning);
+  }
+  if (should_exit) {
+    tor_assert_nonfatal(protocol_warning);
+  }
+  tor_free(protocol_warning);
+  if (should_exit)
+    exit(1);
+}
+
 /** Try to replace the current cached v3 networkstatus with the one in
  * <b>consensus</b>.  If we don't have enough certificates to validate it,
  * store it in consensus_waiting_for_certs and launch a certificate fetch.
@@ -1595,6 +1620,7 @@ networkstatus_set_current_consensus(const char *consensus,
   time_t current_valid_after = 0;
   int free_consensus = 1; /* Free 'c' at the end of the function */
   int old_ewma_enabled;
+  int checked_protocols_already = 0;
 
   if (flav < 0) {
     /* XXXX we don't handle unrecognized flavors yet. */
@@ -1610,6 +1636,16 @@ networkstatus_set_current_consensus(const char *consensus,
     goto done;
   }
 
+  if (from_cache && !was_waiting_for_certs) {
+    /* We previously stored this; check _now_ to make sure that version-kills
+     * really work.  This happens even before we check signatures: we did so
+     * before when we stored this to disk. This does mean an attacker who can
+     * write to the datadir can make us not start: such an attacker could
+     * already harm us by replacing our guards, which would be worse. */
+    checked_protocols_already = 1;
+    handle_missing_protocol_warning(c, options);
+  }
+
   if ((int)c->flavor != flav) {
     /* This wasn't the flavor we thought we were getting. */
     if (require_flavor) {
@@ -1735,6 +1771,10 @@ networkstatus_set_current_consensus(const char *consensus,
   if (!from_cache && flav == usable_consensus_flavor())
     control_event_client_status(LOG_NOTICE, "CONSENSUS_ARRIVED");
 
+  if (!checked_protocols_already) {
+    handle_missing_protocol_warning(c, options);
+  }
+
   /* Are we missing any certificates at all? */
   if (r != 1 && dl_certs)
     authority_certs_fetch_missing(c, now, source_dir);





More information about the tor-commits mailing list