From 3671a765cbf2ab17379f6b18a12d2c4181e136cd Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Sat, 7 Feb 2004 15:49:37 +0000 Subject: [PATCH] this should be the last "big commit" before release :p. - Added snomasks 'S' (Spamfilter) which notifies you of any spamfilter matches. - [internal] always return after spamfilter match, don't continue looping trough targets list (eg in case of: /msg #a,#b,#c spamspam), otherwise you would get duplicate notification msgs. - Added SENDSNO server command, similar to SENDUMODE but for snomasks, this is used by the spamfilter snomask (+S) so you get network-wide notifications. - Added "compiled for.." versioning system, this way a beta17 module can't be loaded on beta18, etc... People often forgot to recompile their modules or had old ones somewhere by mistake, therefore crashing after upgrades... this should fix this (in the future). Module coders don't have to do anything for making this work, it's done automatically (via modules.h). --- Changes | 11 +++++++++++ include/h.h | 5 ++++- include/modules.h | 6 ++++++ include/msg.h | 3 +++ makefile.win32 | 5 ++++- src/channel.c | 2 +- src/modules.c | 11 +++++++++++ src/modules/Makefile.in | 4 ++-- src/modules/l_commands.c | 13 +++++++++++-- src/modules/m_message.c | 20 +++++++------------- src/modules/m_quit.c | 2 +- src/s_kline.c | 17 ++++++++++++++++- src/s_misc.c | 22 ++++++++++++++++++++++ src/umodes.c | 2 ++ 14 files changed, 101 insertions(+), 22 deletions(-) diff --git a/Changes b/Changes index 7a5a08648..659992a15 100644 --- a/Changes +++ b/Changes @@ -2821,3 +2821,14 @@ seen. gmtime warning still there spamfilter::word to spamfilter::regex to make it even more clear (since we match on the whole line and have nothing to do with words.. 'word' doesn't make sense). - Updated docs with some better regex examples, reported by AngryWolf (#0001520). +- Added snomasks 'S' (Spamfilter) which notifies you of any spamfilter matches. +- [internal] always return after spamfilter match, don't continue looping trough + targets list (eg in case of: /msg #a,#b,#c spamspam), otherwise you would get + duplicate notification msgs. +- Added SENDSNO server command, similar to SENDUMODE but for snomasks, this is + used by the spamfilter snomask (+S) so you get network-wide notifications. +- Added "compiled for.." versioning system, this way a beta17 module can't be loaded + on beta18, etc... People often forgot to recompile their modules or had old ones + somewhere by mistake, therefore crashing after upgrades... this should fix this + (in the future). Module coders don't have to do anything for making this work, + it's done automatically (via modules.h). diff --git a/include/h.h b/include/h.h index 9696b34b3..51afc3966 100644 --- a/include/h.h +++ b/include/h.h @@ -451,6 +451,7 @@ extern long SNO_NICKCHANGE; extern long SNO_FNICKCHANGE; extern long SNO_QLINE; extern long SNO_SNOTICE; +extern long SNO_SPAMF; #ifdef EXTCMODE /* Extended chanmodes... */ @@ -651,7 +652,9 @@ extern char banact_valtochar(int val); extern int spamfilter_gettargets(char *s, aClient *sptr); extern char *spamfilter_target_inttostring(int v); extern Spamfilter *unreal_buildspamfilter(char *s); -extern int dospamfilter(aClient *sptr, char *str, int type); +extern int dospamfilter(aClient *sptr, char *str_in, int type, char *target); extern char *our_strcasestr(char *haystack, char *needle); extern int spamfilter_getconftargets(char *s); extern void remove_oper_snomasks(aClient *sptr); +extern char *spamfilter_inttostring_long(int v); +extern int check_channelmask(aClient *, aClient *, char *); diff --git a/include/modules.h b/include/modules.h index 85dfb6bef..cef93a2f8 100644 --- a/include/modules.h +++ b/include/modules.h @@ -562,4 +562,10 @@ int CallCmdoverride(Cmdoverride *ovr, aClient *cptr, aClient *sptr, int parc, ch #define MOD_UNLOAD(name) name##_Unload #endif +#ifdef DYNAMIC_LINKING +/* ugly alert!!!! */ +#include "version.h" +char Mod_Version[] = BASE_VERSION PATCH1 PATCH2 PATCH3 PATCH4 PATCH5 PATCH6 PATCH7 PATCH8 PATCH9; +#endif + #endif diff --git a/include/msg.h b/include/msg.h index a2a38056b..d28871c80 100644 --- a/include/msg.h +++ b/include/msg.h @@ -292,6 +292,9 @@ #define TOK_MODULE "BQ" /* BR and BT are in use */ +#define MSG_SENDSNO "SENDSNO" +#define TOK_SENDSNO "Ss" + #define MSG_EOS "EOS" #define TOK_EOS "ES" diff --git a/makefile.win32 b/makefile.win32 index 6dd97801f..9392738d6 100644 --- a/makefile.win32 +++ b/makefile.win32 @@ -146,7 +146,7 @@ MOD_FILES=SRC/L_COMMANDS.OBJ SRC/M_CHGHOST.OBJ SRC/M_SDESC.OBJ SRC/M_SETIDENT.OB SRC/M_UNSQLINE.OBJ SRC/M_UNZLINE.OBJ SRC/M_WHOIS.OBJ \ SRC/M_TKL.OBJ SRC/M_VHOST.OBJ \ SRC/M_CYCLE.OBJ SRC/M_SVSJOIN.OBJ SRC/M_SVSPART.OBJ SRC/M_SVSLUSERS.OBJ \ - SRC/M_SVSWATCH.OBJ SRC/M_SVSSILENCE.OBJ + SRC/M_SVSWATCH.OBJ SRC/M_SVSSILENCE.OBJ SRC/M_SENDSNO.OBJ ALL: CONF UNREAL.EXE WIRCD.EXE @@ -491,6 +491,9 @@ src/m_svswatch.obj: src/modules/m_svswatch.c $(INCLUDES) src/m_svssilence.obj: src/modules/m_svssilence.c $(INCLUDES) $(CC) $(CFLAGS) src/modules/m_svssilence.c +src/m_sendsno.obj: src/modules/m_sendsno.c $(INCLUDES) + $(CC) $(CFLAGS) src/modules/m_sendsno.c + src/win32/win32.res: src/win32/win32gui.rc $(RC) /l 0x409 /fosrc/win32/win32.res /i ./include /i ./src \ /d NDEBUG src/win32/win32gui.rc diff --git a/src/channel.c b/src/channel.c index 09e543932..317a12901 100644 --- a/src/channel.c +++ b/src/channel.c @@ -4006,7 +4006,7 @@ CMD_FUNC(m_part) } if (commentx) { - n = dospamfilter(sptr, commentx, SPAMF_PART); + n = dospamfilter(sptr, commentx, SPAMF_PART, name); if (n == FLUSH_BUFFER) return n; if (n < 0) diff --git a/src/modules.c b/src/modules.c index 2a99219c2..64c2904ae 100644 --- a/src/modules.c +++ b/src/modules.c @@ -144,6 +144,7 @@ char *Module_Create(char *path_) int (*Mod_Init)(); int (*Mod_Load)(); int (*Mod_Unload)(); + char *Mod_Version; static char errorbuf[1024]; char *path, *tmppath; ModuleHeader *mod_header; @@ -169,6 +170,16 @@ char *Module_Create(char *path_) if ((Mod = irc_dlopen(tmppath, RTLD_NOW))) { /* We have engaged the borg cube. Scan for lifesigns. */ + irc_dlsym(Mod, "Mod_Version", Mod_Version); + if (Mod_Version && strcmp(version, Mod_Version)) + { + snprintf(errorbuf, sizeof(errorbuf), + "Module was compiled for '%s', we are '%s', please recompile the module", + Mod_Version, version); + irc_dlclose(Mod); + remove(tmppath); + return errorbuf; + } irc_dlsym(Mod, "Mod_Header", mod_header); if (!mod_header) { diff --git a/src/modules/Makefile.in b/src/modules/Makefile.in index fa7bbfffe..d88251397 100644 --- a/src/modules/Makefile.in +++ b/src/modules/Makefile.in @@ -33,7 +33,7 @@ R_MODULES=m_sethost.so m_chghost.so m_chgident.so m_setname.so \ m_quit.so m_rakill.so m_rping.so m_sendumode.so m_sqline.so \ m_tsctl.so m_unkline.so m_unsqline.so m_unzline.so m_whois.so \ m_tkl.so m_vhost.so m_cycle.so m_svsjoin.so m_svspart.so \ - m_svswatch.so m_svssilence.so + m_svswatch.so m_svssilence.so m_sendsno.c COMMANDS=m_sethost.c m_chghost.c m_chgident.c m_setname.c m_setident.c \ m_sdesc.c m_svsmode.c m_swhois.c m_svsmotd.c m_svsnline.c \ @@ -43,7 +43,7 @@ COMMANDS=m_sethost.c m_chghost.c m_chgident.c m_setname.c m_setident.c \ m_quit.c m_rakill.c m_rping.c m_sendumode.c m_sqline.c \ m_tsctl.c m_unkline.c m_unsqline.c m_unzline.c m_whois.c \ m_tkl.c m_vhost.c m_cycle.c m_svsjoin.c m_svspart.c \ - m_svslusers.c m_svswatch.c m_svssilence.c + m_svslusers.c m_svswatch.c m_svssilence.c m_sendsno.c MODULES=commands.so $(R_MODULES) diff --git a/src/modules/l_commands.c b/src/modules/l_commands.c index 1ffc00c5b..57909599d 100644 --- a/src/modules/l_commands.c +++ b/src/modules/l_commands.c @@ -38,15 +38,18 @@ #ifdef STRIPBADWORDS #include "badwords.h" #endif -#ifdef _WIN32 #include "version.h" -#endif #ifndef STATIC_LINKING #define DYNAMIC_LINKING #else #undef DYNAMIC_LINKING #endif +/* l_commands.c/commands.so is a special case so we have to do this manually :p */ +#ifdef DYNAMIC_LINKING +char Mod_Version[] = BASE_VERSION PATCH1 PATCH2 PATCH3 PATCH4 PATCH5 PATCH6 PATCH7 PATCH8 PATCH9; +#endif + extern ModuleHeader m_svsnoop_Header; ModuleInfo *ModCmdsInfo; /* Place includes here */ @@ -87,6 +90,7 @@ extern int m_sqline_Init(ModuleInfo *modinfo), m_unsqline_Init(ModuleInfo *modin extern int m_vhost_Init(ModuleInfo *modinfo), m_cycle_Init(ModuleInfo *modinfo), m_svsjoin_Init(ModuleInfo *modinfo); extern int m_svspart_Init(ModuleInfo *modinfo), m_svslusers_Init(ModuleInfo *modinfo); extern int m_svswatch_Init(ModuleInfo *modinfo), m_svssilence_Init(ModuleInfo *modinfo); +extern int m_sendsno_Init(ModuleInfo *modinfo); #ifdef GUEST extern int m_guest_Init(ModuleInfo *modinfo); #endif @@ -107,6 +111,7 @@ extern int m_sqline_Load(int module_load), m_unsqline_Load(int module_load), m_t extern int m_vhost_Load(int module_load), m_cycle_Load(int module_load), m_svsjoin_Load(int module_load); extern int m_svspart_Load(int module_load), m_svslusers_Load(int module_load); extern int m_svswatch_Load(int module_load), m_svssilence_Load(int module_load); +extern int m_sendsno_Load(int module_load); #ifdef GUEST extern int m_guest_Load(int module_load); #endif @@ -123,6 +128,7 @@ extern int m_unzline_Unload(), m_unkline_Unload(); extern int m_sqline_Unload(), m_unsqline_Unload(), m_tkl_Unload(), m_vhost_Unload(); extern int m_cycle_Unload(), m_svsjoin_Unload(), m_svspart_Unload(), m_svslusers_Unload(); extern int m_svswatch_Unload(), m_svssilence_Unload(); +extern int m_sendsno_Unload(); #ifdef GUEST extern int m_guest_Unload(); #endif @@ -200,6 +206,7 @@ int l_commands_Init(ModuleInfo *modinfo) m_svswatch_Init(ModCmdsInfo); m_svssilence_Init(ModCmdsInfo); m_svslusers_Init(ModCmdsInfo); + m_sendsno_Init(ModCmdsInfo); #ifdef GUEST m_guest_Init(ModCmdsInfo); #endif @@ -256,6 +263,7 @@ int l_commands_Load(int module_load) m_svswatch_Load(module_load); m_svssilence_Load(module_load); m_svslusers_Load(module_load); + m_sendsno_Load(module_load); #ifdef GUEST m_guest_Load(module_load); #endif @@ -312,6 +320,7 @@ int l_commands_Unload(int module_unload) m_svswatch_Unload(); m_svssilence_Unload(); m_svslusers_Unload(); + m_sendsno_Unload(); #ifdef GUEST m_guest_Unload(); #endif diff --git a/src/modules/m_message.c b/src/modules/m_message.c index aded34081..063188218 100644 --- a/src/modules/m_message.c +++ b/src/modules/m_message.c @@ -122,6 +122,7 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int int cansend = 0; int prefix = 0; char pfixchan[CHANNELLEN + 32]; + int n; /* * Reasons why someone can't send to a channel @@ -221,7 +222,7 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int { ConfigItem_deny_dcc *fl; char *end, file[BUFSIZE]; - int size_string = 0, n; + int size_string = 0; if (sptr->flags & FLAGS_DCCBLOCK) { @@ -247,11 +248,8 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int strncpy(file, ctcp, size_string); file[size_string] = '\0'; - n = dospamfilter(sptr, file, SPAMF_DCC); - if (n == FLUSH_BUFFER) + if ((n = dospamfilter(sptr, file, SPAMF_DCC, acptr->name)) < 0) return n; - if (n < 0) - continue; if ((fl = (ConfigItem_deny_dcc *) @@ -319,11 +317,9 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int if (MyClient(sptr)) { - int n = dospamfilter(sptr, text, newcmd == MSG_NOTICE ? SPAMF_USERNOTICE : SPAMF_USERMSG); - if (n == FLUSH_BUFFER) - return FLUSH_BUFFER; + n = dospamfilter(sptr, text, newcmd == MSG_NOTICE ? SPAMF_USERNOTICE : SPAMF_USERMSG, acptr->name); if (n < 0) - continue; + return FLUSH_BUFFER; } for (tmphook = Hooks[HOOKTYPE_USERMSG]; tmphook; tmphook = tmphook->next) { @@ -442,11 +438,9 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int if (MyClient(sptr)) { - int n = dospamfilter(sptr, text, notice ? SPAMF_CHANNOTICE : SPAMF_CHANMSG); - if (n == FLUSH_BUFFER) - return FLUSH_BUFFER; + n = dospamfilter(sptr, text, notice ? SPAMF_CHANNOTICE : SPAMF_CHANMSG, chptr->chname); if (n < 0) - continue; + return n; } for (tmphook = Hooks[HOOKTYPE_CHANMSG]; tmphook; tmphook = tmphook->next) { diff --git a/src/modules/m_quit.c b/src/modules/m_quit.c index 7140fb3aa..dbf98005a 100644 --- a/src/modules/m_quit.c +++ b/src/modules/m_quit.c @@ -116,7 +116,7 @@ DLLFUNC int m_quit(aClient *cptr, aClient *sptr, int parc, char *parv[]) if (blocked) ocomment = parv[0]; #endif - n = dospamfilter(sptr, ocomment, SPAMF_QUIT); + n = dospamfilter(sptr, ocomment, SPAMF_QUIT, NULL); if (n == FLUSH_BUFFER) return n; if (n < 0) diff --git a/src/s_kline.c b/src/s_kline.c index 26a52302f..adc89d1e3 100644 --- a/src/s_kline.c +++ b/src/s_kline.c @@ -1090,7 +1090,7 @@ int place_host_ban(aClient *sptr, int action, char *reason, long duration) * (like from m_message, m_part, m_quit, etc). */ -int dospamfilter(aClient *sptr, char *str_in, int type) +int dospamfilter(aClient *sptr, char *str_in, int type, char *target) { aTKline *tk; int n; @@ -1106,6 +1106,21 @@ char *str = (char *)StripControlCodes(str_in); if (!regexec(&tk->spamf->expr, str, 0, NULL, 0)) { /* matched! */ + char buf[1024]; + char targetbuf[48]; + if (target) { + targetbuf[0] = ' '; + strlcpy(targetbuf+1, target, sizeof(targetbuf)-1); /* cut it off */ + } else + targetbuf[0] = '\0'; + ircsprintf(buf, "[Spamfilter] %s!%s@%s matches filter '%s': [%s%s: '%s']", + sptr->name, sptr->user->username, sptr->user->realhost, + tk->reason, + spamfilter_inttostring_long(type), targetbuf, str); + + sendto_snomask(SNO_SPAMF, "%s", buf); + sendto_serv_butone_token(NULL, me.name, MSG_SENDSNO, TOK_SENDSNO, "S :%s", buf); + if (tk->spamf->action != BAN_ACT_BLOCK) return place_host_ban(sptr, tk->spamf->action, SPAMFILTER_BAN_REASON, SPAMFILTER_BAN_TIME); else diff --git a/src/s_misc.c b/src/s_misc.c index c7c5b60b2..b6472f4a0 100644 --- a/src/s_misc.c +++ b/src/s_misc.c @@ -973,3 +973,25 @@ char *p = buf; *p = '\0'; return buf; } + +/* only used by dospamfilter() */ +char *spamfilter_inttostring_long(int v) +{ + switch(v) + { + case SPAMF_CHANMSG: + case SPAMF_USERMSG: + return "PRIVMSG"; + case SPAMF_USERNOTICE: + case SPAMF_CHANNOTICE: + return "NOTICE"; + case SPAMF_PART: + return "PART"; + case SPAMF_QUIT: + return "QUIT"; + case SPAMF_DCC: + return "DCC"; + default: + return "UNKNOWN"; + } +} diff --git a/src/umodes.c b/src/umodes.c index c7e68e8d7..a39f30941 100644 --- a/src/umodes.c +++ b/src/umodes.c @@ -89,6 +89,7 @@ long SNO_TKL = 0L; long SNO_NICKCHANGE = 0L; long SNO_FNICKCHANGE = 0L; long SNO_QLINE = 0L; +long SNO_SPAMF = 0L; long SNO_SNOTICE = 0L; long AllUmodes; /* All umodes */ @@ -156,6 +157,7 @@ void umode_init(void) SnomaskAdd(NULL, 'n', umode_allow_opers, &SNO_NICKCHANGE); SnomaskAdd(NULL, 'N', umode_allow_opers, &SNO_FNICKCHANGE); SnomaskAdd(NULL, 'q', umode_allow_opers, &SNO_QLINE); + SnomaskAdd(NULL, 'S', umode_allow_opers, &SNO_SPAMF); SnomaskAdd(NULL, 's', umode_allow_all, &SNO_SNOTICE); }