1
0
mirror of https://github.com/anope/anope.git synced 2026-07-07 01:03:13 +02:00

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.
This commit is contained in:
Sadie Powell
2023-11-16 18:14:15 +00:00
parent 1eba69d035
commit ba163027bd
+28 -18
View File
@@ -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)
{
sasl->Fail(sess);
delete sess;
return;
}
decoded = decoded.substr(p + 1);
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;
}
Anope::string acc = decoded.substr(0, p),
pass = decoded.substr(p + 1);
if (acc.empty() || pass.empty() || !IRCD->IsNickValid(acc) || pass.find_first_of("\r\n") != Anope::string::npos)
size_t cpsep = message.find('\0', zcsep + 1);
if (cpsep == Anope::string::npos)
{
sasl->Fail(sess);
delete sess;
return;
}
SASL::IdentifyRequest *req = new SASL::IdentifyRequest(this->owner, m.source, acc, pass, sess->hostname, sess->ip);
Anope::string authzid = message.substr(0, zcsep);
Anope::string authcid = message.substr(zcsep + 1, cpsep - zcsep - 1);
// We don't support having an authcid that is different to the authzid.
if (!authzid.empty() && authzid != authcid)
{
sasl->Fail(sess);
delete sess;
return;
}
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();
}