X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fextra%2Fm_filter_pcre.cpp;h=faf1718e458421c96ee0be68d92e2026b4e1b6e7;hb=b45e7cfebbeaad4ecc3c55bc3060140f50f710d3;hp=ca002f578be98bd1b4adb480417891d3615a74c3;hpb=1383dba43e463f292aea094d01f62f355946049d;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/extra/m_filter_pcre.cpp b/src/modules/extra/m_filter_pcre.cpp index ca002f578..faf1718e4 100644 --- a/src/modules/extra/m_filter_pcre.cpp +++ b/src/modules/extra/m_filter_pcre.cpp @@ -14,8 +14,6 @@ * --------------------------------------------------- */ -using namespace std; - // Message and notice filtering using regex patterns // a module based on the original work done by Craig Edwards in 2003 // for the chatspike network. @@ -26,208 +24,163 @@ using namespace std; #include "users.h" #include "channels.h" #include "modules.h" -#include "helperfuncs.h" +#include "inspircd.h" + +/** Thrown by m_filter_pcre + */ +class FilterPCREException : public ModuleException +{ + public: + virtual const char* GetReason() + { + return "Could not find definition in your config file!"; + } +}; /* $ModDesc: m_filter with regexps */ -/* $CompileFlags: -I/usr/local/include */ -/* $LinkerFlags: -L/usr/local/lib -lpcre */ +/* $CompileFlags: -I`pcre-config --prefix`/include */ +/* $LinkerFlags: `pcre-config --libs` `perl extra/pcre_rpath.pl` -lpcre */ class ModuleFilterPCRE : public Module { - Server *Srv; - ConfigReader *Conf, *MyConf; - std::vector filters; + class Filter + { + public: + pcre* regexp; + std::string reason; + std::string action; + + Filter(pcre* r, const std::string &rea, const std::string &act) + : regexp(r), reason(rea), action(act) + { + } + }; + + InspIRCd* Srv; + std::vector filters; pcre *re; const char *error; int erroffset; public: - ModuleFilterPCRE(Server* Me) - : Module::Module(Me) + ModuleFilterPCRE(InspIRCd* Me) + : Module::Module(Me), Srv(Me) { - // read the configuration file on startup. - // it is perfectly valid to set to the value of the - // main config file, then append your tags to the bottom - // of the main config... but rather messy. That's why the capability - // of using a seperate config file is provided. - Srv = Me; - Conf = new ConfigReader; - std::string filterfile = Conf->ReadValue("filter","file",0); - MyConf = new ConfigReader(filterfile); - if ((filterfile == "") || (!MyConf->Verify())) - { - printf("Error, could not find definition in your config file!\n"); - log(DEFAULT,"Error, could not find definition in your config file!"); - return; - } - Srv->Log(DEFAULT,std::string("m_filter_pcre: read configuration from ")+filterfile); - - filters.clear(); - for (int index = 0; index < MyConf->Enumerate("keyword"); index++) - { - std::string pattern = MyConf->ReadValue("keyword","pattern",index); - re = pcre_compile(pattern.c_str(),0,&error,&erroffset,NULL); - if (!re) - { - log(DEFAULT,"Error in regular expression: %s at offset %d: %s\n", pattern.c_str(), erroffset, error); - log(DEFAULT,"Regular expression %s not loaded.", pattern.c_str()); - } - else - { - filters.push_back(re); - log(DEFAULT,"Regular expression %s loaded.", pattern.c_str()); - } - } - + OnRehash(""); } virtual ~ModuleFilterPCRE() { - delete MyConf; - delete Conf; } - void Implements(char* List) - { - List[I_OnUserPreMessage] = List[I_OnUserPreNotice] = List[I_OnRehash] = 1; - } + void Implements(char* List) + { + List[I_OnUserPreMessage] = List[I_OnUserPreNotice] = List[I_OnRehash] = 1; + } // format of a config entry is - virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text) + virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text, char status) { - for (unsigned int index = 0; index < filters.size(); index++) - { - if (pcre_exec(filters[index],NULL,text.c_str(),text.length(),0,0,NULL,0) > -1) - { - std::string target = ""; - std::string reason = MyConf->ReadValue("keyword","reason",index); - std::string do_action = MyConf->ReadValue("keyword","action",index); - - if (do_action == "") - do_action = "none"; - - if (target_type == TYPE_USER) - { - userrec* t = (userrec*)dest; - target = std::string(t->nick); - } - else if (target_type == TYPE_CHANNEL) - { - chanrec* t = (chanrec*)dest; - target = std::string(t->name); - } - if (do_action == "block") - { - Srv->SendOpers(std::string("FilterPCRE: ")+std::string(user->nick)+ - std::string(" had their message filtered, target was ")+ - target+": "+reason); - // this form of SendTo (with the source as NuLL) sends a server notice - Srv->SendTo(NULL,user,"NOTICE "+std::string(user->nick)+ - " :Your message has been filtered and opers notified: "+reason); - } - - Srv->Log(DEFAULT,std::string("Filter: ")+std::string(user->nick)+ - std::string(" had their message filtered, target was ")+ - target+": "+reason+" Action: "+do_action); - - if (do_action == "kill") - { - Srv->QuitUser(user,reason); - } - return 1; - } - } - return 0; + return OnUserPreNotice(user,dest,target_type,text,status); } - virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text) + virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text, char status) { for (unsigned int index = 0; index < filters.size(); index++) { - if (pcre_exec(filters[index],NULL,text.c_str(),text.length(),0,0,NULL,0) > -1) + Filter& filt = filters[index]; + + if (pcre_exec(filt.regexp,NULL,text.c_str(),text.length(),0,0,NULL,0) > -1) { - std::string target = ""; - std::string reason = MyConf->ReadValue("keyword","reason",index); - std::string do_action = MyConf->ReadValue("keyword","action",index); - - if (do_action == "") - do_action = "none"; + const char* target; + + if(filt.action.empty()) + filt.action = "none"; if (target_type == TYPE_USER) { userrec* t = (userrec*)dest; - target = std::string(t->nick); + target = t->nick; } else if (target_type == TYPE_CHANNEL) { chanrec* t = (chanrec*)dest; - target = std::string(t->name); + target = t->name; } - if (do_action == "block") - { - Srv->SendOpers(std::string("Filter: ")+std::string(user->nick)+ - std::string(" had their notice filtered, target was ")+ - target+": "+reason); - Srv->SendTo(NULL,user,"NOTICE "+std::string(user->nick)+ - " :Your notice has been filtered and opers notified: "+reason); - } - Srv->Log(DEFAULT,std::string("Filter: ")+std::string(user->nick)+ - std::string(" had their notice filtered, target was ")+ - target+": "+reason+" Action: "+do_action); - - if (do_action == "kill") + else + { + target = ""; + } + + ServerInstance->Log(DEFAULT, "Filter: %s had their notice filtered, target was %s: %s Action: %s", user->nick, target, filt.reason.c_str(), filt.action.c_str()); + + if (filt.action == "block") + { + Srv->WriteOpers("Filter: %s had their notice filtered, target was %s: %s", user->nick, target, filt.reason.c_str()); + user->WriteServ("NOTICE "+std::string(user->nick)+" :Your notice has been filtered and opers notified: "+filt.reason); + } + else if (filt.action == "kill") { - Srv->QuitUser(user,reason); + userrec::QuitUser(Srv, user, filt.reason); } + return 1; } } return 0; } - virtual void OnRehash(std::string parameter) + virtual void OnRehash(const std::string ¶meter) { - // reload our config file on rehash - we must destroy and re-allocate the classes - // to call the constructor again and re-read our data. - delete Conf; - delete MyConf; - Conf = new ConfigReader; - std::string filterfile = Conf->ReadValue("filter","file",0); - // this automatically re-reads the configuration file into the class - MyConf = new ConfigReader(filterfile); - if ((filterfile == "") || (!MyConf->Verify())) + /* Read the configuration file on startup and rehash. + * It is perfectly valid to set to the value of the + * main config file, then append your tags to the bottom + * of the main config... but rather messy. That's why the capability + * of using a seperate config file is provided. + */ + + ConfigReader Conf(Srv); + + std::string filterfile = Conf.ReadValue("filter", "file", 0); + + ConfigReader MyConf(Srv, filterfile); + + if (filterfile.empty() || !MyConf.Verify()) { - // bail if the user forgot to create a config file - printf("Error, could not find definition in your config file!"); - log(DEFAULT,"Error, could not find definition in your config file!"); - return; + FilterPCREException e; + throw(e); } - Srv->Log(DEFAULT,std::string("m_filter_pcre: read configuration from ")+filterfile); - - filters.clear(); - for (int index = 0; index < MyConf->Enumerate("keyword"); index++) - { - std::string pattern = MyConf->ReadValue("keyword","pattern",index); - re = pcre_compile(pattern.c_str(),0,&error,&erroffset,NULL); - if (!re) - { - log(DEFAULT,"Error in regular expression: %s at offset %d: %s\n", pattern.c_str(), erroffset, error); - log(DEFAULT,"Regular expression %s not loaded.", pattern.c_str()); - } - else - { - filters.push_back(re); - log(DEFAULT,"Regular expression %s loaded.", pattern.c_str()); - } - } + + ServerInstance->Log(DEFAULT,"m_filter_pcre: read configuration from "+filterfile); + filters.clear(); + + for (int index = 0; index < MyConf.Enumerate("keyword"); index++) + { + std::string pattern = MyConf.ReadValue("keyword","pattern",index); + std::string reason = MyConf.ReadValue("keyword","reason",index); + std::string action = MyConf.ReadValue("keyword","action",index); + + re = pcre_compile(pattern.c_str(),0,&error,&erroffset,NULL); + + if (!re) + { + ServerInstance->Log(DEFAULT,"Error in regular expression: %s at offset %d: %s\n", pattern.c_str(), erroffset, error); + ServerInstance->Log(DEFAULT,"Regular expression %s not loaded.", pattern.c_str()); + } + else + { + filters.push_back(Filter(re, reason, action)); + ServerInstance->Log(DEFAULT,"Regular expression %s loaded.", pattern.c_str()); + } + } } virtual Version GetVersion() { - // This is version 2 because version 1.x is the unreleased unrealircd module - return Version(3,0,0,0,VF_VENDOR); + /* Version 1.x is the unreleased unrealircd module */ + return Version(3,2,0,0,VF_VENDOR); } }; @@ -245,7 +198,7 @@ class ModuleFilterPCREFactory : public ModuleFactory { } - virtual Module * CreateModule(Server* Me) + virtual Module * CreateModule(InspIRCd* Me) { return new ModuleFilterPCRE(Me); } @@ -257,4 +210,3 @@ extern "C" void * init_module( void ) { return new ModuleFilterPCREFactory; } -