]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_filter.cpp
Don't sync filters defined in the config and expire them on rehash.
[user/henk/code/inspircd.git] / src / modules / m_filter.cpp
index fa78e833b7cb778ea56d286f0203b4e4840cd1b6..239135655f0754e293432c47df1faf7d943e2e1f 100644 (file)
@@ -53,6 +53,7 @@ class FilterResult
        std::string reason;
        FilterAction action;
        long duration;
+       bool from_config;
 
        bool flag_no_opers;
        bool flag_part_message;
@@ -61,11 +62,12 @@ class FilterResult
        bool flag_notice;
        bool flag_strip_color;
 
-       FilterResult(dynamic_reference<RegexFactory>& RegexEngine, const std::string& free, const std::string& rea, FilterAction act, long gt, const std::string& fla)
+       FilterResult(dynamic_reference<RegexFactory>& RegexEngine, const std::string& free, const std::string& rea, FilterAction act, long gt, const std::string& fla, bool cfg)
                : freeform(free)
                , reason(rea)
                , action(act)
                , duration(gt)
+               , from_config(cfg)
        {
                if (!RegexEngine)
                        throw ModuleException("Regex module implementing '"+RegexEngine.GetProvider()+"' is not loaded!");
@@ -184,6 +186,7 @@ class ModuleFilter : public Module, public ServerEventListener, public Stats::Ev
        ExemptTargetSet exemptednicks;
 
        ModuleFilter();
+       void init() CXX11_OVERRIDE;
        CullResult cull() CXX11_OVERRIDE;
        ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) CXX11_OVERRIDE;
        FilterResult* FilterMatch(User* user, const std::string &text, int flags);
@@ -213,7 +216,7 @@ CmdResult CommandFilter::Handle(User* user, const Params& parameters)
                if (static_cast<ModuleFilter *>(me)->DeleteFilter(parameters[0]))
                {
                        user->WriteNotice("*** Removed filter '" + parameters[0] + "'");
-                       ServerInstance->SNO->WriteToSnoMask(IS_LOCAL(user) ? 'a' : 'A', "FILTER: "+user->nick+" removed filter '"+parameters[0]+"'");
+                       ServerInstance->SNO->WriteToSnoMask(IS_LOCAL(user) ? 'f' : 'F', "FILTER: "+user->nick+" removed filter '"+parameters[0]+"'");
                        return CMD_SUCCESS;
                }
                else
@@ -268,7 +271,7 @@ CmdResult CommandFilter::Handle(User* user, const Params& parameters)
                                        (duration ? ", duration " +  parameters[3] : "") + ", flags '" + flags + "', reason: '" +
                                        parameters[reasonindex] + "'");
 
-                               ServerInstance->SNO->WriteToSnoMask(IS_LOCAL(user) ? 'a' : 'A', "FILTER: "+user->nick+" added filter '"+freeform+"', type '"+parameters[1]+"', "+(duration ? "duration "+parameters[3]+", " : "")+"flags '"+flags+"', reason: "+parameters[reasonindex]);
+                               ServerInstance->SNO->WriteToSnoMask(IS_LOCAL(user) ? 'f' : 'F', "FILTER: "+user->nick+" added filter '"+freeform+"', type '"+parameters[1]+"', "+(duration ? "duration "+parameters[3]+", " : "")+"flags '"+flags+"', reason: "+parameters[reasonindex]);
 
                                return CMD_SUCCESS;
                        }
@@ -311,6 +314,11 @@ ModuleFilter::ModuleFilter()
 {
 }
 
+void ModuleFilter::init()
+{
+       ServerInstance->SNO->EnableSnomask('f', "FILTER");
+}
+
 CullResult ModuleFilter::cull()
 {
        FreeFilters();
@@ -356,7 +364,8 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                }
                if (f->action == FA_BLOCK)
                {
-                       ServerInstance->SNO->WriteGlobalSno('a', "FILTER: "+user->nick+" had their message filtered, target was "+target+": "+f->reason);
+                       ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s had their message to %s filtered as it matched %s (%s)",
+                               user->nick.c_str(), target.c_str(), f->freeform.c_str(), f->reason.c_str()));
                        if (notifyuser)
                        {
                                if (msgtarget.type == MessageTarget::TYPE_CHANNEL)
@@ -365,7 +374,7 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                                        user->WriteNotice("Your message to "+target+" was blocked and opers notified: "+f->reason);
                        }
                        else
