mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
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
This commit is contained in:
parent
8f085841ef
commit
9b511dc5d6
@ -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
|
not an authorization mechanism; it is instead meant to be a mild
|
||||||
inconvenience to port-scanners.) (Default: 0)
|
inconvenience to port-scanners.) (Default: 0)
|
||||||
|
|
||||||
[[HiddenServiceExportCircuitID]] **HiddenServiceExportCircuitID** **0**|**1**::
|
[[HiddenServiceExportCircuitID]] **HiddenServiceExportCircuitID** __protocol__::
|
||||||
If set to 1, then the onion service will use the HAProxy proxy protocol to
|
The onion service will use the given protocol to expose the global circuit
|
||||||
assign a unique IPv6 address (in an unused IPv6 range) to each inbound
|
identifier of each inbound client circuit via the selected protocol. The only
|
||||||
client circuit. (Default: 0)
|
protocol supported right now \'haproxy\'. This option is only for v3 services.
|
||||||
|
|
||||||
[[HiddenServiceMaxStreams]] **HiddenServiceMaxStreams** __N__::
|
[[HiddenServiceMaxStreams]] **HiddenServiceMaxStreams** __N__::
|
||||||
The maximum number of simultaneous streams (connections) per rendezvous
|
The maximum number of simultaneous streams (connections) per rendezvous
|
||||||
|
@ -600,10 +600,15 @@ connected_cell_format_payload(uint8_t *payload_out,
|
|||||||
/* This is an onion service client connection: Export the client circuit ID
|
/* This is an onion service client connection: Export the client circuit ID
|
||||||
* according to the HAProxy proxy protocol. */
|
* according to the HAProxy proxy protocol. */
|
||||||
STATIC void
|
STATIC void
|
||||||
export_hs_client_circuit_id_haproxy(const edge_connection_t *edge_conn,
|
export_hs_client_circuit_id(const edge_connection_t *edge_conn,
|
||||||
connection_t *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";
|
const char dst_ipv6[] = "::1";
|
||||||
/* See RFC4193 regarding fc00::/7 */
|
/* See RFC4193 regarding fc00::/7 */
|
||||||
const char src_ipv6_prefix[] = "fc00:dead:beef:4dad:";
|
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;
|
conn->state = EXIT_CONN_STATE_OPEN;
|
||||||
|
|
||||||
/* If it's an onion service connection, we might want to include the proxy
|
/* If it's an onion service connection, we might want to include the proxy
|
||||||
* protocol header */
|
* protocol header: */
|
||||||
if (edge_conn->hs_ident &&
|
if (edge_conn->hs_ident) {
|
||||||
hs_service_exports_circuit_id(&edge_conn->hs_ident->identity_pk)) {
|
hs_circuit_id_protocol_t circuit_id_protocol =
|
||||||
export_hs_client_circuit_id_haproxy(edge_conn, conn);
|
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 */
|
connection_watch_events(conn, READ_EVENT); /* stop writing, keep reading */
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include "lib/testsupport/testsupport.h"
|
#include "lib/testsupport/testsupport.h"
|
||||||
|
|
||||||
|
#include "feature/hs/hs_service.h"
|
||||||
|
|
||||||
edge_connection_t *TO_EDGE_CONN(connection_t *);
|
edge_connection_t *TO_EDGE_CONN(connection_t *);
|
||||||
entry_connection_t *TO_ENTRY_CONN(connection_t *);
|
entry_connection_t *TO_ENTRY_CONN(connection_t *);
|
||||||
entry_connection_t *EDGE_TO_ENTRY_CONN(edge_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 int connection_ap_process_http_connect(entry_connection_t *conn);
|
||||||
STATIC void
|
STATIC void
|
||||||
export_hs_client_circuit_id_haproxy(const edge_connection_t *edge_conn,
|
export_hs_client_circuit_id(const edge_connection_t *edge_conn,
|
||||||
connection_t *conn);
|
connection_t *conn,
|
||||||
|
hs_circuit_id_protocol_t protocol);
|
||||||
|
|
||||||
#endif /* defined(CONNECTION_EDGE_PRIVATE) */
|
#endif /* defined(CONNECTION_EDGE_PRIVATE) */
|
||||||
|
|
||||||
#endif /* !defined(TOR_CONNECTION_EDGE_H) */
|
#endif /* !defined(TOR_CONNECTION_EDGE_H) */
|
||||||
|
@ -145,6 +145,31 @@ helper_parse_uint64(const char *opt, const char *value, uint64_t min,
|
|||||||
return ret;
|
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
|
/* 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
|
* any. If nothing is found, the current service configured version is
|
||||||
* returned. */
|
* returned. */
|
||||||
@ -295,8 +320,8 @@ config_service_v3(const config_line_t *line_,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcasecmp(line->key, "HiddenServiceExportCircuitID")) {
|
if (!strcasecmp(line->key, "HiddenServiceExportCircuitID")) {
|
||||||
config->export_circuit_id =
|
config->circuit_id_protocol =
|
||||||
(unsigned int) helper_parse_uint64(line->key, line->value, 0, 1, &ok);
|
helper_parse_circuit_id_protocol(line->key, line->value, &ok);
|
||||||
if (!ok || export_circuit_id) {
|
if (!ok || export_circuit_id) {
|
||||||
if (export_circuit_id) {
|
if (export_circuit_id) {
|
||||||
dup_opt_seen = line->key;
|
dup_opt_seen = line->key;
|
||||||
|
@ -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
|
/** Does the service with identity pubkey <b>pk</b> export the circuit IDs of
|
||||||
* its clients? */
|
* its clients? */
|
||||||
bool
|
hs_circuit_id_protocol_t
|
||||||
hs_service_exports_circuit_id(const ed25519_public_key_t *pk)
|
hs_service_exports_circuit_id(const ed25519_public_key_t *pk)
|
||||||
{
|
{
|
||||||
hs_service_t *service = find_service(hs_service_map, pk);
|
hs_service_t *service = find_service(hs_service_map, pk);
|
||||||
if (!service) {
|
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
|
/* Add to file_list every filename used by a configured hidden service, and to
|
||||||
|
@ -161,6 +161,15 @@ typedef struct hs_service_authorized_client_t {
|
|||||||
curve25519_public_key_t client_pk;
|
curve25519_public_key_t client_pk;
|
||||||
} hs_service_authorized_client_t;
|
} 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
|
/* Service configuration. The following are set from the torrc options either
|
||||||
* set by the configuration file or by the control port. Nothing else should
|
* set by the configuration file or by the control port. Nothing else should
|
||||||
* change those values. */
|
* change those values. */
|
||||||
@ -212,7 +221,7 @@ typedef struct hs_service_config_t {
|
|||||||
unsigned int is_ephemeral : 1;
|
unsigned int is_ephemeral : 1;
|
||||||
|
|
||||||
/* Does this service export the circuit ID of its clients? */
|
/* 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;
|
} hs_service_config_t;
|
||||||
|
|
||||||
/* Service state. */
|
/* 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 ed25519_public_key_t *blinded_pk,
|
||||||
const routerstatus_t *hsdir_rs);
|
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
|
#ifdef HS_SERVICE_PRIVATE
|
||||||
|
|
||||||
|
@ -2025,10 +2025,10 @@ test_export_client_circuit_id(void *arg)
|
|||||||
/* Create service */
|
/* Create service */
|
||||||
hs_service_t *service = helper_create_service();
|
hs_service_t *service = helper_create_service();
|
||||||
/* Check that export circuit ID detection works */
|
/* 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,
|
tt_int_op(0, OP_EQ,
|
||||||
hs_service_exports_circuit_id(&service->keys.identity_pk));
|
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,
|
tt_int_op(1, OP_EQ,
|
||||||
hs_service_exports_circuit_id(&service->keys.identity_pk));
|
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;
|
or_circ->global_identifier = 666;
|
||||||
|
|
||||||
/* Export circuit ID */
|
/* 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 */
|
/* Check contents */
|
||||||
cp1 = buf_get_contents(conn->outbuf, &sz);
|
cp1 = buf_get_contents(conn->outbuf, &sz);
|
||||||
@ -2058,7 +2059,8 @@ test_export_client_circuit_id(void *arg)
|
|||||||
or_circ->global_identifier = 22;
|
or_circ->global_identifier = 22;
|
||||||
|
|
||||||
/* check changes */
|
/* 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);
|
cp2 = buf_get_contents(conn->outbuf, &sz);
|
||||||
tt_str_op(cp1, OP_NE, cp2);
|
tt_str_op(cp1, OP_NE, cp2);
|
||||||
tor_free(cp1);
|
tor_free(cp1);
|
||||||
@ -2066,7 +2068,8 @@ test_export_client_circuit_id(void *arg)
|
|||||||
/* Check that GID with UINT32_MAX works. */
|
/* Check that GID with UINT32_MAX works. */
|
||||||
or_circ->global_identifier = UINT32_MAX;
|
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);
|
cp1 = buf_get_contents(conn->outbuf, &sz);
|
||||||
tt_str_op(cp1, OP_EQ,
|
tt_str_op(cp1, OP_EQ,
|
||||||
"PROXY TCP6 fc00:dead:beef:4dad::ffff:ffff ::1 65535 42\r\n");
|
"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. */
|
/* Check that GID with UINT16_MAX works. */
|
||||||
or_circ->global_identifier = UINT16_MAX;
|
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);
|
cp1 = buf_get_contents(conn->outbuf, &sz);
|
||||||
tt_str_op(cp1, OP_EQ,
|
tt_str_op(cp1, OP_EQ,
|
||||||
"PROXY TCP6 fc00:dead:beef:4dad::0:ffff ::1 65535 42\r\n");
|
"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. */
|
/* Check that GID with UINT16_MAX + 7 works. */
|
||||||
or_circ->global_identifier = UINT16_MAX + 7;
|
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);
|
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");
|
tt_str_op(cp1, OP_EQ, "PROXY TCP6 fc00:dead:beef:4dad::1:6 ::1 6 42\r\n");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user