commit 4a7964b3bcfa5439ba10e227c2ca8a4564123538 Author: David Goulet dgoulet@ev0ke.net Date: Tue Dec 8 13:42:27 2015 -0500
Don't allow a rendezvous point to have a private address
When an HS process an INTRODUCE2 cell, we didn't validate if the IP address of the rendezvous point was a local address. If it's the case, we end up wasting resources by trying to extend to a local address which fails since we do not allow that in circuit_extend().
This commit now rejects a rendezvous point that has a local address once seen at the hidden service side unless ExtendAllowPrivateAddresses is set.
Fixes #8976
Signed-off-by: David Goulet dgoulet@ev0ke.net --- src/or/circuitbuild.c | 15 +++++++++++++++ src/or/circuitbuild.h | 1 + src/or/rendservice.c | 12 ++++++++++++ 3 files changed, 28 insertions(+)
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 0688398..6a3c164 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -2403,3 +2403,18 @@ 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) && + !get_options()->ExtendAllowPrivateAddresses) { + goto disallow; + } + /* Allowed! */ + return 1; + disallow: + return 0; +} diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index 0156379..5d6222e 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -53,6 +53,7 @@ extend_info_t *extend_info_new(const char *nickname, const char *digest, 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); +int extend_info_addr_is_allowed(const tor_addr_t *addr); const node_t *build_state_get_exit_node(cpath_build_state_t *state); const char *build_state_get_exit_nickname(cpath_build_state_t *state);
diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 15d98bf..aad47bb 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1818,6 +1818,18 @@ find_rp_for_intro(const rend_intro_cell_t *intro, goto err; }
+ /* 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)) { + if (err_msg_out) { + tor_asprintf(&err_msg, + "Relay IP in INTRODUCE2 cell is private address."); + } + extend_info_free(rp); + rp = NULL; + goto err; + } goto done;
err: