diff options
author | Sadie Powell <sadie@witchery.services> | 2025-03-31 16:58:22 +0100 |
---|---|---|
committer | Sadie Powell <sadie@witchery.services> | 2025-03-31 16:58:22 +0100 |
commit | 65bb0a374bb0e04aac2daa8c28daae9f41fc5d65 (patch) | |
tree | 70d496ffe2968e0a8a6a5ac651098ded410b55c2 /modules | |
parent | ea4877dc16bb84aa3a256b8a0249d9dc690295be (diff) |
Move SASL::IdentifyRequest to ns_sasl.
This is only useful for plain authentication and doesn't need to
be in the header.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/nickserv/ns_sasl.cpp | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/modules/nickserv/ns_sasl.cpp b/modules/nickserv/ns_sasl.cpp index bf9ac9eae..44686fc4c 100644 --- a/modules/nickserv/ns_sasl.cpp +++ b/modules/nickserv/ns_sasl.cpp @@ -10,6 +10,78 @@ #include "modules/nickserv/cert.h" #include "modules/nickserv/sasl.h" +class SASLIdentifyRequest final + : public IdentifyRequest +{ +private: + Anope::string uid; + Anope::string hostname; + + inline Anope::string GetUserInfo() + { + auto *u = User::Find(uid); + if (u) + return u->GetMask(); + if (!hostname.empty() && !GetAddress().empty()) + return Anope::printf("%s (%s)", hostname.c_str(), GetAddress().c_str()); + return "A user"; + }; + +public: + SASLIdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass, const Anope::string &h, const Anope::string &i) + : IdentifyRequest(m, acc, pass, i) + , uid(id) + , hostname(h) + { + } + + void OnSuccess() override + { + if (!SASL::service) + return; + + auto *na = NickAlias::Find(GetAccount()); + if (!na || na->nc->HasExt("NS_SUSPENDED") || na->nc->HasExt("UNCONFIRMED")) + return OnFail(); + + auto maxlogins = Config->GetModule("ns_identify").Get<unsigned int>("maxlogins"); + if (maxlogins && na->nc->users.size() >= maxlogins) + return OnFail(); + + auto *s = SASL::service->GetSession(uid); + if (s) + { + Log(this->GetOwner(), "sasl", Config->GetClient("NickServ")) << GetUserInfo() << " identified to account " << this->GetAccount() << " using SASL"; + SASL::service->Succeed(s, na->nc); + delete s; + } + } + + void OnFail() override + { + if (!SASL::service) + return; + + auto *s = SASL::service->GetSession(uid); + if (s) + { + SASL::service->Fail(s); + delete s; + } + + Anope::string accountstatus; + auto *na = NickAlias::Find(GetAccount()); + if (!na) + accountstatus = "nonexistent "; + else if (na->nc->HasExt("NS_SUSPENDED")) + accountstatus = "suspended "; + else if (na->nc->HasExt("UNCONFIRMED")) + accountstatus = "unconfirmed "; + + Log(this->GetOwner(), "sasl", Config->GetClient("NickServ")) << GetUserInfo() << " failed to identify for " << accountstatus << "account " << this->GetAccount() << " using SASL"; + } +}; + class Plain final : public SASL::Mechanism { @@ -51,7 +123,7 @@ public: if (authcid.empty() || passwd.empty() || !IRCD->IsNickValid(authcid) || passwd.find_first_of("\r\n\0") != Anope::string::npos) return false; - SASL::IdentifyRequest *req = new SASL::IdentifyRequest(this->owner, m.source, authcid, passwd, sess->hostname, sess->ip); + auto *req = new SASLIdentifyRequest(this->owner, m.source, authcid, passwd, sess->hostname, sess->ip); FOREACH_MOD(OnCheckAuthentication, (NULL, req)); req->Dispatch(); } |