diff --git a/src/net.cpp b/src/net.cpp index 571fc1c2c..e284ef3f5 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -217,7 +217,7 @@ bool AddLocal(const CService& addr, int nScore) return false; bool isTorActived = !gArgs.GetBoolArg("-without-tor", false); - if(isTorActived && !addr.IsTor()) + if((isTorActived && !addr.IsTor()) && (isTorActived && !addr.IsTorV3())) return false; LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore); diff --git a/src/netaddress.cpp b/src/netaddress.cpp index ce0e9d7c3..68d15736b 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -56,14 +56,27 @@ bool CNetAddr::SetInternal(const std::string &name) bool CNetAddr::SetSpecial(const std::string &strName) { - if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") { + if (strName.size() > 6 && strName.substr(strName.size() - 6, 6) == ".onion") { std::vector vchAddr = DecodeBase32(strName.substr(0, strName.size() - 6).c_str()); - if (vchAddr.size() != 16-sizeof(pchOnionCat)) - return false; - memcpy(ip, pchOnionCat, sizeof(pchOnionCat)); - for (unsigned int i=0; i<16-sizeof(pchOnionCat); i++) - ip[i + sizeof(pchOnionCat)] = vchAddr[i]; - return true; + // 16' length - v2 tor addresses + if (vchAddr.size() == 16 - sizeof(pchOnionCat)){ + memcpy(ip, pchOnionCat, sizeof(pchOnionCat)); + for (unsigned int i = 0; i < 16 - sizeof(pchOnionCat); i++) + ip[i + sizeof(pchOnionCat)] = vchAddr[i]; + usesTorV3 = false; + return true; + } + + // 56' length - v3 tor addressess + std::vector vchAddrV3 = DecodeBase32(strName.substr(0, strName.size() - 6).c_str()); + if (vchAddrV3.size() == 41 - sizeof(pchOnionCat)){ + memcpy(ip, pchOnionCat, sizeof(pchOnionCat)); + for (unsigned int i = 0; i < 41 - sizeof(pchOnionCat); i++) + ip[i + sizeof(pchOnionCat)] = vchAddrV3[i]; + usesTorV3 = true; + return true; + } + } return false; } @@ -91,7 +104,7 @@ bool CNetAddr::IsIPv4() const bool CNetAddr::IsIPv6() const { - return (!IsIPv4() && !IsTor() && !IsInternal()); + return (!IsIPv4() && !IsTor() && !IsTorV3() && !IsInternal()); } bool CNetAddr::IsRFC1918() const @@ -169,7 +182,12 @@ bool CNetAddr::IsRFC4843() const bool CNetAddr::IsTor() const { - return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0); + return !usesTorV3 && (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0); +} + +bool CNetAddr::IsTorV3() const +{ + return usesTorV3 && (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0); } bool CNetAddr::IsLocal() const @@ -227,7 +245,7 @@ bool CNetAddr::IsValid() const bool CNetAddr::IsRoutable() const { - return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal() || IsInternal()); + return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && (!IsTor() && !IsTorV3())) || IsRFC4843() || IsLocal() || IsInternal()); } bool CNetAddr::IsInternal() const @@ -246,7 +264,7 @@ enum Network CNetAddr::GetNetwork() const if (IsIPv4()) return NET_IPV4; - if (IsTor()) + if (IsTor() || IsTorV3()) return NET_TOR; return NET_IPV6; @@ -256,6 +274,8 @@ std::string CNetAddr::ToStringIP() const { if (IsTor()) return EncodeBase32(&ip[6], 10) + ".onion"; + if (IsTorV3()) + return EncodeBase32(&ip[6], 35) + ".onion"; if (IsInternal()) return EncodeBase32(ip + sizeof(g_internal_prefix), sizeof(ip) - sizeof(g_internal_prefix)) + ".internal"; CService serv(*this, 0); @@ -354,7 +374,7 @@ std::vector CNetAddr::GetGroup() const vchRet.push_back(GetByte(2) ^ 0xFF); return vchRet; } - else if (IsTor()) + else if (IsTor() || IsTorV3()) { nClass = NET_TOR; nStartByte = 6; @@ -562,7 +582,7 @@ std::string CService::ToStringPort() const std::string CService::ToStringIPPort() const { - if (IsIPv4() || IsTor() || IsInternal()) { + if (IsIPv4() || IsTor() || IsTorV3() || IsInternal()) { return ToStringIP() + ":" + ToStringPort(); } else { return "[" + ToStringIP() + "]:" + ToStringPort(); diff --git a/src/netaddress.h b/src/netaddress.h index cb5a242f8..878689cc3 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -33,7 +34,8 @@ enum Network class CNetAddr { protected: - unsigned char ip[16]; // in network byte order + unsigned char ip[41]; // in network byte order + bool usesTorV3 = false; uint32_t scopeId; // for scoped/link-local ipv6 addresses public: @@ -72,6 +74,7 @@ class CNetAddr bool IsRFC6052() const; // IPv6 well-known prefix (64:FF9B::/96) bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) bool IsTor() const; + bool IsTorV3() const; bool IsLocal() const; bool IsRoutable() const; bool IsInternal() const; @@ -96,7 +99,19 @@ class CNetAddr template inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(ip); + if(s.GetVersion() > TORV3_SERVICES_VERSION) { + READWRITE(ip); + } else { // backwards compatibility + if(ser_action.ForRead()){ + unsigned char compatibleIP[16]; + READWRITE(compatibleIP); + memcpy(CNetAddr::ip, compatibleIP, sizeof(compatibleIP)); + } else { + unsigned char compatibleIP[16]; + memcpy(compatibleIP, CNetAddr::ip, sizeof(compatibleIP)); + READWRITE(compatibleIP); + } + } } friend class CSubNet; @@ -168,7 +183,19 @@ class CService : public CNetAddr template inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(ip); + if(s.GetVersion() >= TORV3_SERVICES_VERSION) { + READWRITE(ip); + } else { + if(ser_action.ForRead()){ + unsigned char compatibleIP[16]; + READWRITE(compatibleIP); + memcpy(CNetAddr::ip, compatibleIP, sizeof(compatibleIP)); + } else { + unsigned char compatibleIP[16]; // backwards compatibility + memcpy(compatibleIP, CNetAddr::ip, sizeof(compatibleIP)); + READWRITE(compatibleIP); + } + } READWRITE(WrapBigEndian(port)); } }; diff --git a/src/netbase.cpp b/src/netbase.cpp index 37ab593f6..a0b5fc32f 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -597,10 +597,9 @@ bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int // do socks negotiation if (proxy.randomize_credentials) { ProxyCredentials random_auth; - static std::atomic_int counter(0); - random_auth.username = GetRandomString(); random_auth.password = GetRandomString(); + if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket)) { return false; } diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 531898335..606f707ce 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -504,7 +504,7 @@ void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlRe } return; } - service = LookupNumeric(std::string(service_id+".onion").c_str(), GetListenPort()); + service = LookupNumeric(std::string(service_id + ".onion").c_str(), GetListenPort()); LogPrintf("tor: Got service ID %s, advertising service %s\n", service_id, service.ToString()); if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) { LogPrint(BCLog::TOR, "tor: Cached service private key to %s\n", GetPrivateKeyFile().string()); @@ -536,12 +536,13 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply& // Finally - now create the service if (private_key.empty()) // No private key, generate one - private_key = "NEW:RSA1024"; // Explicitly request RSA1024 - see issue #9214 + private_key = "NEW:ED25519-V3"; // Request hidden service, redirect port. // Note that the 'virtual' port doesn't have to be the same as our internal port, but this is just a convenient // choice. TODO; refactor the shutdown sequence some day. _conn.Command(strprintf("ADD_ONION %s Port=%i,127.0.0.1:%i", private_key, GetListenPort(), GetListenPort()), boost::bind(&TorController::add_onion_cb, this, _1, _2)); + } else { LogPrintf("tor: Authentication failed\n"); } diff --git a/src/torcontroller.cpp b/src/torcontroller.cpp index e494ffe88..566645f38 100644 --- a/src/torcontroller.cpp +++ b/src/torcontroller.cpp @@ -35,27 +35,27 @@ void run_tor() { printf("TOR thread started.\n"); - /*torrc_stream.open(torrc_file.string().c_str()); - while (getline(torrc_stream, line)) { - if (regex_search (line, bridge_regex)) { - ++bridgeNum; - } - } - torrc_stream.close(); - - if (stat("/usr/bin/obfs4proxy", &sb) == 0 && sb.st_mode & S_IXUSR) { - obfs4proxy_path = "/usr/bin/obfs4proxy"; - } - if (stat("/usr/local/bin/obfs4proxy", &sb) == 0 && sb.st_mode & S_IXUSR) { - obfs4proxy_path = "/usr/local/bin/obfs4proxy"; - } - if (stat("c:\\bin\\obfs4proxy.exe", &sb) == 0 && sb.st_mode & S_IXUSR) { - obfs4proxy_path = "c:\\bin\\obfs4proxy.exe"; - } - - if ((bridgeNum > 0) && (!obfs4proxy_path.empty())) { - clientTransportPlugin = "obfs4 exec " + obfs4proxy_path; - }*/ + // torrc_stream.open(torrc_file.string().c_str()); + // while (getline(torrc_stream, line)) { + // if (regex_search(line, bridge_regex)) { + // ++bridgeNum; + // } + // } + // torrc_stream.close(); + + // if (stat("/usr/bin/obfs4proxy", &sb) == 0 && sb.st_mode & S_IXUSR) { + // obfs4proxy_path = "/usr/bin/obfs4proxy"; + // } + // if (stat("/usr/local/bin/obfs4proxy", &sb) == 0 && sb.st_mode & S_IXUSR) { + // obfs4proxy_path = "/usr/local/bin/obfs4proxy"; + // } + // if (stat("c:\\bin\\obfs4proxy.exe", &sb) == 0 && sb.st_mode & S_IXUSR) { + // obfs4proxy_path = "c:\\bin\\obfs4proxy.exe"; + // } + + // if ((bridgeNum > 0) && (!obfs4proxy_path.empty())) { + // clientTransportPlugin = "obfs4 exec " + obfs4proxy_path; + // } std::vector argv; argv.push_back("tor"); @@ -75,12 +75,14 @@ void run_tor() { argv.push_back((tor_dir / "torrc").string()); argv.push_back("--HiddenServiceDir"); argv.push_back((tor_dir / "onion").string()); + argv.push_back("--ControlPort"); + argv.push_back(std::to_string(DEFAULT_TOR_CONTROL_PORT)); + argv.push_back("--HiddenServiceVersion"); + argv.push_back("3"); argv.push_back("--HiddenServicePort"); argv.push_back("21102"); argv.push_back("--CookieAuthentication"); argv.push_back("1"); - argv.push_back("--ControlPort"); - argv.push_back(std::to_string(DEFAULT_TOR_CONTROL_PORT)); if(!clientTransportPlugin.empty()){ printf("Using OBFS4.\n"); diff --git a/src/torcontroller.h b/src/torcontroller.h index fb8f1cb24..09b96d9bc 100644 --- a/src/torcontroller.h +++ b/src/torcontroller.h @@ -23,7 +23,7 @@ #include /** Default Port to run tor entry node on **/ -static const unsigned int DEFAULT_TOR_PORT = 9089; +static const unsigned int DEFAULT_TOR_PORT = 9090; /** Default Port for handling tor's control port **/ static const unsigned int DEFAULT_TOR_CONTROL_PORT = 9051; diff --git a/src/version.h b/src/version.h index 1694eb5af..0ce686c88 100644 --- a/src/version.h +++ b/src/version.h @@ -12,6 +12,8 @@ static const int PROTOCOL_VERSION = 90007; +static const int TORV3_SERVICES_VERSION = 90007; + //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209;