diff options
-rw-r--r-- | conf/modules.conf.example | 45 | ||||
-rw-r--r-- | src/modules/extra/m_regex_pcre.cpp | 7 | ||||
-rw-r--r-- | src/modules/extra/m_regex_posix.cpp | 7 | ||||
-rw-r--r-- | src/modules/extra/m_regex_tre.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_regex_glob.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_rline.cpp (renamed from src/modules/extra/m_rline.cpp) | 89 |
6 files changed, 140 insertions, 22 deletions
diff --git a/conf/modules.conf.example b/conf/modules.conf.example index 7db93fac9..6edd70269 100644 --- a/conf/modules.conf.example +++ b/conf/modules.conf.example @@ -1062,6 +1062,37 @@ #<module name="m_redirect.so"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# Regular Expression Provider for Glob or wildcard (?/*) matching. +# You must have at least 1 provider loaded to use m_filter or m_rline +# modules. This module has no additional requirements, as it uses the +# matching already present in InspIRCd core. +#<module name="m_regex_glob.so"> + +#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# Regular Expression Provider for PCRE (Perl-Compatible Regular +# Expressions). You need libpcre installed to compile and load this +# module. You must have at least 1 provider loaded to use m_filter or +# m_rline. +#<module name="m_regex_pcre.so"> + +#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# Regular Expression Provider for POSIX Regular Expressions. +# You shouldn't need any additional libraries on a POSIX-compatible +# system (ie: any Linux, BSD, but not Windows). You must have at least +# 1 provider loaded to use m_filter or m_rline. +# On POSIX-compliant systems, regex syntax can be found by using the +# command: 'man 7 regex'. +#<module name="m_regex_posix.so"> + +#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# Regular Expression Provider for TRE Regular Expressions. +# This is the same regular expression engine used by UnrealIRCd, so +# if you are most familiar with the syntax of /spamfilter from there, +# this is the provider you want. You need libtre installed in order +# to compile and load this module. +#<module name="m_regex_tre.so"> + +#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Registered users only channel creation # Allows only registered users and opers to create new channels. #<module name="m_regonlycreate.so"> @@ -1093,7 +1124,19 @@ # If you wish to re-check a user when they change nickname (can be # useful under some situations, but *can* also use CPU with more users # on a server) then set the following configuration value: -#<rline matchonnickchange="yes"> +# Also, this is where you set what Regular Expression engine is to be +# used. If you ever change it while running, all of your R-Lines will be +# wiped. This is the regex engine used by all R-Lines set, and +# m_regex_<engine>.so must be loaded, or rline will be nonfunctional +# until you load it or change the engine to one that is loaded. +#<rline matchonnickchange="yes" engine="pcre"> +# Generally, you will not want to use 'glob' here, as this turns +# rline into just another gline. The exceptions are that rline will +# always use the full nick!user@host realname string, rather than only +# user@host, but beware that only the ? and * wildcards are available, +# and are the only way to specify where the space can occur if you do +# use glob. For this reason, is recommended to use a real regex engine +# so that at least \s or [[:space:]] is available. #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # JSON-RPC module: Encode and decode JSON-RPC requests for modules diff --git a/src/modules/extra/m_regex_pcre.cpp b/src/modules/extra/m_regex_pcre.cpp index aea4cbbb6..f9b237416 100644 --- a/src/modules/extra/m_regex_pcre.cpp +++ b/src/modules/extra/m_regex_pcre.cpp @@ -77,6 +77,11 @@ public: Me->Modules->Attach(eventlist, this, 1); } + virtual Version GetVersion() + { + return Version("$Id: m_regex_pcre.cpp 10291 2008-08-25 20:35:51Z w00t $", VF_COMMON | VF_VENDOR | VF_SERVICEPROVIDER, API_VERSION); + } + virtual ~ModuleRegexPCRE() { ServerInstance->Modules->UnpublishInterface("RegularExpression", this); @@ -98,3 +103,5 @@ public: return NULL; } }; + +MODULE_INIT(ModuleRegexPCRE) diff --git a/src/modules/extra/m_regex_posix.cpp b/src/modules/extra/m_regex_posix.cpp index ab5d44b99..63ba61df8 100644 --- a/src/modules/extra/m_regex_posix.cpp +++ b/src/modules/extra/m_regex_posix.cpp @@ -84,6 +84,11 @@ public: OnRehash(NULL, ""); } + virtual Version GetVersion() + { + return Version("$Id: m_regex_posix.cpp 10291 2008-08-25 20:35:51Z w00t $", VF_COMMON | VF_VENDOR | VF_SERVICEPROVIDER, API_VERSION); + } + virtual ~ModuleRegexPOSIX() { ServerInstance->Modules->UnpublishInterface("RegularExpression", this); @@ -111,3 +116,5 @@ public: return NULL; } }; + +MODULE_INIT(ModuleRegexPOSIX) diff --git a/src/modules/extra/m_regex_tre.cpp b/src/modules/extra/m_regex_tre.cpp index 2a89015d9..e0468d3c5 100644 --- a/src/modules/extra/m_regex_tre.cpp +++ b/src/modules/extra/m_regex_tre.cpp @@ -83,6 +83,11 @@ public: Me->Modules->Attach(eventlist, this, 1); } + virtual Version GetVersion() + { + return Version("$Id: m_regex_tre.cpp 10291 2008-08-25 20:35:51Z w00t $", VF_COMMON | VF_VENDOR | VF_SERVICEPROVIDER, API_VERSION); + } + virtual ~ModuleRegexTRE() { ServerInstance->Modules->UnpublishInterface("RegularExpression", this); @@ -104,3 +109,5 @@ public: return NULL; } }; + +MODULE_INIT(ModuleRegexTRE) diff --git a/src/modules/m_regex_glob.cpp b/src/modules/m_regex_glob.cpp index 7977c77f1..2f7174f0d 100644 --- a/src/modules/m_regex_glob.cpp +++ b/src/modules/m_regex_glob.cpp @@ -44,6 +44,11 @@ public: Me->Modules->Attach(eventlist, this, 1); } + virtual Version GetVersion() + { + return Version("$Id: m_regex_glob.cpp 10291 2008-08-25 20:35:51Z w00t $", VF_COMMON | VF_VENDOR | VF_SERVICEPROVIDER, API_VERSION); + } + virtual ~ModuleRegexGlob() { ServerInstance->Modules->UnpublishInterface("RegularExpression", this); @@ -65,3 +70,5 @@ public: return NULL; } }; + +MODULE_INIT(ModuleRegexGlob) diff --git a/src/modules/extra/m_rline.cpp b/src/modules/m_rline.cpp index cdb725a83..e6340cc0f 100644 --- a/src/modules/extra/m_rline.cpp +++ b/src/modules/m_rline.cpp @@ -12,16 +12,13 @@ */ #include "inspircd.h" -#include <pcre.h> +#include "m_regex.h" #include "xline.h" -/* $ModDesc: RLINE: Regexp user banning. */ -/* $CompileFlags: exec("pcre-config --cflags") */ -/* $LinkerFlags: exec("pcre-config --libs") rpath("pcre-config --libs") -lpcre */ +static Module* rxengine = 0; +static Module* mymodule = 0; /* Needed to let RLine send request! */ -#ifdef WINDOWS -#pragma comment(lib, "pcre.lib") -#endif +/* $ModDesc: RLINE: Regexp user banning. */ class CoreExport RLine : public XLine { @@ -37,17 +34,19 @@ class CoreExport RLine : public XLine */ RLine(InspIRCd* Instance, time_t s_time, long d, const char* src, const char* re, const char* regexs) : XLine(Instance, s_time, d, src, re, "R") { - const char *error; - int erroffset; - matchtext = regexs; - regex = pcre_compile(regexs, 0, &error, &erroffset, NULL); - - if (!regex) + if (!rxengine) { - ServerInstance->SNO->WriteToSnoMask('x',"Error in regular expression: %s at offset %d: %s\n", regexs, erroffset, error); - throw ModuleException("Bad regex pattern."); + ServerInstance->SNO->WriteToSnoMask('x', "Cannot create regexes until engine is set to a loaded provider!"); + throw ModuleException("Regex engine not set or loaded!"); + } + + try { + regex = RegexFactoryRequest(mymodule, rxengine, regexs).Create(); + } catch (ModuleException& ex) { + ServerInstance->SNO->WriteToSnoMask('x', "Bad regex: %s", ex.GetReason()); + throw; } } @@ -55,7 +54,7 @@ class CoreExport RLine : public XLine */ ~RLine() { - pcre_free(regex); + delete regex; } bool Matches(User *u) @@ -64,7 +63,7 @@ class CoreExport RLine : public XLine ServerInstance->Logs->Log("m_rline",DEBUG, "Matching " + matchtext + " against string " + compare); - if (pcre_exec(regex, NULL, compare.c_str(), compare.length(), 0, 0, NULL, 0) > -1) + if (regex->Matches(compare)) { // Bang. :D return true; @@ -75,7 +74,7 @@ class CoreExport RLine : public XLine bool Matches(const std::string &compare) { - if (pcre_exec(regex, NULL, compare.c_str(), compare.length(), 0, 0, NULL, 0) > -1) + if (regex->Matches(compare)) { // Bang. :D return true; @@ -101,7 +100,7 @@ class CoreExport RLine : public XLine std::string matchtext; - pcre *regex; + Regex *regex; }; @@ -125,6 +124,8 @@ class CoreExport RLineFactory : public XLineFactory */ class CommandRLine : public Command { + std::string rxengine; + public: CommandRLine (InspIRCd* Instance) : Command(Instance,"RLINE", "o", 1) { @@ -197,12 +198,16 @@ class ModuleRLine : public Module CommandRLine *r; RLineFactory *f; bool MatchOnNickChange; + std::string RegexEngine; public: ModuleRLine(InspIRCd* Me) : Module(Me) { + mymodule = this; OnRehash(NULL, ""); + Me->Modules->UseInterface("RegularExpression"); + // Create a new command r = new CommandRLine(ServerInstance); ServerInstance->AddCommand(r); @@ -210,13 +215,14 @@ class ModuleRLine : public Module f = new RLineFactory(ServerInstance); ServerInstance->XLines->RegisterFactory(f); - Implementation eventlist[] = { I_OnUserConnect, I_OnRehash, I_OnUserPostNick }; + Implementation eventlist[] = { I_OnUserConnect, I_OnRehash, I_OnUserPostNick, I_OnLoadModule }; ServerInstance->Modules->Attach(eventlist, this, 3); } virtual ~ModuleRLine() { + ServerInstance->Modules->DoneWithInterface("RegularExpression"); ServerInstance->XLines->DelAll("R"); ServerInstance->XLines->UnregisterFactory(f); } @@ -242,7 +248,48 @@ class ModuleRLine : public Module { ConfigReader Conf(ServerInstance); - MatchOnNickChange = Conf.ReadFlag("rline", "matchonnickchange", 1); + MatchOnNickChange = Conf.ReadFlag("rline", "matchonnickchange", 0); + + std::string newrxengine; + + newrxengine = Conf.ReadValue("rline", "engine", 0); + + if (!RegexEngine.empty()) + { + if (RegexEngine == newrxengine) + return; + ServerInstance->SNO->WriteToSnoMask('x', "Dumping all R-Lines due to regex engine change (was '%s', now '%s')", RegexEngine.c_str(), newrxengine.c_str()); + ServerInstance->XLines->DelAll("R"); + } + rxengine = 0; + RegexEngine = newrxengine; + modulelist* ml = ServerInstance->Modules->FindInterface("RegularExpression"); + for (modulelist::iterator i = ml->begin(); i != ml->end(); ++i) + { + std::string rxname = RegexNameRequest(this, *i).Send(); + if (rxname == newrxengine) + { + ServerInstance->SNO->WriteToSnoMask('x', "R-Line now using engine '%s'", RegexEngine.c_str()); + rxengine = *i; + } + } + if (!rxengine) + { + ServerInstance->SNO->WriteToSnoMask('x', "WARNING: Regex engine '%s' is not loaded - R-Line functionality disabled until this is corrected.", RegexEngine.c_str()); + } + } + + virtual void OnLoadModule(Module* mod, const std::string& name) + { + if (ServerInstance->Modules->ModuleHasInterface(mod, "RegularExpression")) + { + std::string rxname = RegexNameRequest(this, mod).Send(); + if (rxname == RegexEngine) + { + ServerInstance->SNO->WriteToSnoMask('x', "R-Line now using engine '%s'", RegexEngine.c_str()); + rxengine = mod; + } + } } virtual void OnUserPostNick(User *user, const std::string &oldnick) |