diff options
author | Adam <Adam@anope.org> | 2012-10-07 22:39:58 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2012-10-07 22:39:58 -0400 |
commit | b8b63ff115f0daddf479b0da507a2f731255a06d (patch) | |
tree | d6b82bf0dfc39fdfe6a6a23ba318bb0c2906d6c1 | |
parent | 0a111c19764ed14ab5f724c78d9dd8c08a3c124f (diff) |
Remove the asynchronous identifing hack and replace it with something better. Fixes m_*_authentication only being able to properly work when people identify normally using nickserv/identify
54 files changed, 680 insertions, 463 deletions
diff --git a/data/modules.example.conf b/data/modules.example.conf index db8b555ba..4ff3c710c 100644 --- a/data/modules.example.conf +++ b/data/modules.example.conf @@ -359,6 +359,9 @@ m_sql_authentication * @n@ is replaced with the user's nickname * @i@ is replaced with the user's IP * + * Note that @n@ and @i@ may not always exist in the case of a user identifying outside of the normal + * nickserv/identify command, such as through the web panel. + * * Furthermore, if a field named email is returned from this query the user's email is * set to its value. */ diff --git a/include/account.h b/include/account.h index 8b4920fe4..7aecab43a 100644 --- a/include/account.h +++ b/include/account.h @@ -304,7 +304,39 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END * Deletes all the memory allocated in the certificate list vector and then clears the vector. */ void ClearCert(); +}; + +class IdentifyRequest +{ + Anope::string account; + Anope::string password; + + std::set<Module *> holds; + bool dispatched; + bool success; + + static std::set<IdentifyRequest *> requests; + + protected: + IdentifyRequest(const Anope::string &acc, const Anope::string &pass); + virtual ~IdentifyRequest(); + + public: + virtual void OnSuccess() = 0; + virtual void OnFail() = 0; + + const Anope::string &GetAccount() const { return account; } + const Anope::string &GetPassword() const { return password; } + + /* Hold this request. Once held it must be Release()d later on */ + void Hold(Module *m); + void Release(Module *m); + + void Success(Module *m); + + void Dispatch(); + static void ModuleUnload(Module *m); }; extern CoreExport void change_core_display(NickCore *nc); diff --git a/include/defs.h b/include/defs.h index d58f7fed6..c08d683a0 100644 --- a/include/defs.h +++ b/include/defs.h @@ -26,6 +26,7 @@ class ConnectionSocket; class DNSPacket; class dynamic_reference_base; class Entry; +class IdentifyRequest; class InfoFormatter; class ListenSocket; class Log; diff --git a/include/modules.h b/include/modules.h index 4b992a15d..14fdff066 100644 --- a/include/modules.h +++ b/include/modules.h @@ -765,15 +765,11 @@ class CoreExport Module : public Extensible */ virtual void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool ShowHidden) { } - /** Check whether a users password is correct. - * @param u The user - * @param command The command the user is doing - * @param params Command params - * @param account The account the password should be checked against - * @param password The password - * @return EVENT_ALLOW to allow the password, EVENT_STOP to stop processing completely + /** Check whether a username and password is correct + * @param u The user trying to identify, if applicable. + * @param req The login request */ - virtual EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> ¶ms, const Anope::string &account, const Anope::string &password) { return EVENT_CONTINUE; } + virtual void OnCheckAuthentication(User *u, IdentifyRequest *req) { } /** Called when a user does /ns update * @param u The user diff --git a/modules/commands/ns_ghost.cpp b/modules/commands/ns_ghost.cpp index 3362cf408..9b48a43d1 100644 --- a/modules/commands/ns_ghost.cpp +++ b/modules/commands/ns_ghost.cpp @@ -13,6 +13,43 @@ #include "module.h" +class NSGhostRequest : public IdentifyRequest +{ + CommandSource source; + Command *cmd; + + public: + NSGhostRequest(CommandSource &src, Command *c, const Anope::string &user, const Anope::string &pass) : IdentifyRequest(user, pass), source(src), cmd(c) { } + + void OnSuccess() anope_override + { + if (!source.GetUser() || !source.service) + return; + + User *user = source.GetUser(); + if (!user->IsIdentified()) + source.Reply(_("You may not ghost an unidentified user, use RECOVER instead.")); + else + { + Log(LOG_COMMAND, source, cmd) << "for " << GetAccount(); + Anope::string buf = "GHOST command used by " + source.GetNick(); + user->Kill(source.service->nick, buf); + source.Reply(_("Ghost with your nick has been killed.")); + } + } + + void OnFail() anope_override + { + source.Reply(ACCESS_DENIED); + if (!GetPassword().empty()) + { + Log(LOG_COMMAND, source, cmd) << "with an invalid password for " << GetAccount(); + if (source.GetUser()) + bad_password(source.GetUser()); + } + } +}; + class CommandNSGhost : public Command { public: @@ -50,37 +87,21 @@ class CommandNSGhost : public Command ok = true; else if (source.GetUser() && !source.GetUser()->fingerprint.empty() && na->nc->FindCert(source.GetUser()->fingerprint)) ok = true; - else if (!pass.empty()) - { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(this, &source, params, na->nc->display, pass)); - if (MOD_RESULT == EVENT_STOP) - return; - else if (MOD_RESULT == EVENT_ALLOW) - ok = true; - } - if (ok) + if (ok == false && !pass.empty()) { - if (!user->IsIdentified()) - source.Reply(_("You may not ghost an unidentified user, use RECOVER instead.")); - else - { - Log(LOG_COMMAND, source, this) << "for " << nick; - Anope::string buf = "GHOST command used by " + source.GetNick(); - user->Kill(Config->NickServ, buf); - source.Reply(_("Ghost with your nick has been killed."), nick.c_str()); - } + NSGhostRequest *req = new NSGhostRequest(source, this, na->nc->display, pass); + FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(source.GetUser(), req)); + req->Dispatch(); } else { - source.Reply(ACCESS_DENIED); - if (!pass.empty()) - { - Log(LOG_COMMAND, source, this) << "with an invalid password for " << nick; - if (source.GetUser()) - bad_password(source.GetUser()); - } + NSGhostRequest req(source, this, na->nc->display, pass); + + if (ok) + req.OnSuccess(); + else + req.OnFail(); } } diff --git a/modules/commands/ns_group.cpp b/modules/commands/ns_group.cpp index 3df4b3460..30026c109 100644 --- a/modules/commands/ns_group.cpp +++ b/modules/commands/ns_group.cpp @@ -13,6 +13,61 @@ #include "module.h" +class NSGroupRequest : public IdentifyRequest +{ + CommandSource source; + Command *cmd; + Anope::string nick; + dynamic_reference<NickAlias> target; + + public: + NSGroupRequest(CommandSource &src, Command *c, const Anope::string &n, NickAlias *targ, const Anope::string &pass) : IdentifyRequest(targ->nc->display, pass), source(src), cmd(c), nick(n), target(targ) { } + + void OnSuccess() anope_override + { + if (!source.GetUser() || source.GetUser()->nick != nick || !target || !target->nc) + return; + + User *u = source.GetUser(); + NickAlias *na = findnick(nick); + /* If the nick is already registered, drop it. */ + if (na) + { + FOREACH_MOD(I_OnChangeCoreDisplay, OnChangeCoreDisplay(na->nc, u->nick)); + na->destroy(); + } + + na = new NickAlias(nick, target->nc); + + Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost(); + na->last_usermask = last_usermask; + na->last_realname = u->realname; + na->time_registered = na->last_seen = Anope::CurTime; + + u->Login(target->nc); + ircdproto->SendLogin(u); + if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasFlag(NI_UNCONFIRMED) == false) + u->SetMode(findbot(Config->NickServ), UMODE_REGISTERED); + FOREACH_MOD(I_OnNickGroup, OnNickGroup(u, target)); + + Log(LOG_COMMAND, source, cmd) << "makes " << nick << " join group of " << target->nick << " (" << target->nc->display << ") (email: " << (!target->nc->email.empty() ? target->nc->email : "none") << ")"; + source.Reply(_("You are now in the group of \002%s\002."), target->nick.c_str()); + + u->lastnickreg = Anope::CurTime; + + } + + void OnFail() anope_override + { + if (!source.GetUser()) + return; + + Log(LOG_COMMAND, source, cmd) << "failed group for " << target->nick; + source.Reply(PASSWORD_INCORRECT); + bad_password(source.GetUser()); + } +}; + class CommandNSGroup : public Command { public: @@ -62,7 +117,7 @@ class CommandNSGroup : public Command source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); else if (Anope::CurTime < u->lastnickreg + Config->NSRegDelay) source.Reply(_("Please wait %d seconds before using the GROUP command again."), (Config->NSRegDelay + u->lastnickreg) - Anope::CurTime); - else if (target && target->nc->HasFlag(NI_SUSPENDED)) + else if (target->nc->HasFlag(NI_SUSPENDED)) { Log(LOG_COMMAND, source, this) << "tried to use GROUP for SUSPENDED nick " << target->nick; source.Reply(NICK_X_SUSPENDED, target->nick.c_str()); @@ -75,6 +130,12 @@ class CommandNSGroup : public Command source.Reply(_("Your nick is already registered.")); else if (Config->NSMaxAliases && (target->nc->aliases.size() >= Config->NSMaxAliases) && !target->nc->IsServicesOper()) source.Reply(_("There are too many nicks in %s's group.")); + else if (u->nick.length() <= Config->NSGuestNickPrefix.length() + 7 && + u->nick.length() >= Config->NSGuestNickPrefix.length() + 1 && + !u->nick.find_ci(Config->NSGuestNickPrefix) && !u->nick.substr(Config->NSGuestNickPrefix.length()).find_first_not_of("1234567890")) + { + source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str()); + } else { bool ok = false; @@ -82,63 +143,23 @@ class CommandNSGroup : public Command ok = true; else if (!u->fingerprint.empty() && target->nc->FindCert(u->fingerprint)) ok = true; - else if (!pass.empty()) - { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(this, &source, params, target->nc->display, pass)); - if (MOD_RESULT == EVENT_STOP) - return; - else if (MOD_RESULT == EVENT_ALLOW) - ok = true; - } - if (ok) - { - /* If the nick is already registered, drop it. - * If not, check that it is valid. - */ - if (na) - { - FOREACH_MOD(I_OnChangeCoreDisplay, OnChangeCoreDisplay(na->nc, u->nick)); - na->destroy(); - } - else - { - size_t prefixlen = Config->NSGuestNickPrefix.length(); - size_t nicklen = u->nick.length(); - - if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1 && !u->nick.find_ci(Config->NSGuestNickPrefix) && !u->nick.substr(prefixlen).find_first_not_of("1234567890")) - { - source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str()); - return; - } - } - - na = new NickAlias(u->nick, target->nc); - - Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost(); - na->last_usermask = last_usermask; - na->last_realname = u->realname; - na->time_registered = na->last_seen = Anope::CurTime; - - u->Login(target->nc); - ircdproto->SendLogin(u); - if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasFlag(NI_UNCONFIRMED) == false) - u->SetMode(findbot(Config->NickServ), UMODE_REGISTERED); - FOREACH_MOD(I_OnNickGroup, OnNickGroup(u, target)); - Log(LOG_COMMAND, source, this) << "makes " << u->nick << " join group of " << target->nick << " (" << target->nc->display << ") (email: " << (!target->nc->email.empty() ? target->nc->email : "none") << ")"; - source.Reply(_("You are now in the group of \002%s\002."), target->nick.c_str()); - - u->lastnickreg = Anope::CurTime; + if (ok == false && !pass.empty()) + { + NSGroupRequest *req = new NSGroupRequest(source, this, u->nick, target, pass); + FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(source.GetUser(), req)); + req->Dispatch(); } else { - Log(LOG_COMMAND, source, this) << "failed group for " << target->nick; - source.Reply(PASSWORD_INCORRECT); - bad_password(u); + NSGroupRequest req(source, this, u->nick, target, pass); + + if (ok) + req.OnSuccess(); + else + req.OnFail(); } } - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override diff --git a/modules/commands/ns_identify.cpp b/modules/commands/ns_identify.cpp index cce0569dd..47df4255b 100644 --- a/modules/commands/ns_identify.cpp +++ b/modules/commands/ns_identify.cpp @@ -13,6 +13,47 @@ #include "module.h" +class NSIdentifyRequest : public IdentifyRequest +{ + CommandSource source; + Command *cmd; + + public: + NSIdentifyRequest(CommandSource &s, Command *c, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(acc, pass), source(s), cmd(c) { } + + void OnSuccess() anope_override + { + if (!source.GetUser()) + return; + + User *u = source.GetUser(); + NickAlias *na = findnick(GetAccount()); + + if (!na) + source.Reply(NICK_X_NOT_REGISTERED, GetAccount().c_str()); + else + { + if (u->IsIdentified()) + Log(LOG_COMMAND, source, cmd) << "to log out of account " << u->Account()->display; + + Log(LOG_COMMAND, source, cmd) << "and identified for account " << na->nc->display; + source.Reply(_("Password accepted - you are now recognized.")); + u->Identify(na); + na->Release(); + } + } + + void OnFail() anope_override + { + if (source.GetUser()) + { + Log(LOG_COMMAND, source, cmd) << "and failed to identify"; + source.Reply(PASSWORD_INCORRECT); + bad_password(source.GetUser()); + } + } +}; + class CommandNSIdentify : public Command { public: @@ -40,29 +81,9 @@ class CommandNSIdentify : public Command source.Reply(_("You are already identified.")); else { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(this, &source, params, na ? na->nc->display : nick, pass)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (!na) - source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); - else if (MOD_RESULT != EVENT_ALLOW) - { - Log(LOG_COMMAND, source, this) << "and failed to identify"; - source.Reply(PASSWORD_INCORRECT); - bad_password(u); - } - else - { - if (u->IsIdentified()) - Log(LOG_COMMAND, source, this) << "to log out of account " << u->Account()->display; - - Log(LOG_COMMAND, source, this) << "and identified for account " << na->nc->display; - source.Reply(_("Password accepted - you are now recognized.")); - u->Identify(na); - na->Release(); - } + NSIdentifyRequest *req = new NSIdentifyRequest(source, this, na ? na->nc->display : nick, pass); + FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(source.GetUser(), req)); + req->Dispatch(); } return; } diff --git a/modules/commands/ns_recover.cpp b/modules/commands/ns_recover.cpp index 7c5b6cbeb..0611e6589 100644 --- a/modules/commands/ns_recover.cpp +++ b/modules/commands/ns_recover.cpp @@ -14,11 +14,22 @@ #include "module.h" -class CommandNSRecover : public Command +class NSRecoverRequest : public IdentifyRequest { - private: - void DoRecover(CommandSource &source, User *u, NickAlias *na, const Anope::string &nick) + CommandSource source; + Command *cmd; + dynamic_reference<NickAlias> na; + + public: + NSRecoverRequest(CommandSource &src, Command *c, NickAlias *n, const Anope::string &pass) : IdentifyRequest(n->nc->display, pass), source(src), cmd(c), na(n) { } + + void OnSuccess() anope_override { + if (!source.GetUser() || !na) + return; + + User *u = source.GetUser(); + u->SendMessage(source.owner, FORCENICKCHANGE_NOW); if (u->Account() == na->nc) @@ -31,9 +42,27 @@ class CommandNSRecover : public Command /* Convert Config->NSReleaseTimeout seconds to string format */ Anope::string relstr = duration(Config->NSReleaseTimeout); - source.Reply(NICK_RECOVERED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), nick.c_str(), relstr.c_str()); + source.Reply(NICK_RECOVERED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), na->nick.c_str(), relstr.c_str()); } + void OnFail() anope_override + { + if (!source.GetUser()) + return; + + User *u = source.GetUser(); + + source.Reply(ACCESS_DENIED); + if (!GetPassword().empty()) + { + Log(LOG_COMMAND, source, cmd) << "with invalid password for " << na->nick; + bad_password(u); + } + } +}; + +class CommandNSRecover : public Command +{ public: CommandNSRecover(Module *creator) : Command(creator, "nickserv/recover", 1, 2) { @@ -60,25 +89,6 @@ class CommandNSRecover : public Command source.Reply(NICK_X_SUSPENDED, na->nick.c_str()); else if (nick.equals_ci(source.GetNick())) source.Reply(_("You can't recover yourself!")); - else if (!pass.empty()) - { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(this, &source, params, na->nc->display, pass)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT == EVENT_ALLOW) - { - this->DoRecover(source, u2, na, nick); - } - else - { - source.Reply(ACCESS_DENIED); - Log(LOG_COMMAND, source, this) << "with invalid password for " << nick; - if (source.GetUser()) - bad_password(source.GetUser()); - } - } else { bool ok = false; @@ -88,12 +98,23 @@ class CommandNSRecover : public Command ok = true; else if (source.GetUser() && !source.GetUser()->fingerprint.empty() && na->nc->FindCert(source.GetUser()->fingerprint)) ok = true; - if (ok) - this->DoRecover(source, u2, na, nick); + + if (ok == false && !pass.empty()) + { + NSRecoverRequest *req = new NSRecoverRequest(source, this, na, pass); + FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(source.GetUser(), req)); + req->Dispatch(); + } else - source.Reply(ACCESS_DENIED); + { + NSRecoverRequest req(source, this, na, pass); + + if (ok) + req.OnSuccess(); + else + req.OnFail(); + } } - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override diff --git a/modules/commands/ns_release.cpp b/modules/commands/ns_release.cpp index 9e12685aa..8afd9fade 100644 --- a/modules/commands/ns_release.cpp +++ b/modules/commands/ns_release.cpp @@ -13,6 +13,38 @@ #include "module.h" +class NSReleaseRequest : public IdentifyRequest +{ + CommandSource source; + Command *cmd; + dynamic_reference<NickAlias> na; + + public: + NSReleaseRequest(CommandSource &src, Command *c, NickAlias *n, const Anope::string &pass) : IdentifyRequest(n->nc->display, pass), source(src), cmd(c), na(n) { } + + void OnSuccess() anope_override + { + if (!source.GetUser() || !na) + return; + + bool override = source.GetAccount() != na->nc && source.HasPriv("nickserv/release"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, cmd) << "for nickname " << na->nick; + na->Release(); + source.Reply(_("Services' hold on \002%s\002 has been released."), na->nick.c_str()); + } + + void OnFail() anope_override + { + source.Reply(ACCESS_DENIED); + if (!GetPassword().empty()) + { + Log(LOG_COMMAND, source, cmd) << "with invalid password for " << na->nick; + if (!source.GetUser()) + bad_password(source.GetUser()); + } + } +}; + class CommandNSRelease : public Command { public: @@ -35,27 +67,6 @@ class CommandNSRelease : public Command source.Reply(NICK_X_SUSPENDED, na->nick.c_str()); else if (!na->HasFlag(NS_HELD)) source.Reply(_("Nick \002%s\002 isn't being held."), nick.c_str()); - else if (!pass.empty()) - { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(this, &source, params, na->nc->display, pass)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT == EVENT_ALLOW) - { - Log(LOG_COMMAND, source, this) << "for nickname " << na->nick; - na->Release(); - source.Reply(_("Services' hold on \002%s\002 has been released."), nick.c_str()); - } - else - { - source.Reply(ACCESS_DENIED); - Log(LOG_COMMAND, source, this) << "invalid password for " << nick; - if (source.GetUser()) - bad_password(source.GetUser()); - } - } else { bool override = source.GetAccount() != na->nc && source.HasPriv("nickserv/release"); @@ -67,14 +78,22 @@ class CommandNSRelease : public Command ok = true; else if (source.GetUser() && !source.GetUser()->fingerprint.empty() && na->nc->FindCert(source.GetUser()->fingerprint)) ok = true; - if (ok) + + if (ok == false && !pass.empty()) { - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this) << "for nickname " << na->nick; - na->Release(); - source.Reply(_("Services' hold on \002%s\002 has been released."), nick.c_str()); + NSReleaseRequest *req = new NSReleaseRequest(source, this, na, pass); + FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(source.GetUser(), req)); + req->Dispatch(); } else - source.Reply(ACCESS_DENIED); + { + NSReleaseRequest req(source, this, na, pass); + + if (ok) + req.OnSuccess(); + else + req.OnFail(); + } } return; } diff --git a/modules/encryption/enc_md5.cpp b/modules/encryption/enc_md5.cpp index 73bc29557..bcbe4aeed 100644 --- a/modules/encryption/enc_md5.cpp +++ b/modules/encryption/enc_md5.cpp @@ -339,33 +339,31 @@ class EMD5 : public Module return EVENT_ALLOW; } - EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> ¶ms, const Anope::string &account, const Anope::string &password) anope_override + void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override { - const NickAlias *na = findnick(account); + const NickAlias *na = findnick(req->GetAccount()); if (na == NULL) - return EVENT_CONTINUE; + return; NickCore *nc = na->nc; size_t pos = nc->pass.find(':'); if (pos == Anope::string::npos) - return EVENT_CONTINUE; + return; Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos); if (!hash_method.equals_cs("md5")) - return EVENT_CONTINUE; + return; Anope::string buf; - this->OnEncrypt(password, buf); + this->OnEncrypt(req->GetPassword(), buf); if (nc->pass.equals_cs(buf)) { /* if we are NOT the first module in the list, * we want to re-encrypt the pass with the new encryption */ if (ModuleManager::FindFirstOf(ENCRYPTION) != this) - enc_encrypt(password, nc->pass); - return EVENT_ALLOW; + enc_encrypt(req->GetPassword(), nc->pass); + req->Success(this); } - - return EVENT_CONTINUE; } }; diff --git a/modules/encryption/enc_none.cpp b/modules/encryption/enc_none.cpp index 778ed6cba..9496939fd 100644 --- a/modules/encryption/enc_none.cpp +++ b/modules/encryption/enc_none.cpp @@ -41,33 +41,31 @@ class ENone : public Module return EVENT_ALLOW; } - EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> ¶ms, const Anope::string &account, const Anope::string &password) anope_override + void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override { - const NickAlias *na = findnick(account); + const NickAlias *na = findnick(req->GetAccount()); if (na == NULL) - return EVENT_CONTINUE; + return; NickCore *nc = na->nc; size_t pos = nc->pass.find(':'); if (pos == Anope::string::npos) - return EVENT_CONTINUE; + return; Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos); if (!hash_method.equals_cs("plain")) - return EVENT_CONTINUE; + return; Anope::string buf; - this->OnEncrypt(password, buf); + this->OnEncrypt(req->GetPassword(), buf); if (nc->pass.equals_cs(buf)) { /* if we are NOT the first module in the list, * we want to re-encrypt the pass with the new encryption */ if (ModuleManager::FindFirstOf(ENCRYPTION) != this) - enc_encrypt(password, nc->pass); - return EVENT_ALLOW; + enc_encrypt(req->GetPassword(), nc->pass); + req->Success(this); } - - return EVENT_CONTINUE; } }; diff --git a/modules/encryption/enc_old.cpp b/modules/encryption/enc_old.cpp index 9fba199dc..b5ce86540 100644 --- a/modules/encryption/enc_old.cpp +++ b/modules/encryption/enc_old.cpp @@ -349,33 +349,31 @@ class EOld : public Module return EVENT_ALLOW; } - EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> ¶ms, const Anope::string &account, const Anope::string &password) anope_override + void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override { - const NickAlias *na = findnick(account); + const NickAlias *na = findnick(req->GetAccount()); if (na == NULL) - return EVENT_CONTINUE; + return; NickCore *nc = na->nc; size_t pos = nc->pass.find(':'); if (pos == Anope::string::npos) - return EVENT_CONTINUE; + return; Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos); if (!hash_method.equals_cs("oldmd5")) - return EVENT_CONTINUE; + return; Anope::string buf; - this->OnEncrypt(password, buf); + this->OnEncrypt(req->GetPassword(), buf); if (nc->pass.equals_cs(buf)) { /* if we are NOT the first module in the list, * we want to re-encrypt the pass with the new encryption */ if (ModuleManager::FindFirstOf(ENCRYPTION) != this) - enc_encrypt(password, nc->pass); - return EVENT_ALLOW; + enc_encrypt(req->GetPassword(), nc->pass); + req->Success(this); } - - return EVENT_CONTINUE; } }; diff --git a/modules/encryption/enc_sha1.cpp b/modules/encryption/enc_sha1.cpp index 3735e65bc..28d216972 100644 --- a/modules/encryption/enc_sha1.cpp +++ b/modules/encryption/enc_sha1.cpp @@ -192,30 +192,28 @@ class ESHA1 : public Module return EVENT_ALLOW; } - EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> ¶ms, const Anope::string &account, const Anope::string &password) anope_override + void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override { - const NickAlias *na = findnick(account); + const NickAlias *na = findnick(req->GetAccount()); if (na == NULL) - return EVENT_CONTINUE; + return; NickCore *nc = na->nc; size_t pos = nc->pass.find(':'); if (pos == Anope::string::npos) - return EVENT_CONTINUE; + return; Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos); if (!hash_method.equals_cs("sha1")) - return EVENT_CONTINUE; + return; Anope::string buf; - this->OnEncrypt(password, buf); + this->OnEncrypt(req->GetPassword(), buf); if (nc->pass.equals_cs(buf)) { if (ModuleManager::FindFirstOf(ENCRYPTION) != this) - enc_encrypt(password, nc->pass); - return EVENT_ALLOW; + enc_encrypt(req->GetPassword(), nc->pass); + req->Success(this); } - - return EVENT_CONTINUE; } }; diff --git a/modules/encryption/enc_sha256.cpp b/modules/encryption/enc_sha256.cpp index cee21b01d..36eaa98fc 100644 --- a/modules/encryption/enc_sha256.cpp +++ b/modules/encryption/enc_sha256.cpp @@ -278,24 +278,24 @@ class ESHA256 : public Module return EVENT_ALLOW; } - EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> ¶ms, const Anope::string &account, const Anope::string &password) anope_override + void OnCheckAuthentication(User *, IdentifyRequest *req) anope_override { - const NickAlias *na = findnick(account); + const NickAlias *na = findnick(req->GetAccount()); if (na == NULL) - return EVENT_CONTINUE; + return; NickCore *nc = na->nc; size_t pos = nc->pass.find(':'); if (pos == Anope::string::npos) - return EVENT_CONTINUE; + return; Anope::string hash_method(nc->pass.begin(), nc->pass.begin() + pos); if (!hash_method.equals_cs("sha256")) - return EVENT_CONTINUE; + return; GetIVFromPass(nc->pass); use_iv = true; Anope::string buf; - this->OnEncrypt(password, buf); + this->OnEncrypt(req->GetPassword(), buf); if (nc->pass.equals_cs(buf)) { @@ -303,11 +303,9 @@ class ESHA256 : public Module * we want to re-encrypt the pass with the new encryption */ if (ModuleManager::FindFirstOf(ENCRYPTION) != this) - enc_encrypt(password, nc->pass); - return EVENT_ALLOW; + enc_encrypt(req->GetPassword(), nc->pass); + req->Success(this); } - - return EVENT_CONTINUE; } }; diff --git a/modules/extra/httpd.h b/modules/extra/httpd.h index 684c11512..d9e800d13 100644 --- a/modules/extra/httpd.h +++ b/modules/extra/httpd.h @@ -21,6 +21,23 @@ struct HTTPReply HTTPReply() : error(HTTP_ERROR_OK), length(0) { } + HTTPReply(const HTTPReply& other) : error(other.error), length(other.length) + { + content_type = other.content_type; + headers = other.headers; + cookies = other.cookies; + + for (unsigned i = 0; i < other.out.size(); ++i) + out.push_back(new Data(other.out[i]->buf, other.out[i]->len)); + } + + ~HTTPReply() + { + for (unsigned i = 0; i < out.size(); ++i) + delete out[i]; + out.clear(); + } + struct Data { char *buf; @@ -87,10 +104,10 @@ class HTTPPage : public Base * @param The HTTP header sent from the client to request the page * @param The HTTP header that will be sent back to the client */ - virtual void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) = 0; + virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) = 0; }; -class HTTPClient : public ClientSocket, public BufferedSocket, public BinarySocket +class HTTPClient : public ClientSocket, public BufferedSocket, public BinarySocket, public Base { protected: void WriteClient(const Anope::string &message) diff --git a/modules/extra/m_httpd.cpp b/modules/extra/m_httpd.cpp index 626a62e8c..e802ed055 100644 --- a/modules/extra/m_httpd.cpp +++ b/modules/extra/m_httpd.cpp @@ -35,7 +35,7 @@ static Anope::string GetStatusFromCode(HTTPError err) return "501 Not Implemented"; } -class MyHTTPClient : public HTTPClient, public Base +class MyHTTPClient : public HTTPClient { HTTPProvider *provider; HTTPMessage header; @@ -78,9 +78,8 @@ class MyHTTPClient : public HTTPClient, public Base HTTPReply reply; - this->page->OnRequest(this->provider, this->page_name, this, this->header, reply); - - this->SendReply(&reply); + if (this->page->OnRequest(this->provider, this->page_name, this, this->header, reply)) + this->SendReply(&reply); } public: diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/m_ldap_authentication.cpp index 7fcd67e5d..2ca08f975 100644 --- a/modules/extra/m_ldap_authentication.cpp +++ b/modules/extra/m_ldap_authentication.cpp @@ -2,6 +2,8 @@ #include "nickserv.h" #include "ldap.h" +static Module *me; + static Anope::string basedn; static Anope::string search_filter; static Anope::string object_class; @@ -10,17 +12,21 @@ static Anope::string username_attribute; struct IdentifyInfo { - dynamic_reference<Command> command; - CommandSource source; - std::vector<Anope::string> params; - Anope::string account; - Anope::string pass; - Anope::string dn; + dynamic_reference<User> user; + IdentifyRequest *req; service_reference<LDAPProvider> lprov; bool admin_bind; + Anope::string dn; - IdentifyInfo(Command *c, CommandSource &s, const std::vector<Anope::string> &pa, const Anope::string &a, const Anope::string &p, service_reference<LDAPProvider> &lp) : - command(c), source(s), params(pa), account(a), pass(p), lprov(lp), admin_bind(true) { } + IdentifyInfo(User *u, IdentifyRequest *r, service_reference<LDAPProvider> &lp) : user(u), req(r), lprov(lp), admin_bind(true) + { + req->Hold(me); + } + + ~IdentifyInfo() + { + req->Release(me); + } }; class IdentifyInterface : public LDAPInterface @@ -46,9 +52,9 @@ class IdentifyInterface : public LDAPInterface IdentifyInfo *ii = it->second; this->requests.erase(it); - if (!ii->source.GetUser() || !ii->command || !ii->lprov) + if (!ii->lprov) { - delete this; + delete ii; return; } @@ -63,69 +69,55 @@ class IdentifyInterface : public LDAPInterface const LDAPAttributes &attr = r.get(0); ii->dn = attr.get("dn"); Log(LOG_DEBUG) << "m_ldap_authenticationn: binding as " << ii->dn; - LDAPQuery id = ii->lprov->Bind(this, ii->dn, ii->pass); + LDAPQuery id = ii->lprov->Bind(this, ii->dn, ii->req->GetPassword()); this->Add(id, ii); + return; } catch (const LDAPException &ex) { Log() << "m_ldap_authentication: Error binding after search: " << ex.GetReason(); - delete ii; } } - else - { - User *u = ii->source.GetUser(); - Command *c = ii->command; - - u->Extend("m_ldap_authentication_error", NULL); - - c->Execute(ii->source, ii->params); - - delete ii; - } break; } case LDAPResult::QUERY_BIND: { if (ii->admin_bind) { - Anope::string sf = search_filter.replace_all_cs("%account", ii->account).replace_all_cs("%object_class", object_class); + Anope::string sf = search_filter.replace_all_cs("%account", ii->req->GetAccount()).replace_all_cs("%object_class", object_class); Log(LOG_DEBUG) << "m_ldap_authentication: searching for " << sf; LDAPQuery id = ii->lprov->Search(this, basedn, sf); this->Add(id, ii); ii->admin_bind = false; + return; } else { - User *u = ii->source.GetUser(); - Command *c = ii->command; - - u->Extend("m_ldap_authentication_authenticated", NULL); - - NickAlias *na = findnick(ii->account); + NickAlias *na = findnick(ii->req->GetAccount()); if (na == NULL) { - na = new NickAlias(ii->account, new NickCore(ii->account)); - if (Config->NSAddAccessOnReg) - na->nc->AddAccess(create_mask(u)); - - BotInfo *bi = findbot(Config->NickServ); - if (bi) - u->SendMessage(bi, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); + na = new NickAlias(ii->req->GetAccount(), new NickCore(ii->req->GetAccount())); + if (ii->user) + { + if (Config->NSAddAccessOnReg) + na->nc->AddAccess(create_mask(ii->user)); + + const BotInfo *bi = findbot(Config->NickServ); + if (bi) + ii->user->SendMessage(bi, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); + } } - na->nc->Extend("m_ldap_authentication_dn", new ExtensibleItemClass<Anope::string>(ii->dn)); - - enc_encrypt(ii->pass, na->nc->pass); - - c->Execute(ii->source, ii->params); - delete ii; + + ii->req->Success(me); } break; } default: - delete ii; + break; } + + delete ii; } void OnError(const LDAPResult &r) anope_override @@ -135,20 +127,6 @@ class IdentifyInterface : public LDAPInterface return; IdentifyInfo *ii = it->second; this->requests.erase(it); - - if (!ii->source.GetUser() || !ii->command) - { - delete ii; - return; - } - - User *u = ii->source.GetUser(); - Command *c = ii->command; - - u->Extend("m_ldap_authentication_error", NULL); - - c->Execute(ii->source, ii->params); - delete ii; } }; @@ -235,6 +213,8 @@ class NSIdentifyLDAP : public Module { this->SetAuthor("Anope"); + me = this; + Implementation i[] = { I_OnReload, I_OnPreCommand, I_OnCheckAuthentication, I_OnNickIdentify, I_OnNickRegister }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); ModuleManager::SetPriority(this, PRIORITY_FIRST); @@ -267,28 +247,12 @@ class NSIdentifyLDAP : public Module return EVENT_CONTINUE; } - EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> ¶ms, const Anope::string &account, const Anope::string &password) anope_override + void OnCheckAuthentication(User *u, IdentifyRequest *req) anope_override { + if (!this->ldap) + return; - if (c == NULL || source == NULL || !this->ldap) - return EVENT_CONTINUE; - - User *u = source->GetUser(); - if (!u) - return EVENT_CONTINUE; - - if (u->HasExt("m_ldap_authentication_authenticated")) - { - u->Shrink("m_ldap_authentication_authenticated"); - return EVENT_ALLOW; - } - else if (u->HasExt("m_ldap_authentication_error")) - { - u->Shrink("m_ldap_authentication_error"); - return EVENT_CONTINUE; - } - - IdentifyInfo *ii = new IdentifyInfo(c, *source, params, account, password, this->ldap); + IdentifyInfo *ii = new IdentifyInfo(u, req, this->ldap); try { LDAPQuery id = this->ldap->BindAsAdmin(&this->iinterface); @@ -298,10 +262,7 @@ class NSIdentifyLDAP : public Module { delete ii; Log() << "ns_identify_ldap: " << ex.GetReason(); - return EVENT_CONTINUE; } - - return EVENT_STOP; } void OnNickIdentify(User *u) anope_override diff --git a/modules/extra/m_sql_authentication.cpp b/modules/extra/m_sql_authentication.cpp index 957258fcb..9375615ee 100644 --- a/modules/extra/m_sql_authentication.cpp +++ b/modules/extra/m_sql_authentication.cpp @@ -1,71 +1,71 @@ #include "module.h" #include "sql.h" +static Module *me; + class SQLAuthenticationResult : public SQLInterface { - dynamic_reference<Command> cmd; - CommandSource source; - std::vector<Anope::string> params; dynamic_reference<User> user; - Anope::string account; + IdentifyRequest *req; public: - SQLAuthenticationResult(Module *m, Command *c, CommandSource &s, const std::vector<Anope::string> &p, User *u, const Anope::string &a) : SQLInterface(m), cmd(c), source(s), params(p), user(u), account(a) { } + SQLAuthenticationResult(User *u, IdentifyRequest *r) : SQLInterface(me), user(u), req(r) + { + req->Hold(me); + } + + ~SQLAuthenticationResult() + { + req->Release(me); + } void OnResult(const SQLResult &r) anope_override { - if (user && cmd) + if (r.Rows() == 0) { - Anope::string email; + Log(LOG_DEBUG) << "m_sql_authentication: Unsuccessful authentication for " << req->GetAccount(); + delete this; + return; + } - if (r.Rows() > 0) - { - user->Extend("m_sql_authentication_success", NULL); + Log(LOG_DEBUG) << "m_sql_authentication: Successful authentication for " << req->GetAccount(); - try - { - email = r.Get(0, "email"); - } - catch (const SQLException &) { } - } - else - user->Extend("m_sql_authentication_failed", NULL); + Anope::string email; + try + { + email = r.Get(0, "email"); + } + catch (const SQLException &) { } - BotInfo *bi = findbot(Config->NickServ); - NickAlias *na = findnick(account); - if (na == NULL) + const BotInfo *bi = findbot(Config->NickServ); + NickAlias *na = findnick(req->GetAccount()); + if (na == NULL) + { + na = new NickAlias(req->GetAccount(), new NickCore(req->GetAccount())); + if (user) { - na = new NickAlias(account, new NickCore(account)); if (Config->NSAddAccessOnReg) na->nc->AddAccess(create_mask(user)); if (bi) user->SendMessage(bi, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); } + } - if (!email.empty() && email != na->nc->email) - { - na->nc->email = email; - if (bi) - user->SendMessage(bi, _("Your email has been updated to \002%s\002."), email.c_str()); - } - - cmd->Execute(source, params); + if (!email.empty() && email != na->nc->email) + { + na->nc->email = email; + if (user && bi) + user->SendMessage(bi, _("Your email has been updated to \002%s\002."), email.c_str()); } + req->Success(me); delete this; } void OnError(const SQLResult &r) anope_override { Log() << "m_sql_authentication: Error executing query " << r.GetQuery().query << ": " << r.GetError(); - - if (user && cmd) - { - user->Extend("m_sql_authentication_failed", NULL); - cmd->Execute(source, params); - } - delete this; } }; @@ -84,6 +84,8 @@ class ModuleSQLAuthentication : public Module { this->SetAuthor("Anope"); + me = this; + Implementation i[] = { I_OnReload, I_OnPreCommand, I_OnCheckAuthentication }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); @@ -113,37 +115,32 @@ class ModuleSQLAuthentication : public Module return EVENT_CONTINUE; } - EventReturn OnCheckAuthentication(Command *c, CommandSource *source, const std::vector<Anope::string> ¶ms, const Anope::string &account, const Anope::string &password) anope_override + void OnCheckAuthentication(User *u, IdentifyRequest *req) anope_override { - if (!source || !source->GetUser()) - return EVENT_CONTINUE; - else if (!this->SQL) + if (!this->SQL) { Log() << "m_sql_authentication: Unable to find SQL engine"; - return EVENT_CONTINUE; + return; } - else if (source->GetUser()->HasExt("m_sql_authentication_success")) + + SQLQuery q(this->query); + q.setValue("a", req->GetAccount()); + q.setValue("p", req->GetPassword()); + if (u) { - source->GetUser()->Shrink("m_sql_authentication_success"); - return EVENT_ALLOW; + q.setValue("n", u->nick); + q.setValue("i", u->ip); } - else if (source->GetUser()->HasExt("m_sql_authentication_failed")) + else { - source->GetUser()->Shrink("m_sql_authentication_failed"); - return EVENT_CONTINUE; + q.setValue("n", ""); + q.setValue("i", ""); } - SQLQuery q(this->query); - q.setValue("a", account); - q.setValue("p", password); - q.setValue("n", source->GetNick()); - q.setValue("i", source->GetUser()->ip); - - this->SQL->Run(new SQLAuthenticationResult(this, c, *source, params, source->GetUser(), account), q); - Log(LOG_DEBUG) << "m_sql_authentication: Checking authentication for " << account; + this->SQL->Run(new SQLAuthenticationResult(u, req), q); - return EVENT_STOP; + Log(LOG_DEBUG) << "m_sql_authentication: Checking authentication for " << req->GetAccount(); } }; diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp index dc12d565e..cd7b68967 100644 --- a/modules/extra/m_xmlrpc_main.cpp +++ b/modules/extra/m_xmlrpc_main.cpp @@ -1,6 +1,37 @@ #include "module.h" #include "xmlrpc.h" +class XMLRPCIdentifyRequest : public IdentifyRequest +{ + XMLRPCRequest request; + dynamic_reference<XMLRPCServiceInterface> xinterface; + dynamic_reference<XMLRPCClientSocket> source; + + public: + XMLRPCIdentifyRequest(XMLRPCRequest& req, XMLRPCServiceInterface* iface, XMLRPCClientSocket* s, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(acc, pass), request(req), xinterface(iface), source(s) { } + + void OnSuccess() anope_override + { + if (!xinterface || !source) + return; + + request.reply("result", "Success"); + request.reply("account", GetAccount()); + + xinterface->Reply(source, &request); + } + + void OnFail() anope_override + { + if (!xinterface || !source) + return; + + request.reply("error", "Invalid password"); + + xinterface->Reply(source, &request); + } +}; + class MyXMLRPCEvent : public XMLRPCEvent { public: @@ -77,22 +108,9 @@ class MyXMLRPCEvent : public XMLRPCEvent request->reply("error", "Invalid parameters"); else { - const NickAlias *na = findnick(username); - - if (!na) - request->reply("error", "Invalid account"); - else - { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(NULL, NULL, std::vector<Anope::string>(), na->nc->display, password)); - if (MOD_RESULT == EVENT_ALLOW) - { - request->reply("result", "Success"); - request->reply("account", na->nc->display); - } - else - request->reply("error", "Invalid password"); - } + XMLRPCIdentifyRequest *req = new XMLRPCIdentifyRequest(*request, iface, source, username, password); + FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(NULL, req)); + req->Dispatch(); } } diff --git a/modules/extra/webcpanel/pages/chanserv/access.cpp b/modules/extra/webcpanel/pages/chanserv/access.cpp index d3ec2ad99..71fe1a7e9 100644 --- a/modules/extra/webcpanel/pages/chanserv/access.cpp +++ b/modules/extra/webcpanel/pages/chanserv/access.cpp @@ -11,7 +11,7 @@ WebCPanel::ChanServ::Access::Access(const Anope::string &cat, const Anope::strin { } -void WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { const Anope::string &chname = message.get_data["channel"]; @@ -19,19 +19,19 @@ void WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s { reply.error = HTTP_FOUND; reply.headers["Location"] = "http://" + message.headers["Host"] + "/chanserv/info"; - return; + return true; } ChannelInfo *ci = cs_findchan(chname); if (!ci) - return; + return true; AccessGroup u_access = ci->AccessFor(na->nc); bool has_priv = na->nc->IsServicesOper() && na->nc->o->ot->HasPriv("chanserv/access/modify"); if (!u_access.HasPriv("ACCESS_LIST") && !has_priv) - return; + return true; const ChanAccess *highest = u_access.Highest(); @@ -136,6 +136,7 @@ void WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s TemplateFileServer page("chanserv/access.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } std::set<Anope::string> WebCPanel::ChanServ::Access::GetData() anope_override diff --git a/modules/extra/webcpanel/pages/chanserv/access.h b/modules/extra/webcpanel/pages/chanserv/access.h index 50425aa40..d5fbbf68c 100644 --- a/modules/extra/webcpanel/pages/chanserv/access.h +++ b/modules/extra/webcpanel/pages/chanserv/access.h @@ -16,7 +16,7 @@ class Access : public WebPanelProtectedPage public: Access(const Anope::string &cat, const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; std::set<Anope::string> GetData() anope_override; }; diff --git a/modules/extra/webcpanel/pages/chanserv/akick.cpp b/modules/extra/webcpanel/pages/chanserv/akick.cpp index bc80437cc..bb38c5e06 100644 --- a/modules/extra/webcpanel/pages/chanserv/akick.cpp +++ b/modules/extra/webcpanel/pages/chanserv/akick.cpp @@ -11,7 +11,7 @@ WebCPanel::ChanServ::Akick::Akick(const Anope::string &cat, const Anope::string { } -void WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { const Anope::string &chname = message.get_data["channel"]; @@ -19,19 +19,19 @@ void WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st { reply.error = HTTP_FOUND; reply.headers["Location"] = "http://" + message.headers["Host"] + "/chanserv/info"; - return; + return true; } ChannelInfo *ci = cs_findchan(chname); if (!ci) - return; + return true; AccessGroup u_access = ci->AccessFor(na->nc); bool has_priv = na->nc->IsServicesOper() && na->nc->o->ot->HasPriv("chanserv/access/modify"); if (!u_access.HasPriv("akick") && !has_priv) - return; + return true; if (message.get_data["del"].empty() == false && message.get_data["mask"].empty() == false) { @@ -70,6 +70,7 @@ void WebCPanel::ChanServ::Akick::OnRequest(HTTPProvider *server, const Anope::st TemplateFileServer page("chanserv/akick.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } std::set<Anope::string> WebCPanel::ChanServ::Akick::GetData() anope_override diff --git a/modules/extra/webcpanel/pages/chanserv/akick.h b/modules/extra/webcpanel/pages/chanserv/akick.h index ff4a4653e..cd8408934 100644 --- a/modules/extra/webcpanel/pages/chanserv/akick.h +++ b/modules/extra/webcpanel/pages/chanserv/akick.h @@ -16,7 +16,7 @@ class Akick : public WebPanelProtectedPage public: Akick(const Anope::string &cat, const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; std::set<Anope::string> GetData() anope_override; }; diff --git a/modules/extra/webcpanel/pages/chanserv/info.cpp b/modules/extra/webcpanel/pages/chanserv/info.cpp index 8db88f496..44ae98537 100644 --- a/modules/extra/webcpanel/pages/chanserv/info.cpp +++ b/modules/extra/webcpanel/pages/chanserv/info.cpp @@ -11,7 +11,7 @@ WebCPanel::ChanServ::Info::Info(const Anope::string &cat, const Anope::string &u { } -void WebCPanel::ChanServ::Info::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::ChanServ::Info::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { // XXX this is slightly inefficient for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it) @@ -25,8 +25,8 @@ void WebCPanel::ChanServ::Info::OnRequest(HTTPProvider *server, const Anope::str } } - TemplateFileServer page("chanserv/main.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } diff --git a/modules/extra/webcpanel/pages/chanserv/info.h b/modules/extra/webcpanel/pages/chanserv/info.h index 87dc9836b..c55e1b1eb 100644 --- a/modules/extra/webcpanel/pages/chanserv/info.h +++ b/modules/extra/webcpanel/pages/chanserv/info.h @@ -16,7 +16,7 @@ class Info : public WebPanelProtectedPage public: Info(const Anope::string &cat, const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; }; } diff --git a/modules/extra/webcpanel/pages/chanserv/set.cpp b/modules/extra/webcpanel/pages/chanserv/set.cpp index 764eb13ac..7d144c6de 100644 --- a/modules/extra/webcpanel/pages/chanserv/set.cpp +++ b/modules/extra/webcpanel/pages/chanserv/set.cpp @@ -11,7 +11,7 @@ WebCPanel::ChanServ::Set::Set(const Anope::string &cat, const Anope::string &u) { } -void WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { const Anope::string &chname = message.get_data["channel"]; @@ -19,13 +19,13 @@ void WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri { reply.error = HTTP_FOUND; reply.headers["Location"] = "http://" + message.headers["Host"] + "/chanserv/info"; - return; + return true; } ChannelInfo *ci = cs_findchan(chname); if (!ci || !ci->AccessFor(na->nc).HasPriv("SET")) - return; + return true; if (message.post_data.empty() == false) { @@ -125,6 +125,7 @@ void WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri TemplateFileServer page("chanserv/set.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } std::set<Anope::string> WebCPanel::ChanServ::Set::GetData() anope_override diff --git a/modules/extra/webcpanel/pages/chanserv/set.h b/modules/extra/webcpanel/pages/chanserv/set.h index 67e817493..4d4113b5a 100644 --- a/modules/extra/webcpanel/pages/chanserv/set.h +++ b/modules/extra/webcpanel/pages/chanserv/set.h @@ -16,7 +16,7 @@ class Set : public WebPanelProtectedPage public: Set(const Anope::string &cat, const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; std::set<Anope::string> GetData() anope_override; }; diff --git a/modules/extra/webcpanel/pages/confirm.cpp b/modules/extra/webcpanel/pages/confirm.cpp index f18d28129..18e2004b5 100644 --- a/modules/extra/webcpanel/pages/confirm.cpp +++ b/modules/extra/webcpanel/pages/confirm.cpp @@ -7,7 +7,7 @@ #include "../webcpanel.h" -void WebCPanel::Confirm::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) +bool WebCPanel::Confirm::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) { TemplateFileServer::Replacements replacements; const Anope::string &user = message.post_data["username"], &pass = message.post_data["password"], &email = message.post_data["email"]; @@ -27,5 +27,6 @@ void WebCPanel::Confirm::OnRequest(HTTPProvider *server, const Anope::string &pa TemplateFileServer page("confirm.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } diff --git a/modules/extra/webcpanel/pages/confirm.h b/modules/extra/webcpanel/pages/confirm.h index d4d19d9c6..c6a5d180d 100644 --- a/modules/extra/webcpanel/pages/confirm.h +++ b/modules/extra/webcpanel/pages/confirm.h @@ -15,7 +15,7 @@ class Confirm : public WebPanelPage public: Confirm(const Anope::string &u) : WebPanelPage(u) { } - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override; }; } diff --git a/modules/extra/webcpanel/pages/index.cpp b/modules/extra/webcpanel/pages/index.cpp index e0db8f8de..73f7224f4 100644 --- a/modules/extra/webcpanel/pages/index.cpp +++ b/modules/extra/webcpanel/pages/index.cpp @@ -7,67 +7,93 @@ #include "../webcpanel.h" -void WebCPanel::Index::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) +class WebpanelRequest : public IdentifyRequest { + HTTPReply reply; + HTTPMessage message; + dynamic_reference<HTTPProvider> server; + Anope::string page_name; + dynamic_reference<HTTPClient> client; TemplateFileServer::Replacements replacements; - const Anope::string &user = message.post_data["username"], &pass = message.post_data["password"]; - replacements["TITLE"] = page_title; + public: + WebpanelRequest(HTTPReply &r, HTTPMessage &m, HTTPProvider *s, const Anope::string &p_n, HTTPClient *c, TemplateFileServer::Replacements &re, const Anope::string &user, const Anope::string &pass) : IdentifyRequest(user, pass), reply(r), message(m), server(s), page_name(p_n), client(c), replacements(re) { } - if (!user.empty() && !pass.empty()) + void OnSuccess() anope_override { - // Rate limit check. - - NickAlias *na = findnick(user); - - EventReturn MOD_RESULT = EVENT_CONTINUE; - - if (na) + if (!client) + return; + NickAlias *na = findnick(this->GetAccount()); + if (!na) { - FOREACH_RESULT(I_OnCheckAuthentication, OnCheckAuthentication(NULL, NULL, std::vector<Anope::string>(), na->nc->display, pass)); + this->OnFail(); + return; } - if (MOD_RESULT == EVENT_ALLOW) + Anope::string id; + for (int i = 0; i < 64; ++i) { - Anope::string id; - for (int i = 0; i < 64; ++i) - { - char c; - do - c = 48 + (rand() % 75); - while (!isalnum(c)); - id += c; - } - - na->Extend("webcpanel_id", new ExtensibleItemClass<Anope::string>(id)); - na->Extend("webcpanel_ip", new ExtensibleItemClass<Anope::string>(client->GetIP())); - - { - HTTPReply::cookie c; - c.push_back(std::make_pair("account", na->nick)); - c.push_back(std::make_pair("Path", "/")); - reply.cookies.push_back(c); - } - - { - HTTPReply::cookie c; - c.push_back(std::make_pair("id", id)); - c.push_back(std::make_pair("Path", "/")); - reply.cookies.push_back(c); - } - - reply.error = HTTP_FOUND; - reply.headers["Location"] = "http://" + message.headers["Host"] + "/nickserv/info"; - return; + char c; + do + c = 48 + (rand() % 75); + while (!isalnum(c)); + id += c; } - else + + na->Extend("webcpanel_id", new ExtensibleItemClass<Anope::string>(id)); + na->Extend("webcpanel_ip", new ExtensibleItemClass<Anope::string>(client->GetIP())); + { - replacements["INVALID_LOGIN"] = "Invalid username or password"; + HTTPReply::cookie c; + c.push_back(std::make_pair("account", na->nick)); + c.push_back(std::make_pair("Path", "/")); + reply.cookies.push_back(c); + } + + { + HTTPReply::cookie c; + c.push_back(std::make_pair("id", id)); + c.push_back(std::make_pair("Path", "/")); + reply.cookies.push_back(c); } + + reply.error = HTTP_FOUND; + reply.headers["Location"] = "http://" + message.headers["Host"] + "/nickserv/info"; + + client->SendReply(&reply); } - TemplateFileServer page("login.html"); + void OnFail() anope_override + { + if (!client) + return; + replacements["INVALID_LOGIN"] = "Invalid username or password"; + TemplateFileServer page("login.html"); + page.Serve(server, page_name, client, message, reply, replacements); + client->SendReply(&reply); + } +}; + +bool WebCPanel::Index::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) +{ + TemplateFileServer::Replacements replacements; + const Anope::string &user = message.post_data["username"], &pass = message.post_data["password"]; + + replacements["TITLE"] = page_title; + + if (!user.empty() && !pass.empty()) + { + // Rate limit check. + + WebpanelRequest *req = new WebpanelRequest(reply, message, server, page_name, client, replacements, user, pass); + FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(NULL, req)); + req->Dispatch(); + return false; + } + + TemplateFileServer page("login.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } diff --git a/modules/extra/webcpanel/pages/index.h b/modules/extra/webcpanel/pages/index.h index 2f4d9c400..e67d7181a 100644 --- a/modules/extra/webcpanel/pages/index.h +++ b/modules/extra/webcpanel/pages/index.h @@ -15,7 +15,7 @@ class Index : public WebPanelPage public: Index(const Anope::string &u) : WebPanelPage(u) { } - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override; }; } diff --git a/modules/extra/webcpanel/pages/logout.cpp b/modules/extra/webcpanel/pages/logout.cpp index 90a6a8a9b..efa93ab4f 100644 --- a/modules/extra/webcpanel/pages/logout.cpp +++ b/modules/extra/webcpanel/pages/logout.cpp @@ -11,12 +11,13 @@ WebCPanel::Logout::Logout(const Anope::string &u) : WebPanelProtectedPage("", u) { } -void WebCPanel::Logout::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::Logout::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { na->Shrink("webcpanel_id"); na->Shrink("webcpanel_ip"); reply.error = HTTP_FOUND; reply.headers["Location"] = "http://" + message.headers["Host"]; + return true; } diff --git a/modules/extra/webcpanel/pages/logout.h b/modules/extra/webcpanel/pages/logout.h index 4f31e4a00..d00a83733 100644 --- a/modules/extra/webcpanel/pages/logout.h +++ b/modules/extra/webcpanel/pages/logout.h @@ -13,7 +13,7 @@ class Logout : public WebPanelProtectedPage public: Logout(const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; }; } diff --git a/modules/extra/webcpanel/pages/memoserv/memos.cpp b/modules/extra/webcpanel/pages/memoserv/memos.cpp index eafbde3a5..00b913ef0 100644 --- a/modules/extra/webcpanel/pages/memoserv/memos.cpp +++ b/modules/extra/webcpanel/pages/memoserv/memos.cpp @@ -11,7 +11,7 @@ WebCPanel::MemoServ::Memos::Memos(const Anope::string &cat, const Anope::string { } -void WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { const Anope::string &chname = message.get_data["channel"]; ChannelInfo *ci; @@ -117,5 +117,6 @@ void WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st TemplateFileServer page("memoserv/memos.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } diff --git a/modules/extra/webcpanel/pages/memoserv/memos.h b/modules/extra/webcpanel/pages/memoserv/memos.h index 00c4c346b..32942147f 100644 --- a/modules/extra/webcpanel/pages/memoserv/memos.h +++ b/modules/extra/webcpanel/pages/memoserv/memos.h @@ -16,7 +16,7 @@ class Memos : public WebPanelProtectedPage public: Memos(const Anope::string &cat, const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; }; } diff --git a/modules/extra/webcpanel/pages/nickserv/access.cpp b/modules/extra/webcpanel/pages/nickserv/access.cpp index c18c5ccb0..40128f47e 100644 --- a/modules/extra/webcpanel/pages/nickserv/access.cpp +++ b/modules/extra/webcpanel/pages/nickserv/access.cpp @@ -11,7 +11,7 @@ WebCPanel::NickServ::Access::Access(const Anope::string &cat, const Anope::strin { } -void WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { if (message.post_data.count("access") > 0) { @@ -35,5 +35,6 @@ void WebCPanel::NickServ::Access::OnRequest(HTTPProvider *server, const Anope::s TemplateFileServer page("nickserv/access.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } diff --git a/modules/extra/webcpanel/pages/nickserv/access.h b/modules/extra/webcpanel/pages/nickserv/access.h index 3f4059aa4..068757877 100644 --- a/modules/extra/webcpanel/pages/nickserv/access.h +++ b/modules/extra/webcpanel/pages/nickserv/access.h @@ -16,7 +16,7 @@ class Access : public WebPanelProtectedPage public: Access(const Anope::string &cat, const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; }; } diff --git a/modules/extra/webcpanel/pages/nickserv/alist.cpp b/modules/extra/webcpanel/pages/nickserv/alist.cpp index d3c92dcf4..2fd184dbb 100644 --- a/modules/extra/webcpanel/pages/nickserv/alist.cpp +++ b/modules/extra/webcpanel/pages/nickserv/alist.cpp @@ -11,7 +11,7 @@ WebCPanel::NickServ::Alist::Alist(const Anope::string &cat, const Anope::string { } -void WebCPanel::NickServ::Alist::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::NickServ::Alist::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { int chan_count = 0; @@ -45,5 +45,6 @@ void WebCPanel::NickServ::Alist::OnRequest(HTTPProvider *server, const Anope::st TemplateFileServer page("nickserv/alist.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } diff --git a/modules/extra/webcpanel/pages/nickserv/alist.h b/modules/extra/webcpanel/pages/nickserv/alist.h index 5e4b31724..93ec85d03 100644 --- a/modules/extra/webcpanel/pages/nickserv/alist.h +++ b/modules/extra/webcpanel/pages/nickserv/alist.h @@ -16,7 +16,7 @@ class Alist : public WebPanelProtectedPage public: Alist(const Anope::string &cat, const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; }; } diff --git a/modules/extra/webcpanel/pages/nickserv/cert.cpp b/modules/extra/webcpanel/pages/nickserv/cert.cpp index e354addca..5c799d2f6 100644 --- a/modules/extra/webcpanel/pages/nickserv/cert.cpp +++ b/modules/extra/webcpanel/pages/nickserv/cert.cpp @@ -11,7 +11,7 @@ WebCPanel::NickServ::Cert::Cert(const Anope::string &cat, const Anope::string &u { } -void WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { if (message.post_data.count("certfp") > 0) { @@ -35,5 +35,6 @@ void WebCPanel::NickServ::Cert::OnRequest(HTTPProvider *server, const Anope::str TemplateFileServer page("nickserv/cert.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } diff --git a/modules/extra/webcpanel/pages/nickserv/cert.h b/modules/extra/webcpanel/pages/nickserv/cert.h index 1f9f1b4ad..bcc148132 100644 --- a/modules/extra/webcpanel/pages/nickserv/cert.h +++ b/modules/extra/webcpanel/pages/nickserv/cert.h @@ -16,7 +16,7 @@ class Cert : public WebPanelProtectedPage public: Cert(const Anope::string &cat, const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; }; } diff --git a/modules/extra/webcpanel/pages/nickserv/info.cpp b/modules/extra/webcpanel/pages/nickserv/info.cpp index 7ae07ad28..3ec61b03f 100644 --- a/modules/extra/webcpanel/pages/nickserv/info.cpp +++ b/modules/extra/webcpanel/pages/nickserv/info.cpp @@ -11,7 +11,7 @@ WebCPanel::NickServ::Info::Info(const Anope::string &cat, const Anope::string &u { } -void WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { if (message.post_data.empty() == false) { @@ -107,5 +107,6 @@ void WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::str TemplateFileServer page("nickserv/info.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } diff --git a/modules/extra/webcpanel/pages/nickserv/info.h b/modules/extra/webcpanel/pages/nickserv/info.h index 05fc981ac..45ffbc882 100644 --- a/modules/extra/webcpanel/pages/nickserv/info.h +++ b/modules/extra/webcpanel/pages/nickserv/info.h @@ -16,7 +16,7 @@ class Info : public WebPanelProtectedPage public: Info(const Anope::string &cat, const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; }; } diff --git a/modules/extra/webcpanel/pages/operserv/akill.cpp b/modules/extra/webcpanel/pages/operserv/akill.cpp index 8a66b8d9b..3d66b5c6a 100644 --- a/modules/extra/webcpanel/pages/operserv/akill.cpp +++ b/modules/extra/webcpanel/pages/operserv/akill.cpp @@ -11,7 +11,7 @@ WebCPanel::OperServ::Akill::Akill(const Anope::string &cat, const Anope::string { } -void WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) +bool WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { static service_reference<XLineManager> akills("XLineManager","xlinemanager/sgline"); @@ -59,5 +59,6 @@ void WebCPanel::OperServ::Akill::OnRequest(HTTPProvider *server, const Anope::st TemplateFileServer page("operserv/akill.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } diff --git a/modules/extra/webcpanel/pages/operserv/akill.h b/modules/extra/webcpanel/pages/operserv/akill.h index 4b5f8f1dd..270ae84a7 100644 --- a/modules/extra/webcpanel/pages/operserv/akill.h +++ b/modules/extra/webcpanel/pages/operserv/akill.h @@ -16,7 +16,7 @@ class Akill : public WebPanelProtectedPage public: Akill(const Anope::string &cat, const Anope::string &u); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) anope_override; }; } diff --git a/modules/extra/webcpanel/pages/register.cpp b/modules/extra/webcpanel/pages/register.cpp index 84efb3fc0..e8ed84303 100644 --- a/modules/extra/webcpanel/pages/register.cpp +++ b/modules/extra/webcpanel/pages/register.cpp @@ -7,7 +7,7 @@ #include "../webcpanel.h" -void WebCPanel::Register::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) +bool WebCPanel::Register::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) { TemplateFileServer::Replacements replacements; @@ -19,5 +19,6 @@ void WebCPanel::Register::OnRequest(HTTPProvider *server, const Anope::string &p TemplateFileServer page("register.html"); page.Serve(server, page_name, client, message, reply, replacements); + return true; } diff --git a/modules/extra/webcpanel/pages/register.h b/modules/extra/webcpanel/pages/register.h index 0651bfba6..deb46c950 100644 --- a/modules/extra/webcpanel/pages/register.h +++ b/modules/extra/webcpanel/pages/register.h @@ -15,7 +15,7 @@ class Register : public WebPanelPage public: Register(const Anope::string &u) : WebPanelPage(u) { } - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override; }; } diff --git a/modules/extra/webcpanel/static_fileserver.cpp b/modules/extra/webcpanel/static_fileserver.cpp index 6e6d5ccd4..1fbf46ee8 100644 --- a/modules/extra/webcpanel/static_fileserver.cpp +++ b/modules/extra/webcpanel/static_fileserver.cpp @@ -17,7 +17,7 @@ StaticFileServer::StaticFileServer(const Anope::string &f_n, const Anope::string { } -void StaticFileServer::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) +bool StaticFileServer::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) { int fd = open((template_base + "/" + this->file_name).c_str(), O_RDONLY); if (fd < 0) @@ -25,7 +25,7 @@ void StaticFileServer::OnRequest(HTTPProvider *server, const Anope::string &page Log(LOG_NORMAL, "httpd") << "Error serving file " << page_name << " (" << (template_base + "/" + this->file_name) << "): " << strerror(errno); client->SendError(HTTP_PAGE_NOT_FOUND, "Page not found"); - return; + return true; } reply.content_type = this->GetContentType(); @@ -37,5 +37,6 @@ void StaticFileServer::OnRequest(HTTPProvider *server, const Anope::string &page reply.Write(buffer, i); close(fd); + return true; } diff --git a/modules/extra/webcpanel/static_fileserver.h b/modules/extra/webcpanel/static_fileserver.h index 17fa7d6b2..238614610 100644 --- a/modules/extra/webcpanel/static_fileserver.h +++ b/modules/extra/webcpanel/static_fileserver.h @@ -14,6 +14,6 @@ class StaticFileServer : public HTTPPage public: StaticFileServer(const Anope::string &f_n, const Anope::string &u, const Anope::string &c_t); - void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override; + bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) anope_override; }; diff --git a/modules/extra/webcpanel/template_fileserver.cpp b/modules/extra/webcpanel/template_fileserver.cpp index 45dc4dadd..b1881b811 100644 --- a/modules/extra/webcpanel/template_fileserver.cpp +++ b/modules/extra/webcpanel/template_fileserver.cpp @@ -239,5 +239,6 @@ void TemplateFileServer::Serve(HTTPProvider *server, const Anope::string &page_n } reply.Write(finished); + return; } diff --git a/modules/extra/webcpanel/webcpanel.h b/modules/extra/webcpanel/webcpanel.h index 9573bbb6c..e33025b52 100644 --- a/modules/extra/webcpanel/webcpanel.h +++ b/modules/extra/webcpanel/webcpanel.h @@ -66,7 +66,7 @@ class WebPanelPage : public HTTPPage { } - virtual void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) = 0; + virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &) = 0; }; class WebPanelProtectedPage : public WebPanelPage @@ -78,14 +78,14 @@ class WebPanelProtectedPage : public WebPanelPage { } - void OnRequest(HTTPProvider *provider, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) anope_override anope_final + bool OnRequest(HTTPProvider *provider, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) anope_override anope_final { service_reference<Panel> panel("Panel", "webcpanel"); NickAlias *na; if (!panel || !(na = panel->GetNickFromSession(client, message))) { - return; // Access denied + return true; // Access denied } TemplateFileServer::Replacements replacements; @@ -123,10 +123,10 @@ class WebPanelProtectedPage : public WebPanelPage } } - this->OnRequest(provider, page_name, client, message, reply, na, replacements); + return this->OnRequest(provider, page_name, client, message, reply, na, replacements); } - virtual void OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) = 0; + virtual bool OnRequest(HTTPProvider *, const Anope::string &, HTTPClient *, HTTPMessage &, HTTPReply &, NickAlias *, TemplateFileServer::Replacements &) = 0; /* What get data should be appended to links in the navbar */ virtual std::set<Anope::string> GetData() { return std::set<Anope::string>(); } diff --git a/modules/extra/xmlrpc.h b/modules/extra/xmlrpc.h index baff9b18d..bc3ba893d 100644 --- a/modules/extra/xmlrpc.h +++ b/modules/extra/xmlrpc.h @@ -3,7 +3,7 @@ class XMLRPCClientSocket; class XMLRPCListenSocket; class XMLRPCServiceInterface; -class XMLRPCClientSocket : public ClientSocket, public BufferedSocket +class XMLRPCClientSocket : public ClientSocket, public BufferedSocket, public Base { protected: Anope::string query; diff --git a/src/module.cpp b/src/module.cpp index 2f70cb96b..e69b7c6a3 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -52,6 +52,7 @@ Module::~Module() ModuleManager::DetachAll(this); /* Clear any active callbacks this module has */ ModuleManager::ClearCallBacks(this); + IdentifyRequest::ModuleUnload(this); std::list<Module *>::iterator it = std::find(Modules.begin(), Modules.end(), this); if (it != Modules.end()) diff --git a/src/nickserv.cpp b/src/nickserv.cpp index 65126b987..53939c6d3 100644 --- a/src/nickserv.cpp +++ b/src/nickserv.cpp @@ -93,3 +93,62 @@ void change_core_display(NickCore *nc) change_core_display(nc, na->nick); } +std::set<IdentifyRequest *> IdentifyRequest::requests; + +IdentifyRequest::IdentifyRequest(const Anope::string &acc, const Anope::string &pass) : account(acc), password(pass), dispatched(false), success(false) +{ + requests.insert(this); +} + +IdentifyRequest::~IdentifyRequest() +{ + requests.erase(this); +} + +void IdentifyRequest::Hold(Module *m) +{ + holds.insert(m); +} + +void IdentifyRequest::Release(Module *m) +{ + holds.erase(m); + if (holds.empty() && dispatched) + { + if (!success) + this->OnFail(); + delete this; + } +} + +void IdentifyRequest::Success(Module *m) +{ + if (!success) + { + this->OnSuccess(); + success = true; + } +} + +void IdentifyRequest::Dispatch() +{ + if (holds.empty()) + { + if (!success) + this->OnFail(); + delete this; + } + else + dispatched = true; +} + +void IdentifyRequest::ModuleUnload(Module *m) +{ + for (std::set<IdentifyRequest *>::iterator it = requests.begin(), it_end = requests.end(); it != it_end;) + { + IdentifyRequest *ir = *it; + ++it; + + ir->Release(m); + } +} |