From eeb18ee6e3b1b07574a7f0fda2c0c20ac3f773df Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 16:03:21 +0100 Subject: Ensure all dynrefs with the same target resolve to the same object when one name points to multiple objects --- src/modules.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/modules.cpp b/src/modules.cpp index d7aa534ab..6510c9423 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -684,8 +684,10 @@ void dynamic_reference_base::SetProvider(const std::string& newname) void dynamic_reference_base::resolve() { - std::multimap::iterator i = ServerInstance->Modules->DataProviders.find(name); - if (i != ServerInstance->Modules->DataProviders.end()) + // Because find() may return any element with a matching key in case count(key) > 1 use lower_bound() + // to ensure a dynref with the same name as another one resolves to the same object + std::multimap::iterator i = ServerInstance->Modules.DataProviders.lower_bound(name); + if ((i != ServerInstance->Modules.DataProviders.end()) && (i->first == this->name)) value = static_cast(i->second); else value = NULL; -- cgit v1.2.3 From e37add3fab8f39b18a69453ee1533e09e7f156de Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 16:06:47 +0100 Subject: Allow dynrefs to have an OnCapture() hook --- include/dynref.h | 16 ++++++++++++++++ src/modules.cpp | 12 ++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/include/dynref.h b/include/dynref.h index a3d2f9966..2069a87eb 100644 --- a/include/dynref.h +++ b/include/dynref.h @@ -24,8 +24,18 @@ class CoreExport dynamic_reference_base : public interfacebase, public insp::intrusive_list_node { + public: + class CaptureHook + { + public: + /** Called when the target of the dynamic_reference has been acquired + */ + virtual void OnCapture() = 0; + }; + private: std::string name; + CaptureHook* hook; void resolve(); protected: ServiceProvider* value; @@ -35,6 +45,12 @@ class CoreExport dynamic_reference_base : public interfacebase, public insp::int ~dynamic_reference_base(); inline const std::string& GetProvider() { return name; } void SetProvider(const std::string& newname); + + /** Set handler to call when the target object becomes available + * @param h Handler to call + */ + void SetCaptureHook(CaptureHook* h) { hook = h; } + void check(); operator bool() { return (value != NULL); } static void reset_all(); diff --git a/src/modules.cpp b/src/modules.cpp index 6510c9423..55d41674b 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -655,7 +655,7 @@ ServiceProvider* ModuleManager::FindService(ServiceType type, const std::string& } dynamic_reference_base::dynamic_reference_base(Module* Creator, const std::string& Name) - : name(Name), value(NULL), creator(Creator) + : name(Name), hook(NULL), value(NULL), creator(Creator) { if (!dynrefs) dynrefs = new insp::intrusive_list; @@ -688,7 +688,15 @@ void dynamic_reference_base::resolve() // to ensure a dynref with the same name as another one resolves to the same object std::multimap::iterator i = ServerInstance->Modules.DataProviders.lower_bound(name); if ((i != ServerInstance->Modules.DataProviders.end()) && (i->first == this->name)) - value = static_cast(i->second); + { + ServiceProvider* newvalue = i->second; + if (value != newvalue) + { + value = newvalue; + if (hook) + hook->OnCapture(); + } + } else value = NULL; } -- cgit v1.2.3 From 8c2135aad0b2bbd8afca21a6c0664a9e4182dc9b Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 16:46:11 +0100 Subject: Convert the account login event to use the new cross-module event system --- include/modules/account.h | 27 +++++++++++++++++---------- src/modules/m_ircv3.cpp | 36 +++++++++++++++++------------------- src/modules/m_services_account.cpp | 13 ++++++------- 3 files changed, 40 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/include/modules/account.h b/include/modules/account.h index c00b044e4..0368127a6 100644 --- a/include/modules/account.h +++ b/include/modules/account.h @@ -22,16 +22,7 @@ #include #include -class AccountEvent : public Event -{ - public: - User* const user; - const std::string account; - AccountEvent(Module* me, User* u, const std::string& name) - : Event(me, "account_login"), user(u), account(name) - { - } -}; +#include "event.h" typedef StringExtItem AccountExtItem; @@ -39,3 +30,19 @@ inline AccountExtItem* GetAccountExtItem() { return static_cast(ServerInstance->Extensions.GetItem("accountname")); } + +class AccountEventListener : public Events::ModuleEventListener +{ + public: + AccountEventListener(Module* mod) + : ModuleEventListener(mod, "event/account") + { + } + + /** Called when a user logs in or logs out + * @param user User logging in or out + * @param newaccount New account name of the user or empty string if the user + * logged out + */ + virtual void OnAccountChange(User* user, const std::string& newaccount) = 0; +}; diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp index b1c04cdf5..b80c110f4 100644 --- a/src/modules/m_ircv3.cpp +++ b/src/modules/m_ircv3.cpp @@ -40,7 +40,7 @@ class WriteNeighboursWithExt : public User::ForEachNeighborHandler } }; -class ModuleIRCv3 : public Module +class ModuleIRCv3 : public Module, public AccountEventListener { GenericCap cap_accountnotify; GenericCap cap_awaynotify; @@ -52,7 +52,9 @@ class ModuleIRCv3 : public Module CUList last_excepts; public: - ModuleIRCv3() : cap_accountnotify(this, "account-notify"), + ModuleIRCv3() + : AccountEventListener(this) + , cap_accountnotify(this, "account-notify"), cap_awaynotify(this, "away-notify"), cap_extendedjoin(this, "extended-join") { @@ -74,25 +76,21 @@ class ModuleIRCv3 : public Module cap_extendedjoin.HandleEvent(ev); if (accountnotify) - { cap_accountnotify.HandleEvent(ev); + } - if (ev.id == "account_login") - { - AccountEvent* ae = static_cast(&ev); - - // :nick!user@host ACCOUNT account - // or - // :nick!user@host ACCOUNT * - std::string line = ":" + ae->user->GetFullHost() + " ACCOUNT "; - if (ae->account.empty()) - line += "*"; - else - line += std::string(ae->account); - - WriteNeighboursWithExt(ae->user, line, cap_accountnotify.ext); - } - } + void OnAccountChange(User* user, const std::string& newaccount) CXX11_OVERRIDE + { + // :nick!user@host ACCOUNT account + // or + // :nick!user@host ACCOUNT * + std::string line = ":" + user->GetFullHost() + " ACCOUNT "; + if (newaccount.empty()) + line += "*"; + else + line += newaccount; + + WriteNeighboursWithExt(user, line, cap_accountnotify.ext); } void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts) CXX11_OVERRIDE diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp index aac0b9ce0..26a53b4d7 100644 --- a/src/modules/m_services_account.cpp +++ b/src/modules/m_services_account.cpp @@ -104,9 +104,12 @@ class AChannel_M : public SimpleChannelModeHandler class AccountExtItemImpl : public AccountExtItem { + Events::ModuleEventProvider eventprov; + public: AccountExtItemImpl(Module* mod) : AccountExtItem("accountname", ExtensionItem::EXT_USER, mod) + , eventprov(mod, "event/account") { } @@ -123,14 +126,10 @@ class AccountExtItemImpl : public AccountExtItem user->WriteNumeric(900, "%s %s :You are now logged in as %s", user->GetFullHost().c_str(), value.c_str(), value.c_str()); } - - AccountEvent(creator, user, value).Send(); - } - else - { - // Logged out - AccountEvent(creator, user, "").Send(); } + // If value is empty then logged out + + FOREACH_MOD_CUSTOM(eventprov, AccountEventListener, OnAccountChange, (user, value)); } }; -- cgit v1.2.3 From 971788e42fbdce52a6dcf201e52afd690506c3a9 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 16:52:39 +0100 Subject: Allow enabling/disabling caps via GenericCap::SetActive() --- include/modules/cap.h | 11 ++++++++++- src/modules/m_ircv3.cpp | 27 ++++++++++----------------- 2 files changed, 20 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/include/modules/cap.h b/include/modules/cap.h index cc1cb8d8c..fae7fff15 100644 --- a/include/modules/cap.h +++ b/include/modules/cap.h @@ -40,11 +40,14 @@ class CapEvent : public Event class GenericCap { + bool active; + public: LocalIntExt ext; const std::string cap; GenericCap(Module* parent, const std::string& Cap) - : ext("cap_" + Cap, ExtensionItem::EXT_USER, parent) + : active(true) + , ext("cap_" + Cap, ExtensionItem::EXT_USER, parent) , cap(Cap) { } @@ -54,6 +57,9 @@ class GenericCap if (ev.id != "cap_request") return; + if (!active) + return; + CapEvent *data = static_cast(&ev); if (data->type == CapEvent::CAPEVENT_REQ) { @@ -87,4 +93,7 @@ class GenericCap ext.set(data->user, 0); } } + + void SetActive(bool newstate) { active = newstate; } + bool IsActive() const { return active; } }; diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp index b80c110f4..861ccec14 100644 --- a/src/modules/m_ircv3.cpp +++ b/src/modules/m_ircv3.cpp @@ -45,9 +45,6 @@ class ModuleIRCv3 : public Module, public AccountEventListener GenericCap cap_accountnotify; GenericCap cap_awaynotify; GenericCap cap_extendedjoin; - bool accountnotify; - bool awaynotify; - bool extendedjoin; CUList last_excepts; @@ -63,20 +60,16 @@ class ModuleIRCv3 : public Module, public AccountEventListener void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE { ConfigTag* conf = ServerInstance->Config->ConfValue("ircv3"); - accountnotify = conf->getBool("accountnotify", true); - awaynotify = conf->getBool("awaynotify", true); - extendedjoin = conf->getBool("extendedjoin", true); + cap_accountnotify.SetActive(conf->getBool("accountnotify", true)); + cap_awaynotify.SetActive(conf->getBool("awaynotify", true)); + cap_extendedjoin.SetActive(conf->getBool("extendedjoin", true)); } void OnEvent(Event& ev) CXX11_OVERRIDE { - if (awaynotify) - cap_awaynotify.HandleEvent(ev); - if (extendedjoin) - cap_extendedjoin.HandleEvent(ev); - - if (accountnotify) - cap_accountnotify.HandleEvent(ev); + cap_awaynotify.HandleEvent(ev); + cap_extendedjoin.HandleEvent(ev); + cap_accountnotify.HandleEvent(ev); } void OnAccountChange(User* user, const std::string& newaccount) CXX11_OVERRIDE @@ -96,10 +89,10 @@ class ModuleIRCv3 : public Module, public AccountEventListener void OnUserJoin(Membership* memb, bool sync, bool created, CUList& excepts) CXX11_OVERRIDE { // Remember who is not going to see the JOIN because of other modules - if ((awaynotify) && (memb->user->IsAway())) + if ((cap_awaynotify.IsActive()) && (memb->user->IsAway())) last_excepts = excepts; - if (!extendedjoin) + if (!cap_extendedjoin.IsActive()) return; /* @@ -168,7 +161,7 @@ class ModuleIRCv3 : public Module, public AccountEventListener ModResult OnSetAway(User* user, const std::string &awaymsg) CXX11_OVERRIDE { - if (awaynotify) + if (cap_awaynotify.IsActive()) { // Going away: n!u@h AWAY :reason // Back from away: n!u@h AWAY @@ -183,7 +176,7 @@ class ModuleIRCv3 : public Module, public AccountEventListener void OnPostJoin(Membership *memb) CXX11_OVERRIDE { - if ((!awaynotify) || (!memb->user->IsAway())) + if ((!cap_awaynotify.IsActive()) || (!memb->user->IsAway())) return; std::string line = ":" + memb->user->GetFullHost() + " AWAY :" + memb->user->awaymsg; -- cgit v1.2.3 From f3ef8a230cf3a0e3c3f75f7e37d2a1945e531754 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 17:01:00 +0100 Subject: Convert the CAP event to use the new cross-module event system --- include/modules/cap.h | 16 ++++++++-------- src/modules/m_cap.cpp | 9 ++++++--- src/modules/m_ircv3.cpp | 7 ------- src/modules/m_namesx.cpp | 5 ----- src/modules/m_sasl.cpp | 5 ----- src/modules/m_starttls.cpp | 5 ----- src/modules/m_uhnames.cpp | 5 ----- 7 files changed, 14 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/include/modules/cap.h b/include/modules/cap.h index fae7fff15..7aa60cd21 100644 --- a/include/modules/cap.h +++ b/include/modules/cap.h @@ -20,7 +20,9 @@ #pragma once -class CapEvent : public Event +#include "event.h" + +class CapEvent { public: enum CapEventType @@ -35,10 +37,10 @@ class CapEvent : public Event std::vector wanted; std::vector ack; User* user; - CapEvent(Module* sender, User* u, CapEventType capevtype) : Event(sender, "cap_request"), type(capevtype), user(u) {} + CapEvent(Module* sender, User* u, CapEventType capevtype) : type(capevtype), user(u) {} }; -class GenericCap +class GenericCap : public Events::ModuleEventListener { bool active; @@ -46,17 +48,15 @@ class GenericCap LocalIntExt ext; const std::string cap; GenericCap(Module* parent, const std::string& Cap) - : active(true) + : Events::ModuleEventListener(parent, "event/cap") + , active(true) , ext("cap_" + Cap, ExtensionItem::EXT_USER, parent) , cap(Cap) { } - void HandleEvent(Event& ev) + void OnCapEvent(CapEvent& ev) CXX11_OVERRIDE { - if (ev.id != "cap_request") - return; - if (!active) return; diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp index db5d85f0f..2c2178a18 100644 --- a/src/modules/m_cap.cpp +++ b/src/modules/m_cap.cpp @@ -39,9 +39,12 @@ CAP END */ class CommandCAP : public Command { + Events::ModuleEventProvider capevprov; + public: LocalIntExt reghold; CommandCAP (Module* mod) : Command(mod, "CAP", 1), + capevprov(mod, "event/cap"), reghold("CAP_REGHOLD", ExtensionItem::EXT_USER, mod) { works_before_reg = true; @@ -70,7 +73,7 @@ class CommandCAP : public Command } reghold.set(user, 1); - Data.Send(); + FOREACH_MOD_CUSTOM(capevprov, GenericCap, OnCapEvent, (Data)); if (Data.ack.size() > 0) { @@ -93,7 +96,7 @@ class CommandCAP : public Command CapEvent Data(creator, user, subcommand == "LS" ? CapEvent::CAPEVENT_LS : CapEvent::CAPEVENT_LIST); reghold.set(user, 1); - Data.Send(); + FOREACH_MOD_CUSTOM(capevprov, GenericCap, OnCapEvent, (Data)); std::string Result = irc::stringjoiner(Data.wanted); user->WriteCommand("CAP", subcommand + " :" + Result); @@ -103,7 +106,7 @@ class CommandCAP : public Command CapEvent Data(creator, user, CapEvent::CAPEVENT_CLEAR); reghold.set(user, 1); - Data.Send(); + FOREACH_MOD_CUSTOM(capevprov, GenericCap, OnCapEvent, (Data)); std::string Result = irc::stringjoiner(Data.ack); user->WriteCommand("CAP", "ACK :" + Result); diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp index 861ccec14..caee0d329 100644 --- a/src/modules/m_ircv3.cpp +++ b/src/modules/m_ircv3.cpp @@ -65,13 +65,6 @@ class ModuleIRCv3 : public Module, public AccountEventListener cap_extendedjoin.SetActive(conf->getBool("extendedjoin", true)); } - void OnEvent(Event& ev) CXX11_OVERRIDE - { - cap_awaynotify.HandleEvent(ev); - cap_extendedjoin.HandleEvent(ev); - cap_accountnotify.HandleEvent(ev); - } - void OnAccountChange(User* user, const std::string& newaccount) CXX11_OVERRIDE { // :nick!user@host ACCOUNT account diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp index f211b01d8..c701f16bf 100644 --- a/src/modules/m_namesx.cpp +++ b/src/modules/m_namesx.cpp @@ -94,11 +94,6 @@ class ModuleNamesX : public Module line.erase(pos, 1); line.insert(pos, prefixes); } - - void OnEvent(Event& ev) CXX11_OVERRIDE - { - cap.HandleEvent(ev); - } }; MODULE_INIT(ModuleNamesX) diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp index 0a2c840bd..ade998b4e 100644 --- a/src/modules/m_sasl.cpp +++ b/src/modules/m_sasl.cpp @@ -283,11 +283,6 @@ class ModuleSASL : public Module { return Version("Provides support for IRC Authentication Layer (aka: atheme SASL) via AUTHENTICATE.",VF_VENDOR); } - - void OnEvent(Event &ev) CXX11_OVERRIDE - { - cap.HandleEvent(ev); - } }; MODULE_INIT(ModuleSASL) diff --git a/src/modules/m_starttls.cpp b/src/modules/m_starttls.cpp index d591eed55..b05302fa9 100644 --- a/src/modules/m_starttls.cpp +++ b/src/modules/m_starttls.cpp @@ -102,11 +102,6 @@ class ModuleStartTLS : public Module ssl.SetProvider("ssl/" + newprovider); } - void OnEvent(Event& ev) CXX11_OVERRIDE - { - tls.HandleEvent(ev); - } - void On005Numeric(std::map& tokens) CXX11_OVERRIDE { tokens["STARTTLS"]; diff --git a/src/modules/m_uhnames.cpp b/src/modules/m_uhnames.cpp index 0a171c4dc..90bac54f5 100644 --- a/src/modules/m_uhnames.cpp +++ b/src/modules/m_uhnames.cpp @@ -66,11 +66,6 @@ class ModuleUHNames : public Module return MOD_RES_PASSTHRU; } - - void OnEvent(Event& ev) CXX11_OVERRIDE - { - cap.HandleEvent(ev); - } }; MODULE_INIT(ModuleUHNames) -- cgit v1.2.3 From c19e9d0edbb1be9d5fd6f281bce054066fc4a003 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 17:04:26 +0100 Subject: Convert the SASL fallback event to use the new cross-module event system --- include/modules/sasl.h | 12 +++++++----- src/modules/m_sasl.cpp | 6 +++++- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/include/modules/sasl.h b/include/modules/sasl.h index 321711a68..0a7b19a70 100644 --- a/include/modules/sasl.h +++ b/include/modules/sasl.h @@ -19,13 +19,15 @@ #pragma once -class SASLFallback : public Event +#include "event.h" + +class SASLEventListener : public Events::ModuleEventListener { public: - const parameterlist& params; - SASLFallback(Module* me, const parameterlist& p) - : Event(me, "sasl_fallback"), params(p) + SASLEventListener(Module* mod) + : ModuleEventListener(mod, "event/sasl") { - Send(); } + + virtual void OnSASLAuth(const parameterlist& params) = 0; }; diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp index ade998b4e..c96b87034 100644 --- a/src/modules/m_sasl.cpp +++ b/src/modules/m_sasl.cpp @@ -28,12 +28,13 @@ enum SaslState { SASL_INIT, SASL_COMM, SASL_DONE }; enum SaslResult { SASL_OK, SASL_FAIL, SASL_ABORT }; static std::string sasl_target = "*"; +static Events::ModuleEventProvider* saslevprov; static void SendSASL(const parameterlist& params) { if (!ServerInstance->PI->SendEncapsulatedData(sasl_target, "SASL", params)) { - SASLFallback(NULL, params); + FOREACH_MOD_CUSTOM(*saslevprov, SASLEventListener, OnSASLAuth, (params)); } } @@ -246,6 +247,7 @@ class ModuleSASL : public Module GenericCap cap; CommandAuthenticate auth; CommandSASL sasl; + Events::ModuleEventProvider sasleventprov; public: ModuleSASL() @@ -253,7 +255,9 @@ class ModuleSASL : public Module , cap(this, "sasl") , auth(this, authExt, cap) , sasl(this, authExt) + , sasleventprov(this, "event/sasl") { + saslevprov = &sasleventprov; } void init() CXX11_OVERRIDE -- cgit v1.2.3 From 96dd0a52d93219a214130c18fe34bb81ce5acdbd Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 17:09:59 +0100 Subject: Convert the HTTPd ACL event to use the new cross-module event system --- include/modules/httpd.h | 12 ++++++++++++ src/modules/m_httpd.cpp | 9 +++++++-- src/modules/m_httpd_acl.cpp | 26 +++++++++++++++++--------- 3 files changed, 36 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/include/modules/httpd.h b/include/modules/httpd.h index 86234d53f..5e3e780dc 100644 --- a/include/modules/httpd.h +++ b/include/modules/httpd.h @@ -24,6 +24,7 @@ #pragma once #include "base.h" +#include "event.h" #include #include @@ -237,3 +238,14 @@ class HTTPdAPI : public dynamic_reference { } }; + +class HTTPACLEventListener : public Events::ModuleEventListener +{ + public: + HTTPACLEventListener(Module* mod) + : ModuleEventListener(mod, "event/http-acl") + { + } + + virtual ModResult OnHTTPACLCheck(HTTPRequest& req) = 0; +}; diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index bbd9f1275..0dd028924 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -31,6 +31,7 @@ class ModuleHttpServer; static ModuleHttpServer* HttpModule; static bool claimed; static insp::intrusive_list sockets; +static Events::ModuleEventProvider* aclevprov; /** HTTP socket states */ @@ -323,9 +324,10 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru InternalState = HTTP_SERVE_SEND_DATA; claimed = false; + ModResult MOD_RESULT; HTTPRequest acl((Module*)HttpModule, "httpd_acl", request_type, uri, &headers, this, ip, postdata); - acl.Send(); - if (!claimed) + FIRST_MOD_RESULT_CUSTOM(*aclevprov, HTTPACLEventListener, OnHTTPACLCheck, MOD_RESULT, (acl)); + if (MOD_RESULT != MOD_RES_DENY) { HTTPRequest url((Module*)HttpModule, "httpd_url", request_type, uri, &headers, this, ip, postdata); url.Send(); @@ -372,11 +374,14 @@ class ModuleHttpServer : public Module { HTTPdAPIImpl APIImpl; unsigned int timeoutsec; + Events::ModuleEventProvider acleventprov; public: ModuleHttpServer() : APIImpl(this) + , acleventprov(this, "event/http-acl") { + aclevprov = &acleventprov; } void init() CXX11_OVERRIDE diff --git a/src/modules/m_httpd_acl.cpp b/src/modules/m_httpd_acl.cpp index 58bbbde2a..866fa0e86 100644 --- a/src/modules/m_httpd_acl.cpp +++ b/src/modules/m_httpd_acl.cpp @@ -36,7 +36,7 @@ class HTTPACL blacklist(set_blacklist) { } }; -class ModuleHTTPAccessList : public Module +class ModuleHTTPAccessList : public Module, public HTTPACLEventListener { std::string stylesheet; std::vector acl_list; @@ -44,7 +44,8 @@ class ModuleHTTPAccessList : public Module public: ModuleHTTPAccessList() - : API(this) + : HTTPACLEventListener(this) + , API(this) { } @@ -104,12 +105,10 @@ class ModuleHTTPAccessList : public Module API->SendResponse(response); } - void OnEvent(Event& event) CXX11_OVERRIDE + bool IsAccessAllowed(HTTPRequest* http) { - if (event.id == "httpd_acl") { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Handling httpd acl event"); - HTTPRequest* http = (HTTPRequest*)&event; for (std::vector::const_iterator this_acl = acl_list.begin(); this_acl != acl_list.end(); ++this_acl) { @@ -128,7 +127,7 @@ class ModuleHTTPAccessList : public Module ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Denying access to blacklisted resource %s (matched by pattern %s) from ip %s (matched by entry %s)", http->GetURI().c_str(), this_acl->path.c_str(), http->GetIP().c_str(), entry.c_str()); BlockAccess(http, 403); - return; + return false; } } } @@ -150,7 +149,7 @@ class ModuleHTTPAccessList : public Module ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Denying access to whitelisted resource %s (matched by pattern %s) from ip %s (Not in whitelist)", http->GetURI().c_str(), this_acl->path.c_str(), http->GetIP().c_str()); BlockAccess(http, 403); - return; + return false; } } if (!this_acl->password.empty() && !this_acl->username.empty()) @@ -186,7 +185,7 @@ class ModuleHTTPAccessList : public Module if (user == this_acl->username && pass == this_acl->password) { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "HTTP authorization: password and username match"); - return; + return true; } else /* Invalid password */ @@ -205,13 +204,22 @@ class ModuleHTTPAccessList : public Module /* No password given at all, access denied */ BlockAccess(http, 401, "WWW-Authenticate", "Basic realm=\"Restricted Object\""); } + return false; } /* A path may only match one ACL (the first it finds in the config file) */ - return; + break; } } } + return true; + } + + ModResult OnHTTPACLCheck(HTTPRequest& req) CXX11_OVERRIDE + { + if (IsAccessAllowed(&req)) + return MOD_RES_PASSTHRU; + return MOD_RES_DENY; } Version GetVersion() CXX11_OVERRIDE -- cgit v1.2.3 From 1e8e379dce7a3311eff7161269593f1655f577eb Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 17:13:08 +0100 Subject: Convert the HTTPd request event to use the new cross-module event system --- include/modules/httpd.h | 15 +++++++++++++-- src/modules/m_httpd.cpp | 8 ++++++-- src/modules/m_httpd_config.cpp | 16 +++++++++++----- src/modules/m_httpd_stats.cpp | 16 +++++++++++----- 4 files changed, 41 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/include/modules/httpd.h b/include/modules/httpd.h index 5e3e780dc..60032cb16 100644 --- a/include/modules/httpd.h +++ b/include/modules/httpd.h @@ -108,7 +108,7 @@ class HttpServerSocket; /** This class represents a HTTP request. */ -class HTTPRequest : public Event +class HTTPRequest { protected: std::string type; @@ -137,7 +137,7 @@ class HTTPRequest : public Event */ HTTPRequest(Module* me, const std::string &eventid, const std::string &request_type, const std::string &uri, HTTPHeaders* hdr, HttpServerSocket* socket, const std::string &ip, const std::string &pdata) - : Event(me, eventid), type(request_type), document(uri), ipaddr(ip), postdata(pdata), headers(hdr), sock(socket) + : type(request_type), document(uri), ipaddr(ip), postdata(pdata), headers(hdr), sock(socket) { } @@ -249,3 +249,14 @@ class HTTPACLEventListener : public Events::ModuleEventListener virtual ModResult OnHTTPACLCheck(HTTPRequest& req) = 0; }; + +class HTTPRequestEventListener : public Events::ModuleEventListener +{ + public: + HTTPRequestEventListener(Module* mod) + : ModuleEventListener(mod, "event/http-request") + { + } + + virtual ModResult OnHTTPRequest(HTTPRequest& req) = 0; +}; diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index 0dd028924..3558b0a2b 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -32,6 +32,7 @@ static ModuleHttpServer* HttpModule; static bool claimed; static insp::intrusive_list sockets; static Events::ModuleEventProvider* aclevprov; +static Events::ModuleEventProvider* reqevprov; /** HTTP socket states */ @@ -330,8 +331,8 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru if (MOD_RESULT != MOD_RES_DENY) { HTTPRequest url((Module*)HttpModule, "httpd_url", request_type, uri, &headers, this, ip, postdata); - url.Send(); - if (!claimed) + FIRST_MOD_RESULT_CUSTOM(*reqevprov, HTTPRequestEventListener, OnHTTPRequest, MOD_RESULT, (url)); + if (MOD_RESULT == MOD_RES_PASSTHRU) { SendHTTPError(404); } @@ -375,13 +376,16 @@ class ModuleHttpServer : public Module HTTPdAPIImpl APIImpl; unsigned int timeoutsec; Events::ModuleEventProvider acleventprov; + Events::ModuleEventProvider reqeventprov; public: ModuleHttpServer() : APIImpl(this) , acleventprov(this, "event/http-acl") + , reqeventprov(this, "event/http-request") { aclevprov = &acleventprov; + reqevprov = &reqeventprov; } void init() CXX11_OVERRIDE diff --git a/src/modules/m_httpd_config.cpp b/src/modules/m_httpd_config.cpp index 3c4680799..6fd7f4050 100644 --- a/src/modules/m_httpd_config.cpp +++ b/src/modules/m_httpd_config.cpp @@ -21,13 +21,14 @@ #include "inspircd.h" #include "modules/httpd.h" -class ModuleHttpConfig : public Module +class ModuleHttpConfig : public Module, public HTTPRequestEventListener { HTTPdAPI API; public: ModuleHttpConfig() - : API(this) + : HTTPRequestEventListener(this) + , API(this) { } @@ -65,14 +66,12 @@ class ModuleHttpConfig : public Module return ret; } - void OnEvent(Event& event) CXX11_OVERRIDE + ModResult HandleRequest(HTTPRequest* http) { std::stringstream data(""); - if (event.id == "httpd_url") { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Handling httpd event"); - HTTPRequest* http = (HTTPRequest*)&event; if ((http->GetURI() == "/config") || (http->GetURI() == "/config/")) { @@ -96,8 +95,15 @@ class ModuleHttpConfig : public Module response.headers.SetHeader("X-Powered-By", MODNAME); response.headers.SetHeader("Content-Type", "text/html"); API->SendResponse(response); + return MOD_RES_DENY; // Handled } } + return MOD_RES_PASSTHRU; + } + + ModResult OnHTTPRequest(HTTPRequest& req) CXX11_OVERRIDE + { + return HandleRequest(&req); } Version GetVersion() CXX11_OVERRIDE diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index 30eacd7a7..983566e55 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -25,14 +25,15 @@ #include "modules/httpd.h" #include "xline.h" -class ModuleHttpStats : public Module +class ModuleHttpStats : public Module, public HTTPRequestEventListener { static const insp::flat_map& entities; HTTPdAPI API; public: ModuleHttpStats() - : API(this) + : HTTPRequestEventListener(this) + , API(this) { } @@ -87,14 +88,12 @@ class ModuleHttpStats : public Module data << ""; } - void OnEvent(Event& event) CXX11_OVERRIDE + ModResult HandleRequest(HTTPRequest* http) { std::stringstream data(""); - if (event.id == "httpd_url") { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Handling httpd event"); - HTTPRequest* http = (HTTPRequest*)&event; if ((http->GetURI() == "/stats") || (http->GetURI() == "/stats/")) { @@ -231,8 +230,15 @@ class ModuleHttpStats : public Module response.headers.SetHeader("X-Powered-By", MODNAME); response.headers.SetHeader("Content-Type", "text/xml"); API->SendResponse(response); + return MOD_RES_DENY; // Handled } } + return MOD_RES_PASSTHRU; + } + + ModResult OnHTTPRequest(HTTPRequest& req) CXX11_OVERRIDE + { + return HandleRequest(&req); } Version GetVersion() CXX11_OVERRIDE -- cgit v1.2.3 From 3b83968416bcc5710c394892bb2ac1cc79f0298a Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 17:15:57 +0100 Subject: Remove unused parameters from HTTPRequest constructor --- include/modules/httpd.h | 2 +- src/modules/m_httpd.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/include/modules/httpd.h b/include/modules/httpd.h index 60032cb16..b4b88bed5 100644 --- a/include/modules/httpd.h +++ b/include/modules/httpd.h @@ -135,7 +135,7 @@ class HTTPRequest * @param ip The IP address making the web request. * @param pdata The post data (content after headers) received with the request, up to Content-Length in size */ - HTTPRequest(Module* me, const std::string &eventid, const std::string &request_type, const std::string &uri, + HTTPRequest(const std::string& request_type, const std::string& uri, HTTPHeaders* hdr, HttpServerSocket* socket, const std::string &ip, const std::string &pdata) : type(request_type), document(uri), ipaddr(ip), postdata(pdata), headers(hdr), sock(socket) { diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index 3558b0a2b..47416406e 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -326,11 +326,11 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru claimed = false; ModResult MOD_RESULT; - HTTPRequest acl((Module*)HttpModule, "httpd_acl", request_type, uri, &headers, this, ip, postdata); + HTTPRequest acl(request_type, uri, &headers, this, ip, postdata); FIRST_MOD_RESULT_CUSTOM(*aclevprov, HTTPACLEventListener, OnHTTPACLCheck, MOD_RESULT, (acl)); if (MOD_RESULT != MOD_RES_DENY) { - HTTPRequest url((Module*)HttpModule, "httpd_url", request_type, uri, &headers, this, ip, postdata); + HTTPRequest url(request_type, uri, &headers, this, ip, postdata); FIRST_MOD_RESULT_CUSTOM(*reqevprov, HTTPRequestEventListener, OnHTTPRequest, MOD_RESULT, (url)); if (MOD_RESULT == MOD_RES_PASSTHRU) { -- cgit v1.2.3 From 0b8a9b55667e767f93e93adc1aee9bc3c05f1888 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 17:23:08 +0100 Subject: Convert the spanningtree events to use the new cross-module event system --- include/modules/spanningtree.h | 29 +++++++++++++++-------------- src/modules/m_spanningtree/main.cpp | 1 + src/modules/m_spanningtree/main.h | 7 +++++++ src/modules/m_spanningtree/treeserver.cpp | 4 ++-- 4 files changed, 25 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/include/modules/spanningtree.h b/include/modules/spanningtree.h index 99f4f9fc4..0f51c35db 100644 --- a/include/modules/spanningtree.h +++ b/include/modules/spanningtree.h @@ -19,22 +19,23 @@ #pragma once -struct AddServerEvent : public Event -{ - const std::string servername; - AddServerEvent(Module* me, const std::string& name) - : Event(me, "new_server"), servername(name) - { - Send(); - } -}; +#include "event.h" -struct DelServerEvent : public Event +class SpanningTreeEventListener : public Events::ModuleEventListener { - const std::string servername; - DelServerEvent(Module* me, const std::string& name) - : Event(me, "lost_server"), servername(name) + public: + SpanningTreeEventListener(Module* mod) + : ModuleEventListener(mod, "event/spanningtree") { - Send(); } + + /** Fired when a server finishes burst + * @param server Server that recently linked and finished burst + */ + virtual void OnServerLink(const std::string& server) { } + + /** Fired when a server splits + * @param server Server that split + */ + virtual void OnServerSplit(const std::string& server) { } }; diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 31d822789..e5e6e522b 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -39,6 +39,7 @@ ModuleSpanningTree::ModuleSpanningTree() : rconnect(this), rsquit(this), map(this) , commands(NULL) , currmembid(0) + , eventprov(this, "event/spanningtree") , DNS(this, "DNS") , loopCall(false) { diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index 13c743f73..9fde32cad 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -24,6 +24,7 @@ #pragma once #include "inspircd.h" +#include "event.h" #include "modules/dns.h" #include "servercommand.h" #include "commands.h" @@ -72,6 +73,10 @@ class ModuleSpanningTree : public Module */ SpanningTreeProtocolInterface protocolinterface; + /** Event provider for our events + */ + Events::ModuleEventProvider eventprov; + public: dynamic_reference DNS; @@ -135,6 +140,8 @@ class ModuleSpanningTree : public Module */ static std::string TimeToStr(time_t secs); + const Events::ModuleEventProvider& GetEventProvider() const { return eventprov; } + /** ** *** MODULE EVENTS *** **/ diff --git a/src/modules/m_spanningtree/treeserver.cpp b/src/modules/m_spanningtree/treeserver.cpp index e004f897e..6ebce07f9 100644 --- a/src/modules/m_spanningtree/treeserver.cpp +++ b/src/modules/m_spanningtree/treeserver.cpp @@ -151,7 +151,7 @@ void TreeServer::FinishBurst() unsigned long bursttime = ts - this->StartBurst; ServerInstance->SNO->WriteToSnoMask(Parent == Utils->TreeRoot ? 'l' : 'L', "Received end of netburst from \2%s\2 (burst time: %lu %s)", GetName().c_str(), (bursttime > 10000 ? bursttime / 1000 : bursttime), (bursttime > 10000 ? "secs" : "msecs")); - AddServerEvent(Utils->Creator, GetName()); + FOREACH_MOD_CUSTOM(Utils->Creator->GetEventProvider(), SpanningTreeEventListener, OnServerLink, (GetName())); StartBurst = 0; FinishBurstInternal(); @@ -159,7 +159,7 @@ void TreeServer::FinishBurst() void TreeServer::SQuitChild(TreeServer* server, const std::string& reason) { - DelServerEvent(Utils->Creator, server->GetName()); + FOREACH_MOD_CUSTOM(Utils->Creator->GetEventProvider(), SpanningTreeEventListener, OnServerSplit, (server->GetName())); stdalgo::erase(Children, server); if (IsRoot()) -- cgit v1.2.3 From 0204f2254dd44db8b68fd0e658fda130e84aa9cf Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 17:24:14 +0100 Subject: Remove class Event and the OnEvent hook --- include/modules.h | 36 +----------------------------------- src/modules.cpp | 8 -------- 2 files changed, 1 insertion(+), 43 deletions(-) (limited to 'src') diff --git a/include/modules.h b/include/modules.h index 5a4090dfb..d034ebac2 100644 --- a/include/modules.h +++ b/include/modules.h @@ -206,34 +206,6 @@ class CoreExport Version virtual ~Version() {} }; -/** The Event class is a unicast message directed at all modules. - * When the class is properly instantiated it may be sent to all modules - * using the Send() method, which will trigger the OnEvent method in - * all modules passing the object as its parameter. - */ -class CoreExport Event : public classbase -{ - public: - /** This is a pointer to the sender of the message, which can be used to - * directly trigger events, or to create a reply. - */ - ModuleRef source; - /** The event identifier. - * This is arbitary text which should be used to distinguish - * one type of event from another. - */ - const std::string id; - - /** Create a new Event - */ - Event(Module* src, const std::string &eventid); - /** Send the Event. - * The return result of an Event::Send() will always be NULL as - * no replies are expected. - */ - void Send(); -}; - class CoreExport DataProvider : public ServiceProvider { public: @@ -260,7 +232,7 @@ enum Implementation I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite, I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckChannelBan, I_OnExtBanCheck, I_OnStats, I_OnChangeLocalUserHost, I_OnPreTopicChange, - I_OnPostTopicChange, I_OnEvent, I_OnPostConnect, + I_OnPostTopicChange, I_OnPostConnect, I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete, I_OnPostOper, I_OnSyncNetwork, I_OnSetAway, I_OnPostCommand, I_OnPostJoin, I_OnWhoisLine, I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass, @@ -952,12 +924,6 @@ class CoreExport Module : public classbase, public usecountbase */ virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic); - /** Called whenever an Event class is sent to all modules by another module. - * You should *always* check the value of Event::id to determine the event type. - * @param event The Event class being received - */ - virtual void OnEvent(Event& event); - /** Called whenever a password check is to be made. Replaces the old OldOperCompare API. * The password field (from the config file) is in 'password' and is to be compared against * 'input'. This method allows for encryption of passwords (oper, connect:allow, die/restart, etc). diff --git a/src/modules.cpp b/src/modules.cpp index 55d41674b..1c33785b0 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -52,13 +52,6 @@ Version::Version(const std::string &desc, int flags, const std::string& linkdata { } -Event::Event(Module* src, const std::string &eventid) : source(src), id(eventid) { } - -void Event::Send() -{ - FOREACH_MOD(OnEvent, (*this)); -} - // These declarations define the behavours of the base class Module (which does nothing at all) Module::Module() { } @@ -119,7 +112,6 @@ ModResult Module::OnStats(char, User*, string_list&) { DetachEvent(I_OnStats); r ModResult Module::OnChangeLocalUserHost(LocalUser*, const std::string&) { DetachEvent(I_OnChangeLocalUserHost); return MOD_RES_PASSTHRU; } ModResult Module::OnChangeLocalUserGECOS(LocalUser*, const std::string&) { DetachEvent(I_OnChangeLocalUserGECOS); return MOD_RES_PASSTHRU; } ModResult Module::OnPreTopicChange(User*, Channel*, const std::string&) { DetachEvent(I_OnPreTopicChange); return MOD_RES_PASSTHRU; } -void Module::OnEvent(Event&) { DetachEvent(I_OnEvent); } ModResult Module::OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype) { DetachEvent(I_OnPassCompare); return MOD_RES_PASSTHRU; } void Module::OnPostConnect(User*) { DetachEvent(I_OnPostConnect); } void Module::OnUserMessage(User*, void*, int, const std::string&, char, const CUList&, MessageType) { DetachEvent(I_OnUserMessage); } -- cgit v1.2.3 From 7918febc630d7d6f94fda1a918fe7b98c2d0e742 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 17:26:16 +0100 Subject: m_httpd Remove now unused variable "claimed" --- src/modules/m_httpd.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index 47416406e..e09ca3fa2 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -29,7 +29,6 @@ class ModuleHttpServer; static ModuleHttpServer* HttpModule; -static bool claimed; static insp::intrusive_list sockets; static Events::ModuleEventProvider* aclevprov; static Events::ModuleEventProvider* reqevprov; @@ -324,7 +323,6 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru { InternalState = HTTP_SERVE_SEND_DATA; - claimed = false; ModResult MOD_RESULT; HTTPRequest acl(request_type, uri, &headers, this, ip, postdata); FIRST_MOD_RESULT_CUSTOM(*aclevprov, HTTPACLEventListener, OnHTTPACLCheck, MOD_RESULT, (acl)); @@ -366,7 +364,6 @@ class HTTPdAPIImpl : public HTTPdAPIBase void SendResponse(HTTPDocumentResponse& resp) CXX11_OVERRIDE { - claimed = true; resp.src.sock->Page(resp.document, resp.responsecode, &resp.headers); } }; -- cgit v1.2.3