Quellcode durchsuchen

Merge branch 'bug14084'

Nick Mathewson vor 9 Jahren
Ursprung
Commit
e7e33d4b04
5 geänderte Dateien mit 43 neuen und 5 gelöschten Zeilen
  1. 6 0
      changes/bug14084
  2. 6 0
      doc/tor.1.txt
  3. 1 0
      src/or/config.c
  4. 7 2
      src/or/connection_edge.c
  5. 23 3
      src/or/rendservice.c

+ 6 - 0
changes/bug14084

@@ -0,0 +1,6 @@
+  o Minor features:
+    - New option "HiddenServiceAllowUnknownPorts" to allow hidden
+      services to disable the anti-scanning feature introduced in
+      0.2.6.2-alpha. With this option not set, a connection to an
+      unlisted port closes the circuit.  With this option set, only a
+      RELAY_DONE cell is sent.  Closes ticket #14084.

+ 6 - 0
doc/tor.1.txt

@@ -2093,6 +2093,12 @@ The following options are used to configure a hidden service.
     found in the hostname file. Clients need to put this authorization data in
     found in the hostname file. Clients need to put this authorization data in
     their configuration file using **HidServAuth**.
     their configuration file using **HidServAuth**.
 
 
+[[HiddenServiceAllowUnknownPorts]] **HiddenServiceAllowUnknownPorts** **0**|**1**::
+   If set to 1, then connections to unrecognized ports do not cause the
+   current hidden service to close rendezvous circuits. (Setting this to 0 is
+   not an authorization mechanism; it is instead meant to be a mild
+   inconvenience to port-scanners.) (Default: 0)
+
 [[RendPostPeriod]] **RendPostPeriod** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**::
 [[RendPostPeriod]] **RendPostPeriod** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**::
     Every time the specified period elapses, Tor uploads any rendezvous
     Every time the specified period elapses, Tor uploads any rendezvous
     service descriptors to the directory servers. This information  is also
     service descriptors to the directory servers. This information  is also

+ 1 - 0
src/or/config.c

@@ -281,6 +281,7 @@ static config_var_t option_vars_[] = {
   VAR("HiddenServicePort",   LINELIST_S, RendConfigLines,    NULL),
   VAR("HiddenServicePort",   LINELIST_S, RendConfigLines,    NULL),
   VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines,    NULL),
   VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines,    NULL),
   VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
   VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
+  VAR("HiddenServiceAllowUnknownPorts",LINELIST_S, RendConfigLines, NULL),
   V(HiddenServiceStatistics,     BOOL,     "0"),
   V(HiddenServiceStatistics,     BOOL,     "0"),
   V(HidServAuth,                 LINELIST, NULL),
   V(HidServAuth,                 LINELIST, NULL),
   V(CloseHSClientCircuitsImmediatelyOnTimeout, BOOL, "0"),
   V(CloseHSClientCircuitsImmediatelyOnTimeout, BOOL, "0"),

+ 7 - 2
src/or/connection_edge.c

@@ -2788,7 +2788,9 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
     n_stream->rend_data = rend_data_dup(origin_circ->rend_data);
     n_stream->rend_data = rend_data_dup(origin_circ->rend_data);
     tor_assert(connection_edge_is_rendezvous_stream(n_stream));
     tor_assert(connection_edge_is_rendezvous_stream(n_stream));
     assert_circuit_ok(circ);
     assert_circuit_ok(circ);
-    if (rend_service_set_connection_addr_port(n_stream, origin_circ) < 0) {
+
+    const int r = rend_service_set_connection_addr_port(n_stream, origin_circ);
+    if (r < 0) {
       log_info(LD_REND,"Didn't find rendezvous service (port %d)",
       log_info(LD_REND,"Didn't find rendezvous service (port %d)",
                n_stream->base_.port);
                n_stream->base_.port);
       /* Send back reason DONE because we want to make hidden service port
       /* Send back reason DONE because we want to make hidden service port
@@ -2807,7 +2809,10 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
        * scanning the hidden service ports. Note that this mitigates port
        * scanning the hidden service ports. Note that this mitigates port
        * scanning by adding more work on the attacker side to successfully
        * scanning by adding more work on the attacker side to successfully
        * scan but does not fully solve it. */
        * scan but does not fully solve it. */
-      return END_CIRC_AT_ORIGIN;
+      if (r < -1)
+        return END_CIRC_AT_ORIGIN;
+      else
+        return 0;
     }
     }
     assert_circuit_ok(circ);
     assert_circuit_ok(circ);
     log_debug(LD_REND,"Finished assigning addr/port");
     log_debug(LD_REND,"Finished assigning addr/port");

