This PR want to:
- replace tor repy code with const to improve out maintainability.
- cherry-picked #31973 , add comment to explain Proxy credential randomization for Tor privacy
<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--006a51241073e994b41acfe9ec718e94-->
For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32166.
<!--021abf342d371248e50ceaed478a90ca-->
See the guideline for information on the review process.
| Type | Reviewers |
|---|---|
| ACK | hodlinator, laanwj |
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
<!--174a7506f384e20aa4161008e828411d-->
Reviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
Could probably be cherry-picked into #31973, so that there is only a single pull with doc/refactor fixups of the same file?
Probably this was meant the other way around: cherry-pick this change into that PR, which already has review, to not have to open a new one. But this works too.
Signed-off-by: Eval EXEC <execvy@gmail.com>
52 | @@ -53,6 +53,9 @@ const std::string DEFAULT_TOR_CONTROL = "127.0.0.1:" + ToString(DEFAULT_TOR_CONT 53 | static const int TOR_COOKIE_SIZE = 32; 54 | /** Size of client/server nonce for SAFECOOKIE */ 55 | static const int TOR_NONCE_SIZE = 32; 56 | +//* Tor control reply code. Ref: https://spec.torproject.org/control-spec/replies.html */
nit: Please use the same comment syntax as the other comments
Thank you, fixed.
402 | @@ -400,7 +403,11 @@ void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlRe 403 | 404 | Assume(resolved.IsValid()); 405 | LogDebug(BCLog::TOR, "Configuring onion proxy for %s\n", resolved.ToStringAddrPort()); 406 | - Proxy addrOnion = Proxy(resolved, true); 407 | + 408 | + // With m_randomize_credentials = true, generates unique SOCKS credentials per proxy connection (e.g., Tor). 409 | + // Prevents connection correlation and enhances privacy by forcing different Tor circuits. 410 | + // Requires Tor's IsolateSOCKSAuth (default enabled) for effective isolation (see IsolateSOCKSAuth section in https://2019.www.torproject.org/docs/tor-manual.html.en).
It's strange that the only torproject.org link for the C Tor manual is a 2019 backup of the site, but haven't found anything better either. The only up-to-date canonical source is the manual page, which isn't particularly readable on the web https://gitlab.torproject.org/tpo/core/tor/-/blob/main/doc/man/tor.1.txt (nothing to do here really, just noting)
Yes the web url link is old, but the IsolateSOCKSAuth explaination content is same with https://gitlab.torproject.org/tpo/core/tor/-/blob/main/doc/man/tor.1.txt
Oh yes the site is correct, i'm just a bit worried about it going offline at some point, so was trying to find a more up-to-date official link. But it doesn't exist.
Code review ACK f31ce35966bb84608938b0ba2272b415bcd42618
52 | @@ -53,6 +53,9 @@ const std::string DEFAULT_TOR_CONTROL = "127.0.0.1:" + ToString(DEFAULT_TOR_CONT 53 | static const int TOR_COOKIE_SIZE = 32; 54 | /** Size of client/server nonce for SAFECOOKIE */ 55 | static const int TOR_NONCE_SIZE = 32; 56 | +/** Tor control reply code. Ref: https://spec.torproject.org/control-spec/replies.html */ 57 | +static const int TOR_REPLY_OK = 250; 58 | +static const int TOR_REPLY_UNRECOGNIZED = 510;
nit: Others might disagree but I prefer grouping with an enum:
enum {
TOR_REPLY_OK = 250,
TOR_REPLY_UNRECOGNIZED = 510,
};
(Developer-notes prefer enum class but I think implicit conversion to int is more important in this case, and there is no risk of forgetting the non-existent enum name).
These constants are hardcoded in src/test/fuzz/torcontrol.cpp as well, but I think it's okay to let that be.
If you decide to not convert them to enum, it would be nice to use constexpr on these new lines.
I'm fine with either option; let the Bitcoin maintainers decide.
i considered commenting this, but didn't because it's a bit much for defining two response values. Seems the benefit of enum class would be to make sure they're grouped by name TorReply::OK TorReply::UNRECOGNIZED?
Seems the benefit of enum class would be to make sure they're grouped by name
TorReply::OKTorReply::UNRECOGNIZED?
Yes, but then one would have to do if (foo->bar == static_cast<int>(TorReply::OK)) which becomes a bit verbose.
Oh, right, and enums are not good for types that might have values that are not specifically defined, might as well keep this as-is.
402 | @@ -400,7 +403,11 @@ void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlRe 403 | 404 | Assume(resolved.IsValid()); 405 | LogDebug(BCLog::TOR, "Configuring onion proxy for %s\n", resolved.ToStringAddrPort()); 406 | - Proxy addrOnion = Proxy(resolved, true); 407 | + 408 | + // With m_randomize_credentials = true, generates unique SOCKS credentials per proxy connection (e.g., Tor). 409 | + // Prevents connection correlation and enhances privacy by forcing different Tor circuits. 410 | + // Requires Tor's IsolateSOCKSAuth (default enabled) for effective isolation (see IsolateSOCKSAuth section in https://2019.www.torproject.org/docs/tor-manual.html.en). 411 | + Proxy addrOnion = Proxy(resolved, /*_randomize_credentials*/ true);
informational, related:
Still feels scary to me how _randomize_credentials=true leads to a predictably incrementing integer to be used for user/pass after 5eaaa83ac1f5eb525f93e2808fafd73f5ed97013. What if guarantees of the Tor API were misunderstood, or change in the future?
Guess it's very unlikely to be a problem if these are only used to authenticate with the local SOCKS5 proxy and don't reach any further.
nit: Think clang-tidy will verify the name matches if you append = to the comment.
Proxy addrOnion = Proxy(resolved, /*_randomize_credentials=*/ true);
Thank you.
The requirements for stream isolation are documented here: https://spec.torproject.org/socks-extensions.html#stream-isolation . Our case is "They are both SOCKS5 with USERNAME/PASSWORD authentication, using legacy isolation parameters, and they have identical usernames and identical passwords". The <torS0X> extension is very recent so we don't use that (yet?).
So using different credentials is enough, there is no requirement, nor even benefit for them to be random.
Although thinking of it, it's possible to think of edge cases:
So maybe it's worth doing something else here, for example generate a unique prefix per bitcoind session startup (this would be once, so no need for performant randomness). But it's out of scope for this PR.
Pretty sure it is was already validated, this is how we discovered that the parameter is _randomize_credentials not randomize_credentials (https://github.com/bitcoin/bitcoin/pull/31973#discussion_r1977739770).
Oh, we used to have a = but it was lost? You're right.
So maybe it's worth doing something else here, for example generate a unique prefix per bitcoind session startup (this would be once, so no need for performant randomness). But it's out of scope for this PR.
i'll open a PR for this. i am also going to rename the parameter to tor_stream_isolation to make it more specific.
Thanks! Happy I managed to prompt you to come up with those edge-cases.
crACK f31ce35966bb84608938b0ba2272b415bcd42618
Could move "Friendly invite ..." out of PR description into its own comment.
Signed-off-by: Eval EXEC <execvy@gmail.com>
re-ACK 8e4a0ddd5084ba5bb4613f422b3ff044d0da3927
Only re-added accidentally dropped = in comment since previous review (f31ce35966bb84608938b0ba2272b415bcd42618).
re-ACK 8e4a0ddd5084ba5bb4613f422b3ff044d0da3927
Post-merge review ACK