Commit ff62154b authored by Roger Dingledine's avatar Roger Dingledine
Browse files

New config options WarnPlaintextPorts and RejectPlaintextPorts so

Tor can warn and/or refuse connections to ports commonly used with
vulnerable-plaintext protocols.

We still need to figure out some good defaults for them.


svn:r13198
parent a1f28173
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -6,6 +6,9 @@ Changes in version 0.2.0.18-alpha - 2008-01-??
    - If we've gone 12 hours since our last bandwidth check, and we
      estimate we have less than 50KB bandwidth capacity but we could
      handle more, do another bandwidth test.
    - New config options WarnPlaintextPorts and RejectPlaintextPorts so
      Tor can warn and/or refuse connections to ports commonly used with
      vulnerable-plaintext protocols.

  o Minor features:
    - Don't answer "/tor/networkstatus-bridges" directory requests if
+15 −2
Original line number Diff line number Diff line
@@ -1300,9 +1300,22 @@ $Id$
       to do so.}
       [Note: only REASON=CLOCK_JUMPED is implemented currently.]

     DANGEROUS_PORT
     "PORT=" port
     "RESULT=" "REJECT" / "WARN"
       A stream was initiated to a port that's commonly used for
       vulnerable-plaintext protocols. If the Result is "reject", we
       refused the connection; whereas if it's "warn", we allowed it.

       {Controllers should warn their users when this occurs, unless they
       happen to know that the application using Tor is in fact doing so
       correctly (e.g., because it is part of a distributed bundle). They
       might also want some sort of interface to let the user configure
       their RejectPlaintextPorts and WarnPlaintextPorts config options.}

     DANGEROUS_SOCKS
     "PROTOCOL=SOCKS4/SOCKS5"
     "ADDRESS=IP:port"
     "PROTOCOL=" "SOCKS4" / "SOCKS5"
     "ADDRESS=" IP:port
       A connection was made to Tor's SOCKS port using one of the SOCKS
       approaches that doesn't support hostnames -- only raw IP addresses.
       If the client application got this address from gethostbyname(),
+10 −0
Original line number Diff line number Diff line
@@ -253,6 +253,7 @@ static config_var_t _option_vars[] = {
  V(RecommendedClientVersions,   LINELIST, NULL),
  V(RecommendedServerVersions,   LINELIST, NULL),
  V(RedirectExit,                LINELIST, NULL),
  V(RejectPlaintextPorts,        CSV,      ""),
  V(RelayBandwidthBurst,         MEMUNIT,  "0"),
  V(RelayBandwidthRate,          MEMUNIT,  "0"),
  V(RendExcludeNodes,            STRING,   NULL),
@@ -300,6 +301,7 @@ static config_var_t _option_vars[] = {
  V(V3AuthNIntervalsValid,       UINT,     "3"),
  VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
  V(VirtualAddrNetwork,          STRING,   "127.192.0.0/10"),
  V(WarnPlaintextPorts,          CSV,      "23,109,110,143"),
  VAR("__AllDirActionsPrivate",  BOOL,  AllDirActionsPrivate,     "0"),
  VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
  VAR("__LeaveStreamsUnattached",BOOL,  LeaveStreamsUnattached,   "0"),
@@ -2898,6 +2900,14 @@ options_validate(or_options_t *old_options, or_options_t *options,
  if (validate_ports_csv(options->LongLivedPorts, "LongLivedPorts", msg) < 0)
    return -1;

  if (validate_ports_csv(options->RejectPlaintextPorts,
                         "RejectPlaintextPorts", msg) < 0)
    return -1;

  if (validate_ports_csv(options->WarnPlaintextPorts,
                         "WarnPlaintextPorts", msg) < 0)
    return -1;

  if (options->FascistFirewall && !options->ReachableAddresses) {
    if (options->FirewallPorts && smartlist_len(options->FirewallPorts)) {
      /* We already have firewall ports set, so migrate them to
+36 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ static int connection_ap_handshake_process_socks(edge_connection_t *conn);
static int connection_ap_process_natd(edge_connection_t *conn);
static int connection_exit_connect_dir(edge_connection_t *exitconn);
static int address_is_in_virtual_range(const char *addr);
static int consider_plaintext_ports(edge_connection_t *conn, uint16_t port);

/** An AP stream has failed/finished. If it hasn't already sent back
 * a socks reply, send one now (based on endreason). Also set
@@ -470,6 +471,7 @@ circuit_discard_optional_exit_enclaves(extend_info_t *info)
  {
    if (conn->marked_for_close ||
        conn->type != CONN_TYPE_AP ||
        conn->state != AP_CONN_STATE_CIRCUIT_WAIT ||
        !conn->chosen_exit_optional)
      continue;
    edge_conn = TO_EDGE_CONN(conn);
@@ -482,6 +484,9 @@ circuit_discard_optional_exit_enclaves(extend_info_t *info)
               escaped_safe_str(edge_conn->socks_request->address));
      conn->chosen_exit_optional = 0;
      tor_free(edge_conn->chosen_exit_name); /* clears it */
      /* if this port is dangerous, warn or reject it now that we don't
       * think it'll be using an enclave. */
      consider_plaintext_ports(edge_conn, edge_conn->socks_request->port);
    }
  });
}
@@ -1182,6 +1187,32 @@ addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
   }
}

