Skip to content

Commit

Permalink
Fix --anonymouns-inbound data leak
Browse files Browse the repository at this point in the history
  • Loading branch information
vtnerd committed Dec 19, 2024
1 parent 58a1d54 commit 9221a8d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
8 changes: 8 additions & 0 deletions src/crypto/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,14 @@ namespace crypto {
return crypto::rand_range<T>(0, sz-1);
}

template<typename T>
struct random_distribution
{
static_assert(std::is_unsigned<T>::value, "expected unsigned type");
typedef T result_type;
result_type operator()(const result_type max) const { return rand_idx(max); }
};

/* Generate a new key pair
*/
inline secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false) {
Expand Down
33 changes: 23 additions & 10 deletions src/p2p/net_node.inl
Original file line number Diff line number Diff line change
Expand Up @@ -2483,6 +2483,25 @@ namespace nodetool
std::vector<peerlist_entry> local_peerlist_new;
zone.m_peerlist.get_peerlist_head(local_peerlist_new, true, max_peerlist_size);

/* Tor/I2P nodes receiving connections via forwarding (from tor/i2p daemon)
do not know the address of the connecting peer. This is relayed to them,
iff the node has setup an inbound hidden service. The other peer will have
to use the random peer_id value to link the two. My initial thought is that
the inbound peer should leave the other side marked as `<unknown tor host>`,
etc., because someone could give faulty addresses over Tor/I2P to get the
real peer with that identity banned/blacklisted.
\note Insert into `local_peerlist_new` so that it is only sent once like
the other peers. */
static constexpr const std::uint32_t max_random_time =
1 /*day*/ * 24 /*hours*/ * 60 /*minutes*/ * 60 /*seconds*/;
if(outgoing_to_same_zone)
local_peerlist_new.push_back(
peerlist_entry{
zone.m_our_address, zone.m_config.m_peer_id, std::time(nullptr) - crypto::rand_idx(max_random_time)
}
);

//only include out peers we did not already send
rsp.local_peerlist_new.reserve(local_peerlist_new.size());
for (auto &pe: local_peerlist_new)
Expand All @@ -2493,16 +2512,10 @@ namespace nodetool
}
m_payload_handler.get_payload_sync_data(rsp.payload_data);

/* Tor/I2P nodes receiving connections via forwarding (from tor/i2p daemon)
do not know the address of the connecting peer. This is relayed to them,
iff the node has setup an inbound hidden service. The other peer will have
to use the random peer_id value to link the two. My initial thought is that
the inbound peer should leave the other side marked as `<unknown tor host>`,
etc., because someone could give faulty addresses over Tor/I2P to get the
real peer with that identity banned/blacklisted. */

if(outgoing_to_same_zone)
rsp.local_peerlist_new.push_back(peerlist_entry{zone.m_our_address, zone.m_config.m_peer_id, std::time(nullptr)});
// randomize so location of local inbound is not easily found
std::random_shuffle(
rsp.local_peerlist_new.begin(), rsp.local_peerlist_new.end(), crypto::random_distribution<std::size_t>{}
);

LOG_DEBUG_CC(context, "COMMAND_TIMED_SYNC");
return 1;
Expand Down

0 comments on commit 9221a8d

Please sign in to comment.