From ec5c0b26cefd5ad124745b578d6d92269d68debe Mon Sep 17 00:00:00 2001 From: Eval EXEC Date: Sun, 30 Mar 2025 18:58:57 +0800 Subject: [PATCH 1/2] torcontrol: Define tor reply code as const to improve maintainability Signed-off-by: Eval EXEC --- src/torcontrol.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 79001d54664..f2855b10935 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -53,6 +53,9 @@ const std::string DEFAULT_TOR_CONTROL = "127.0.0.1:" + ToString(DEFAULT_TOR_CONT static const int TOR_COOKIE_SIZE = 32; /** Size of client/server nonce for SAFECOOKIE */ static const int TOR_NONCE_SIZE = 32; +/** Tor control reply code. Ref: https://spec.torproject.org/control-spec/replies.html */ +static const int TOR_REPLY_OK = 250; +static const int TOR_REPLY_UNRECOGNIZED = 510; /** For computing serverHash in SAFECOOKIE */ static const std::string TOR_SAFE_SERVERKEY = "Tor safe cookie authentication server-to-controller hash"; /** For computing clientHash in SAFECOOKIE */ @@ -357,7 +360,7 @@ void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlRe { // NOTE: We can only get here if -onion is unset std::string socks_location; - if (reply.code == 250) { + if (reply.code == TOR_REPLY_OK) { for (const auto& line : reply.lines) { if (line.starts_with("net/listeners/socks=")) { const std::string port_list_str = line.substr(20); @@ -382,7 +385,7 @@ void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlRe } else { LogPrintf("tor: Get SOCKS port command returned nothing\n"); } - } else if (reply.code == 510) { // 510 Unrecognized command + } else if (reply.code == TOR_REPLY_UNRECOGNIZED) { LogPrintf("tor: Get SOCKS port command failed with unrecognized command (You probably should upgrade Tor)\n"); } else { LogPrintf("tor: Get SOCKS port command failed; error code %d\n", reply.code); @@ -422,7 +425,7 @@ void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlRe void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlReply& reply) { - if (reply.code == 250) { + if (reply.code == TOR_REPLY_OK) { LogDebug(BCLog::TOR, "ADD_ONION successful\n"); for (const std::string &s : reply.lines) { std::map m = ParseTorReplyMapping(s); @@ -448,7 +451,7 @@ void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlRe } AddLocal(service, LOCAL_MANUAL); // ... onion requested - keep connection open - } else if (reply.code == 510) { // 510 Unrecognized command + } else if (reply.code == TOR_REPLY_UNRECOGNIZED) { LogPrintf("tor: Add onion failed with unrecognized command (You probably need to upgrade Tor)\n"); } else { LogPrintf("tor: Add onion failed; error code %d\n", reply.code); @@ -457,7 +460,7 @@ void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlRe void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply& reply) { - if (reply.code == 250) { + if (reply.code == TOR_REPLY_OK) { LogDebug(BCLog::TOR, "Authentication successful\n"); // Now that we know Tor is running setup the proxy for onion addresses @@ -508,7 +511,7 @@ static std::vector ComputeResponse(const std::string &key, const std::v void TorController::authchallenge_cb(TorControlConnection& _conn, const TorControlReply& reply) { - if (reply.code == 250) { + if (reply.code == TOR_REPLY_OK) { LogDebug(BCLog::TOR, "SAFECOOKIE authentication challenge successful\n"); std::pair l = SplitTorReplyLine(reply.lines[0]); if (l.first == "AUTHCHALLENGE") { @@ -543,7 +546,7 @@ void TorController::authchallenge_cb(TorControlConnection& _conn, const TorContr void TorController::protocolinfo_cb(TorControlConnection& _conn, const TorControlReply& reply) { - if (reply.code == 250) { + if (reply.code == TOR_REPLY_OK) { std::set methods; std::string cookiefile; /* From 8e4a0ddd5084ba5bb4613f422b3ff044d0da3927 Mon Sep 17 00:00:00 2001 From: Eval EXEC Date: Mon, 3 Mar 2025 23:26:04 +0800 Subject: [PATCH 2/2] torcontrol: Add comment explaining Proxy credential randomization for Tor privacy Signed-off-by: Eval EXEC --- src/torcontrol.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index f2855b10935..5b8f5c74fe1 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -403,7 +403,11 @@ void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlRe Assume(resolved.IsValid()); LogDebug(BCLog::TOR, "Configuring onion proxy for %s\n", resolved.ToStringAddrPort()); - Proxy addrOnion = Proxy(resolved, true); + + // With m_randomize_credentials = true, generates unique SOCKS credentials per proxy connection (e.g., Tor). + // Prevents connection correlation and enhances privacy by forcing different Tor circuits. + // Requires Tor's IsolateSOCKSAuth (default enabled) for effective isolation (see IsolateSOCKSAuth section in https://2019.www.torproject.org/docs/tor-manual.html.en). + Proxy addrOnion = Proxy(resolved, /*_randomize_credentials=*/ true); SetProxy(NET_ONION, addrOnion); const auto onlynets = gArgs.GetArgs("-onlynet");