+ 23 - 3
src/or/rendservice.c

@@ -129,6 +129,9 @@ typedef struct rend_service_t {
    * when they do, this keeps us from launching multiple simultaneous attempts
    * when they do, this keeps us from launching multiple simultaneous attempts
    * to connect to the same rend point. */
    * to connect to the same rend point. */
   replaycache_t *accepted_intro_dh_parts;
   replaycache_t *accepted_intro_dh_parts;
+  /** If true, we don't close circuits for making requests to unsupported
+   * ports. */
+  int allow_unknown_ports;
 } rend_service_t;
 } rend_service_t;
 
 
 /** A list of rend_service_t's for services run on this OP.
 /** A list of rend_service_t's for services run on this OP.
@@ -397,6 +400,19 @@ rend_config_services(const or_options_t *options, int validate_only)
          return -1;
          return -1;
        }
        }
        smartlist_add(service->ports, portcfg);
        smartlist_add(service->ports, portcfg);
+     } else if (!strcasecmp(line->key, "HiddenServiceAllowUnknownPorts")) {
+       service->allow_unknown_ports = (int)tor_parse_long(line->value,
+                                                         10, 0, 1, &ok, NULL);
+       if (!ok) {
+         log_warn(LD_CONFIG,
+                  "HiddenServiceAllowUnknownPorts should be 0 or 1, not %s",
+                  line->value);
+         rend_service_free(service);
+         return -1;
+       }
+       log_info(LD_CONFIG,
+                "HiddenServiceAllowUnknownPorts=%d for %s",
+                (int)service->allow_unknown_ports, service->directory);
      } else if (!strcasecmp(line->key,
      } else if (!strcasecmp(line->key,
                             "HiddenServiceDirGroupReadable")) {
                             "HiddenServiceDirGroupReadable")) {
          service->dir_group_readable = (int)tor_parse_long(line->value,
          service->dir_group_readable = (int)tor_parse_long(line->value,
@@ -3388,7 +3404,8 @@ rend_service_dump_stats(int severity)
 
 
 /** Given <b>conn</b>, a rendezvous exit stream, look up the hidden service for
 /** Given <b>conn</b>, a rendezvous exit stream, look up the hidden service for
  * 'circ', and look up the port and address based on conn-\>port.
  * 'circ', and look up the port and address based on conn-\>port.
- * Assign the actual conn-\>addr and conn-\>port. Return -1 if failure,
+ * Assign the actual conn-\>addr and conn-\>port. Return -2 on failure
+ * for which the circuit should be closed, -1 on other failure,
  * or 0 for success.
  * or 0 for success.
  */
  */
 int
 int
@@ -3411,7 +3428,7 @@ rend_service_set_connection_addr_port(edge_connection_t *conn,
     log_warn(LD_REND, "Couldn't find any service associated with pk %s on "
     log_warn(LD_REND, "Couldn't find any service associated with pk %s on "
              "rendezvous circuit %u; closing.",
              "rendezvous circuit %u; closing.",
              serviceid, (unsigned)circ->base_.n_circ_id);
              serviceid, (unsigned)circ->base_.n_circ_id);
-    return -1;
+    return -2;
   }
   }
   matching_ports = smartlist_new();
   matching_ports = smartlist_new();
   SMARTLIST_FOREACH(service->ports, rend_service_port_config_t *, p,
   SMARTLIST_FOREACH(service->ports, rend_service_port_config_t *, p,
@@ -3429,6 +3446,9 @@ rend_service_set_connection_addr_port(edge_connection_t *conn,
   }
   }
   log_info(LD_REND, "No virtual port mapping exists for port %d on service %s",
   log_info(LD_REND, "No virtual port mapping exists for port %d on service %s",
            conn->base_.port,serviceid);
            conn->base_.port,serviceid);
-  return -1;
+  if (service->allow_unknown_ports)
+    return -1;
+  else
+    return -2;
 }
 }