added camouflaging functionality and instrumentation

This commit is contained in:
eerieaerial 2025-04-30 17:40:54 +04:00
parent cdaf5e5468
commit 083b833bf8
16 changed files with 904 additions and 43 deletions

View file

@ -47,6 +47,7 @@
#include "../node/Bond.hpp"
#include "../node/Peer.hpp"
#include "../node/PacketMultiplexer.hpp"
#include "../node/CamoPattern.hpp"
#include "../osdep/Phy.hpp"
#include "../osdep/OSUtils.hpp"
@ -1454,6 +1455,18 @@ public:
}
}
// Camo settings defaults
CamoLevel camoLevel = CamoLevel::NONE;
std::string camoWordStr = ZT_CAMO_DEFAULT_WORDSTR;
uint32_t camoWord = 0;
for (size_t i = 0; i < BYTES_IN_WORD; i++)
{
camoWord |= camoWordStr[i];
camoWord <<= 8;
}
CamoRelayRule relayRule = CamoRelayRule::LEAVE;
std::unordered_map<Address, CamoLevel> knownHosts;
json &settings = lc["settings"];
if (settings.is_object()) {
// Allow controller DB path to be put somewhere else
@ -1487,7 +1500,150 @@ public:
}
}
}
// Camo settings
json &camo = settings["camo"];
if (camo.is_object())
{
CT("CAMO CONFIG SECTION FOUND");
std::string camoLevelStr = OSUtils::jsonString(camo["level"], "none");
std::transform(camoLevelStr.begin(), camoLevelStr.end(), camoLevelStr.begin(), [](unsigned char c)
{
return std::tolower(c);
});
CT("CAMO LEVEL SETTING: %s", camoLevelStr.c_str());
if (camoLevelStr == "node")
{
camoLevel = CamoLevel::NODE;
}
else if (camoLevelStr == "controller")
{
camoLevel = CamoLevel::CONTROLLER;
}
else if (camoLevelStr == "moon")
{
camoLevel = CamoLevel::MOON;
}
else if (camoLevelStr == "planet")
{
camoLevel = CamoLevel::PLANET;
}
if (camo.contains("word"))
{
std::string temp = OSUtils::jsonString(camo["word"], ZT_CAMO_DEFAULT_WORDSTR);
if (temp.substr(0, 2) == "0x")
{
try
{
camoWord = std::stoul(temp.substr(2), nullptr, 16);
}
catch (...)
{
}
}
else
{
for (size_t i = 0; i < BYTES_IN_WORD; i++)
{
char c = ' ';
if (i < temp.size())
{
c = temp[i];
}
camoWord |= c;
camoWord <<= 8;
}
}
}
CT("CAMO WORD SETTING: %x", camoWord);
std::string relayRuleStr = OSUtils::jsonString(camo["relayRule"], "leave");
std::transform(relayRuleStr.begin(), relayRuleStr.end(), relayRuleStr.begin(), [](unsigned char c)
{
return std::tolower(c);
});
if (relayRuleStr == "knownhosts")
{
relayRule = CamoRelayRule::KNOWNHOSTS;
}
else if (relayRuleStr == "strip")
{
relayRule = CamoRelayRule::STRIP;
}
else if (relayRuleStr == "apply")
{
relayRule = CamoRelayRule::APPLY;
}
CT("CAMO RELAY RULE SETTING: %s", relayRuleStr.c_str());
json &knownHostsSection = camo["knownHosts"];
if (knownHostsSection.is_object())
{
CT("KNOWN HOSTS SECTION FOUND");
auto processLevelSection = [&knownHosts](const json &section, CamoLevel level)
{
if (section.is_array())
{
for (const auto &addrStr: section)
{
std::string addr = OSUtils::jsonString(addrStr, "");
if (!addr.empty())
{
Address host (Utils::hexStrToU64(addr.c_str()));
if (host)
{
CT("VALID HOST FOUND: %s", addr.c_str());
knownHosts[host] = level;
}
}
}
}
};
for (auto it = knownHostsSection.begin(); it != knownHostsSection.end(); it++)
{
std::string levelKey = it.key();
std::transform(levelKey.begin(), levelKey.end(), levelKey.begin(), [](unsigned char c)
{
return std::tolower(c);
});
CT("FOUND CAMO LEVEL: %s", levelKey.c_str());
if (levelKey == "none")
{
processLevelSection(it.value(), CamoLevel::NONE);
}
else if (levelKey == "node")
{
processLevelSection(it.value(), CamoLevel::NODE);
}
else if (levelKey == "controller")
{
processLevelSection(it.value(), CamoLevel::CONTROLLER);
}
else if (levelKey == "moon")
{
processLevelSection(it.value(), CamoLevel::MOON);
}
else if (levelKey == "planet")
{
processLevelSection(it.value(), CamoLevel::PLANET);
}
else
{
processLevelSection(it.value(), CamoLevel::INAPPLICABLE);
}
}
}
}
else
{
CT("CAMO CONFIG SECTION NOT FOUND");
}
}
CamoPattern::init(camoLevel, camoWord, knownHosts, relayRule);
// Set trusted paths if there are any
if (!ppc.empty()) {