diff options
author | Sadie Powell <sadie@witchery.services> | 2023-11-16 18:14:15 +0000 |
---|---|---|
committer | Sadie Powell <sadie@witchery.services> | 2023-11-16 18:14:15 +0000 |
commit | ba163027bd9d62d3ae22bc1f8eb8cbe8bc478bf7 (patch) | |
tree | 050d85abfe98fa113bdc451a0bb13a91f7498dd4 /modules | |
parent | 1eba69d0352b8396de19ab0b19f3aa7d2eb2ef87 (diff) |
Make the SASL PLAIN implementation more robust.
- Reject auth attempts that try to authenticate using an alternate
authorization identity.
- Reject auth attempts that contain extraneous null bytes in the
string as required by the SASL PLAIN RFC.
- General code quality cleanup.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/m_sasl.cpp | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/modules/m_sasl.cpp b/modules/m_sasl.cpp index 0475b94e5..70ea2feaf 100644 --- a/modules/m_sasl.cpp +++ b/modules/m_sasl.cpp @@ -25,37 +25,47 @@ class Plain : public Mechanism } else if (m.type == "C") { - Anope::string decoded; - Anope::B64Decode(m.data, decoded); + // message = [authzid] UTF8NUL authcid UTF8NUL passwd + Anope::string message; + Anope::B64Decode(m.data, message); - size_t p = decoded.find('\0'); - if (p == Anope::string::npos) + size_t zcsep = message.find('\0'); + if (zcsep == Anope::string::npos) { sasl->Fail(sess); delete sess; return; } - decoded = decoded.substr(p + 1); - p = decoded.find('\0'); - if (p == Anope::string::npos) + size_t cpsep = message.find('\0', zcsep + 1); + if (cpsep == Anope::string::npos) { sasl->Fail(sess); delete sess; return; } - Anope::string acc = decoded.substr(0, p), - pass = decoded.substr(p + 1); + Anope::string authzid = message.substr(0, zcsep); + Anope::string authcid = message.substr(zcsep + 1, cpsep - zcsep - 1); - if (acc.empty() || pass.empty() || !IRCD->IsNickValid(acc) || pass.find_first_of("\r\n") != Anope::string::npos) + // We don't support having an authcid that is different to the authzid. + if (!authzid.empty() && authzid != authcid) { sasl->Fail(sess); delete sess; return; } - SASL::IdentifyRequest *req = new SASL::IdentifyRequest(this->owner, m.source, acc, pass, sess->hostname, sess->ip); + Anope::string passwd = message.substr(cpsep + 1); + + if (authcid.empty() || passwd.empty() || !IRCD->IsNickValid(authcid) || passwd.find_first_of("\r\n\0") != Anope::string::npos) + { + sasl->Fail(sess); + delete sess; + return; + } + + SASL::IdentifyRequest *req = new SASL::IdentifyRequest(this->owner, m.source, authcid, passwd, sess->hostname, sess->ip); FOREACH_MOD(OnCheckAuthentication, (NULL, req)); req->Dispatch(); } |