]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Change HiddenServiceExportCircuitID to take a string parameter: the protocol.
authorAlexander Færøy <ahf@torproject.org>
Sat, 15 Sep 2018 13:33:31 +0000 (16:33 +0300)
committerGeorge Kadianakis <desnacked@riseup.net>
Sat, 15 Sep 2018 13:52:36 +0000 (16:52 +0300)
This patch changes HiddenServiceExportCircuitID so instead of being a
boolean it takes a string, which is the protocol. Currently only the
'haproxy' protocol is defined.

See: https://bugs.torproject.org/4700

doc/tor.1.txt
src/core/or/connection_edge.c
src/core/or/connection_edge.h
src/feature/hs/hs_config.c
src/feature/hs/hs_service.c
src/feature/hs/hs_service.h
src/test/test_hs_service.c

index abd1fdefa2a76f1122e5835d2a4e3b8191aeda1d..d260eec10d4cbec15209cdfeafadcec298c46e5f 100644 (file)
@@ -2835,10 +2835,10 @@ The following options are used to configure a hidden service.
    not an authorization mechanism; it is instead meant to be a mild
    inconvenience to port-scanners.) (Default: 0)
 
-[[HiddenServiceExportCircuitID]] **HiddenServiceExportCircuitID** **0**|**1**::
-   If set to 1, then the onion service will use the HAProxy proxy protocol to
-   assign a unique IPv6 address (in an unused IPv6 range) to each inbound
-   client circuit. (Default: 0)
+[[HiddenServiceExportCircuitID]] **HiddenServiceExportCircuitID** __protocol__::
+   The onion service will use the given protocol to expose the global circuit
+   identifier of each inbound client circuit via the selected protocol. The only
+   protocol supported right now \'haproxy\'. This option is only for v3 services.
 
 [[HiddenServiceMaxStreams]] **HiddenServiceMaxStreams** __N__::
    The maximum number of simultaneous streams (connections) per rendezvous
