]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_filter.cpp
Fix the behaviour of multi-value PING and PONG messages.
[user/henk/code/inspircd.git] / src / modules / m_filter.cpp
index e7aab2eeb9dad4ba6d0d2f48073bcc6d9da3c850..786ea673bb27cce92881c678b42e01ba7cedda5b 100644 (file)
@@ -1,10 +1,21 @@
 /*
  * InspIRCd -- Internet Relay Chat Daemon
  *
- *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2004, 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2019 Matt Schatz <genius3000@g3k.solutions>
+ *   Copyright (C) 2019 Filippo Cortigiani <simos@simosnap.org>
+ *   Copyright (C) 2018-2019 linuxdaemon <linuxdaemon.irc@gmail.com>
+ *   Copyright (C) 2018 Michael Hazell <michaelhazell@hotmail.com>
+ *   Copyright (C) 2017 B00mX0r <b00mx0r@aureus.pw>
+ *   Copyright (C) 2012-2014, 2016 Attila Molnar <attilamolnar@hush.com>
+ *   Copyright (C) 2012-2013, 2017-2020 Sadie Powell <sadie@witchery.services>
+ *   Copyright (C) 2012, 2018-2019 Robby <robby@chatbelgie.be>
+ *   Copyright (C) 2011 Adam <Adam@anope.org>
+ *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2009 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2009 Matt Smith <dz@inspircd.org>
+ *   Copyright (C) 2009 John Brooks <special@inspircd.org>
+ *   Copyright (C) 2007-2010 Craig Edwards <brain@inspircd.org>
  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
- *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
  *
  * This file is part of InspIRCd.  InspIRCd is free software: you can
  * redistribute it and/or modify it under the terms of the GNU General Public
@@ -173,7 +184,10 @@ class CommandFilter : public Command
        }
 };
 
-class ModuleFilter : public Module, public ServerEventListener, public Stats::EventListener
+class ModuleFilter
+       : public Module
+       , public ServerProtocol::SyncEventListener
+       , public Stats::EventListener
 {
        typedef insp::flat_set<std::string, irc::insensitive_swo> ExemptTargetSet;
 
@@ -332,7 +346,7 @@ bool ModuleFilter::AppliesToMe(User* user, FilterResult* filter, int iflags)
 }
 
 ModuleFilter::ModuleFilter()
-       : ServerEventListener(this)
+       : ServerProtocol::SyncEventListener(this)
        , Stats::EventListener(this)
        , initing(true)
        , filtcommand(this)
@@ -371,7 +385,6 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
        if (f)
        {
                bool is_selfmsg = false;
-               std::string target;
                switch (msgtarget.type)
                {
                        case MessageTarget::TYPE_USER:
@@ -383,8 +396,6 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
 
                                if (user == t)
                                        is_selfmsg = true;
-
-                               target = t->nick;
                                break;
                        }
                        case MessageTarget::TYPE_CHANNEL:
@@ -392,12 +403,10 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                                Channel* t = msgtarget.Get<Channel>();
                                if (exemptedchans.count(t->name))
                                        return MOD_RES_PASSTHRU;
-
-                               target = t->name;
                                break;
                        }
                        case MessageTarget::TYPE_SERVER:
-                               break;
+                               return MOD_RES_PASSTHRU;
                }
 
                if (is_selfmsg && warnonselfmsg)
@@ -409,19 +418,19 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                else if (f->action == FA_WARN)
                {
                        ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("WARNING: %s's message to %s matched %s (%s)",
-                               user->nick.c_str(), target.c_str(), f->freeform.c_str(), f->reason.c_str()));
+                               user->nick.c_str(), msgtarget.GetName().c_str(), f->freeform.c_str(), f->reason.c_str()));
                        return MOD_RES_PASSTHRU;
                }
                else if (f->action == FA_BLOCK)
                {
                        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()));
+                               user->nick.c_str(), msgtarget.GetName().c_str(), f->freeform.c_str(), f->reason.c_str()));
                        if (notifyuser)
                        {
                                if (msgtarget.type == MessageTarget::TYPE_CHANNEL)
-                                       user->WriteNumeric(ERR_CANNOTSENDTOCHAN, target, InspIRCd::Format("Message to channel blocked and opers notified (%s)", f->reason.c_str()));
+                                       user->WriteNumeric(Numerics::CannotSendTo(msgtarget.Get<Channel>(), InspIRCd::Format("Your message to this channel was blocked: %s.", f->reason.c_str())));
                                else
-                                       user->WriteNotice("Your message to "+target+" was blocked and opers notified: "+f->reason);
+                                       user->WriteNumeric(Numerics::CannotSendTo(msgtarget.Get<User>(), InspIRCd::Format("Your message to this user was blocked: %s.", f->reason.c_str())));
                        }
                        else
                                details.echo_original = true;
@@ -431,9 +440,9 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                        if (notifyuser)
                        {
                                if (msgtarget.type == MessageTarget::TYPE_CHANNEL)
-                                       user->WriteNumeric(ERR_CANNOTSENDTOCHAN, target, InspIRCd::Format("Message to channel blocked (%s)", f->reason.c_str()));
+                                       user->WriteNumeric(Numerics::CannotSendTo(msgtarget.Get<Channel>(), InspIRCd::Format("Your message to this channel was blocked: %s.", f->reason.c_str())));
                                else
-                                       user->WriteNotice("Your message to "+target+" was blocked: "+f->reason);
+                                       user->WriteNumeric(Numerics::CannotSendTo(msgtarget.Get<User>(), InspIRCd::Format("Your message to this user was blocked: %s.", f->reason.c_str())));
                        }
                        else
                                details.echo_original = true;
@@ -441,7 +450,7 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                else if (f->action == FA_KILL)
                {
                        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()));
+                               user->nick.c_str(), msgtarget.GetName().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")))
@@ -450,7 +459,7 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                        ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s (%s) was shunned for %s (expires on %s) because their message to %s matched %s (%s)",
                                user->nick.c_str(), sh->Displayable().c_str(), InspIRCd::DurationString(f->duration).c_str(),
                                InspIRCd::TimeString(ServerInstance->Time() + f->duration).c_str(),
-                               target.c_str(), f->freeform.c_str(), f->reason.c_str()));
+                               msgtarget.GetName().c_str(), f->freeform.c_str(), f->reason.c_str()));
                        if (ServerInstance->XLines->AddLine(sh, NULL))
                        {
                                ServerInstance->XLines->ApplyLines();
@@ -464,7 +473,7 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                        ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s (%s) was G-lined for %s (expires on %s) because their message to %s matched %s (%s)",
                                user->nick.c_str(), gl->Displayable().c_str(), InspIRCd::DurationString(f->duration).c_str(),
                                InspIRCd::TimeString(ServerInstance->Time() + f->duration).c_str(),
-                               target.c_str(), f->freeform.c_str(), f->reason.c_str()));
+                               msgtarget.GetName().c_str(), f->freeform.c_str(), f->reason.c_str()));
                        if (ServerInstance->XLines->AddLine(gl,NULL))
                        {
                                ServerInstance->XLines->ApplyLines();
@@ -478,7 +487,7 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                        ServerInstance->SNO->WriteGlobalSno('f', InspIRCd::Format("%s (%s) was Z-lined for %s (expires on %s) because their message to %s matched %s (%s)",
                                user->nick.c_str(), zl->Displayable().c_str(), InspIRCd::DurationString(f->duration).c_str(),
                                InspIRCd::TimeString(ServerInstance->Time() + f->duration).c_str(),
-                               target.c_str(), f->freeform.c_str(), f->reason.c_str()));
+                               msgtarget.GetName().c_str(), f->freeform.c_str(), f->reason.c_str()));
                        if (ServerInstance->XLines->AddLine(zl,NULL))
                        {
                                ServerInstance->XLines->ApplyLines();
@@ -487,7 +496,7 @@ ModResult ModuleFilter::OnUserPreMessage(User* user, const MessageTarget& msgtar
                                delete zl;
                }
 
-               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, user->nick + " had their message filtered, target was " + target + ": " + f->reason + " Action: " + ModuleFilter::FilterActionToString(f->action));
+               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, user->nick + " had their message filtered, target was " + msgtarget.GetName() + ": " + f->reason + " Action: " + ModuleFilter::FilterActionToString(f->action));
                return MOD_RES_DENY;
        }
        return MOD_RES_PASSTHRU;
@@ -533,7 +542,7 @@ ModResult ModuleFilter::OnPreCommand(std::string& command, CommandBase::Params&
                /* We cant block a part or quit, so instead we change the reason to 'Reason filtered' */
                parameters[parting ? 1 : 0] = "Reason filtered";
 