/** Check if <b>conn</b> is using a dangerous port. Then warn and/or
 * reject depending on our config options. */
static int
consider_plaintext_ports(edge_connection_t *conn, uint16_t port)
{
  or_options_t *options = get_options();
  int reject = smartlist_string_num_isin(options->RejectPlaintextPorts, port);

  if (smartlist_string_num_isin(options->WarnPlaintextPorts, port)) {
    log_warn(LD_APP, "Application request to port %d: this port is "
             "commonly used for unencrypted protocols. Please make sure "
             "you don't send anything you would mind the rest of the "
             "Internet reading!%s", port, reject ? " Closing." : "");
    control_event_client_status(LOG_WARN, "DANGEROUS_PORT PORT=%d RESULT=%s",
                                port, reject ? "REJECT" : "WARN");
  }

  if (reject) {
    log_info(LD_APP, "Port %d listed in RejectPlaintextPorts. Closing.", port);
    connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    return -1;
  }

  return 0;
}

/** Connection <b>conn</b> just finished its socks handshake, or the
 * controller asked us to take care of it. If <b>circ</b> is defined,
 * then that's where we'll want to attach it. Otherwise we have to
@@ -1396,6 +1427,11 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
        }
      }

      /* warn or reject if it's using a dangerous port */
      if (!conn->use_begindir && !conn->chosen_exit_name && !circ)
        if (consider_plaintext_ports(conn, socks->port) < 0)
          return -1;

      if (!conn->use_begindir) {
        /* help predict this next time */
        rep_hist_note_used_port(socks->port, time(NULL));
+10 −0
Original line number Diff line number Diff line
@@ -529,6 +529,7 @@ typedef enum {
#define END_STREAM_REASON_CONNRESET 12
#define END_STREAM_REASON_TORPROTOCOL 13
#define END_STREAM_REASON_NOTDIRECTORY 14
#define END_STREAM_REASON_ENTRYPOLICY 15

/* These high-numbered end reasons are not part of the official spec,
 * and are not intended to be put in relay end cells. They are here
@@ -2132,6 +2133,15 @@ typedef struct {
  /** Application ports that require all nodes in circ to have sufficient
   * uptime. */
  smartlist_t *LongLivedPorts;
  /** Application ports that are likely to be unencrypted and
   * unauthenticated; we reject requests for them to prevent the
   * user from screwing up and leaking plaintext secrets to an
   * observer somewhere on the Internet. */
  smartlist_t *RejectPlaintextPorts;
  /** Related to RejectPlaintextPorts above, except this config option
   * controls whether we warn (in the log and via a controller status
   * event) every time a risky connection is attempted. */
  smartlist_t *WarnPlaintextPorts;
  /** Should we try to reuse the same exit node for a given host */
  smartlist_t *TrackHostExits;
  int TrackHostExitsExpire; /**< Number of seconds until we expire an
Loading