index 62d12f498614ce95d9d61185e11a8fa49b6cbbaf..0eff007e36c7f63dc7e5cbd0968b4eb4dfc51871 100644 (file)
@@ -600,10 +600,15 @@ connected_cell_format_payload(uint8_t *payload_out,
 /* This is an onion service client connection: Export the client circuit ID
  * according to the HAProxy proxy protocol. */
 STATIC void
-export_hs_client_circuit_id_haproxy(const edge_connection_t *edge_conn,
-                                    connection_t *conn)
+export_hs_client_circuit_id(const edge_connection_t *edge_conn,
+                            connection_t *conn,
+                            hs_circuit_id_protocol_t protocol)
 {
-  char *buf;
+  /* We only support HAProxy right now. */
+  if (protocol != HS_CIRCUIT_ID_PROTOCOL_HAPROXY)
+    return;
+
+  char *buf = NULL;
   const char dst_ipv6[] = "::1";
   /* See RFC4193 regarding fc00::/7 */
   const char src_ipv6_prefix[] = "fc00:dead:beef:4dad:";
@@ -655,10 +660,11 @@ connection_edge_finished_connecting(edge_connection_t *edge_conn)
   conn->state = EXIT_CONN_STATE_OPEN;
 
   /* If it's an onion service connection, we might want to include the proxy
-   * protocol header */
-  if (edge_conn->hs_ident &&
-      hs_service_exports_circuit_id(&edge_conn->hs_ident->identity_pk)) {
-    export_hs_client_circuit_id_haproxy(edge_conn, conn);
+   * protocol header: */
+  if (edge_conn->hs_ident) {
+    hs_circuit_id_protocol_t circuit_id_protocol =
+      hs_service_exports_circuit_id(&edge_conn->hs_ident->identity_pk);
+    export_hs_client_circuit_id(edge_conn, conn, circuit_id_protocol);
   }
 
   connection_watch_events(conn, READ_EVENT); /* stop writing, keep reading */
index adec4998e8524eb24b70970a35b5f051483aeb4c..c5ad3128a264462227fb48d63c40f722bfec6d81 100644 (file)
@@ -14,6 +14,8 @@
 
 #include "lib/testsupport/testsupport.h"
 
+#include "feature/hs/hs_service.h"
+
 edge_connection_t *TO_EDGE_CONN(connection_t *);
 entry_connection_t *TO_ENTRY_CONN(connection_t *);
 entry_connection_t *EDGE_TO_ENTRY_CONN(edge_connection_t *);
@@ -244,8 +246,10 @@ STATIC void connection_ap_handshake_rewrite(entry_connection_t *conn,
 
 STATIC int connection_ap_process_http_connect(entry_connection_t *conn);
 STATIC void
-export_hs_client_circuit_id_haproxy(const edge_connection_t *edge_conn,
-                                    connection_t *conn);
+export_hs_client_circuit_id(const edge_connection_t *edge_conn,
+                            connection_t *conn,
+                            hs_circuit_id_protocol_t protocol);
+
 #endif /* defined(CONNECTION_EDGE_PRIVATE) */
 
 #endif /* !defined(TOR_CONNECTION_EDGE_H) */
index 16bfe7c5448e57a680ac2d18be6608791a0b90fb..2378a4d3b2bc871ea92cea7dd08055de97a5f11b 100644 (file)
@@ -145,6 +145,31 @@ helper_parse_uint64(const char *opt, const char *value, uint64_t min,
   return ret;
 }
 
+/** Helper function: Given a configuration option and its value, parse the
+ * value as a hs_circuit_id_protocol_t. On success, ok is set to 1 and ret is
+ * the parse value. On error, ok is set to 0 and the "none"
+ * hs_circuit_id_protocol_t is returned. This function logs on error. */
+static hs_circuit_id_protocol_t
+helper_parse_circuit_id_protocol(const char *key, const char *value, int *ok)
+{
+  tor_assert(value);
+  tor_assert(ok);
+
+  hs_circuit_id_protocol_t ret = HS_CIRCUIT_ID_PROTOCOL_NONE;
+  *ok = 0;
+
+  if (! strcasecmp(value, "haproxy")) {
+    *ok = 1;
+    ret = HS_CIRCUIT_ID_PROTOCOL_HAPROXY;
+  } else {
+    log_warn(LD_CONFIG, "%s must be 'haproxy'.", key);
+    goto err;
+  }
+
+ err:
+  return ret;
+}
+
 /* Return the service version by trying to learn it from the key on disk if
  * any. If nothing is found, the current service configured version is
  * returned. */
@@ -295,8 +320,8 @@ config_service_v3(const config_line_t *line_,
       continue;
     }
     if (!strcasecmp(line->key, "HiddenServiceExportCircuitID")) {
-      config->export_circuit_id =
-        (unsigned int) helper_parse_uint64(line->key, line->value, 0, 1, &ok);
+      config->circuit_id_protocol =
+        helper_parse_circuit_id_protocol(line->key, line->value, &ok);
       if (!ok || export_circuit_id) {
         if (export_circuit_id) {
           dup_opt_seen = line->key;
index 75d7cb75edff477d25fc2e74ebbe9b128dca51d5..e87cb990f539993d2831ff44b50a327e5e5faa34 100644 (file)
@@ -3764,15 +3764,15 @@ hs_service_set_conn_addr_port(const origin_circuit_t *circ,
 
 /** Does the service with identity pubkey <b>pk</b> export the circuit IDs of
  *  its clients?  */
-bool
+hs_circuit_id_protocol_t
 hs_service_exports_circuit_id(const ed25519_public_key_t *pk)
 {
   hs_service_t *service = find_service(hs_service_map, pk);
   if (!service) {
-    return 0;
+    return HS_CIRCUIT_ID_PROTOCOL_NONE;
   }
 
-  return service->config.export_circuit_id;
+  return service->config.circuit_id_protocol;
 }
 
 /* Add to file_list every filename used by a configured hidden service, and to
index e541cb28b9a1299440454e7f6571682d0a76b8db..6fb15b9d37b01a4a1474791ff85c1e67eb377b30 100644 (file)
@@ -161,6 +161,15 @@ typedef struct hs_service_authorized_client_t {
   curve25519_public_key_t client_pk;
 } hs_service_authorized_client_t;
 
+/** Which protocol to use for exporting HS client circuit ID. */
+typedef enum {
+  /** Don't expose the circuit id. */
+  HS_CIRCUIT_ID_PROTOCOL_NONE,
+
+  /** Use the HAProxy proxy protocol. */
+  HS_CIRCUIT_ID_PROTOCOL_HAPROXY
+} hs_circuit_id_protocol_t;
+
 /* Service configuration. The following are set from the torrc options either
  * set by the configuration file or by the control port. Nothing else should
  * change those values. */
@@ -212,7 +221,7 @@ typedef struct hs_service_config_t {
   unsigned int is_ephemeral : 1;
 
   /* Does this service export the circuit ID of its clients? */
-  bool export_circuit_id;
+  hs_circuit_id_protocol_t circuit_id_protocol;
 } hs_service_config_t;
 
 /* Service state. */
@@ -319,7 +328,8 @@ void hs_service_upload_desc_to_dir(const char *encoded_desc,
                                    const ed25519_public_key_t *blinded_pk,
                                    const routerstatus_t *hsdir_rs);
 
-bool hs_service_exports_circuit_id(const ed25519_public_key_t *pk);
+hs_circuit_id_protocol_t
+hs_service_exports_circuit_id(const ed25519_public_key_t *pk);
 
 #ifdef HS_SERVICE_PRIVATE
 
index 2b8d6e597acedf3856782f7cd3b8c5284a2fa214..955bcc8aff8916e80b75b4705f6c57b23e7e4077 100644 (file)
@@ -2025,10 +2025,10 @@ test_export_client_circuit_id(void *arg)
   /* Create service */
   hs_service_t *service = helper_create_service();
   /* Check that export circuit ID detection works */
-  service->config.export_circuit_id = false;
+  service->config.circuit_id_protocol = HS_CIRCUIT_ID_PROTOCOL_NONE;
   tt_int_op(0, OP_EQ,
             hs_service_exports_circuit_id(&service->keys.identity_pk));
-  service->config.export_circuit_id = true;
+  service->config.circuit_id_protocol = HS_CIRCUIT_ID_PROTOCOL_HAPROXY;
   tt_int_op(1, OP_EQ,
             hs_service_exports_circuit_id(&service->keys.identity_pk));
 
@@ -2047,7 +2047,8 @@ test_export_client_circuit_id(void *arg)
   or_circ->global_identifier = 666;
 
   /* Export circuit ID */
-  export_hs_client_circuit_id_haproxy(edge_conn, conn);
+  export_hs_client_circuit_id(edge_conn, conn,
+                              service->config.circuit_id_protocol);
 
   /* Check contents */
   cp1 = buf_get_contents(conn->outbuf, &sz);
@@ -2058,7 +2059,8 @@ test_export_client_circuit_id(void *arg)
   or_circ->global_identifier = 22;
 
   /* check changes */
-  export_hs_client_circuit_id_haproxy(edge_conn, conn);
+  export_hs_client_circuit_id(edge_conn, conn,
+                              service->config.circuit_id_protocol);
   cp2 = buf_get_contents(conn->outbuf, &sz);
   tt_str_op(cp1, OP_NE, cp2);
   tor_free(cp1);
@@ -2066,7 +2068,8 @@ test_export_client_circuit_id(void *arg)
   /* Check that GID with UINT32_MAX works. */
   or_circ->global_identifier = UINT32_MAX;
 
-  export_hs_client_circuit_id_haproxy(edge_conn, conn);
+  export_hs_client_circuit_id(edge_conn, conn,
+                              service->config.circuit_id_protocol);
   cp1 = buf_get_contents(conn->outbuf, &sz);
   tt_str_op(cp1, OP_EQ,
             "PROXY TCP6 fc00:dead:beef:4dad::ffff:ffff ::1 65535 42\r\n");
@@ -2075,7 +2078,8 @@ test_export_client_circuit_id(void *arg)
   /* Check that GID with UINT16_MAX works. */
   or_circ->global_identifier = UINT16_MAX;
 
-  export_hs_client_circuit_id_haproxy(edge_conn, conn);
+  export_hs_client_circuit_id(edge_conn, conn,
+                              service->config.circuit_id_protocol);
   cp1 = buf_get_contents(conn->outbuf, &sz);
   tt_str_op(cp1, OP_EQ,
             "PROXY TCP6 fc00:dead:beef:4dad::0:ffff ::1 65535 42\r\n");
@@ -2084,7 +2088,8 @@ test_export_client_circuit_id(void *arg)
   /* Check that GID with UINT16_MAX + 7 works. */
   or_circ->global_identifier = UINT16_MAX + 7;
 
-  export_hs_client_circuit_id_haproxy(edge_conn, conn);
+  export_hs_client_circuit_id(edge_conn, conn,
+                              service->config.circuit_id_protocol);
   cp1 = buf_get_contents(conn->outbuf, &sz);
   tt_str_op(cp1, OP_EQ, "PROXY TCP6 fc00:dead:beef:4dad::1:6 ::1 6 42\r\n");