-               /* We're warning or blocking, OR theyre quitting and its a KILL action
+               /* We're warning or blocking, OR they're quitting and its a KILL action
                 * (we cant kill someone whos already quitting, so filter them anyway)
                 */
                if ((f->action == FA_WARN) || (f->action == FA_BLOCK) || (((!parting) && (f->action == FA_KILL))) || (f->action == FA_SILENT))
@@ -615,7 +624,7 @@ void ModuleFilter::ReadConfig(ConfigStatus& status)
                ConfigTag* tag = i->second;
 
                // If "target" is not found, try the old "channel" key to keep compatibility with 2.0 configs
-               const std::string target = tag->getString("target", tag->getString("channel"));
+               const std::string target = tag->getString("target", tag->getString("channel"), 1);
                if (!target.empty())
                {
                        if (target[0] == '#')
@@ -661,7 +670,7 @@ void ModuleFilter::ReadConfig(ConfigStatus& status)
 
 Version ModuleFilter::GetVersion()
 {
-       return Version("Provides text (spam) filtering", VF_VENDOR | VF_COMMON, RegexEngine ? RegexEngine->name : "");
+       return Version("Adds the /FILTER command which allows server operators to define regex matches for inappropriate phrases that are not allowed to be used in channel messages, private messages, part messages, or quit messages.", VF_VENDOR | VF_COMMON, RegexEngine ? RegexEngine->name : "");
 }
 
 std::string ModuleFilter::EncodeFilter(FilterResult* filter)
@@ -890,7 +899,7 @@ ModResult ModuleFilter::OnStats(Stats::Context& stats)
        {
                for (std::vector<FilterResult>::iterator i = filters.begin(); i != filters.end(); i++)
                {
-                       stats.AddRow(223, RegexEngine.GetProvider()+":"+i->freeform+" "+i->GetFlags()+" "+FilterActionToString(i->action)+" "+ConvToStr(i->duration)+" :"+i->reason);
+                       stats.AddRow(223, RegexEngine.GetProvider(), i->freeform, i->GetFlags(), FilterActionToString(i->action), i->duration, i->reason);
                }
                for (ExemptTargetSet::const_iterator i = exemptedchans.begin(); i != exemptedchans.end(); ++i)
                {