mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Enable the ntor handshake on the client side.
"works for me"
This commit is contained in:
parent
ecf88b16b8
commit
b286373908
@ -914,6 +914,8 @@ channel_tls_handle_cell(cell_t *cell, or_connection_t *conn)
|
|||||||
case CELL_RELAY:
|
case CELL_RELAY:
|
||||||
case CELL_RELAY_EARLY:
|
case CELL_RELAY_EARLY:
|
||||||
case CELL_DESTROY:
|
case CELL_DESTROY:
|
||||||
|
case CELL_CREATE2:
|
||||||
|
case CELL_CREATED2:
|
||||||
/*
|
/*
|
||||||
* These are all transport independent and we pass them up through the
|
* These are all transport independent and we pass them up through the
|
||||||
* channel_t mechanism. They are ultimately handled in command.c.
|
* channel_t mechanism. They are ultimately handled in command.c.
|
||||||
|
@ -604,6 +604,73 @@ circuit_timeout_want_to_count_circ(origin_circuit_t *circ)
|
|||||||
&& circ->build_state->desired_path_len == DEFAULT_ROUTE_LEN;
|
&& circ->build_state->desired_path_len == DEFAULT_ROUTE_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CURVE25519_ENABLED
|
||||||
|
/** Return true if the ntor handshake is enabled in the configuration, or if
|
||||||
|
* it's been set to "auto" in the configuration and it's enabled in the
|
||||||
|
* consensus. */
|
||||||
|
static int
|
||||||
|
circuits_can_use_ntor(void)
|
||||||
|
{
|
||||||
|
const or_options_t *options = get_options();
|
||||||
|
if (options->UseNTorHandshake != -1)
|
||||||
|
return options->UseNTorHandshake;
|
||||||
|
return networkstatus_get_param(NULL, "UseNTorHandshake", 0, 0, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Decide whether to use a TAP or ntor handshake for connecting to <b>ei</b>
|
||||||
|
* directly, and set *<b>cell_type_out</b> and *<b>handshake_type_out</b>
|
||||||
|
* accordingly. */
|
||||||
|
static void
|
||||||
|
circuit_pick_create_handshake(uint8_t *cell_type_out,
|
||||||
|
uint16_t *handshake_type_out,
|
||||||
|
const extend_info_t *ei)
|
||||||
|
{
|
||||||
|
#ifdef CURVE25519_ENABLED
|
||||||
|
if (!tor_mem_is_zero((const char*)ei->curve25519_onion_key.public_key,
|
||||||
|
CURVE25519_PUBKEY_LEN) &&
|
||||||
|
circuits_can_use_ntor()) {
|
||||||
|
*cell_type_out = CELL_CREATE2;
|
||||||
|
*handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void) ei;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*cell_type_out = CELL_CREATE;
|
||||||
|
*handshake_type_out = ONION_HANDSHAKE_TYPE_TAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Decide whether to use a TAP or ntor handshake for connecting to <b>ei</b>
|
||||||
|
* directly, and set *<b>handshake_type_out</b> accordingly. Decide whether,
|
||||||
|
* in extending through <b>node</b> to do so, we should use an EXTEND2 or an
|
||||||
|
* EXTEND cell to do so, and set *<b>cell_type_out</b> and
|
||||||
|
* *<b>create_cell_type_out</b> accordingly. */
|
||||||
|
static void
|
||||||
|
circuit_pick_extend_handshake(uint8_t *cell_type_out,
|
||||||
|
uint8_t *create_cell_type_out,
|
||||||
|
uint16_t *handshake_type_out,
|
||||||
|
const node_t *node_prev,
|
||||||
|
const extend_info_t *ei)
|
||||||
|
{
|
||||||
|
uint8_t t;
|
||||||
|
circuit_pick_create_handshake(&t, handshake_type_out, ei);
|
||||||
|
/* XXXX024 The check for whether the node has a curve25519 key is a bad
|
||||||
|
* proxy for whether it can do extend2 cells; once a version that
|
||||||
|
* handles extend2 cells is out, remove it. */
|
||||||
|
if (node_prev &&
|
||||||
|
*handshake_type_out != ONION_HANDSHAKE_TYPE_TAP &&
|
||||||
|
(node_has_curve25519_onion_key(node_prev) ||
|
||||||
|
(node_prev->rs && node_prev->rs->version_supports_extend2_cells))) {
|
||||||
|
*cell_type_out = RELAY_COMMAND_EXTEND2;
|
||||||
|
*create_cell_type_out = CELL_CREATE2;
|
||||||
|
} else {
|
||||||
|
*cell_type_out = RELAY_COMMAND_EXTEND;
|
||||||
|
*create_cell_type_out = CELL_CREATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** This is the backbone function for building circuits.
|
/** This is the backbone function for building circuits.
|
||||||
*
|
*
|
||||||
* If circ's first hop is closed, then we need to build a create
|
* If circ's first hop is closed, then we need to build a create
|
||||||
@ -638,10 +705,10 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
|
|||||||
fast = should_use_create_fast_for_circuit(circ);
|
fast = should_use_create_fast_for_circuit(circ);
|
||||||
if (!fast) {
|
if (!fast) {
|
||||||
/* We are an OR and we know the right onion key: we should
|
/* We are an OR and we know the right onion key: we should
|
||||||
* send an old slow create cell.
|
* send a create cell.
|
||||||
*/
|
*/
|
||||||
cc.cell_type = CELL_CREATE;
|
circuit_pick_create_handshake(&cc.cell_type, &cc.handshake_type,
|
||||||
cc.handshake_type = ONION_HANDSHAKE_TYPE_TAP;
|
circ->cpath->extend_info);
|
||||||
note_request("cell: create", 1);
|
note_request("cell: create", 1);
|
||||||
} else {
|
} else {
|
||||||
/* We are not an OR, and we're building the first hop of a circuit to a
|
/* We are not an OR, and we're building the first hop of a circuit to a
|
||||||
@ -747,15 +814,21 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
|
|||||||
return - END_CIRC_REASON_INTERNAL;
|
return - END_CIRC_REASON_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ec.cell_type = RELAY_COMMAND_EXTEND;
|
{
|
||||||
|
const node_t *prev_node;
|
||||||
|
prev_node = node_get_by_id(hop->prev->extend_info->identity_digest);
|
||||||
|
circuit_pick_extend_handshake(&ec.cell_type,
|
||||||
|
&ec.create_cell.cell_type,
|
||||||
|
&ec.create_cell.handshake_type,
|
||||||
|
prev_node,
|
||||||
|
hop->extend_info);
|
||||||
|
}
|
||||||
|
|
||||||
tor_addr_copy(&ec.orport_ipv4.addr, &hop->extend_info->addr);
|
tor_addr_copy(&ec.orport_ipv4.addr, &hop->extend_info->addr);
|
||||||
ec.orport_ipv4.port = hop->extend_info->port;
|
ec.orport_ipv4.port = hop->extend_info->port;
|
||||||
tor_addr_make_unspec(&ec.orport_ipv6.addr);
|
tor_addr_make_unspec(&ec.orport_ipv6.addr);
|
||||||
memcpy(ec.node_id, hop->extend_info->identity_digest, DIGEST_LEN);
|
memcpy(ec.node_id, hop->extend_info->identity_digest, DIGEST_LEN);
|
||||||
|
|
||||||
ec.create_cell.handshake_type = ONION_HANDSHAKE_TYPE_TAP;
|
|
||||||
ec.create_cell.cell_type = CELL_CREATE;
|
|
||||||
|
|
||||||
len = onion_skin_create(ec.create_cell.handshake_type,
|
len = onion_skin_create(ec.create_cell.handshake_type,
|
||||||
hop->extend_info,
|
hop->extend_info,
|
||||||
&hop->handshake_state,
|
&hop->handshake_state,
|
||||||
@ -903,6 +976,7 @@ circuit_extend(cell_t *cell, circuit_t *circ)
|
|||||||
circ->n_hop = extend_info_new(NULL /*nickname*/,
|
circ->n_hop = extend_info_new(NULL /*nickname*/,
|
||||||
(const char*)ec.node_id,
|
(const char*)ec.node_id,
|
||||||
NULL /*onion_key*/,
|
NULL /*onion_key*/,
|
||||||
|
NULL /*curve25519_key*/,
|
||||||
&ec.orport_ipv4.addr,
|
&ec.orport_ipv4.addr,
|
||||||
ec.orport_ipv4.port);
|
ec.orport_ipv4.port);
|
||||||
|
|
||||||
@ -938,6 +1012,7 @@ circuit_extend(cell_t *cell, circuit_t *circ)
|
|||||||
|
|
||||||
if (circuit_deliver_create_cell(circ, &ec.create_cell, 1) < 0)
|
if (circuit_deliver_create_cell(circ, &ec.create_cell, 1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2311,6 +2386,7 @@ onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice)
|
|||||||
extend_info_t *
|
extend_info_t *
|
||||||
extend_info_new(const char *nickname, const char *digest,
|
extend_info_new(const char *nickname, const char *digest,
|
||||||
crypto_pk_t *onion_key,
|
crypto_pk_t *onion_key,
|
||||||
|
const curve25519_public_key_t *curve25519_key,
|
||||||
const tor_addr_t *addr, uint16_t port)
|
const tor_addr_t *addr, uint16_t port)
|
||||||
{
|
{
|
||||||
extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
|
extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
|
||||||
@ -2319,6 +2395,13 @@ extend_info_new(const char *nickname, const char *digest,
|
|||||||
strlcpy(info->nickname, nickname, sizeof(info->nickname));
|
strlcpy(info->nickname, nickname, sizeof(info->nickname));
|
||||||
if (onion_key)
|
if (onion_key)
|
||||||
info->onion_key = crypto_pk_dup_key(onion_key);
|
info->onion_key = crypto_pk_dup_key(onion_key);
|
||||||
|
#ifdef CURVE25519_ENABLED
|
||||||
|
if (curve25519_key)
|
||||||
|
memcpy(&info->curve25519_onion_key, curve25519_key,
|
||||||
|
sizeof(curve25519_public_key_t));
|
||||||
|
#else
|
||||||
|
(void)curve25519_key;
|
||||||
|
#endif
|
||||||
tor_addr_copy(&info->addr, addr);
|
tor_addr_copy(&info->addr, addr);
|
||||||
info->port = port;
|
info->port = port;
|
||||||
return info;
|
return info;
|
||||||
@ -2353,12 +2436,14 @@ extend_info_from_node(const node_t *node, int for_direct_connect)
|
|||||||
return extend_info_new(node->ri->nickname,
|
return extend_info_new(node->ri->nickname,
|
||||||
node->identity,
|
node->identity,
|
||||||
node->ri->onion_pkey,
|
node->ri->onion_pkey,
|
||||||
|
node->ri->onion_curve25519_pkey,
|
||||||
&ap.addr,
|
&ap.addr,
|
||||||
ap.port);
|
ap.port);
|
||||||
else if (node->rs && node->md)
|
else if (node->rs && node->md)
|
||||||
return extend_info_new(node->rs->nickname,
|
return extend_info_new(node->rs->nickname,
|
||||||
node->identity,
|
node->identity,
|
||||||
node->md->onion_pkey,
|
node->md->onion_pkey,
|
||||||
|
node->md->onion_curve25519_pkey,
|
||||||
&ap.addr,
|
&ap.addr,
|
||||||
ap.port);
|
ap.port);
|
||||||
else
|
else
|
||||||
|
@ -47,6 +47,7 @@ int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *info);
|
|||||||
void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop);
|
void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop);
|
||||||
extend_info_t *extend_info_new(const char *nickname, const char *digest,
|
extend_info_t *extend_info_new(const char *nickname, const char *digest,
|
||||||
crypto_pk_t *onion_key,
|
crypto_pk_t *onion_key,
|
||||||
|
const curve25519_public_key_t *curve25519_key,
|
||||||
const tor_addr_t *addr, uint16_t port);
|
const tor_addr_t *addr, uint16_t port);
|
||||||
extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect);
|
extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect);
|
||||||
extend_info_t *extend_info_dup(extend_info_t *info);
|
extend_info_t *extend_info_dup(extend_info_t *info);
|
||||||
|
@ -1577,7 +1577,7 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
extend_info = extend_info_new(conn->chosen_exit_name+1,
|
extend_info = extend_info_new(conn->chosen_exit_name+1,
|
||||||
digest, NULL, &addr,
|
digest, NULL, NULL, &addr,
|
||||||
conn->socks_request->port);
|
conn->socks_request->port);
|
||||||
} else {
|
} else {
|
||||||
/* We will need an onion key for the router, and we
|
/* We will need an onion key for the router, and we
|
||||||
|
@ -383,6 +383,7 @@ static config_var_t option_vars_[] = {
|
|||||||
V(UseBridges, BOOL, "0"),
|
V(UseBridges, BOOL, "0"),
|
||||||
V(UseEntryGuards, BOOL, "1"),
|
V(UseEntryGuards, BOOL, "1"),
|
||||||
V(UseMicrodescriptors, AUTOBOOL, "auto"),
|
V(UseMicrodescriptors, AUTOBOOL, "auto"),
|
||||||
|
V(UseNTorHandshake, AUTOBOOL, "auto"),
|
||||||
V(User, STRING, NULL),
|
V(User, STRING, NULL),
|
||||||
V(UserspaceIOCPBuffers, BOOL, "0"),
|
V(UserspaceIOCPBuffers, BOOL, "0"),
|
||||||
VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
|
VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
|
||||||
|
@ -1502,7 +1502,7 @@ routerset_contains_bridge(const routerset_t *routerset,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
extinfo = extend_info_new(
|
extinfo = extend_info_new(
|
||||||
NULL, bridge->identity, NULL, &bridge->addr, bridge->port);
|
NULL, bridge->identity, NULL, NULL, &bridge->addr, bridge->port);
|
||||||
result = routerset_contains_extendinfo(routerset, extinfo);
|
result = routerset_contains_extendinfo(routerset, extinfo);
|
||||||
extend_info_free(extinfo);
|
extend_info_free(extinfo);
|
||||||
return result;
|
return result;
|
||||||
|
@ -916,6 +916,18 @@ node_get_pref_ipv6_orport(const node_t *node, tor_addr_port_t *ap_out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return true iff <b>node</b> has a curve25519 onion key. */
|
||||||
|
int
|
||||||
|
node_has_curve25519_onion_key(const node_t *node)
|
||||||
|
{
|
||||||
|
if (node->ri)
|
||||||
|
return node->ri->onion_curve25519_pkey != NULL;
|
||||||
|
else if (node->md)
|
||||||
|
return node->md->onion_curve25519_pkey != NULL;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Refresh the country code of <b>ri</b>. This function MUST be called on
|
/** Refresh the country code of <b>ri</b>. This function MUST be called on
|
||||||
* each router when the GeoIP database is reloaded, and on all new routers. */
|
* each router when the GeoIP database is reloaded, and on all new routers. */
|
||||||
void
|
void
|
||||||
|
@ -54,6 +54,7 @@ int node_ipv6_preferred(const node_t *node);
|
|||||||
int node_get_prim_orport(const node_t *node, tor_addr_port_t *ap_out);
|
int node_get_prim_orport(const node_t *node, tor_addr_port_t *ap_out);
|
||||||
void node_get_pref_orport(const node_t *node, tor_addr_port_t *ap_out);
|
void node_get_pref_orport(const node_t *node, tor_addr_port_t *ap_out);
|
||||||
void node_get_pref_ipv6_orport(const node_t *node, tor_addr_port_t *ap_out);
|
void node_get_pref_ipv6_orport(const node_t *node, tor_addr_port_t *ap_out);
|
||||||
|
int node_has_curve25519_onion_key(const node_t *node);
|
||||||
|
|
||||||
smartlist_t *nodelist_get_list(void);
|
smartlist_t *nodelist_get_list(void);
|
||||||
|
|
||||||
|
@ -2025,6 +2025,9 @@ typedef struct routerstatus_t {
|
|||||||
/** True iff this router is a version that allows DATA cells to arrive on
|
/** True iff this router is a version that allows DATA cells to arrive on
|
||||||
* a stream before it has sent a CONNECTED cell. */
|
* a stream before it has sent a CONNECTED cell. */
|
||||||
unsigned int version_supports_optimistic_data:1;
|
unsigned int version_supports_optimistic_data:1;
|
||||||
|
/** True iff this router has a version that allows it to accept EXTEND2
|
||||||
|
* cells */
|
||||||
|
unsigned int version_supports_extend2_cells:1;
|
||||||
|
|
||||||
unsigned int has_bandwidth:1; /**< The vote/consensus had bw info */
|
unsigned int has_bandwidth:1; /**< The vote/consensus had bw info */
|
||||||
unsigned int has_exitsummary:1; /**< The vote/consensus had exit summaries */
|
unsigned int has_exitsummary:1; /**< The vote/consensus had exit summaries */
|
||||||
@ -3799,6 +3802,8 @@ typedef struct {
|
|||||||
|
|
||||||
int IPv6Exit; /**< Do we support exiting to IPv6 addresses? */
|
int IPv6Exit; /**< Do we support exiting to IPv6 addresses? */
|
||||||
|
|
||||||
|
/** Autobool: should we use the ntor handshake if we can? */
|
||||||
|
int UseNTorHandshake;
|
||||||
} or_options_t;
|
} or_options_t;
|
||||||
|
|
||||||
/** Persistent state for an onion router, as saved to disk. */
|
/** Persistent state for an onion router, as saved to disk. */
|
||||||
|
@ -572,6 +572,7 @@ relay_send_command_from_edge(streamid_t stream_id, circuit_t *circ,
|
|||||||
origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
|
origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
|
||||||
if (origin_circ->remaining_relay_early_cells > 0 &&
|
if (origin_circ->remaining_relay_early_cells > 0 &&
|
||||||
(relay_command == RELAY_COMMAND_EXTEND ||
|
(relay_command == RELAY_COMMAND_EXTEND ||
|
||||||
|
relay_command == RELAY_COMMAND_EXTEND2 ||
|
||||||
cpath_layer != origin_circ->cpath)) {
|
cpath_layer != origin_circ->cpath)) {
|
||||||
/* If we've got any relay_early cells left and (we're sending
|
/* If we've got any relay_early cells left and (we're sending
|
||||||
* an extend cell or we're not talking to the first hop), use
|
* an extend cell or we're not talking to the first hop), use
|
||||||
@ -585,7 +586,8 @@ relay_send_command_from_edge(streamid_t stream_id, circuit_t *circ,
|
|||||||
* task 878. */
|
* task 878. */
|
||||||
origin_circ->relay_early_commands[
|
origin_circ->relay_early_commands[
|
||||||
origin_circ->relay_early_cells_sent++] = relay_command;
|
origin_circ->relay_early_cells_sent++] = relay_command;
|
||||||
} else if (relay_command == RELAY_COMMAND_EXTEND) {
|
} else if (relay_command == RELAY_COMMAND_EXTEND ||
|
||||||
|
relay_command == RELAY_COMMAND_EXTEND2) {
|
||||||
/* If no RELAY_EARLY cells can be sent over this circuit, log which
|
/* If no RELAY_EARLY cells can be sent over this circuit, log which
|
||||||
* commands have been sent as RELAY_EARLY cells before; helps debug
|
* commands have been sent as RELAY_EARLY cells before; helps debug
|
||||||
* task 878. */
|
* task 878. */
|
||||||
|
@ -1071,7 +1071,8 @@ extend_info_from_router(const routerinfo_t *r)
|
|||||||
|
|
||||||
router_get_prim_orport(r, &ap);
|
router_get_prim_orport(r, &ap);
|
||||||
return extend_info_new(r->nickname, r->cache_info.identity_digest,
|
return extend_info_new(r->nickname, r->cache_info.identity_digest,
|
||||||
r->onion_pkey, &ap.addr, ap.port);
|
r->onion_pkey, r->onion_curve25519_pkey,
|
||||||
|
&ap.addr, ap.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Some time has passed, or we just got new directory information.
|
/** Some time has passed, or we just got new directory information.
|
||||||
|
@ -2188,6 +2188,8 @@ routerstatus_parse_entry_from_string(memarea_t *area,
|
|||||||
tor_version_supports_microdescriptors(tok->args[0]);
|
tor_version_supports_microdescriptors(tok->args[0]);
|
||||||
rs->version_supports_optimistic_data =
|
rs->version_supports_optimistic_data =
|
||||||
tor_version_as_new_as(tok->args[0], "0.2.3.1-alpha");
|
tor_version_as_new_as(tok->args[0], "0.2.3.1-alpha");
|
||||||
|
rs->version_supports_extend2_cells =
|
||||||
|
tor_version_as_new_as(tok->args[0], "0.2.4.7-alpha");
|
||||||
}
|
}
|
||||||
if (vote_rs) {
|
if (vote_rs) {
|
||||||
vote_rs->version = tor_strdup(tok->args[0]);
|
vote_rs->version = tor_strdup(tok->args[0]);
|
||||||
|
Loading…
Reference in New Issue
Block a user