diff options
| author | 2026-06-24 03:40:44 +0100 | |
|---|---|---|
| committer | 2026-06-24 21:21:59 +0100 | |
| commit | 7ec34045f5ffbd548ddb72a712a0b175b953ffee (patch) | |
| tree | 2961563a88f0a7cf2fa1139fcb8e5bcbb46eb2fe /modules/spanningtree/capab.cpp | |
| parent | Merge branch 'insp4' into master. (diff) | |
Move the challenge out of CAPAB CAPABILITIES into its own command.
Diffstat (limited to 'modules/spanningtree/capab.cpp')
| -rw-r--r-- | modules/spanningtree/capab.cpp | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/modules/spanningtree/capab.cpp b/modules/spanningtree/capab.cpp index 49c046074..fc124d0a8 100644 --- a/modules/spanningtree/capab.cpp +++ b/modules/spanningtree/capab.cpp @@ -197,7 +197,7 @@ namespace }; // If SHA256 hashing support is available then send a challenge token. - if (ServerInstance->Modules.FindService("Hash::Provider", "sha256")) + if (ts->proto_version < PROTO_INSPIRCD_5 && ServerInstance->Modules.FindService("Hash::Provider", "sha256")) { ts->SetOurChallenge(ServerInstance->GenRandomStr(20)); capabilities["CHALLENGE"] = ts->GetOurChallenge(); @@ -248,6 +248,21 @@ namespace return modules.str(); } + // Parses a challenge in the format "<algo> [<algo>]+ :<challenge>". + void ParseChallenge(const CommandBase::Params& params, std::string& out) + { + for (const auto& algorithm : insp::iterator_range(params.begin() + 1, params.end() - 1)) + { + // For now we only support HMAC-SHA-256 here. + if (insp::casemapped_equals(algorithm, "hmac-sha256")) + { + out = Percent::Decode(params.back()); + ServerInstance->Logs.Debug(MODNAME, "Parsed challenge: {:?}", out); + break; + } + } + } + // Parses a module list in the format "m_foo.so=bar m_bar.so=baz" to a map. void ParseModules(const std::string& modlist, std::optional<CapabData::ModuleMap>& out) { @@ -340,6 +355,20 @@ void TreeSocket::SendCapabilities(int phase) if (phase < 2) return; + + std::vector<std::string> algorithms; + if (proto_version >= PROTO_INSPIRCD_5) + { + std::vector<char> challenge(32); + ServerInstance->GenRandom(challenge.data(), challenge.size()); + SetOurChallenge(std::string(challenge.begin(), challenge.end())); + + MessageBuilder("CAPAB", true) + .Push("CHALLENGE") + .Push("hmac-sha256", Percent::Encode(GetOurChallenge())) + .Unicast(this); + } + MessageBuilder("CAPAB", true) .Push("CAPABILITIES", FormatCapabilities(this)) .Unicast(this); @@ -529,36 +558,15 @@ bool TreeSocket::Capab(const CommandBase::Params& params) } } - /* Challenge response, store their challenge for our password */ - std::map<std::string, std::string>::iterator n = this->capab->CapKeys.find("CHALLENGE"); - if ((n != this->capab->CapKeys.end()) && (ServerInstance->Modules.FindService("Hash::Provider", "sha256"))) + if (this->LinkState == CONNECTING) { - /* Challenge-response is on now */ - this->SetTheirChallenge(n->second); - if (!this->GetTheirChallenge().empty() && (this->LinkState == CONNECTING)) - { - this->SendCapabilities(2); - MessageBuilder("SERVER", true) - .Push(ServerInstance->Config->ServerName, - TreeSocket::MakePass(capab->link->SendPass, capab->theirchallenge), - ServerInstance->Config->ServerId, - ServerInstance->Config->ServerDesc) - .Unicast(this); - } - } - else - { - // They didn't specify a challenge or we don't have sha256, we use plaintext - if (this->LinkState == CONNECTING) - { - this->SendCapabilities(2); - MessageBuilder("SERVER", true) - .Push(ServerInstance->Config->ServerName, - capab->link->SendPass, - ServerInstance->Config->ServerId, - ServerInstance->Config->ServerDesc) - .Unicast(this); - } + this->SendCapabilities(2); + MessageBuilder("SERVER", true) + .Push(ServerInstance->Config->ServerName, + MakePass(capab->link->SendPass, capab->theirchallenge), + ServerInstance->Config->ServerId, + ServerInstance->Config->ServerDesc) + .Unicast(this); } } else if (insp::casemapped_equals(params[0] , "MODULES")) @@ -571,6 +579,11 @@ bool TreeSocket::Capab(const CommandBase::Params& params) if (params.size() >= 2) ParseModules(params[1], capab->optionalmodules); } + else if (insp::casemapped_equals(params[0], "CHALLENGE")) + { + if (params.size() >= 3) + ParseChallenge(params, capab->theirchallenge); + } else if (insp::casemapped_equals(params[0], "CHANMODES") && (params.size() == 2)) { capab->ChanModes = params[1]; @@ -595,6 +608,13 @@ bool TreeSocket::Capab(const CommandBase::Params& params) { std::string var(item, 0, equals); std::string value(item, equals+1); + + if (proto_version < PROTO_INSPIRCD_5 && insp::casemapped_equals(var, "CHALLENGE")) + { + this->SetTheirChallenge(value); + continue; + } + capab->CapKeys[var] = value; } } |
