From 511ca1c3ec696e20f75ba0fa92f34443179c55dc Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Sun, 22 Feb 2004 19:39:43 +0000 Subject: [PATCH] - Minor fix for previous. - Improved 'viruschan' spamfilter target: - better msg after the forced join - +oaq's in set::spamfilter::virus-help-channel receive a notice about which filter the user matched. - it disables all commands except PONG, ADMIN, and msg/notices to set::spamfilter::virus-help-channel. - Made snomask +S also show the spamfilter reason field. - Added class::pingfreq checking, should be 30-600 now.. else you might get mysterious (mass) disconnect issues. - Lol, I made /connect dissapear during modulizing ;). --- Changes | 11 +++++++++++ doc/unreal32docs.html | 5 +++-- include/struct.h | 21 ++++++++++++--------- src/modules/m_admin.c | 2 +- src/modules/m_message.c | 18 +++++++++++++++++- src/modules/m_pingpong.c | 2 +- src/modules/m_quit.c | 4 +++- src/packet.c | 4 ++++ src/parse.c | 2 ++ src/s_conf.c | 12 ++++++++++-- src/s_kline.c | 27 ++++++++++++++++++++++----- 11 files changed, 86 insertions(+), 22 deletions(-) diff --git a/Changes b/Changes index 0880bd428..820afa43a 100644 --- a/Changes +++ b/Changes @@ -2951,3 +2951,14 @@ seen. gmtime warning still there Reported by Fury (#0001575). - Moved the SQLINE system (and ban nick) to TKL and introduced "holds" suggested by Certus +- Minor fix for previous. +- Improved 'viruschan' spamfilter target: + - better msg after the forced join + - +oaq's in set::spamfilter::virus-help-channel receive a notice about + which filter the user matched. + - it disables all commands except PONG, ADMIN, and msg/notices to + set::spamfilter::virus-help-channel. +- Made snomask +S also show the spamfilter reason field. +- Added class::pingfreq checking, should be 30-600 now.. else you might + get mysterious (mass) disconnect issues. +- Lol, I made /connect dissapear during modulizing ;). diff --git a/doc/unreal32docs.html b/doc/unreal32docs.html index 95b26541a..0dbd43cf1 100644 --- a/doc/unreal32docs.html +++ b/doc/unreal32docs.html @@ -457,7 +457,8 @@ Modules can also add other extended ban types.
gzlineputs a gzline (global zline) on the host blockblock the message only dccblockmark the user so (s)he's unable to send any DCCs -viruschanpart all channels and join set::spamfilter::virus-help-channel +viruschanpart all channels, join set::spamfilter::virus-help-channel, disables all commands + except PONG, ADMIN, and msg/notices to set::spamfilter::virus-help-channel [tkltime] The duration of the *line added by the filter, use '-' to use the default or to skip (eg: if action = 'block') @@ -608,7 +609,7 @@ class <name> { or servers from link blocks), you generally have multiple class blocks (ex: for servers, clients, opers).

name is the descriptive name, like "clients" or "servers", this name is used for referring to this class from allow/link/oper/etc blocks

-

pingfreq is the number of seconds between PINGs from the server

+

pingfreq is the number of seconds between PINGs from the server (something between 90 and 180 is recommended).

connfreq is used only for servers and is the number of seconds between connection attempts if autoconnect is enabled

maxclients specifies the maximum (total) number of clients/servers which can be in this class

sendq specifies the amount of data which can be in the send queue (very high for servers with low bandwidth, medium for clients)

