aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexander Færøy <ahf@torproject.org>2018-09-15 16:33:31 +0300
committerGeorge Kadianakis <desnacked@riseup.net>2018-09-15 16:52:36 +0300
commit9b511dc5d6a9e44bd8c8c644ad9445cab7cdafe2 (patch)
tree9bfd824f5f790295477178ebe45232213ce042d2 /src
parent8f085841ef40f00bbc2bb146a2d555aba527738f (diff)
downloadtor-9b511dc5d6a9e44bd8c8c644ad9445cab7cdafe2.tar.gz
tor-9b511dc5d6a9e44bd8c8c644ad9445cab7cdafe2.zip
Change HiddenServiceExportCircuitID to take a string parameter: the protocol.
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
Diffstat (limited to 'src')
-rw-r--r--src/core/or/connection_edge.c20
-rw-r--r--src/core/or/connection_edge.h8
-rw-r--r--src/feature/hs/hs_config.c29
-rw-r--r--src/feature/hs/hs_service.c6
-rw-r--r--src/feature/hs/hs_service.h14
-rw-r--r--src/test/test_hs_service.c19
6 files changed, 73 insertions, 23 deletions
diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c
index 62d12f4986..0eff007e36 100644
--- a/src/core/or/connection_edge.c
+++ b/src/core/or/connection_edge.c
@@ -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 */
diff --git a/src/core/or/connection_edge.h b/src/core/or/connection_edge.h
index adec4998e8..c5ad3128a2 100644
--- a/src/core/or/connection_edge.h
+++ b/src/core/or/connection_edge.h
@@ -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) */
diff --git a/src/feature/hs/hs_config.c b/src/feature/hs/hs_config.c
index 16bfe7c544..2378a4d3b2 100644
--- a/src/feature/hs/hs_config.c
+++ b/src/feature/hs/hs_config.c
@@ -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;
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c
index 75d7cb75ed..e87cb990f5 100644
--- a/src/feature/hs/hs_service.c
+++ b/src/feature/hs/hs_service.c
@@ -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
diff --git a/src/feature/hs/hs_service.h b/src/feature/hs/hs_service.h
index e541cb28b9..6fb15b9d37 100644
--- a/src/feature/hs/hs_service.h
+++ b/src/feature/hs/hs_service.h
@@ -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
diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c
index 2b8d6e597a..955bcc8aff 100644
--- a/src/test/test_hs_service.c
+++ b/src/test/test_hs_service.c
@@ -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");