+ SaslAuthenticator *sasl = authExt.get(target);
+ if (!sasl)
+ return CMD_FAILURE;
+
+ SaslState state = sasl->ProcessInboundMessage(parameters);
+ if (state == SASL_DONE)
+ {
+ sasl->AnnounceState();
+ authExt.unset(target);
+ }
+ return CMD_SUCCESS;
+ }
+
+ RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
+ {
+ return ROUTE_BROADCAST;
+ }
+};
+
+class ModuleSASL : public Module
+{
+ SimpleExtItem<SaslAuthenticator> authExt;
+ GenericCap cap;
+ CommandAuthenticate auth;
+ CommandSASL sasl;
+ public:
+ ModuleSASL()
+ : authExt("sasl_auth", this), cap(this, "sasl"), auth(this, authExt, cap), sasl(this, authExt)
+ {
+ }
+
+ void init()
+ {
+ OnRehash(NULL);
+ Implementation eventlist[] = { I_OnEvent, I_OnUserConnect, I_OnRehash };
+ ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
+
+ ServiceProvider* providelist[] = { &auth, &sasl, &authExt };
+ ServerInstance->Modules->AddServices(providelist, 3);
+
+ if (!ServerInstance->Modules->Find("m_services_account.so") || !ServerInstance->Modules->Find("m_cap.so"))
+ ServerInstance->Logs->Log("m_sasl", DEFAULT, "WARNING: m_services_account.so and m_cap.so are not loaded! m_sasl.so will NOT function correctly until these two modules are loaded!");
+ }
+
+ void OnRehash(User*)
+ {
+ sasl_target = ServerInstance->Config->ConfValue("sasl")->getString("target", "*");
+ }
+
+ void OnUserConnect(LocalUser *user)
+ {
+ SaslAuthenticator *sasl_ = authExt.get(user);
+ if (sasl_)
+ {
+ sasl_->Abort();
+ authExt.unset(user);