diff --git a/include/struct.h b/include/struct.h index fe75d9727..e76ff5393 100644 --- a/include/struct.h +++ b/include/struct.h @@ -306,7 +306,7 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */ #endif #define FLAGS_UNOCCUP2 0x2000000 /* [FREE] */ #define FLAGS_SHUNNED 0x4000000 -#define FLAGS_UNOCCUP3 0x8000000 /* [FREE] */ +#define FLAGS_VIRUS 0x8000000 /* tagged by spamfilter */ #ifdef USE_SSL #define FLAGS_SSL 0x10000000 #endif @@ -391,6 +391,9 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */ #define IsShunned(x) ((x)->flags & FLAGS_SHUNNED) #define SetShunned(x) ((x)->flags |= FLAGS_SHUNNED) #define ClearShunned(x) ((x)->flags &= ~FLAGS_SHUNNED) +#define IsVirus(x) ((x)->flags & FLAGS_VIRUS) +#define SetVirus(x) ((x)->flags |= FLAGS_VIRUS) +#define ClearVirus(x) ((x)->flags |= FLAGS_VIRUS) #ifdef USE_SSL #define IsSecure(x) ((x)->flags & FLAGS_SSL) @@ -723,14 +726,14 @@ struct Server { } flags; }; -#define M_UNREGISTERED 0x0001 -#define M_USER 0x0002 -#define M_SERVER 0x0004 -#define M_SHUN 0x0008 -#define M_NOLAG 0x0010 -#define M_ALIAS 0x0020 -#define M_RESETIDLE 0x0040 - +#define M_UNREGISTERED 0x0001 +#define M_USER 0x0002 +#define M_SERVER 0x0004 +#define M_SHUN 0x0008 +#define M_NOLAG 0x0010 +#define M_ALIAS 0x0020 +#define M_RESETIDLE 0x0040 +#define M_VIRUS 0x0080 /* tkl: diff --git a/src/modules/m_admin.c b/src/modules/m_admin.c index 26ca63fa3..430d1c5a6 100644 --- a/src/modules/m_admin.c +++ b/src/modules/m_admin.c @@ -60,7 +60,7 @@ ModuleHeader MOD_HEADER(m_admin) DLLFUNC int MOD_INIT(m_admin)(ModuleInfo *modinfo) { - add_CommandX(MSG_ADMIN, TOK_ADMIN, m_admin, MAXPARA, M_UNREGISTERED|M_USER|M_SHUN); + add_CommandX(MSG_ADMIN, TOK_ADMIN, m_admin, MAXPARA, M_UNREGISTERED|M_USER|M_SHUN|M_VIRUS); MARK_AS_OFFICIAL_MODULE(modinfo); return MOD_SUCCESS; } diff --git a/src/modules/m_message.c b/src/modules/m_message.c index 063188218..ca9761436 100644 --- a/src/modules/m_message.c +++ b/src/modules/m_message.c @@ -70,7 +70,7 @@ DLLFUNC int MOD_INIT(m_message)(ModuleInfo *modinfo) /* * We call our add_Command crap here */ - add_CommandX(MSG_PRIVATE, TOK_PRIVATE, m_private, 2, M_USER|M_SERVER|M_RESETIDLE); + add_CommandX(MSG_PRIVATE, TOK_PRIVATE, m_private, 2, M_USER|M_SERVER|M_RESETIDLE|M_VIRUS); add_Command(MSG_NOTICE, TOK_NOTICE, m_notice, 2); MARK_AS_OFFICIAL_MODULE(modinfo); return MOD_SUCCESS; @@ -162,6 +162,11 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int for (p = NULL, nick = strtoken(&p, parv[1], ","); nick; nick = strtoken(&p, NULL, ",")) { + if (IsVirus(sptr) && (!strcasecmp(nick, "ircd") || !strcasecmp(nick, "irc"))) + { + sendnotice(sptr, "IRC command(s) unavailable because you are suspected to have a virus"); + continue; + } /* ** nickname addressed? */ @@ -193,6 +198,11 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int } if (*nick != '#' && (acptr = find_person(nick, NULL))) { + if (IsVirus(sptr)) + { + sendnotice(sptr, "You are only allowed to talk in '%s'", SPAMFILTER_VIRUSCHAN); + continue; + } /* Umode +R (idea from Bahamut) */ if (IsRegNickMsg(acptr) && !IsRegNick(sptr) && !IsULine(sptr) && !IsOper(sptr)) { sendto_one(sptr, err_str(ERR_NONONREG), me.name, parv[0], @@ -383,6 +393,12 @@ DLLFUNC int m_message(aClient *cptr, aClient *sptr, int parc, char *parv[], int nick = pfixchan; } + if (IsVirus(sptr) && strcasecmp(chptr->chname, SPAMFILTER_VIRUSCHAN)) + { + sendnotice(sptr, "You are only allowed to talk in '%s'", SPAMFILTER_VIRUSCHAN); + continue; + } + cansend = !IsULine(sptr) ? can_send(sptr, chptr, parv[2], notice) : 0; if (!cansend) diff --git a/src/modules/m_pingpong.c b/src/modules/m_pingpong.c index 21e6e02f9..715610013 100644 --- a/src/modules/m_pingpong.c +++ b/src/modules/m_pingpong.c @@ -74,7 +74,7 @@ DLLFUNC int MOD_INIT(m_pingpong)(ModuleInfo *modinfo) Debug((DEBUG_NOTICE, "INIT")); add_Command(MSG_PING, TOK_PING, m_ping, MAXPARA); - add_CommandX(MSG_PONG, TOK_PONG, m_pong, MAXPARA, M_UNREGISTERED|M_USER|M_SERVER|M_SHUN); + add_CommandX(MSG_PONG, TOK_PONG, m_pong, MAXPARA, M_UNREGISTERED|M_USER|M_SERVER|M_SHUN|M_VIRUS); MARK_AS_OFFICIAL_MODULE(modinfo); return MOD_SUCCESS; } diff --git a/src/modules/m_quit.c b/src/modules/m_quit.c index dbf98005a..25f9a45b6 100644 --- a/src/modules/m_quit.c +++ b/src/modules/m_quit.c @@ -64,7 +64,7 @@ DLLFUNC int MOD_INIT(m_quit)(ModuleInfo *modinfo) /* * We call our add_Command crap here */ - add_CommandX(MSG_QUIT, TOK_QUIT, m_quit, 1, M_UNREGISTERED|M_USER); + add_CommandX(MSG_QUIT, TOK_QUIT, m_quit, 1, M_UNREGISTERED|M_USER|M_VIRUS); MARK_AS_OFFICIAL_MODULE(modinfo); return MOD_SUCCESS; } @@ -107,6 +107,8 @@ DLLFUNC int m_quit(aClient *cptr, aClient *sptr, int parc, char *parv[]) Hook *tmphook; if (STATIC_QUIT) return exit_client(cptr, sptr, sptr, STATIC_QUIT); + if (IsVirus(sptr)) + return exit_client(cptr, sptr, sptr, "Client exited"); if (!prefix_quit || strcmp(prefix_quit, "no")) s = ircsprintf(comment, "%s ", diff --git a/src/packet.c b/src/packet.c index 3b83b68b1..d80724428 100644 --- a/src/packet.c +++ b/src/packet.c @@ -460,6 +460,8 @@ static inline aCommand *find_Token(char *cmd, int flags) continue; if ((flags & M_SHUN) && !(p->flags & M_SHUN)) continue; + if ((flags & M_VIRUS) && !(p->flags & M_VIRUS)) + continue; if ((flags & M_ALIAS) && !(p->flags & M_ALIAS)) continue; if (!strcmp(p->cmd, cmd)) @@ -476,6 +478,8 @@ static inline aCommand *find_Cmd(char *cmd, int flags) continue; if ((flags & M_SHUN) && !(p->flags & M_SHUN)) continue; + if ((flags & M_VIRUS) && !(p->flags & M_VIRUS)) + continue; if ((flags & M_ALIAS) && !(p->flags & M_ALIAS)) continue; if (!stricmp(p->cmd, cmd)) diff --git a/src/parse.c b/src/parse.c index f750d7e5f..6e7e28230 100644 --- a/src/parse.c +++ b/src/parse.c @@ -321,6 +321,8 @@ int parse(aClient *cptr, char *buffer, char *bufend) flags |= M_SERVER; if (IsShunned(from)) flags |= M_SHUN; + if (IsVirus(from)) + flags |= M_VIRUS; cmptr = find_Command(ch, IsServer(cptr) ? 1 : 0, flags); if (!cmptr) { diff --git a/src/s_conf.c b/src/s_conf.c index 88a48d470..a6c32ebf9 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -3139,7 +3139,15 @@ int _test_class(ConfigFile *conf, ConfigEntry *ce) errors++; continue; } if (!strcmp(cep->ce_varname, "pingfreq")) - {} else + { + int v = atol(cep->ce_vardata); + if ((v < 30) || (v > 600)) + { + config_error("%s:%i: class::pingfreq should be a reasonable value (30-600)", + cep->ce_fileptr->cf_filename, cep->ce_varlinenum); + errors++; continue; + } + } else if (!strcmp(cep->ce_varname, "maxclients")) {} else if (!strcmp(cep->ce_varname, "connfreq")) @@ -4755,7 +4763,7 @@ int _conf_spamfilter(ConfigFile *conf, ConfigEntry *ce) cep = config_find_entry(ce->ce_entries, "action"); action = banact_stringtoval(cep->ce_vardata); nl->hostmask = strdup(cep->ce_vardata); - nl->setby = strdup(BadPtr(me.name) ? NULL : me.name); /* Hmm! */ + nl->setby = BadPtr(me.name) ? NULL : strdup(me.name); /* Hmm! */ nl->spamf = unreal_buildspamfilter(word); nl->spamf->action = action; diff --git a/src/s_kline.c b/src/s_kline.c index 6376dbcc6..25f9f27b4 100644 --- a/src/s_kline.c +++ b/src/s_kline.c @@ -1345,10 +1345,11 @@ char *str = (char *)StripControlCodes(str_in); 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']", + ircsprintf(buf, "[Spamfilter] %s!%s@%s matches filter '%s': [%s%s: '%s'] [%s]", sptr->name, sptr->user->username, sptr->user->realhost, tk->reason, - spamfilter_inttostring_long(type), targetbuf, str); + spamfilter_inttostring_long(type), targetbuf, str, + unreal_decodespace(tk->spamf->tkl_reason)); sendto_snomask(SNO_SPAMF, "%s", buf); sendto_serv_butone_token(NULL, me.name, MSG_SENDSNO, TOK_SENDSNO, "S :%s", buf); @@ -1391,7 +1392,11 @@ char *str = (char *)StripControlCodes(str_in); } else if (tk->spamf->action == BAN_ACT_VIRUSCHAN) { - char *xparv[3], buf[CHANNELLEN+16]; + char *xparv[3], chbuf[CHANNELLEN + 16]; + aChannel *chptr; + + if (IsVirus(sptr)) /* Already tagged */ + return 0; ircsprintf(buf, "0,%s", SPAMFILTER_VIRUSCHAN); xparv[0] = sptr->name; xparv[1] = buf; @@ -1399,9 +1404,21 @@ char *str = (char *)StripControlCodes(str_in); /* RECURSIVE CAUTION in case we ever add blacklisted chans */ if (m_join(sptr, sptr, 2, xparv) == FLUSH_BUFFER) return FLUSH_BUFFER; /* don't ask me how we could have died... */ - sendnotice(sptr, "You are now in %s: %s", + sendnotice(sptr, "You are now restricted to talking in %s: %s", SPAMFILTER_VIRUSCHAN, unreal_decodespace(tk->spamf->tkl_reason)); - return 0; + /* todo: send notice to channel? */ + chptr = find_channel(SPAMFILTER_VIRUSCHAN, NULL); + if (chptr) + { + ircsprintf(chbuf, "%s%s", CHANOPPFX, chptr->chname); + ircsprintf(buf, "[Spamfilter] %s matched filter '%s' [%s%s] [%s]", + sptr->name, tk->reason, spamfilter_inttostring_long(type), targetbuf, + unreal_decodespace(tk->spamf->tkl_reason)); + sendto_channelprefix_butone_tok(NULL, &me, chptr, PREFIX_OP|PREFIX_ADMIN|PREFIX_OWNER, + MSG_NOTICE, TOK_NOTICE, chbuf, buf, 0); + } + SetVirus(sptr); + return -1; } else return place_host_ban(sptr, tk->spamf->action, unreal_decodespace(tk->spamf->tkl_reason), tk->spamf->tkl_duration);