+ if (parameters[0][0] == '*')
+ {
+ this->Abort();
+ return false;
+ }
+
+ return true;
+ }
+
+ void AnnounceState(void)
+ {
+ if (this->state_announced)
+ return;
+
+ switch (this->result)
+ {
+ case SASL_OK:
+ this->user->WriteNumeric(903, ":SASL authentication successful");
+ break;
+ case SASL_ABORT:
+ this->user->WriteNumeric(906, ":SASL authentication aborted");
+ break;
+ case SASL_FAIL:
+ this->user->WriteNumeric(904, ":SASL authentication failed");
+ break;
+ default:
+ break;
+ }
+
+ this->state_announced = true;
+ }
+};
+
+class CommandAuthenticate : public Command
+{
+ public:
+ SimpleExtItem<SaslAuthenticator>& authExt;
+ GenericCap& cap;
+ CommandAuthenticate(Module* Creator, SimpleExtItem<SaslAuthenticator>& ext, GenericCap& Cap)
+ : Command(Creator, "AUTHENTICATE", 1), authExt(ext), cap(Cap)
+ {
+ works_before_reg = true;
+ }
+
+ CmdResult Handle (const std::vector<std::string>& parameters, User *user)
+ {
+ /* Only allow AUTHENTICATE on unregistered clients */
+ if (user->registered != REG_ALL)
+ {
+ if (!cap.ext.get(user))
+ return CMD_FAILURE;
+
+ SaslAuthenticator *sasl = authExt.get(user);
+ if (!sasl)
+ authExt.set(user, new SaslAuthenticator(user, parameters[0]));
+ else if (sasl->SendClientMessage(parameters) == false) // IAL abort extension --nenolod
+ {
+ sasl->AnnounceState();
+ authExt.unset(user);