Commit 71bd1009 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

DROPGUARDS controller command

Implements ticket 9934; patch from "ra"
parent 17d36828
Loading
Loading
Loading
Loading

changes/bug9934

0 → 100644
+4 −0
Original line number Diff line number Diff line
  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".
+27 −0
Original line number Diff line number Diff line
@@ -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);
+19 −0
Original line number Diff line number Diff line
@@ -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.
 *
+2 −0
Original line number Diff line number Diff line
@@ -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);