mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Validate address more carefully when checking self-reachability
Previously, we would treat *any* incoming circuit on a non-local
channel as meaning that our ORPort was reachable. With this patch,
we make sure that the address that the peer _says_ we have is the
same as the one we're trying to advertise right now.
Closes 20165. Bugfix on 4f5192b280 in 0.1.0.1-rc, when
reachability self-tests were first introduced.
This commit is contained in:
committed by
George Kadianakis
parent
afd88ee87f
commit
75772ea096
@@ -0,0 +1,6 @@
|
||||
o Minor bugfixes (self-testing):
|
||||
- When receiving an incoming circuit, only accept it as evidence that we
|
||||
are reachable if the declared address of its channel is the same
|
||||
address we think that we have. Otherwise, it could be evidence that
|
||||
we're reachable on some other address. Fixes bug 20165; bugfix on
|
||||
0.1.0.1-rc.
|
||||
@@ -872,6 +872,8 @@ channel_init(channel_t *chan)
|
||||
|
||||
/* Channel is not in the scheduler heap. */
|
||||
chan->sched_heap_idx = -1;
|
||||
|
||||
tor_addr_make_unspec(&chan->addr_according_to_peer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -236,6 +236,9 @@ struct channel_t {
|
||||
/** The handle to this channel (to free on canceled timers) */
|
||||
struct channel_handle_t *timer_handle;
|
||||
|
||||
/** If not UNSPEC, the address that the peer says we have. */
|
||||
tor_addr_t addr_according_to_peer;
|
||||
|
||||
/**
|
||||
* These two fields specify the minimum and maximum negotiated timeout
|
||||
* values for inactivity (send or receive) before we decide to pad a
|
||||
|
||||
@@ -1868,6 +1868,13 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
|
||||
}
|
||||
}
|
||||
|
||||
if (me) {
|
||||
/* We have a descriptor, so we are a relay: record the address that the
|
||||
* other side said we had. */
|
||||
tor_addr_copy(&TLS_CHAN_TO_BASE(chan)->addr_according_to_peer,
|
||||
&my_apparent_addr);
|
||||
}
|
||||
|
||||
n_other_addrs = netinfo_cell_get_n_my_addrs(netinfo_cell);
|
||||
for (uint8_t i = 0; i < n_other_addrs; i++) {
|
||||
/* Consider all the other addresses; if any matches, this connection is
|
||||
|
||||
@@ -588,13 +588,23 @@ onionskin_answer(struct or_circuit_t *circ,
|
||||
if ((!channel_is_local(circ->p_chan)
|
||||
|| get_options()->ExtendAllowPrivateAddresses)
|
||||
&& !channel_is_outgoing(circ->p_chan)) {
|
||||
/* record that we could process create cells from a non-local conn
|
||||
* that we didn't initiate; presumably this means that create cells
|
||||
* can reach us too. */
|
||||
tor_addr_t remote_addr;
|
||||
if (channel_get_addr_if_possible(circ->p_chan, &remote_addr)) {
|
||||
int family = tor_addr_family(&remote_addr);
|
||||
router_orport_found_reachable(family);
|
||||
/* Okay, it's a create cell from a non-local connection
|
||||
* that we didn't initiate. Presumably this means that create cells
|
||||
* can reach us too. But what address can they reach us on? */
|
||||
const tor_addr_t *my_supposed_addr = &circ->p_chan->addr_according_to_peer;
|
||||
if (router_addr_is_my_published_addr(my_supposed_addr)) {
|
||||
/* Great, this create cell came on connection where the peer says
|
||||
* that the our address is an address we're actually advertising!
|
||||
* That should mean that we're reachable. But before we finally
|
||||
* declare ourselves reachable, make sure that the address listed
|
||||
* by the peer is the same family as the peer is actually using.
|
||||
*/
|
||||
tor_addr_t remote_addr;
|
||||
int family = tor_addr_family(my_supposed_addr);
|
||||
if (channel_get_addr_if_possible(circ->p_chan, &remote_addr) &&
|
||||
tor_addr_family(&remote_addr) == family) {
|
||||
router_orport_found_reachable(family);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1729,6 +1729,31 @@ router_is_me(const routerinfo_t *router)
|
||||
return router_digest_is_me(router->cache_info.identity_digest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we are a server, and if @a addr is an address we are
|
||||
* currently publishing (or trying to publish) in our descriptor.
|
||||
* Return false otherwise.
|
||||
**/
|
||||
bool
|
||||
router_addr_is_my_published_addr(const tor_addr_t *addr)
|
||||
{
|
||||
IF_BUG_ONCE(!addr)
|
||||
return false;
|
||||
|
||||
const routerinfo_t *me = router_get_my_routerinfo();
|
||||
if (!me)
|
||||
return false;
|
||||
|
||||
switch (tor_addr_family(addr)) {
|
||||
case AF_INET:
|
||||
return tor_addr_eq(addr, &me->ipv4_addr);
|
||||
case AF_INET6:
|
||||
return tor_addr_eq(addr, &me->ipv6_addr);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a routerinfo for this OR, rebuilding a fresh one if
|
||||
* necessary. Return NULL on error, or if called on an OP. */
|
||||
MOCK_IMPL(const routerinfo_t *,
|
||||
|
||||
@@ -100,6 +100,7 @@ int router_digest_is_me(const char *digest);
|
||||
const uint8_t *router_get_my_id_digest(void);
|
||||
int router_extrainfo_digest_is_me(const char *digest);
|
||||
int router_is_me(const routerinfo_t *router);
|
||||
bool router_addr_is_my_published_addr(const tor_addr_t *addr);
|
||||
int router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e);
|
||||
int router_rebuild_descriptor(int force);
|
||||
char *router_dump_router_to_string(routerinfo_t *router,
|
||||
|
||||
Reference in New Issue
Block a user