00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "inspircd.h"
00015 #include <pcre.h>
00016 #include "users.h"
00017 #include "channels.h"
00018 #include "modules.h"
00019 #include "m_filter.h"
00020
00021
00022
00023
00024
00025
00026 #ifdef WINDOWS
00027 #pragma comment(lib, "pcre.lib")
00028 #endif
00029
00030 class PCREFilter : public FilterResult
00031 {
00032 public:
00033 pcre* regexp;
00034
00035 PCREFilter(pcre* r, const std::string &rea, const std::string &act, long glinetime, const std::string &pat, const std::string &flgs)
00036 : FilterResult(pat, rea, act, glinetime, flgs), regexp(r)
00037 {
00038 }
00039
00040 PCREFilter()
00041 {
00042 }
00043 };
00044
00045 class ModuleFilterPCRE : public FilterBase
00046 {
00047 std::vector<PCREFilter> filters;
00048 pcre *re;
00049 const char *error;
00050 int erroffset;
00051 PCREFilter fr;
00052
00053 public:
00054 ModuleFilterPCRE(InspIRCd* Me)
00055 : FilterBase(Me, "m_filter_pcre.so")
00056 {
00057 OnRehash(NULL,"");
00058
00059 }
00060
00061 virtual ~ModuleFilterPCRE()
00062 {
00063 }
00064
00065 virtual FilterResult* FilterMatch(User* user, const std::string &text, int flgs)
00066 {
00067 for (std::vector<PCREFilter>::iterator index = filters.begin(); index != filters.end(); index++)
00068 {
00069
00070
00071 if (!FilterBase::AppliesToMe(user, dynamic_cast<FilterResult*>(&(*index)), flgs))
00072 continue;
00073
00074 if (pcre_exec(index->regexp, NULL, text.c_str(), text.length(), 0, 0, NULL, 0) > -1)
00075 {
00076 fr = *index;
00077 if (index != filters.begin())
00078 {
00079 filters.erase(index);
00080 filters.insert(filters.begin(), fr);
00081 }
00082 return &fr;
00083 }
00084 }
00085 return NULL;
00086 }
00087
00088 virtual bool DeleteFilter(const std::string &freeform)
00089 {
00090 for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
00091 {
00092 if (i->freeform == freeform)
00093 {
00094 pcre_free((*i).regexp);
00095 filters.erase(i);
00096 return true;
00097 }
00098 }
00099 return false;
00100 }
00101
00102 virtual void SyncFilters(Module* proto, void* opaque)
00103 {
00104 for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
00105 {
00106 this->SendFilter(proto, opaque, &(*i));
00107 }
00108 }
00109
00110 virtual std::pair<bool, std::string> AddFilter(const std::string &freeform, const std::string &type, const std::string &reason, long duration, const std::string &flgs)
00111 {
00112 for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
00113 {
00114 if (i->freeform == freeform)
00115 {
00116 return std::make_pair(false, "Filter already exists");
00117 }
00118 }
00119
00120 re = pcre_compile(freeform.c_str(),0,&error,&erroffset,NULL);
00121
00122 if (!re)
00123 {
00124 ServerInstance->Logs->Log("m_filter_pcre", DEFAULT,"Error in regular expression: %s at offset %d: %s\n", freeform.c_str(), erroffset, error);
00125 ServerInstance->Logs->Log("m_filter_pcre", DEFAULT,"Regular expression %s not loaded.", freeform.c_str());
00126 return std::make_pair(false, "Error in regular expression at offset " + ConvToStr(erroffset) + ": "+error);
00127 }
00128 else
00129 {
00130 filters.push_back(PCREFilter(re, reason, type, duration, freeform, flgs));
00131 return std::make_pair(true, "");
00132 }
00133 }
00134
00135 virtual void OnRehash(User* user, const std::string ¶meter)
00136 {
00137 ConfigReader MyConf(ServerInstance);
00138
00139 for (int index = 0; index < MyConf.Enumerate("keyword"); index++)
00140 {
00141 this->DeleteFilter(MyConf.ReadValue("keyword", "pattern", index));
00142
00143 std::string pattern = MyConf.ReadValue("keyword", "pattern", index);
00144 std::string reason = MyConf.ReadValue("keyword", "reason", index);
00145 std::string action = MyConf.ReadValue("keyword", "action", index);
00146 std::string flgs = MyConf.ReadValue("keyword", "flags", index);
00147 long gline_time = ServerInstance->Duration(MyConf.ReadValue("keyword", "duration", index));
00148 if (action.empty())
00149 action = "none";
00150 if (flgs.empty())
00151 flgs = "*";
00152
00153 re = pcre_compile(pattern.c_str(),0,&error,&erroffset,NULL);
00154
00155 if (!re)
00156 {
00157 ServerInstance->Logs->Log("CONFIG",DEFAULT,"Error in regular expression: %s at offset %d: %s\n", pattern.c_str(), erroffset, error);
00158 ServerInstance->Logs->Log("CONFIG",DEFAULT,"Regular expression %s not loaded.", pattern.c_str());
00159 }
00160 else
00161 {
00162 filters.push_back(PCREFilter(re, reason, action, gline_time, pattern, flgs));
00163 ServerInstance->Logs->Log("CONFIG",DEFAULT,"Regular expression %s loaded.", pattern.c_str());
00164 }
00165 }
00166 FilterBase::OnRehash(user, parameter);
00167 }
00168
00169 virtual int OnStats(char symbol, User* user, string_list &results)
00170 {
00171 if (symbol == 's')
00172 {
00173 std::string sn = ServerInstance->Config->ServerName;
00174 for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
00175 {
00176 results.push_back(sn+" 223 "+user->nick+" :REGEXP:"+i->freeform+" "+i->flags+" "+i->action+" "+ConvToStr(i->gline_time)+" :"+i->reason);
00177 }
00178 for (std::vector<std::string>::iterator i = exemptfromfilter.begin(); i != exemptfromfilter.end(); ++i)
00179 {
00180 results.push_back(sn+" 223 "+user->nick+" :EXEMPT "+(*i));
00181 }
00182 }
00183 return 0;
00184 }
00185 };
00186
00187 MODULE_INIT(ModuleFilterPCRE)
00188