Merge branch 'tor-github/pr/1968'

This commit is contained in:
David Goulet
2020-07-02 14:18:00 -04:00
37 changed files with 560 additions and 332 deletions
+1
View File
@@ -145,6 +145,7 @@ problem function-size /src/core/or/connection_or.c:connection_or_group_set_badne
problem function-size /src/core/or/connection_or.c:connection_or_client_learned_peer_id() 142
problem dependency-violation /src/core/or/connection_or.c 21
problem dependency-violation /src/core/or/dos.c 6
problem dependency-violation /src/core/or/extendinfo.c 6
problem dependency-violation /src/core/or/onion.c 2
problem file-size /src/core/or/or.h 1150
problem include-count /src/core/or/or.h 48
+1 -1
View File
@@ -31,7 +31,7 @@
**/
#include "core/or/or.h"
#include "core/or/circuitbuild.h"
#include "core/or/extendinfo.h"
#include "core/crypto/onion_crypto.h"
#include "core/crypto/onion_fast.h"
#include "core/crypto/onion_ntor.h"
+4 -4
View File
@@ -63,10 +63,10 @@
#include "trunnel/channelpadding_negotiation.h"
#include "trunnel/netinfo.h"
#include "core/or/channelpadding.h"
#include "core/or/extendinfo.h"
#include "core/or/cell_st.h"
#include "core/or/cell_queue_st.h"
#include "core/or/extend_info_st.h"
#include "core/or/or_connection_st.h"
#include "core/or/or_handshake_certs_st.h"
#include "core/or/or_handshake_state_st.h"
@@ -702,9 +702,9 @@ channel_tls_matches_extend_info_method(channel_t *chan,
return 0;
}
return (tor_addr_eq(&(extend_info->addr),
&(TO_CONN(tlschan->conn)->addr)) &&
(extend_info->port == TO_CONN(tlschan->conn)->port));
return extend_info_has_orport(extend_info,
&TO_CONN(tlschan->conn)->addr,
TO_CONN(tlschan->conn)->port);
}
/**
+44 -234
View File
@@ -45,6 +45,7 @@
#include "core/or/command.h"
#include "core/or/connection_edge.h"
#include "core/or/connection_or.h"
#include "core/or/extendinfo.h"
#include "core/or/onion.h"
#include "core/or/ocirc_event.h"
#include "core/or/policies.h"
@@ -78,9 +79,6 @@
#include "feature/nodelist/node_st.h"
#include "core/or/or_circuit_st.h"
#include "core/or/origin_circuit_st.h"
#include "feature/nodelist/microdesc_st.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerstatus_st.h"
static int circuit_send_first_onion_skin(origin_circuit_t *circ);
static int circuit_build_no_more_hops(origin_circuit_t *circ);
@@ -96,13 +94,17 @@ static const node_t *choose_good_middle_server(uint8_t purpose,
* callbacks.
*/
MOCK_IMPL(channel_t *,
channel_connect_for_circuit,(const tor_addr_t *addr, uint16_t port,
const char *id_digest,
const struct ed25519_public_key_t *ed_id))
channel_connect_for_circuit,(const extend_info_t *ei))
{
channel_t *chan;
chan = channel_connect(addr, port, id_digest, ed_id);
const tor_addr_port_t *orport = extend_info_pick_orport(ei);
if (!orport)
return NULL;
const char *id_digest = ei->identity_digest;
const ed25519_public_key_t *ed_id = &ei->ed_identity;
chan = channel_connect(&orport->addr, orport->port, id_digest, ed_id);
if (chan) command_setup_channel(chan);
return chan;
@@ -550,7 +552,7 @@ circuit_handle_first_hop(origin_circuit_t *circ)
* - the address is internal, and
* - we're not connecting to a configured bridge, and
* - we're not configured to allow extends to private addresses. */
if (tor_addr_is_internal(&firsthop->extend_info->addr, 0) &&
if (extend_info_any_orport_addr_is_internal(firsthop->extend_info) &&
!extend_info_is_a_configured_bridge(firsthop->extend_info) &&
!options->ExtendAllowPrivateAddresses) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
@@ -559,19 +561,15 @@ circuit_handle_first_hop(origin_circuit_t *circ)
}
/* now see if we're already connected to the first OR in 'route' */
log_debug(LD_CIRC,"Looking for firsthop '%s'",
fmt_addrport(&firsthop->extend_info->addr,
firsthop->extend_info->port));
/* We'll cleanup this code in #33220, when we add an IPv6 address to
* extend_info_t. */
const bool addr_is_ipv4 =
(tor_addr_family(&firsthop->extend_info->addr) == AF_INET);
const tor_addr_port_t *orport4 =
extend_info_get_orport(firsthop->extend_info, AF_INET);
const tor_addr_port_t *orport6 =
extend_info_get_orport(firsthop->extend_info, AF_INET6);
n_chan = channel_get_for_extend(
firsthop->extend_info->identity_digest,
&firsthop->extend_info->ed_identity,
addr_is_ipv4 ? &firsthop->extend_info->addr : NULL,
addr_is_ipv4 ? NULL : &firsthop->extend_info->addr,
orport4 ? &orport4->addr : NULL,
orport6 ? &orport6->addr : NULL,
&msg,
&should_launch);
@@ -583,11 +581,7 @@ circuit_handle_first_hop(origin_circuit_t *circ)
circ->base_.n_hop = extend_info_dup(firsthop->extend_info);
if (should_launch) {
n_chan = channel_connect_for_circuit(
&firsthop->extend_info->addr,
firsthop->extend_info->port,
firsthop->extend_info->identity_digest,
&firsthop->extend_info->ed_identity);
n_chan = channel_connect_for_circuit(firsthop->extend_info);
if (!n_chan) { /* connect failed, forget the whole thing */
log_info(LD_CIRC,"connect to firsthop failed. Closing.");
return -END_CIRC_REASON_CONNECTFAILED;
@@ -605,7 +599,8 @@ circuit_handle_first_hop(origin_circuit_t *circ)
tor_assert(!circ->base_.n_hop);
circ->base_.n_chan = n_chan;
circuit_chan_publish(circ, n_chan);
log_debug(LD_CIRC,"Conn open. Delivering first onion skin.");
log_debug(LD_CIRC,"Conn open for %s. Delivering first onion skin.",
safe_str_client(extend_info_describe(firsthop->extend_info)));
if ((err_reason = circuit_send_next_onion_skin(circ)) < 0) {
log_info(LD_CIRC,"circuit_send_next_onion_skin failed.");
circ->base_.n_chan = NULL;
@@ -1078,42 +1073,40 @@ circuit_send_intermediate_onion_skin(origin_circuit_t *circ,
crypt_path_t *hop)
{
int len;
int family = tor_addr_family(&hop->extend_info->addr);
extend_cell_t ec;
memset(&ec, 0, sizeof(ec));
log_debug(LD_CIRC,"starting to send subsequent skin.");
/* Relays and bridges can send IPv6 extends. But for clients, it's an
* obvious version distinguisher. */
if (server_mode(get_options())) {
if (family != AF_INET && family != AF_INET6) {
log_warn(LD_BUG, "Server trying to extend to an invalid address "
"family.");
return - END_CIRC_REASON_INTERNAL;
}
} else {
if (family != AF_INET) {
log_warn(LD_BUG, "Client trying to extend to a non-IPv4 address.");
return - END_CIRC_REASON_INTERNAL;
}
}
const bool include_ipv6 = server_mode(get_options());
memset(&ec, 0, sizeof(ec));
tor_addr_make_unspec(&ec.orport_ipv4.addr);
tor_addr_make_unspec(&ec.orport_ipv6.addr);
log_debug(LD_CIRC,"starting to send subsequent skin.");
circuit_pick_extend_handshake(&ec.cell_type,
&ec.create_cell.cell_type,
&ec.create_cell.handshake_type,
hop->extend_info);
/* At the moment, extend_info only has one ORPort address. We'll add a
* second address in #34069, to support dual-stack extend cells. */
if (family == AF_INET) {
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);
} else {
tor_addr_copy(&ec.orport_ipv6.addr, &hop->extend_info->addr);
ec.orport_ipv6.port = hop->extend_info->port;
tor_addr_make_unspec(&ec.orport_ipv4.addr);
const tor_addr_port_t *orport4 =
extend_info_get_orport(hop->extend_info, AF_INET);
const tor_addr_port_t *orport6 =
extend_info_get_orport(hop->extend_info, AF_INET6);
int n_addrs_set = 0;
if (orport4) {
tor_addr_copy(&ec.orport_ipv4.addr, &orport4->addr);
ec.orport_ipv4.port = orport4->port;
++n_addrs_set;
}
if (orport6 && include_ipv6) {
tor_addr_copy(&ec.orport_ipv6.addr, &orport6->addr);
ec.orport_ipv6.port = orport6->port;
++n_addrs_set;
}
if (n_addrs_set == 0) {
log_warn(LD_BUG, "No supported address family found in extend_info.");
return - END_CIRC_REASON_INTERNAL;
}
memcpy(ec.node_id, hop->extend_info->identity_digest, DIGEST_LEN);
/* Set the ED25519 identity too -- it will only get included
@@ -2462,143 +2455,6 @@ onion_extend_cpath(origin_circuit_t *circ)
return 0;
}
/** Allocate a new extend_info object based on the various arguments. */
extend_info_t *
extend_info_new(const char *nickname,
const char *rsa_id_digest,
const ed25519_public_key_t *ed_id,
crypto_pk_t *onion_key,
const curve25519_public_key_t *ntor_key,
const tor_addr_t *addr, uint16_t port)
{
extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
memcpy(info->identity_digest, rsa_id_digest, DIGEST_LEN);
if (ed_id && !ed25519_public_key_is_zero(ed_id))
memcpy(&info->ed_identity, ed_id, sizeof(ed25519_public_key_t));
if (nickname)
strlcpy(info->nickname, nickname, sizeof(info->nickname));
if (onion_key)
info->onion_key = crypto_pk_dup_key(onion_key);
if (ntor_key)
memcpy(&info->curve25519_onion_key, ntor_key,
sizeof(curve25519_public_key_t));
tor_addr_copy(&info->addr, addr);
info->port = port;
return info;
}
/** Allocate and return a new extend_info that can be used to build a
* circuit to or through the node <b>node</b>. Use the primary address
* of the node (i.e. its IPv4 address) unless
* <b>for_direct_connect</b> is true, in which case the preferred
* address is used instead. May return NULL if there is not enough
* info about <b>node</b> to extend to it--for example, if the preferred
* routerinfo_t or microdesc_t is missing, or if for_direct_connect is
* true and none of the node's addresses is allowed by tor's firewall
* and IP version config.
**/
extend_info_t *
extend_info_from_node(const node_t *node, int for_direct_connect)
{
crypto_pk_t *rsa_pubkey = NULL;
extend_info_t *info = NULL;
tor_addr_port_t ap;
int valid_addr = 0;
if (!node_has_preferred_descriptor(node, for_direct_connect)) {
return NULL;
}
/* Choose a preferred address first, but fall back to an allowed address. */
if (for_direct_connect)
fascist_firewall_choose_address_node(node, FIREWALL_OR_CONNECTION, 0, &ap);
else {
node_get_prim_orport(node, &ap);
}
valid_addr = tor_addr_port_is_valid_ap(&ap, 0);
if (valid_addr)
log_debug(LD_CIRC, "using %s for %s",
fmt_addrport(&ap.addr, ap.port),
node->ri ? node->ri->nickname : node->rs->nickname);
else
log_warn(LD_CIRC, "Could not choose valid address for %s",
node->ri ? node->ri->nickname : node->rs->nickname);
/* Every node we connect or extend to must support ntor */
if (!node_has_curve25519_onion_key(node)) {
log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
"Attempted to create extend_info for a node that does not support "
"ntor: %s", node_describe(node));
return NULL;
}
const ed25519_public_key_t *ed_pubkey = NULL;
/* Don't send the ed25519 pubkey unless the target node actually supports
* authenticating with it. */
if (node_supports_ed25519_link_authentication(node, 0)) {
log_info(LD_CIRC, "Including Ed25519 ID for %s", node_describe(node));
ed_pubkey = node_get_ed25519_id(node);
} else if (node_get_ed25519_id(node)) {
log_info(LD_CIRC, "Not including the ed25519 ID for %s, since it won't "
"be able to authenticate it.",
node_describe(node));
}
/* Retrieve the curve25519 pubkey. */
const curve25519_public_key_t *curve_pubkey =
node_get_curve25519_onion_key(node);
rsa_pubkey = node_get_rsa_onion_key(node);
if (valid_addr && node->ri) {
info = extend_info_new(node->ri->nickname,
node->identity,
ed_pubkey,
rsa_pubkey,
curve_pubkey,
&ap.addr,
ap.port);
} else if (valid_addr && node->rs && node->md) {
info = extend_info_new(node->rs->nickname,
node->identity,
ed_pubkey,
rsa_pubkey,
curve_pubkey,
&ap.addr,
ap.port);
}
crypto_pk_free(rsa_pubkey);
return info;
}
/** Release storage held by an extend_info_t struct. */
void
extend_info_free_(extend_info_t *info)
{
if (!info)
return;
crypto_pk_free(info->onion_key);
tor_free(info);
}
/** Allocate and return a new extend_info_t with the same contents as
* <b>info</b>. */
extend_info_t *
extend_info_dup(extend_info_t *info)
{
extend_info_t *newinfo;
tor_assert(info);
newinfo = tor_malloc(sizeof(extend_info_t));
memcpy(newinfo, info, sizeof(extend_info_t));
if (info->onion_key)
newinfo->onion_key = crypto_pk_dup_key(info->onion_key);
else
newinfo->onion_key = NULL;
return newinfo;
}
/** Return the node_t for the chosen exit router in <b>state</b>.
* If there is no chosen exit, or if we don't know the node_t for
* the chosen exit, return NULL.
@@ -2634,43 +2490,6 @@ build_state_get_exit_nickname(cpath_build_state_t *state)
return state->chosen_exit->nickname;
}
/** Return true iff the given address can be used to extend to. */
int
extend_info_addr_is_allowed(const tor_addr_t *addr)
{
tor_assert(addr);
/* Check if we have a private address and if we can extend to it. */
if ((tor_addr_is_internal(addr, 0) || tor_addr_is_multicast(addr)) &&
!get_options()->ExtendAllowPrivateAddresses) {
goto disallow;
}
/* Allowed! */
return 1;
disallow:
return 0;
}
/* Does ei have a valid TAP key? */
int
extend_info_supports_tap(const extend_info_t* ei)
{
tor_assert(ei);
/* Valid TAP keys are not NULL */
return ei->onion_key != NULL;
}
/* Does ei have a valid ntor key? */
int
extend_info_supports_ntor(const extend_info_t* ei)
{
tor_assert(ei);
/* Valid ntor keys have at least one non-zero byte */
return !fast_mem_is_zero(
(const char*)ei->curve25519_onion_key.public_key,
CURVE25519_PUBKEY_LEN);
}
/* Is circuit purpose allowed to use the deprecated TAP encryption protocol?
* The hidden service protocol still uses TAP for some connections, because
* ntor onion keys aren't included in HS descriptors or INTRODUCE cells. */
@@ -2705,15 +2524,6 @@ circuit_has_usable_onion_key(const origin_circuit_t *circ)
circuit_can_use_tap(circ));
}
/* Does ei have an onion key which it would prefer to use?
* Currently, we prefer ntor keys*/
int
extend_info_has_preferred_onion_key(const extend_info_t* ei)
{
tor_assert(ei);
return extend_info_supports_ntor(ei);
}
/** Find the circuits that are waiting to find out whether their guards are
* usable, and if any are ready to become usable, mark them open and try
* attaching streams as appropriate. */
+1 -22
View File
@@ -42,23 +42,8 @@ MOCK_DECL(int, circuit_all_predicted_ports_handled, (time_t now,
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);
extend_info_t *extend_info_new(const char *nickname,
const char *rsa_id_digest,
const struct ed25519_public_key_t *ed_id,
crypto_pk_t *onion_key,
const struct curve25519_public_key_t *ntor_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);
#define extend_info_free(info) \
FREE_AND_NULL(extend_info_t, extend_info_free_, (info))
int extend_info_addr_is_allowed(const tor_addr_t *addr);
int extend_info_supports_tap(const extend_info_t* ei);
int extend_info_supports_ntor(const extend_info_t* ei);
int circuit_can_use_tap(const origin_circuit_t *circ);
int circuit_has_usable_onion_key(const origin_circuit_t *circ);
int extend_info_has_preferred_onion_key(const extend_info_t* ei);
const uint8_t *build_state_get_exit_rsa_id(cpath_build_state_t *state);
MOCK_DECL(const node_t *,
build_state_get_exit_node,(cpath_build_state_t *state));
@@ -71,13 +56,7 @@ const node_t *choose_good_entry_server(uint8_t purpose,
struct circuit_guard_state_t **guard_state_out);
void circuit_upgrade_circuits_from_guard_wait(void);
struct ed25519_public_key_t;
MOCK_DECL(channel_t *,
channel_connect_for_circuit,(const tor_addr_t *addr,
uint16_t port,
const char *id_digest,
const struct ed25519_public_key_t *ed_id));
MOCK_DECL(channel_t *, channel_connect_for_circuit,(const extend_info_t *ei));
struct create_cell_t;
MOCK_DECL(int,
+1
View File
@@ -64,6 +64,7 @@
#include "core/or/circuitstats.h"
#include "core/or/circuitpadding.h"
#include "core/or/crypt_path.h"
#include "core/or/extendinfo.h"
#include "core/mainloop/connection.h"
#include "app/config/config.h"
#include "core/or/connection_edge.h"
+3 -2
View File
@@ -37,6 +37,7 @@
#include "core/or/circuituse.h"
#include "core/or/circuitpadding.h"
#include "core/or/connection_edge.h"
#include "core/or/extendinfo.h"
#include "core/or/policies.h"
#include "feature/client/addressmap.h"
#include "feature/client/bridges.h"
@@ -202,8 +203,8 @@ circuit_is_acceptable(const origin_circuit_t *origin_circ,
const int family = tor_addr_parse(&addr,
conn->socks_request->address);
if (family < 0 ||
!tor_addr_eq(&build_state->chosen_exit->addr, &addr) ||
build_state->chosen_exit->port != conn->socks_request->port)
!extend_info_has_orport(build_state->chosen_exit, &addr,
conn->socks_request->port))
return 0;
}
}
+3 -2
View File
@@ -70,6 +70,7 @@
#include "core/or/circuitpadding.h"
#include "core/or/connection_edge.h"
#include "core/or/connection_or.h"
#include "core/or/extendinfo.h"
#include "core/or/policies.h"
#include "core/or/reasons.h"
#include "core/or/relay.h"
@@ -1444,8 +1445,8 @@ connection_ap_fail_onehop(const char *failed_digest,
continue;
}
if (tor_addr_parse(&addr, entry_conn->socks_request->address)<0 ||
!tor_addr_eq(&build_state->chosen_exit->addr, &addr) ||
build_state->chosen_exit->port != entry_conn->socks_request->port)
!extend_info_has_orport(build_state->chosen_exit, &addr,
entry_conn->socks_request->port))
continue;
}
log_info(LD_APP, "Closing one-hop stream to '%s/%s' because the OR conn "
+1 -1
View File
@@ -30,6 +30,7 @@
#include "core/crypto/onion_crypto.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/extendinfo.h"
#include "lib/crypt_ops/crypto_dh.h"
#include "lib/crypt_ops/crypto_util.h"
@@ -259,4 +260,3 @@ cpath_get_n_hops(crypt_path_t **head_ptr)
}
#endif /* defined(TOR_UNIT_TESTS) */
+12 -4
View File
@@ -15,9 +15,14 @@
#include "lib/crypt_ops/crypto_curve25519.h"
#include "lib/crypt_ops/crypto_ed25519.h"
/** Largest number of addresses we handle in an extend_info.
*
* More are permitted in an EXTEND cell, but we won't handle them. */
#define EXTEND_INFO_MAX_ADDRS 2
/** Information on router used when extending a circuit. We don't need a
* full routerinfo_t to extend: we only need addr:port:keyid to build an OR
* connection, and onion_key to create the onionskin. Note that for onehop
* connection, and onion_key to create the onionskin. Note that for one-hop
* general-purpose tunnels, the onion_key is NULL. */
struct extend_info_t {
char nickname[MAX_HEX_NICKNAME_LEN+1]; /**< This router's nickname for
@@ -26,9 +31,12 @@ struct extend_info_t {
char identity_digest[DIGEST_LEN];
/** Ed25519 identity for this router, if any. */
ed25519_public_key_t ed_identity;
uint16_t port; /**< OR port. */
tor_addr_t addr; /**< IP address. */
crypto_pk_t *onion_key; /**< Current onionskin key. */
/** IP/Port values for this hop's ORPort(s). Any unused values are set
* to a null address. */
tor_addr_port_t orports[EXTEND_INFO_MAX_ADDRS];
/** TAP onion key for this hop. */
crypto_pk_t *onion_key;
/** Ntor onion key for this hop. */
curve25519_public_key_t curve25519_onion_key;
};
+305
View File
@@ -0,0 +1,305 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2020, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* @file extendinfo.c
* @brief Functions for creating and using extend_info_t objects.
*
* An extend_info_t is the information we hold about a relay in order to
* extend a circuit to it.
**/
#include "core/or/or.h"
#include "core/or/extendinfo.h"
#include "app/config/config.h"
#include "core/or/policies.h"
#include "feature/nodelist/describe.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/extend_info_st.h"
#include "feature/nodelist/node_st.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerstatus_st.h"
/** Allocate a new extend_info object based on the various arguments. */
extend_info_t *
extend_info_new(const char *nickname,
const char *rsa_id_digest,
const ed25519_public_key_t *ed_id,
crypto_pk_t *onion_key,
const curve25519_public_key_t *ntor_key,
const tor_addr_t *addr, uint16_t port)
{
extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
if (rsa_id_digest)
memcpy(info->identity_digest, rsa_id_digest, DIGEST_LEN);
if (ed_id && !ed25519_public_key_is_zero(ed_id))
memcpy(&info->ed_identity, ed_id, sizeof(ed25519_public_key_t));
if (nickname)
strlcpy(info->nickname, nickname, sizeof(info->nickname));
if (onion_key)
info->onion_key = crypto_pk_dup_key(onion_key);
if (ntor_key)
memcpy(&info->curve25519_onion_key, ntor_key,
sizeof(curve25519_public_key_t));
for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
tor_addr_make_unspec(&info->orports[i].addr);
}
if (addr) {
extend_info_add_orport(info, addr, port);
}
return info;
}
/**
* Add another address:port pair to a given extend_info_t, if there is
* room. Return 0 on success, -1 on failure.
**/
int
extend_info_add_orport(extend_info_t *ei,
const tor_addr_t *addr,
uint16_t port)
{
for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
if (tor_addr_is_unspec(&ei->orports[i].addr)) {
tor_addr_copy(&ei->orports[i].addr, addr);
ei->orports[i].port = port;
return 0;
}
}
return -1;
}
/** Allocate and return a new extend_info that can be used to build a
* circuit to or through the node <b>node</b>. Use the primary address
* of the node (i.e. its IPv4 address) unless
* <b>for_direct_connect</b> is true, in which case the preferred
* address is used instead. May return NULL if there is not enough
* info about <b>node</b> to extend to it--for example, if the preferred
* routerinfo_t or microdesc_t is missing, or if for_direct_connect is
* true and none of the node's addresses is allowed by tor's firewall
* and IP version config.
**/
extend_info_t *
extend_info_from_node(const node_t *node, int for_direct_connect)
{
crypto_pk_t *rsa_pubkey = NULL;
extend_info_t *info = NULL;
tor_addr_port_t ap;
int valid_addr = 0;
if (!node_has_preferred_descriptor(node, for_direct_connect)) {
return NULL;
}
/* Choose a preferred address first, but fall back to an allowed address. */
if (for_direct_connect)
fascist_firewall_choose_address_node(node, FIREWALL_OR_CONNECTION, 0, &ap);
else {
node_get_prim_orport(node, &ap);
}
valid_addr = tor_addr_port_is_valid_ap(&ap, 0);
if (valid_addr)
log_debug(LD_CIRC, "using %s for %s",
fmt_addrport(&ap.addr, ap.port),
node->ri ? node->ri->nickname : node->rs->nickname);
else
log_warn(LD_CIRC, "Could not choose valid address for %s",
node->ri ? node->ri->nickname : node->rs->nickname);
/* Every node we connect or extend to must support ntor */
if (!node_has_curve25519_onion_key(node)) {
log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
"Attempted to create extend_info for a node that does not support "
"ntor: %s", node_describe(node));
return NULL;
}
const ed25519_public_key_t *ed_pubkey = NULL;
/* Don't send the ed25519 pubkey unless the target node actually supports
* authenticating with it. */
if (node_supports_ed25519_link_authentication(node, 0)) {
log_info(LD_CIRC, "Including Ed25519 ID for %s", node_describe(node));
ed_pubkey = node_get_ed25519_id(node);
} else if (node_get_ed25519_id(node)) {
log_info(LD_CIRC, "Not including the ed25519 ID for %s, since it won't "
"be able to authenticate it.",
node_describe(node));
}
/* Retrieve the curve25519 pubkey. */
const curve25519_public_key_t *curve_pubkey =
node_get_curve25519_onion_key(node);
rsa_pubkey = node_get_rsa_onion_key(node);
if (valid_addr && node->ri) {
info = extend_info_new(node->ri->nickname,
node->identity,
ed_pubkey,
rsa_pubkey,
curve_pubkey,
&ap.addr,
ap.port);
} else if (valid_addr && node->rs && node->md) {
info = extend_info_new(node->rs->nickname,
node->identity,
ed_pubkey,
rsa_pubkey,
curve_pubkey,
&ap.addr,
ap.port);
}
crypto_pk_free(rsa_pubkey);
return info;
}
/** Release storage held by an extend_info_t struct. */
void
extend_info_free_(extend_info_t *info)
{
if (!info)
return;
crypto_pk_free(info->onion_key);
tor_free(info);
}
/** Allocate and return a new extend_info_t with the same contents as
* <b>info</b>. */
extend_info_t *
extend_info_dup(extend_info_t *info)
{
extend_info_t *newinfo;
tor_assert(info);
newinfo = tor_malloc(sizeof(extend_info_t));
memcpy(newinfo, info, sizeof(extend_info_t));
if (info->onion_key)
newinfo->onion_key = crypto_pk_dup_key(info->onion_key);
else
newinfo->onion_key = NULL;
return newinfo;
}
/* Does ei have a valid TAP key? */
int
extend_info_supports_tap(const extend_info_t* ei)
{
tor_assert(ei);
/* Valid TAP keys are not NULL */
return ei->onion_key != NULL;
}
/* Does ei have a valid ntor key? */
int
extend_info_supports_ntor(const extend_info_t* ei)
{
tor_assert(ei);
/* Valid ntor keys have at least one non-zero byte */
return !fast_mem_is_zero(
(const char*)ei->curve25519_onion_key.public_key,
CURVE25519_PUBKEY_LEN);
}
/* Does ei have an onion key which it would prefer to use?
* Currently, we prefer ntor keys*/
int
extend_info_has_preferred_onion_key(const extend_info_t* ei)
{
tor_assert(ei);
return extend_info_supports_ntor(ei);
}
/** Return true iff the given address can be used to extend to. */
int
extend_info_addr_is_allowed(const tor_addr_t *addr)
{
tor_assert(addr);
/* Check if we have a private address and if we can extend to it. */
if ((tor_addr_is_internal(addr, 0) || tor_addr_is_multicast(addr)) &&
!get_options()->ExtendAllowPrivateAddresses) {
goto disallow;
}
/* Allowed! */
return 1;
disallow:
return 0;
}
/**
* Return true if @a addr : @a port is a listed ORPort in @a ei.
**/
bool
extend_info_has_orport(const extend_info_t *ei,
const tor_addr_t *addr, uint16_t port)
{
IF_BUG_ONCE(ei == NULL) {
return false;
}
for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
const tor_addr_port_t *ei_ap = &ei->orports[i];
if (tor_addr_eq(&ei_ap->addr, addr) && ei_ap->port == port)
return true;
}
return false;
}
/**
* If the extend_info @a ei has an orport of the chosen family, then return
* that orport. Otherwise, return NULL.
**/
const tor_addr_port_t *
extend_info_get_orport(const extend_info_t *ei, int family)
{
for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
if (tor_addr_is_unspec(&ei->orports[i].addr))
continue;
if (tor_addr_family(&ei->orports[i].addr) == family)
return &ei->orports[i];
}
return NULL;
}
/**
* Chose an addr_port_t within @a ei to connect to.
**/
const tor_addr_port_t *
extend_info_pick_orport(const extend_info_t *ei)
{
// XXXX S55 -- for now, we just pick the first. We'll work on
// XXXX more choices as we move forward.
IF_BUG_ONCE(!ei) {
return NULL;
}
if (tor_addr_is_unspec(&ei->orports[0].addr)) {
return NULL;
}
return &ei->orports[0];
}
/**
* Return true if any orport address in @a ei is an internal address.
**/
bool
extend_info_any_orport_addr_is_internal(const extend_info_t *ei)
{
IF_BUG_ONCE(ei == NULL) {
return false;
}
for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
if (! tor_addr_is_unspec(&ei->orports[i].addr) &&
tor_addr_is_internal(&ei->orports[i].addr, 0))
return true;
}
return false;
}
+40
View File
@@ -0,0 +1,40 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2020, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* @file extendinfo.h
* @brief Header for core/or/extendinfo.c
**/
#ifndef TOR_CORE_OR_EXTENDINFO_H
#define TOR_CORE_OR_EXTENDINFO_H
extend_info_t *extend_info_new(const char *nickname,
const char *rsa_id_digest,
const struct ed25519_public_key_t *ed_id,
crypto_pk_t *onion_key,
const struct curve25519_public_key_t *ntor_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);
#define extend_info_free(info) \
FREE_AND_NULL(extend_info_t, extend_info_free_, (info))
int extend_info_addr_is_allowed(const tor_addr_t *addr);
int extend_info_supports_tap(const extend_info_t* ei);
int extend_info_supports_ntor(const extend_info_t* ei);
int extend_info_has_preferred_onion_key(const extend_info_t* ei);
bool extend_info_has_orport(const extend_info_t *ei,
const tor_addr_t *addr, uint16_t port);
int extend_info_add_orport(extend_info_t *ei,
const tor_addr_t *addr,
uint16_t port);
const tor_addr_port_t *extend_info_get_orport(const extend_info_t *ei,
int family);
const tor_addr_port_t *extend_info_pick_orport(const extend_info_t *ei);
bool extend_info_any_orport_addr_is_internal(const extend_info_t *ei);
#endif /* !defined(TOR_CORE_OR_EXTENDINFO_H) */
+2
View File
@@ -18,6 +18,7 @@ LIBTOR_APP_A_SOURCES += \
src/core/or/connection_edge.c \
src/core/or/connection_or.c \
src/core/or/dos.c \
src/core/or/extendinfo.c \
src/core/or/onion.c \
src/core/or/ocirc_event.c \
src/core/or/or_periodic.c \
@@ -64,6 +65,7 @@ noinst_HEADERS += \
src/core/or/destroy_cell_queue_st.h \
src/core/or/dos.h \
src/core/or/edge_connection_st.h \
src/core/or/extendinfo.h \
src/core/or/half_edge_st.h \
src/core/or/entry_connection_st.h \
src/core/or/entry_port_cfg_st.h \
+1 -2
View File
@@ -48,8 +48,7 @@ typedef struct extend_cell_t {
uint8_t cell_type;
/** An IPv4 address and port for the node we're connecting to. */
tor_addr_port_t orport_ipv4;
/** An IPv6 address and port for the node we're connecting to. Not currently
* used. */
/** An IPv6 address and port for the node we're connecting to. */
tor_addr_port_t orport_ipv6;
/** Identity fingerprint of the node we're conecting to.*/
uint8_t node_id[DIGEST_LEN];
+1
View File
@@ -56,6 +56,7 @@
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/circuitpadding.h"
#include "core/or/extendinfo.h"
#include "lib/compress/compress.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
+16 -2
View File
@@ -259,12 +259,26 @@ addr_is_a_configured_bridge(const tor_addr_t *addr,
/** If we have a bridge configured whose digest matches
* <b>ei->identity_digest</b>, or a bridge with no known digest whose address
* matches <b>ei->addr</b>:<b>ei->port</b>, return 1. Else return 0.
* If <b>ei->onion_key</b> is NULL, check for address/port matches only. */
* If <b>ei->onion_key</b> is NULL, check for address/port matches only.
*
* Note that if the extend_info_t contains multiple addresses, we return true
* only if _every_ address is a bridge.
*/
int
extend_info_is_a_configured_bridge(const extend_info_t *ei)
{
const char *digest = ei->onion_key ? ei->identity_digest : NULL;
return addr_is_a_configured_bridge(&ei->addr, ei->port, digest);
const tor_addr_port_t *ap1 = NULL, *ap2 = NULL;
if (! tor_addr_is_null(&ei->orports[0].addr))
ap1 = &ei->orports[0];
if (! tor_addr_is_null(&ei->orports[1].addr))
ap2 = &ei->orports[1];
IF_BUG_ONCE(ap1 == NULL) {
return 0;
}
return addr_is_a_configured_bridge(&ap1->addr, ap1->port, digest) &&
(ap2 == NULL ||
addr_is_a_configured_bridge(&ap2->addr, ap2->port, digest));
}
/** Wrapper around get_configured_bridge_by_addr_port_digest() to look
+1
View File
@@ -21,6 +21,7 @@
#include "core/or/circuituse.h"
#include "core/or/connection_edge.h"
#include "core/or/circuitstats.h"
#include "core/or/extendinfo.h"
#include "feature/client/addressmap.h"
#include "feature/client/dnsserv.h"
#include "feature/client/entrynodes.h"
+1
View File
@@ -16,6 +16,7 @@
#include "core/or/policies.h"
#include "core/or/relay.h"
#include "core/or/crypt_path.h"
#include "core/or/extendinfo.h"
#include "feature/client/circpathbias.h"
#include "feature/hs/hs_cell.h"
#include "feature/hs/hs_circuit.h"
+1
View File
@@ -16,6 +16,7 @@
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/connection_edge.h"
#include "core/or/extendinfo.h"
#include "core/or/reasons.h"
#include "feature/client/circpathbias.h"
#include "feature/dirclient/dirclient.h"
+1
View File
@@ -16,6 +16,7 @@
#include "app/config/config.h"
#include "core/or/circuitbuild.h"
#include "core/or/policies.h"
#include "core/or/extendinfo.h"
#include "feature/dirauth/shared_random_state.h"
#include "feature/hs/hs_cache.h"
#include "feature/hs/hs_circuitmap.h"
+1
View File
@@ -16,6 +16,7 @@
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/extendinfo.h"
#include "core/or/relay.h"
#include "feature/client/circpathbias.h"
#include "feature/dirclient/dirclient.h"
+8 -2
View File
@@ -12,6 +12,7 @@
#define DESCRIBE_PRIVATE
#include "core/or/or.h"
#include "core/or/extendinfo.h"
#include "feature/nodelist/describe.h"
#include "core/or/extend_info_st.h"
@@ -208,11 +209,16 @@ extend_info_describe(const extend_info_t *ei)
if (!ei)
return "<null>";
const tor_addr_port_t *ap4 = extend_info_get_orport(ei, AF_INET);
const tor_addr_port_t *ap6 = extend_info_get_orport(ei, AF_INET6);
uint32_t addr4 = ap4 ? tor_addr_to_ipv4h(&ap4->addr) : 0;
const tor_addr_t *addr6 = ap6 ? &ap6->addr : NULL;
return format_node_description(buf,
ei->identity_digest,
ei->nickname,
&ei->addr,
0);
addr6,
addr4);
}
/** Set <b>buf</b> (which must have MAX_VERBOSE_NICKNAME_LEN+1 bytes) to the
+13 -6
View File
@@ -306,12 +306,19 @@ routerset_add_unknown_ccs(routerset_t **setp, int only_if_some_cc_set)
int
routerset_contains_extendinfo(const routerset_t *set, const extend_info_t *ei)
{
return routerset_contains(set,
&ei->addr,
ei->port,
ei->nickname,
ei->identity_digest,
-1 /*country*/);
const tor_addr_port_t *ap1 = NULL, *ap2 = NULL;
if (! tor_addr_is_null(&ei->orports[0].addr))
ap1 = &ei->orports[0];
if (! tor_addr_is_null(&ei->orports[1].addr))
ap2 = &ei->orports[1];
return routerset_contains2(set,
ap1 ? &ap1->addr : NULL,
ap1 ? ap1->port : 0,
ap2 ? &ap2->addr : NULL,
ap2 ? ap2->port : 0,
ei->nickname,
ei->identity_digest,
-1 /*country*/);
}
/** Return true iff <b>ri</b> is in <b>set</b>. If country is <b>-1</b>, we
+2 -5
View File
@@ -33,6 +33,7 @@
#include "core/or/channel.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/extendinfo.h"
#include "core/or/onion.h"
#include "core/or/relay.h"
@@ -400,11 +401,7 @@ circuit_open_connection_for_extend(const struct extend_cell_t *ec,
if (should_launch) {
/* we should try to open a connection */
channel_t *n_chan = channel_connect_for_circuit(
&circ->n_hop->addr,
circ->n_hop->port,
circ->n_hop->identity_digest,
&circ->n_hop->ed_identity);
channel_t *n_chan = channel_connect_for_circuit(circ->n_hop);
if (!n_chan) {
log_info(LD_CIRC,"Launching n_chan failed. Closing circuit.");
circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED);
+4 -2
View File
@@ -24,6 +24,7 @@
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/crypt_path_st.h"
#include "core/or/extendinfo.h"
#include "core/or/extend_info_st.h"
#include "core/or/origin_circuit_st.h"
#include "core/or/relay.h"
@@ -255,14 +256,15 @@ router_do_orport_reachability_checks(const routerinfo_t *me,
* be NULL. */
if (ei) {
const char *family_name = fmt_af_family(family);
const tor_addr_port_t *ap = extend_info_get_orport(ei, family);
log_info(LD_CIRC, "Testing %s of my %s ORPort: %s.",
!orport_reachable ? "reachability" : "bandwidth",
family_name, fmt_addrport(&ei->addr, ei->port));
family_name, fmt_addrport_ap(ap));
if (!orport_reachable) {
/* This is only a 'reachability test' if we don't already think that
* the port is reachable. If we _do_ think it's reachable, then
* it counts as a 'bandwidth test'. */
inform_testing_reachability(&ei->addr, ei->port, false);
inform_testing_reachability(&ap->addr, ap->port, false);
}
circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei,
CIRCLAUNCH_NEED_CAPACITY|
+9 -2
View File
@@ -15,6 +15,7 @@
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/connection_edge.h"
#include "core/or/extendinfo.h"
#include "core/or/relay.h"
#include "feature/client/circpathbias.h"
#include "feature/control/control_events.h"
@@ -234,9 +235,15 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
/* version 2 format */
extend_info_t *extend_info = rendcirc->build_state->chosen_exit;
int klen;
const tor_addr_port_t *orport =
extend_info_get_orport(extend_info, AF_INET);
IF_BUG_ONCE(! orport) {
/* we should never put an IPv6 address here. */
goto perm_err;
}
/* nul pads */
set_uint32(tmp+v3_shift+1, tor_addr_to_ipv4n(&extend_info->addr));
set_uint16(tmp+v3_shift+5, htons(extend_info->port));
set_uint32(tmp+v3_shift+1, tor_addr_to_ipv4n(&orport->addr));
set_uint16(tmp+v3_shift+5, htons(orport->port));
memcpy(tmp+v3_shift+7, extend_info->identity_digest, DIGEST_LEN);
klen = crypto_pk_asn1_encode(extend_info->onion_key,
tmp+v3_shift+7+DIGEST_LEN+2,
+8 -2
View File
@@ -14,6 +14,7 @@
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/extendinfo.h"
#include "app/config/config.h"
#include "feature/control/control_events.h"
#include "lib/crypt_ops/crypto_rand.h"
@@ -233,7 +234,12 @@ rend_encode_v2_intro_points(char **encoded, rend_service_descriptor_t *desc)
goto done;
}
/* Assemble everything for this introduction point. */
address = tor_addr_to_str_dup(&info->addr);
const tor_addr_port_t *orport = extend_info_get_orport(info, AF_INET);
IF_BUG_ONCE(!orport) {
/* There must be an IPv4 address for v2 hs. */
goto done;
}
address = tor_addr_to_str_dup(&orport->addr);
res = tor_snprintf(unenc + unenc_written, unenc_len - unenc_written,
"introduction-point %s\n"
"ip-address %s\n"
@@ -242,7 +248,7 @@ rend_encode_v2_intro_points(char **encoded, rend_service_descriptor_t *desc)
"service-key\n%s",
id_base32,
address,
info->port,
orport->port,
onion_key,
service_key);
tor_free(address);
+12 -5
View File
@@ -10,6 +10,7 @@
**/
#include "core/or/or.h"
#include "core/or/extendinfo.h"
#include "feature/dirparse/parsecommon.h"
#include "feature/dirparse/sigcommon.h"
#include "feature/rend/rendcommon.h"
@@ -428,7 +429,8 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed,
}
/* Allocate new intro point and extend info. */
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
info = intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
info = intro->extend_info =
extend_info_new(NULL, NULL, NULL, NULL, NULL, NULL, 0);
/* Parse identifier. */
tok = find_by_keyword(tokens, R_IPO_IDENTIFIER);
if (base32_decode(info->identity_digest, DIGEST_LEN,
@@ -446,12 +448,13 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed,
info->identity_digest, DIGEST_LEN);
/* Parse IP address. */
tok = find_by_keyword(tokens, R_IPO_IP_ADDRESS);
if (tor_addr_parse(&info->addr, tok->args[0])<0) {
tor_addr_t addr;
if (tor_addr_parse(&addr, tok->args[0])<0) {
log_warn(LD_REND, "Could not parse introduction point address.");
rend_intro_point_free(intro);
goto err;
}
if (tor_addr_family(&info->addr) != AF_INET) {
if (tor_addr_family(&addr) != AF_INET) {
log_warn(LD_REND, "Introduction point address was not ipv4.");
rend_intro_point_free(intro);
goto err;
@@ -459,14 +462,18 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed,
/* Parse onion port. */
tok = find_by_keyword(tokens, R_IPO_ONION_PORT);
info->port = (uint16_t) tor_parse_long(tok->args[0],10,1,65535,
uint16_t port = (uint16_t) tor_parse_long(tok->args[0],10,1,65535,
&num_ok,NULL);
if (!info->port || !num_ok) {
if (!port || !num_ok) {
log_warn(LD_REND, "Introduction point onion port %s is invalid",
escaped(tok->args[0]));
rend_intro_point_free(intro);
goto err;
}
/* Add the address and port. */
extend_info_add_orport(info, &addr, port);
/* Parse onion key. */
tok = find_by_keyword(tokens, R_IPO_ONION_KEY);
if (!crypto_pk_public_exponent_ok(tok->key)) {
+12 -5
View File
@@ -16,6 +16,7 @@
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/extendinfo.h"
#include "core/or/policies.h"
#include "core/or/relay.h"
#include "core/or/crypt_path.h"
@@ -1831,8 +1832,11 @@ rend_service_use_direct_connection(const or_options_t* options,
/* We'll connect directly all reachable addresses, whether preferred or not.
* The prefer_ipv6 argument to fascist_firewall_allows_address_addr is
* ignored, because pref_only is 0. */
const tor_addr_port_t *ap = extend_info_get_orport(ei, AF_INET);
if (!ap)
return 0;
return (rend_service_allow_non_anonymous_connection(options) &&
fascist_firewall_allows_address_addr(&ei->addr, ei->port,
fascist_firewall_allows_address_addr(&ap->addr, ap->port,
FIREWALL_OR_CONNECTION, 0, 0));
}
@@ -2261,7 +2265,8 @@ find_rp_for_intro(const rend_intro_cell_t *intro,
/* Make sure the RP we are being asked to connect to is _not_ a private
* address unless it's allowed. Let's avoid to build a circuit to our
* second middle node and fail right after when extending to the RP. */
if (!extend_info_addr_is_allowed(&rp->addr)) {
const tor_addr_port_t *orport = extend_info_get_orport(rp, AF_INET);
if (! orport || !extend_info_addr_is_allowed(&orport->addr)) {
if (err_msg_out) {
tor_asprintf(&err_msg,
"Relay IP in INTRODUCE2 cell is private address.");
@@ -2530,9 +2535,11 @@ rend_service_parse_intro_for_v2(
goto err;
}
extend_info = tor_malloc_zero(sizeof(extend_info_t));
tor_addr_from_ipv4n(&extend_info->addr, get_uint32(buf + 1));
extend_info->port = ntohs(get_uint16(buf + 5));
extend_info = extend_info_new(NULL, NULL, NULL, NULL, NULL, NULL, 0);
tor_addr_t addr;
tor_addr_from_ipv4n(&addr, get_uint32(buf + 1));
uint16_t port = ntohs(get_uint16(buf + 5));
extend_info_add_orport(extend_info, &addr, port);
memcpy(extend_info->identity_digest, buf + 7, DIGEST_LEN);
extend_info->nickname[0] = '$';
base16_encode(extend_info->nickname + 1, sizeof(extend_info->nickname) - 1,
+10
View File
@@ -95,6 +95,7 @@ static inline uint32_t tor_addr_to_ipv4n(const tor_addr_t *a);
static inline uint32_t tor_addr_to_ipv4h(const tor_addr_t *a);
static inline uint32_t tor_addr_to_mapped_ipv4h(const tor_addr_t *a);
static inline sa_family_t tor_addr_family(const tor_addr_t *a);
static inline bool tor_addr_is_unspec(const tor_addr_t *a);
static inline const struct in_addr *tor_addr_to_in(const tor_addr_t *a);
static inline int tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u);
@@ -188,6 +189,15 @@ tor_addr_family(const tor_addr_t *a)
return a->family;
}
/**
* Return true if the address @a is in the UNSPEC family.
**/
static inline bool
tor_addr_is_unspec(const tor_addr_t *a)
{
return a->family == AF_UNSPEC;
}
/** Return an in_addr* equivalent to <b>a</b>, or NULL if <b>a</b> is not
* an IPv4 address. */
static inline const struct in_addr *
+9 -4
View File
@@ -2,6 +2,7 @@
/* See LICENSE for licensing information */
#include "core/or/or.h"
#include "core/or/extendinfo.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "test/test.h"
#include "feature/rend/rendcommon.h"
@@ -58,7 +59,8 @@ create_descriptor(rend_service_descriptor_t **generated, char **service_id,
for (i = 0; i < intro_points; i++) {
rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t));
crypto_pk_t *okey = pk_generate(2 + i);
intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
intro->extend_info =
extend_info_new(NULL, NULL, NULL, NULL, NULL, NULL, 0);
intro->extend_info->onion_key = okey;
crypto_pk_get_digest(intro->extend_info->onion_key,
intro->extend_info->identity_digest);
@@ -66,8 +68,12 @@ create_descriptor(rend_service_descriptor_t **generated, char **service_id,
base16_encode(intro->extend_info->nickname + 1,
sizeof(intro->extend_info->nickname) - 1,
intro->extend_info->identity_digest, DIGEST_LEN);
tor_addr_from_ipv4h(&intro->extend_info->addr, crypto_rand_int(65536));
intro->extend_info->port = 1 + crypto_rand_int(65535);
tor_addr_t addr;
uint16_t port;
/* Does not cover all IP addresses. */
tor_addr_from_ipv4h(&addr, crypto_rand_int(65536) + 1);
port = 1 + crypto_rand_int(65535);
extend_info_add_orport(intro->extend_info, &addr, port);
intro->intro_key = crypto_pk_dup_key(pk2);
smartlist_add((*generated)->intro_nodes, intro);
}
@@ -91,4 +97,3 @@ mock_rend_data(const char *onion_address)
DIGEST_LEN));
return rend_query;
}
+15 -6
View File
@@ -1,5 +1,5 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
->a * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2020, The Tor Project, Inc. */
/* See LICENSE for licensing information */
@@ -44,6 +44,7 @@
#include "lib/compress/compress.h"
#include "app/config/config.h"
#include "core/or/connection_edge.h"
#include "core/or/extendinfo.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendcache.h"
#include "feature/rend/rendparse.h"
@@ -564,7 +565,8 @@ test_rend_fns(void *arg)
for (i = 0; i < 3; i++) {
rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t));
crypto_pk_t *okey = pk_generate(2 + i);
intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
intro->extend_info =
extend_info_new(NULL, NULL, NULL, NULL, NULL, NULL, 0);
intro->extend_info->onion_key = okey;
crypto_pk_get_digest(intro->extend_info->onion_key,
intro->extend_info->identity_digest);
@@ -573,9 +575,12 @@ test_rend_fns(void *arg)
base16_encode(intro->extend_info->nickname + 1,
sizeof(intro->extend_info->nickname) - 1,
intro->extend_info->identity_digest, DIGEST_LEN);
tor_addr_t addr;
uint16_t port;
/* Does not cover all IP addresses. */
tor_addr_from_ipv4h(&intro->extend_info->addr, crypto_rand_int(65536));
intro->extend_info->port = 1 + crypto_rand_int(65535);
tor_addr_from_ipv4h(&addr, crypto_rand_int(65536) + 1);
port = 1 + crypto_rand_int(65535);
extend_info_add_orport(intro->extend_info, &addr, port);
intro->intro_key = crypto_pk_dup_key(pk2);
smartlist_add(generated->intro_nodes, intro);
}
@@ -613,8 +618,12 @@ test_rend_fns(void *arg)
tt_mem_op(gen_info->identity_digest,OP_EQ, par_info->identity_digest,
DIGEST_LEN);
tt_str_op(gen_info->nickname,OP_EQ, par_info->nickname);
tt_assert(tor_addr_eq(&gen_info->addr, &par_info->addr));
tt_int_op(gen_info->port,OP_EQ, par_info->port);
const tor_addr_port_t *a1, *a2;
a1 = extend_info_get_orport(gen_info, AF_INET);
a2 = extend_info_get_orport(par_info, AF_INET);
tt_assert(a1 && a2);
tt_assert(tor_addr_eq(&a1->addr, &a2->addr));
tt_int_op(a2->port,OP_EQ, a2->port);
}
rend_service_descriptor_free(parsed);
+7 -13
View File
@@ -1001,15 +1001,9 @@ mock_circuit_mark_for_close_(circuit_t *circ, int reason,
static int mock_channel_connect_calls = 0;
static channel_t *mock_channel_connect_nchan = NULL;
static channel_t *
mock_channel_connect_for_circuit(const tor_addr_t *addr,
uint16_t port,
const char *id_digest,
const struct ed25519_public_key_t *ed_id)
mock_channel_connect_for_circuit(const extend_info_t *ei)
{
(void)addr;
(void)port;
(void)id_digest;
(void)ed_id;
(void)ei;
mock_channel_connect_calls++;
return mock_channel_connect_nchan;
}
@@ -1683,14 +1677,14 @@ test_circuit_send_next_onion_skin(void *arg)
extend_info_t ipv6_hop;
memset(&ipv6_hop, 0, sizeof(ipv6_hop));
tor_addr_make_null(&ipv6_hop.addr, AF_INET6);
tor_addr_parse(&ipv6_hop.orports[0].addr, "1::2");
extend_info_t *multi_ipv6_hop[DEFAULT_ROUTE_LEN] = {&ipv6_hop,
&ipv6_hop,
&ipv6_hop};
extend_info_t ipv4_hop;
memset(&ipv4_hop, 0, sizeof(ipv4_hop));
tor_addr_make_null(&ipv4_hop.addr, AF_INET);
tor_addr_from_ipv4h(&ipv4_hop.orports[0].addr, 0x20304050);
extend_info_t *multi_ipv4_hop[DEFAULT_ROUTE_LEN] = {&ipv4_hop,
&ipv4_hop,
&ipv4_hop};
@@ -1743,7 +1737,7 @@ test_circuit_send_next_onion_skin(void *arg)
/* Fail because the address family is invalid */
tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
-END_CIRC_REASON_INTERNAL);
expect_log_msg("Client trying to extend to a non-IPv4 address.\n");
expect_log_msg("No supported address family found in extend_info.\n");
mock_clean_saved_logs();
/* Try an extend, but fail the server valid address check */
@@ -1757,7 +1751,7 @@ test_circuit_send_next_onion_skin(void *arg)
mock_circuit_deliver_create_cell_expect_direct = false;
tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
-END_CIRC_REASON_INTERNAL);
expect_log_msg("Server trying to extend to an invalid address family.\n");
expect_log_msg("No supported address family found in extend_info.\n");
mock_clean_saved_logs();
/* Try an extend, but fail in the client code, with an IPv6 address */
@@ -1771,7 +1765,7 @@ test_circuit_send_next_onion_skin(void *arg)
mock_circuit_deliver_create_cell_expect_direct = false;
tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
-END_CIRC_REASON_INTERNAL);
expect_log_msg("Client trying to extend to a non-IPv4 address.\n");
expect_log_msg("No supported address family found in extend_info.\n");
mock_clean_saved_logs();
/* Stop capturing bugs, but keep capturing logs */
+1
View File
@@ -23,6 +23,7 @@
#include "core/or/circuitbuild.h"
#include "core/or/circuitpadding.h"
#include "core/or/circuitpadding_machines.h"
#include "core/or/extendinfo.h"
#include "core/mainloop/netstatus.h"
#include "core/crypto/relay_crypto.h"
#include "core/or/protover.h"
+4 -2
View File
@@ -41,6 +41,7 @@
#include "feature/rend/rendcache.h"
#include "core/or/circuitlist.h"
#include "core/or/circuitbuild.h"
#include "core/or/extendinfo.h"
#include "core/mainloop/connection.h"
#include "core/or/connection_edge.h"
#include "feature/nodelist/networkstatus.h"
@@ -529,7 +530,7 @@ test_client_pick_intro(void *arg)
get_options_mutable()->ClientUseIPv6 = 1;
intro_ei = hs_get_extend_info_from_lspecs(ip->link_specifiers,
&ip->onion_key, 1);
tt_assert(tor_addr_family(&intro_ei->addr) == AF_INET6);
tt_assert(tor_addr_family(&intro_ei->orports[0].addr) == AF_INET6);
}
tt_assert(intro_ei);
if (intro_ei) {
@@ -537,7 +538,8 @@ test_client_pick_intro(void *arg)
char ip_addr[TOR_ADDR_BUF_LEN];
/* We need to decorate in case it is an IPv6 else routerset_parse()
* doesn't like it. */
ptr = tor_addr_to_str(ip_addr, &intro_ei->addr, sizeof(ip_addr), 1);
ptr = tor_addr_to_str(ip_addr, &intro_ei->orports[0].addr,
sizeof(ip_addr), 1);
tt_assert(ptr == ip_addr);
ret = routerset_parse(get_options_mutable()->ExcludeNodes,
ip_addr, "");
+2 -2
View File
@@ -1182,11 +1182,11 @@ test_nodelist_extend_info_describe(void *arg)
sizeof(mock_ei_ipv4.identity_digest));
strlcpy(mock_ei_ipv4.nickname, "TestOR7890123456789",
sizeof(mock_ei_ipv4.nickname));
tor_addr_parse(&mock_ei_ipv4.addr, "111.222.233.244");
tor_addr_parse(&mock_ei_ipv4.orports[0].addr, "111.222.233.244");
/* Create and modify the other extend info. */
memcpy(&mock_ei_ipv6, &mock_ei_ipv4, sizeof(mock_ei_ipv6));
tor_addr_parse(&mock_ei_ipv6.addr,
tor_addr_parse(&mock_ei_ipv6.orports[0].addr,
"[1111:2222:3333:4444:5555:6666:7777:8888]");
/* We don't test the no-nickname and no-IP cases, because they're covered by
+3 -2
View File
@@ -8,6 +8,7 @@
#include "app/config/config.h"
#include "core/or/circuitbuild.h"
#include "core/or/policies.h"
#include "core/or/extendinfo.h"
#include "feature/dirparse/policy_parse.h"
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_descriptor.h"
@@ -2084,8 +2085,8 @@ test_policies_fascist_firewall_allows_address(void *arg)
expect_single_log_msg("Specified link specifiers is null"); \
} else { \
expect_no_log_entry(); \
tt_assert(tor_addr_eq(&(expect_ap).addr, &ei->addr)); \
tt_int_op((expect_ap).port, OP_EQ, ei->port); \
tt_assert(tor_addr_eq(&(expect_ap).addr, &ei->orports[0].addr)); \
tt_int_op((expect_ap).port, OP_EQ, ei->orports[0].port); \
extend_info_free(ei); \
} \
teardown_capture_of_logs(); \