[tor-commits] [tor/master] DROPGUARDS controller command

nickm at torproject.org nickm at torproject.org
Fri Oct 25 16:17:34 UTC 2013


commit 71bd10097677cd035bd97a6c36b85d07fdbafb62
Author: Nick Mathewson <nickm at torproject.org>
Date:   Mon Oct 21 13:02:25 2013 -0400

    DROPGUARDS controller command
    
    Implements ticket 9934; patch from "ra"
---
 changes/bug9934     |    4 ++++
 src/or/control.c    |   27 +++++++++++++++++++++++++++
 src/or/entrynodes.c |   19 +++++++++++++++++++
 src/or/entrynodes.h |    2 ++
 4 files changed, 52 insertions(+)

diff --git a/changes/bug9934 b/changes/bug9934
new file mode 100644
index 0000000..2a636db
--- /dev/null
+++ b/changes/bug9934
@@ -0,0 +1,4 @@
+  o Minor features (controller):
+    - New DROPGUARDS command to forget all current entry guards. Not
+      recommended for ordinary use, since replacing guards too frequently
+      makes several attacks easier. Resolves ticket #9934; patch from "ra".
diff --git a/src/or/control.c b/src/or/control.c
index e97c18d..65c543a 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -3141,6 +3141,30 @@ handle_control_usefeature(control_connection_t *conn,
   return 0;
 }
 
+/** Implementation for the DROPGUARDS command. */
+static int
+handle_control_dropguards(control_connection_t *conn,
+                          uint32_t len,
+                          const char *body)
+{
+  smartlist_t *args;
+  (void) len; /* body is nul-terminated; it's safe to ignore the length */
+  args = smartlist_new();
+  smartlist_split_string(args, body, " ",
+                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+
+  if (smartlist_len(args)) {
+    connection_printf_to_buf(conn, "512 Too many arguments to DROPGUARDS\r\n");
+  } else {
+    remove_all_entry_guards();
+    send_control_done(conn);
+  }
+
+  SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
+  smartlist_free(args);
+  return 0;
+}
+
 /** Called when <b>conn</b> has no more bytes left on its outbuf. */
 int
 connection_control_finished_flushing(control_connection_t *conn)
@@ -3440,6 +3464,9 @@ connection_control_process_inbuf(control_connection_t *conn)
   } else if (!strcasecmp(conn->incoming_cmd, "AUTHCHALLENGE")) {
     if (handle_control_authchallenge(conn, cmd_data_len, args))
       return -1;
+  } else if (!strcasecmp(conn->incoming_cmd, "DROPGUARDS")) {
+    if (handle_control_dropguards(conn, cmd_data_len, args))
+      return -1;
   } else {
     connection_printf_to_buf(conn, "510 Unrecognized command \"%s\"\r\n",
                              conn->incoming_cmd);
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index b97b2ea..59cc9a3 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -598,6 +598,25 @@ remove_dead_entry_guards(time_t now)
   return changed ? 1 : 0;
 }
 
+/** Remove all currently listed entry guards. So new ones will be chosen. */
+void
+remove_all_entry_guards(void)
+{
+  char dbuf[HEX_DIGEST_LEN+1];
+
+  while (smartlist_len(entry_guards)) {
+    entry_guard_t *entry = smartlist_get(entry_guards, 0);
+    base16_encode(dbuf, sizeof(dbuf), entry->identity, DIGEST_LEN);
+    log_info(LD_CIRC, "Entry guard '%s' (%s) has been dropped.",
+             entry->nickname, dbuf);
+    control_event_guard(entry->nickname, entry->identity, "DROPPED");
+    entry_guard_free(entry);
+    smartlist_del(entry_guards, 0);
+  }
+  log_entry_guards(LOG_INFO);
+  entry_guards_changed();
+}
+
 /** A new directory or router-status has arrived; update the down/listed
  * status of the entry guards.
  *
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index 533f202..1f8cff7 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -77,6 +77,8 @@ int num_live_entry_guards(int for_directory);
 
 #endif
 
+void remove_all_entry_guards(void);
+
 void entry_guards_compute_status(const or_options_t *options, time_t now);
 int entry_guard_register_connect_status(const char *digest, int succeeded,
                                         int mark_relay_status, time_t now);





More information about the tor-commits mailing list