-                               details.echooriginal = true;
+                               details.echo_original = true;
                }
                else if (f->action == FA_SILENT)
                {
@@ -377,17 +386,19 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                                        user->WriteNotice("Your message to "+target+" was blocked: "+f->reason);
                        }
                        else
-                               details.echooriginal = true;
+                               details.echo_original = true;
                }
                else if (f->action == FA_KILL)
                {
-                       ServerInstance->SNO->WriteGlobalSno('a', "FILTER: " + user->nick + " had their message filtered and was killed, target was " + target + ": " + f->reason);
+                       ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was killed because their message to %s matched %s (%s)",
+                               user->nick.c_str(), target.c_str(), f->freeform.c_str(), f->reason.c_str()));
                        ServerInstance->Users->QuitUser(user, "Filtered: " + f->reason);
                }
                else if (f->action == FA_SHUN && (ServerInstance->XLines->GetFactory("SHUN")))
                {
                        Shun* sh = new Shun(ServerInstance->Time(), f->duration, ServerInstance->Config->ServerName.c_str(), f->reason.c_str(), user->GetIPString());
-                       ServerInstance->SNO->WriteGlobalSno('a', "FILTER: " + user->nick + " had their message filtered and was shunned, target was " + target + ": " + f->reason);
+                       ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was shunned because their message to %s matched %s (%s)",
+                               user->nick.c_str(), target.c_str(), f->freeform.c_str(), f->reason.c_str()));
                        if (ServerInstance->XLines->AddLine(sh, NULL))
                        {
                                ServerInstance->XLines->ApplyLines();
@@ -398,7 +409,8 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                else if (f->action == FA_GLINE)
                {
                        GLine* gl = new GLine(ServerInstance->Time(), f->duration, ServerInstance->Config->ServerName.c_str(), f->reason.c_str(), "*", user->GetIPString());
-                       ServerInstance->SNO->WriteGlobalSno('a', "FILTER: " + user->nick + " had their message filtered and was G-Lined, target was " + target + ": " + f->reason);
+                       ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was glined because their message to %s matched %s (%s)",
+                               user->nick.c_str(), target.c_str(), f->freeform.c_str(), f->reason.c_str()));
                        if (ServerInstance->XLines->AddLine(gl,NULL))
                        {
                                ServerInstance->XLines->ApplyLines();
@@ -472,7 +484,9 @@ ModResult ModuleFilter::OnPreCommand(std::string& command, CommandBase::Params&
                        {
                                /* Note: We gline *@IP so that if their host doesnt resolve the gline still applies. */
                                GLine* gl = new GLine(ServerInstance->Time(), f->duration, ServerInstance->Config->ServerName.c_str(), f->reason.c_str(), "*", user->GetIPString());
-                               ServerInstance->SNO->WriteGlobalSno('a', "FILTER: " + user->nick + " had their " + command + " message filtered and was G-Lined: " + f->reason);
+                               ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was glined because their %s message matched %s (%s)",
+                                       user->nick.c_str(), command.c_str(), f->freeform.c_str(), f->reason.c_str()));
+
                                if (ServerInstance->XLines->AddLine(gl,NULL))
                                {
                                        ServerInstance->XLines->ApplyLines();
@@ -484,7 +498,8 @@ ModResult ModuleFilter::OnPreCommand(std::string& command, CommandBase::Params&
                        {
                                /* Note: We shun *!*@IP so that if their host doesnt resolve the shun still applies. */
                                Shun* sh = new Shun(ServerInstance->Time(), f->duration, ServerInstance->Config->ServerName.c_str(), f->reason.c_str(), user->GetIPString());
-                               ServerInstance->SNO->WriteGlobalSno('a', "FILTER: " + user->nick + " had their " + command + " message filtered and was shunned: " + f->reason);
+                               ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s was shunned because their %s message matched %s (%s)",
+                                       user->nick.c_str(), command.c_str(), f->freeform.c_str(), f->reason.c_str()));
                                if (ServerInstance->XLines->AddLine(sh, NULL))
                                {
                                        ServerInstance->XLines->ApplyLines();
@@ -533,9 +548,9 @@ void ModuleFilter::ReadConfig(ConfigStatus& status)
        if (!RegexEngine)
        {
                if (newrxengine.empty())
-                       ServerInstance->SNO->WriteGlobalSno('a', "WARNING: No regex engine loaded - Filter functionality disabled until this is corrected.");
+                       ServerInstance->SNO->WriteGlobalSno('f', "WARNING: No regex engine loaded - Filter functionality disabled until this is corrected.");
                else
-                       ServerInstance->SNO->WriteGlobalSno('a', "WARNING: Regex engine '%s' is not loaded - Filter functionality disabled until this is corrected.", newrxengine.c_str());
+                       ServerInstance->SNO->WriteGlobalSno('f', "WARNING: Regex engine '%s' is not loaded - Filter functionality disabled until this is corrected.", newrxengine.c_str());
 
                initing = false;
                FreeFilters();
@@ -544,7 +559,7 @@ void ModuleFilter::ReadConfig(ConfigStatus& status)
 
        if ((!initing) && (RegexEngine.operator->() != factory))
        {
-               ServerInstance->SNO->WriteGlobalSno('a', "Dumping all filters due to regex engine change");
+               ServerInstance->SNO->WriteGlobalSno('f', "Dumping all filters due to regex engine change");
                FreeFilters();
        }
 
@@ -605,7 +620,11 @@ void ModuleFilter::OnSyncNetwork(ProtocolInterface::Server& server)
 {
        for (std::vector<FilterResult>::iterator i = filters.begin(); i != filters.end(); ++i)
        {
-               server.SendMetaData("filter", EncodeFilter(&(*i)));
+               FilterResult& filter = *i;
+               if (filter.from_config)
+                       continue;
+
+               server.SendMetaData("filter", EncodeFilter(&filter));
        }
 }
 
@@ -676,7 +695,7 @@ std::pair<bool, std::string> ModuleFilter::AddFilter(const std::string &freeform
 
        try
        {
-               filters.push_back(FilterResult(RegexEngine, freeform, reason, type, duration, flgs));
+               filters.push_back(FilterResult(RegexEngine, freeform, reason, type, duration, flgs, false));
        }
        catch (ModuleException &e)
        {
@@ -721,12 +740,24 @@ std::string ModuleFilter::FilterActionToString(FilterAction fa)
 
 void ModuleFilter::ReadFilters()
 {
+       for (std::vector<FilterResult>::iterator filter = filters.begin(); filter != filters.end(); )
+       {
+               if (filter->from_config)
+               {
+                       ServerInstance->SNO->WriteGlobalSno('f', "FILTER: removing filter '" + filter->freeform + "' due to config rehash.");
+                       delete filter->regex;
+                       filter = filters.erase(filter);
+                       continue;
+               }
+
+               // The filter is not from the config.
+               filter++;
+       }
+
        ConfigTagList tags = ServerInstance->Config->ConfTags("keyword");
        for (ConfigIter i = tags.first; i != tags.second; ++i)
        {
                std::string pattern = i->second->getString("pattern");
-               this->DeleteFilter(pattern);
-
                std::string reason = i->second->getString("reason");
                std::string action = i->second->getString("action");
                std::string flgs = i->second->getString("flags");
@@ -740,7 +771,7 @@ void ModuleFilter::ReadFilters()
 
                try
                {
-                       filters.push_back(FilterResult(RegexEngine, pattern, reason, fa, duration, flgs));
+                       filters.push_back(FilterResult(RegexEngine, pattern, reason, fa, duration, flgs, true));
                        ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Regular expression %s loaded.", pattern.c_str());
                }
                catch (ModuleException &e)