summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2016-10-02 13:07:51 -0400
committerAdam <Adam@anope.org>2016-10-02 13:07:51 -0400
commit3bcb041dc67f9335c9543d89ba144e43d0274a81 (patch)
treea30904f9d95cc922c8f1ab08ce12747f9d8ec217
parent3af83256c654711fa03d5c3a78d7d126112cc538 (diff)
Implement support for SASL 3.2 mechanism lists.
-rw-r--r--include/protocol.h1
-rw-r--r--modules/protocol/inspircd20.cpp9
-rw-r--r--modules/sasl.cpp42
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)