diff options
author | Peter Powell <petpow@saberuk.com> | 2016-10-02 13:07:51 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2016-10-02 13:07:51 -0400 |
commit | 3bcb041dc67f9335c9543d89ba144e43d0274a81 (patch) | |
tree | a30904f9d95cc922c8f1ab08ce12747f9d8ec217 | |
parent | 3af83256c654711fa03d5c3a78d7d126112cc538 (diff) |
Implement support for SASL 3.2 mechanism lists.
-rw-r--r-- | include/protocol.h | 1 | ||||
-rw-r--r-- | modules/protocol/inspircd20.cpp | 9 | ||||
-rw-r--r-- | modules/sasl.cpp | 42 |
3 files changed, 52 insertions, 0 deletions
diff --git a/include/protocol.h b/include/protocol.h index 898d1a51b..de83cd203 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -245,6 +245,7 @@ class CoreExport IRCDProto : public Service */ virtual void SendOper(User *u); + virtual void SendSASLMechanisms(std::vector<Anope::string> &) { } virtual void SendSASLMessage(const SASL::Message &) { } virtual void SendSVSLogin(const Anope::string &uid, const Anope::string &acc) { } diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index 3444c4412..f4dfcb12f 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -401,6 +401,15 @@ class InspIRCd20Proto : public IRCDProto Uplink::Send(Me, "FJOIN", c->name, c->creation_time, "+" + c->GetModes(true, true), ""); } + void SendSASLMechanisms(std::vector<Anope::string> &mechanisms) override + { + Anope::string mechlist; + for (unsigned i = 0; i < mechanisms.size(); ++i) + mechlist += "," + mechanisms[i]; + + Uplink::Send(Me, "METADATA", "*", "saslmechlist", mechlist.empty() ? "" : mechlist.substr(1)); + } + void SendSASLMessage(const SASL::Message &message) override { if (!message.ext.empty()) diff --git a/modules/sasl.cpp b/modules/sasl.cpp index d5a3acf6f..42d3bd9f3 100644 --- a/modules/sasl.cpp +++ b/modules/sasl.cpp @@ -321,14 +321,38 @@ void IdentifyRequestListener::OnFail(NickServ::IdentifyRequest *req) } class ModuleSASL : public Module + , public EventHook<Event::ModuleLoad> + , public EventHook<Event::ModuleUnload> + , public EventHook<Event::PreUplinkSync> { SASLService sasl; Plain plain; External *external = nullptr; + std::vector<Anope::string> mechs; + + void CheckMechs() + { + std::vector<Anope::string> names; + for (Mechanism *mech : ServiceManager::Get()->FindServices<Mechanism *>()) + names.push_back(mech->GetName()); + + if (mechs == names) + return; + + mechs = names; + + // If we are connected to the network then broadcast the mechlist. + if (Me && Me->IsSynced()) + IRCD->SendSASLMechanisms(mechs); + } + public: ModuleSASL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) + , EventHook<Event::ModuleLoad>(this) + , EventHook<Event::ModuleUnload>(this) + , EventHook<Event::PreUplinkSync>(this) , sasl(this) , plain(&sasl, this) { @@ -337,12 +361,30 @@ class ModuleSASL : public Module external = new External(&sasl, this); } catch (ModuleException &) { } + + CheckMechs(); } ~ModuleSASL() { delete external; } + + void OnModuleLoad(User *, Module *) override + { + CheckMechs(); + } + + void OnModuleUnload(User *, Module *) override + { + CheckMechs(); + } + + void OnPreUplinkSync(Server *) override + { + // We have not yet sent a mechanism list so always do it here. + IRCD->SendSASLMechanisms(mechs); + } }; MODULE_INIT(ModuleSASL) |