v29.4-roots.3 · Commit 3: [PATCH 03/30] policy: restore conservative relay and network controls
src/netbase.cpp
Before: src/netbase.cpp · After: src/netbase.cpp
File metadata
index d3d54048272415bb349f73acb0db8b1a59d901d4..775e459cca189a47a90112e26c8d36ab93079110 100644
Download original patch · Release notes
Diff rows 1–110 of 110. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
src/netbase.cpp
CHANGED
|
@@ -103,7 +103,7 @@ enum Network ParseNetwork(const std::string& net_in) {
|
|
| 103 |
if (net == "ipv6") return NET_IPV6;
|
| 104 |
if (net == "onion") return NET_ONION;
|
| 105 |
if (net == "tor") {
|
| 106 |
-
LogPrintf("Warning: net name 'tor' is deprecated and will be removed in the future. You should use 'onion' instead.\n");
|
| 107 |
return NET_ONION;
|
| 108 |
}
|
| 109 |
if (net == "i2p") {
|
|
@@ -277,6 +277,14 @@ enum SOCKS5Reply: uint8_t {
|
|
| 277 |
TTLEXPIRED = 0x06, //!< TTL expired
|
| 278 |
CMDUNSUPPORTED = 0x07, //!< Command not supported
|
| 279 |
ATYPEUNSUPPORTED = 0x08, //!< Address type not supported
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 280 |
};
|
| 281 |
|
| 282 |
/** Values defined for ATYPE in RFC1928 */
|
|
@@ -364,8 +372,24 @@ static std::string Socks5ErrorString(uint8_t err)
|
|
| 364 |
return "protocol error";
|
| 365 |
case SOCKS5Reply::ATYPEUNSUPPORTED:
|
| 366 |
return "address type not supported";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 367 |
default:
|
| 368 |
-
return "unknown";
|
| 369 |
}
|
| 370 |
}
|
| 371 |
|
|
@@ -411,8 +435,8 @@ bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* a
|
|
| 411 |
vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end());
|
| 412 |
vAuth.push_back(auth->password.size());
|
| 413 |
vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end());
|
|
|
|
| 414 |
sock.SendComplete(vAuth, g_socks5_recv_timeout, g_socks5_interrupt);
|
| 415 |
-
LogDebug(BCLog::PROXY, "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
|
| 416 |
uint8_t pchRetA[2];
|
| 417 |
if (InterruptibleRecv(pchRetA, 2, g_socks5_recv_timeout, sock) != IntrRecvError::OK) {
|
| 418 |
LogError("Error reading proxy authentication response\n");
|
|
@@ -725,6 +749,43 @@ bool IsProxy(const CNetAddr &addr) {
|
|
| 725 |
return false;
|
| 726 |
}
|
| 727 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 728 |
std::unique_ptr<Sock> ConnectThroughProxy(const Proxy& proxy,
|
| 729 |
const std::string& dest,
|
| 730 |
uint16_t port,
|
|
@@ -739,9 +800,8 @@ std::unique_ptr<Sock> ConnectThroughProxy(const Proxy& proxy,
|
|
| 739 |
|
| 740 |
// do socks negotiation
|
| 741 |
if (proxy.m_randomize_credentials) {
|
| 742 |
-
ProxyCredentials random_auth;
|
| 743 |
-
static std::atomic_int counter(0);
|
| 744 |
-
random_auth.username = random_auth.password = strprintf("%i", counter++);
|
| 745 |
if (!Socks5(dest, port, &random_auth, *sock)) {
|
| 746 |
return {};
|
| 747 |
}
|
|
|
|
| 103 |
if (net == "ipv6") return NET_IPV6;
|
| 104 |
if (net == "onion") return NET_ONION;
|
| 105 |
if (net == "tor") {
|
| 106 |
+
LogWarning("Net name 'tor' is deprecated and will be removed in the future. You should use 'onion' instead.");
|
| 107 |
return NET_ONION;
|
| 108 |
}
|
| 109 |
if (net == "i2p") {
|
|
|
|
| 277 |
TTLEXPIRED = 0x06, //!< TTL expired
|
| 278 |
CMDUNSUPPORTED = 0x07, //!< Command not supported
|
| 279 |
ATYPEUNSUPPORTED = 0x08, //!< Address type not supported
|
| 280 |
+
TOR_HS_DESC_NOT_FOUND = 0xf0, //!< Tor: Onion service descriptor can not be found
|
| 281 |
+
TOR_HS_DESC_INVALID = 0xf1, //!< Tor: Onion service descriptor is invalid
|
| 282 |
+
TOR_HS_INTRO_FAILED = 0xf2, //!< Tor: Onion service introduction failed
|
| 283 |
+
TOR_HS_REND_FAILED = 0xf3, //!< Tor: Onion service rendezvous failed
|
| 284 |
+
TOR_HS_MISSING_CLIENT_AUTH = 0xf4, //!< Tor: Onion service missing client authorization
|
| 285 |
+
TOR_HS_WRONG_CLIENT_AUTH = 0xf5, //!< Tor: Onion service wrong client authorization
|
| 286 |
+
TOR_HS_BAD_ADDRESS = 0xf6, //!< Tor: Onion service invalid address
|
| 287 |
+
TOR_HS_INTRO_TIMEOUT = 0xf7, //!< Tor: Onion service introduction timed out
|
| 288 |
};
|
| 289 |
|
| 290 |
/** Values defined for ATYPE in RFC1928 */
|
|
|
|
| 372 |
return "protocol error";
|
| 373 |
case SOCKS5Reply::ATYPEUNSUPPORTED:
|
| 374 |
return "address type not supported";
|
| 375 |
+
case SOCKS5Reply::TOR_HS_DESC_NOT_FOUND:
|
| 376 |
+
return "onion service descriptor can not be found";
|
| 377 |
+
case SOCKS5Reply::TOR_HS_DESC_INVALID:
|
| 378 |
+
return "onion service descriptor is invalid";
|
| 379 |
+
case SOCKS5Reply::TOR_HS_INTRO_FAILED:
|
| 380 |
+
return "onion service introduction failed";
|
| 381 |
+
case SOCKS5Reply::TOR_HS_REND_FAILED:
|
| 382 |
+
return "onion service rendezvous failed";
|
| 383 |
+
case SOCKS5Reply::TOR_HS_MISSING_CLIENT_AUTH:
|
| 384 |
+
return "onion service missing client authorization";
|
| 385 |
+
case SOCKS5Reply::TOR_HS_WRONG_CLIENT_AUTH:
|
| 386 |
+
return "onion service wrong client authorization";
|
| 387 |
+
case SOCKS5Reply::TOR_HS_BAD_ADDRESS:
|
| 388 |
+
return "onion service invalid address";
|
| 389 |
+
case SOCKS5Reply::TOR_HS_INTRO_TIMEOUT:
|
| 390 |
+
return "onion service introduction timed out";
|
| 391 |
default:
|
| 392 |
+
return strprintf("unknown (0x%02x)", err);
|
| 393 |
}
|
| 394 |
}
|
| 395 |
|
|
|
|
| 435 |
vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end());
|
| 436 |
vAuth.push_back(auth->password.size());
|
| 437 |
vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end());
|
| 438 |
+
LogDebug(BCLog::PROXY, "SOCKS5 sending username/password authentication\n");
|
| 439 |
sock.SendComplete(vAuth, g_socks5_recv_timeout, g_socks5_interrupt);
|
|
|
|
| 440 |
uint8_t pchRetA[2];
|
| 441 |
if (InterruptibleRecv(pchRetA, 2, g_socks5_recv_timeout, sock) != IntrRecvError::OK) {
|
| 442 |
LogError("Error reading proxy authentication response\n");
|
|
|
|
| 749 |
return false;
|
| 750 |
}
|
| 751 |
|
| 752 |
+
/**
|
| 753 |
+
* Generate unique credentials for Tor stream isolation. Tor will create
|
| 754 |
+
* separate circuits for SOCKS5 proxy connections with different credentials, which
|
| 755 |
+
* makes it harder to correlate the connections.
|
| 756 |
+
*/
|
| 757 |
+
class TorStreamIsolationCredentialsGenerator
|
| 758 |
+
{
|
| 759 |
+
public:
|
| 760 |
+
TorStreamIsolationCredentialsGenerator():
|
| 761 |
+
m_prefix(GenerateUniquePrefix()) {
|
| 762 |
+
}
|
| 763 |
+
|
| 764 |
+
/** Return the next unique proxy credentials. */
|
| 765 |
+
ProxyCredentials Generate() {
|
| 766 |
+
ProxyCredentials auth;
|
| 767 |
+
auth.username = auth.password = strprintf("%s%i", m_prefix, m_counter);
|
| 768 |
+
++m_counter;
|
| 769 |
+
return auth;
|
| 770 |
+
}
|
| 771 |
+
|
| 772 |
+
/** Size of session prefix in bytes. */
|
| 773 |
+
static constexpr size_t PREFIX_BYTE_LENGTH = 8;
|
| 774 |
+
private:
|
| 775 |
+
const std::string m_prefix;
|
| 776 |
+
std::atomic<uint64_t> m_counter;
|
| 777 |
+
|
| 778 |
+
/** Generate a random prefix for each of the credentials returned by this generator.
|
| 779 |
+
* This makes sure that different launches of the application (either successively or in parallel)
|
| 780 |
+
* will not share the same circuits, as would be the case with a bare counter.
|
| 781 |
+
*/
|
| 782 |
+
static std::string GenerateUniquePrefix() {
|
| 783 |
+
std::array<uint8_t, PREFIX_BYTE_LENGTH> prefix_bytes;
|
| 784 |
+
GetRandBytes(prefix_bytes);
|
| 785 |
+
return HexStr(prefix_bytes) + "-";
|
| 786 |
+
}
|
| 787 |
+
};
|
| 788 |
+
|
| 789 |
std::unique_ptr<Sock> ConnectThroughProxy(const Proxy& proxy,
|
| 790 |
const std::string& dest,
|
| 791 |
uint16_t port,
|
|
|
|
| 800 |
|
| 801 |
// do socks negotiation
|
| 802 |
if (proxy.m_randomize_credentials) {
|
| 803 |
+
static TorStreamIsolationCredentialsGenerator generator;
|
| 804 |
+
ProxyCredentials random_auth{generator.Generate()};
|
|
|
|
| 805 |
if (!Socks5(dest, port, &random_auth, *sock)) {
|
| 806 |
return {};
|
| 807 |
}
|