Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tor Hidden Services v3 #872

Merged
merged 4 commits into from
Feb 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
46 changes: 33 additions & 13 deletions src/netaddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<unsigned char> 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<unsigned char> 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;
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -354,7 +374,7 @@ std::vector<unsigned char> CNetAddr::GetGroup() const
vchRet.push_back(GetByte(2) ^ 0xFF);
return vchRet;
}
else if (IsTor())
else if (IsTor() || IsTorV3())
{
nClass = NET_TOR;
nStartByte = 6;
Expand Down Expand Up @@ -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();
Expand Down
33 changes: 30 additions & 3 deletions src/netaddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <compat.h>
#include <serialize.h>
#include <span.h>
#include <version.h>

#include <stdint.h>
#include <string>
Expand All @@ -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:
Expand Down Expand Up @@ -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;
Expand All @@ -96,7 +99,19 @@ class CNetAddr

template <typename Stream, typename Operation>
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;
Expand Down Expand Up @@ -168,7 +183,19 @@ class CService : public CNetAddr

template <typename Stream, typename Operation>
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));
}
};
Expand Down
3 changes: 1 addition & 2 deletions src/netbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
5 changes: 3 additions & 2 deletions src/torcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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");
}
Expand Down
48 changes: 25 additions & 23 deletions src/torcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string> argv;
argv.push_back("tor");
Expand All @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion src/torcontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include <scheduler.h>

/** 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;
Expand Down
2 changes: 2 additions & 0 deletions src/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down