mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +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_EARLY:
|
||||
case CELL_DESTROY:
|
||||
case CELL_CREATE2:
|
||||
case CELL_CREATED2:
|
||||
/*
|
||||
* These are all transport independent and we pass them up through the
|
||||
* 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;
|
||||
}
|
||||
|
||||
#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.
|
||||
*
|
||||
* 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);
|
||||
if (!fast) {
|
||||
/* 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;
|
||||
cc.handshake_type = ONION_HANDSHAKE_TYPE_TAP;
|
||||
circuit_pick_create_handshake(&cc.cell_type, &cc.handshake_type,
|
||||
circ->cpath->extend_info);
|
||||
note_request("cell: create", 1);
|
||||
} else {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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);
|
||||
ec.orport_ipv4.port = hop->extend_info->port;
|
||||
tor_addr_make_unspec(&ec.orport_ipv6.addr);
|
||||
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,
|
||||
hop->extend_info,
|
||||
&hop->handshake_state,
|
||||
@ -903,6 +976,7 @@ circuit_extend(cell_t *cell, circuit_t *circ)
|
||||
circ->n_hop = extend_info_new(NULL /*nickname*/,
|
||||
(const char*)ec.node_id,
|
||||
NULL /*onion_key*/,
|
||||
NULL /*curve25519_key*/,
|
||||
&ec.orport_ipv4.addr,
|
||||
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)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2310,8 +2385,9 @@ onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice)
|
||||
/** Allocate a new extend_info object based on the various arguments. */
|
||||
extend_info_t *
|
||||
extend_info_new(const char *nickname, const char *digest,
|
||||
crypto_pk_t *onion_key,
|
||||
const tor_addr_t *addr, uint16_t port)
|
||||
crypto_pk_t *onion_key,
|
||||
const curve25519_public_key_t *curve25519_key,
|
||||
const tor_addr_t *addr, uint16_t port)
|
||||
{
|
||||
extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
|
||||
memcpy(info->identity_digest, digest, DIGEST_LEN);
|
||||
@ -2319,6 +2395,13 @@ extend_info_new(const char *nickname, const char *digest,
|
||||
strlcpy(info->nickname, nickname, sizeof(info->nickname));
|
||||
if (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);
|
||||
info->port = port;
|
||||
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,
|
||||
node->identity,
|
||||
node->ri->onion_pkey,
|
||||
node->ri->onion_curve25519_pkey,
|
||||
&ap.addr,
|
||||
ap.port);
|
||||
else if (node->rs && node->md)
|
||||
return extend_info_new(node->rs->nickname,
|
||||
node->identity,
|
||||
node->md->onion_pkey,
|
||||
node->md->onion_curve25519_pkey,
|
||||
&ap.addr,
|
||||
ap.port);
|
||||
else
|
||||
|
@ -46,8 +46,9 @@ int circuit_append_new_exit(origin_circuit_t *circ, extend_info_t *info);
|
||||
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);
|
||||
extend_info_t *extend_info_new(const char *nickname, const char *digest,
|
||||
crypto_pk_t *onion_key,
|
||||
const tor_addr_t *addr, uint16_t port);
|
||||
crypto_pk_t *onion_key,
|
||||
const curve25519_public_key_t *curve25519_key,
|
||||
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_dup(extend_info_t *info);
|
||||
void extend_info_free(extend_info_t *info);
|
||||
|
@ -1577,8 +1577,8 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn,
|
||||
return -1;
|
||||
}
|
||||
extend_info = extend_info_new(conn->chosen_exit_name+1,
|
||||
digest, NULL, &addr,
|
||||
conn->socks_request->port);
|
||||
digest, NULL, NULL, &addr,
|
||||
conn->socks_request->port);
|
||||
} else {
|
||||
/* We will need an onion key for the router, and we
|
||||
* don't have one. Refuse or relax requirements. */
|
||||
|
@ -383,6 +383,7 @@ static config_var_t option_vars_[] = {
|
||||
V(UseBridges, BOOL, "0"),
|
||||
V(UseEntryGuards, BOOL, "1"),
|
||||
V(UseMicrodescriptors, AUTOBOOL, "auto"),
|
||||
V(UseNTorHandshake, AUTOBOOL, "auto"),
|
||||
V(User, STRING, NULL),
|
||||
V(UserspaceIOCPBuffers, BOOL, "0"),
|
||||
VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
|
||||
|
@ -1502,7 +1502,7 @@ routerset_contains_bridge(const routerset_t *routerset,
|
||||
return 0;
|
||||
|
||||
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);
|
||||
extend_info_free(extinfo);
|
||||
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
|
||||
* each router when the GeoIP database is reloaded, and on all new routers. */
|
||||
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);
|
||||
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);
|
||||
int node_has_curve25519_onion_key(const node_t *node);
|
||||
|
||||
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
|
||||
* a stream before it has sent a CONNECTED cell. */
|
||||
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_exitsummary:1; /**< The vote/consensus had exit summaries */
|
||||
@ -3799,6 +3802,8 @@ typedef struct {
|
||||
|
||||
int IPv6Exit; /**< Do we support exiting to IPv6 addresses? */
|
||||
|
||||
/** Autobool: should we use the ntor handshake if we can? */
|
||||
int UseNTorHandshake;
|
||||
} or_options_t;
|
||||
|
||||
/** 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);
|
||||
if (origin_circ->remaining_relay_early_cells > 0 &&
|
||||
(relay_command == RELAY_COMMAND_EXTEND ||
|
||||
relay_command == RELAY_COMMAND_EXTEND2 ||
|
||||
cpath_layer != origin_circ->cpath)) {
|
||||
/* 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
|
||||
@ -585,7 +586,8 @@ relay_send_command_from_edge(streamid_t stream_id, circuit_t *circ,
|
||||
* task 878. */
|
||||
origin_circ->relay_early_commands[
|
||||
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
|
||||
* commands have been sent as RELAY_EARLY cells before; helps debug
|
||||
* task 878. */
|
||||
|
@ -1071,7 +1071,8 @@ extend_info_from_router(const routerinfo_t *r)
|
||||
|
||||
router_get_prim_orport(r, &ap);
|
||||
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.
|
||||
|
@ -2188,6 +2188,8 @@ routerstatus_parse_entry_from_string(memarea_t *area,
|
||||
tor_version_supports_microdescriptors(tok->args[0]);
|
||||
rs->version_supports_optimistic_data =
|
||||
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) {
|
||||
vote_rs->version = tor_strdup(tok->args[0]);
|
||||
|
Loading…
Reference in New Issue
Block a user