X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=blobdiff_plain;f=src%2Fmodules%2FNeonSpam.mod%2Fevent_neonspam_chanmsg.c;h=b70a7a5f565bcf7d1935640df3dfd5c4bf50a6ef;hp=4ab7c833b23c72867924953d6419845066df6a3e;hb=3e82313bfb3eaf4f2b59dfc165372e3174be838b;hpb=44af45fb4b2528227e66b05d69d2952c62fce8e9 diff --git a/src/modules/NeonSpam.mod/event_neonspam_chanmsg.c b/src/modules/NeonSpam.mod/event_neonspam_chanmsg.c index 4ab7c83..b70a7a5 100644 --- a/src/modules/NeonSpam.mod/event_neonspam_chanmsg.c +++ b/src/modules/NeonSpam.mod/event_neonspam_chanmsg.c @@ -20,14 +20,16 @@ static int neonspam_floodscan(struct NeonSpamSettings *settings, struct ChanUser static int neonspam_botnetscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message); static int neonspam_capsscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message); static int neonspam_digitscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message); +static int neonspam_badwordscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message, int punish_now, int uaccess); static USERAUTH_CALLBACK(neonspam_event_chanmsg_nick_lookup); -static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, unsigned int warn, unsigned int punish); +static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, char *message, unsigned int warn, unsigned int punish); struct neonspam_event_chanmsg_cache { struct ClientSocket *client; struct ChanUser *chanuser; struct NeonSpamSettings *settings; + char *message; unsigned int warn; unsigned int punish; }; @@ -127,12 +129,28 @@ static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan, break; } } + if((settings->flags & SPAMSETTINGS_BADWORDSCAN)) { + if(user->flags & USERFLAG_ISAUTHED) { + result = neonspam_badwordscan(client, settings, chanuser, message, 1, getChannelAccess(chanuser->user, chanuser->chan)); + } else + result = neonspam_badwordscan(client, settings, chanuser, message, 0, 0); + switch(result) { + case SPAMSERV_CHECK_DEAD: + return; + case SPAMSERV_CHECK_IGNORE: + break; + case SPAMSERV_CHECK_PUNISH: + punish |= SPAMSETTINGS_BADWORDSCAN; + needwho = 1; + break; + } + } //some other checks? if(warn || punish) { //whois the user to check against exceptlevel if(!needwho || (user->flags & USERFLAG_ISAUTHED)) { - neonspam_event_chanmsg_punish(client, chanuser, settings, warn, punish); + neonspam_event_chanmsg_punish(client, chanuser, settings, message, warn, punish); } else { struct neonspam_event_chanmsg_cache *cache = malloc(sizeof(*cache)); if (!cache) { @@ -142,6 +160,7 @@ static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan, cache->client = client; cache->chanuser = chanuser; cache->settings = settings; + cache->message = strdup(message); cache->warn = warn; cache->punish = punish; get_userauth(user, module_id, neonspam_event_chanmsg_nick_lookup, cache); @@ -156,11 +175,12 @@ static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan, static USERAUTH_CALLBACK(neonspam_event_chanmsg_nick_lookup) { struct neonspam_event_chanmsg_cache *cache = data; - neonspam_event_chanmsg_punish(cache->client, cache->chanuser, cache->settings, cache->warn, cache->punish); + neonspam_event_chanmsg_punish(cache->client, cache->chanuser, cache->settings, cache->message, cache->warn, cache->punish); + free(cache->message); free(cache); } -static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, unsigned int warn, unsigned int punish) { +static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct ChanUser *chanuser, struct NeonSpamSettings *settings, char *message, unsigned int warn, unsigned int punish) { MYSQL_RES *res; MYSQL_ROW row, defaults; loadChannelSettings(chanuser->chan); @@ -223,6 +243,16 @@ static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct Ch punishment = atoi((row[0] ? row[0] : defaults[0])) + 1; punish_time = atoi((row[1] ? row[1] : defaults[1])); } + if(!punishment && (punish & SPAMSETTINGS_BADWORDSCAN)) { + int result = neonspam_badwordscan(client, settings, chanuser, message, 1, uaccess); + switch(result) { + case SPAMSERV_CHECK_DEAD: + return; + case SPAMSERV_CHECK_IGNORE: + break; + } + + } if(!punishment && (warn & SPAMSETTINGS_SPAMSCAN) && settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] > uaccess) { sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_SPAM); } @@ -390,3 +420,110 @@ static int neonspam_digitscan(struct NeonSpamSettings *settings, struct ChanUser return SPAMSERV_CHECK_IGNORE; } +static int neonspam_badwordscan(struct ClientSocket *client, struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message, int punish_now, int uaccess) { + struct NeonSpamBadword *badword; + int kick_user = 0; + int ban_user = 0; + int staticban_user = 0; + int ban_duration = 0; + int checked_defaults = 0; + int apply_default_reaction = 0; + for(badword = settings->badwords; badword; badword = badword->next) { + if(!match(badword->badword, message)) { + if(badword->use_defaults) { + if(checked_defaults == 2) continue; + else if(!checked_defaults) { + if(!(settings->flags & SPAMSETTINGS_BADWORDSCAN_OPS) && (chanuser->flags & CHANUSERFLAG_OPPED)) { + checked_defaults = 2; + continue; + } + if(!(settings->flags & SPAMSETTINGS_BADWORDSCAN_VOICE) && (chanuser->flags & CHANUSERFLAG_VOICED)) { + checked_defaults = 2; + continue; + } + if(settings->exceptlevel[SPAMSETTINGS_BADWORDEXCINDEX] && settings->exceptlevel[SPAMSETTINGS_BADWORDEXCINDEX] < 501) { + if(!punish_now) + return SPAMSERV_CHECK_PUNISH; + if(settings->exceptlevel[SPAMSETTINGS_BADWORDEXCINDEX] <= uaccess) { + checked_defaults = 2; + continue; + } + } + checked_defaults = 1; + } + } else { + if(!badword->scan_ops && (chanuser->flags & CHANUSERFLAG_OPPED)) continue; + if(!badword->scan_voice && (chanuser->flags & CHANUSERFLAG_VOICED)) continue; + if(badword->exceptlevel && badword->exceptlevel < 501) { + if(!punish_now) + return SPAMSERV_CHECK_PUNISH; + if(badword->exceptlevel <= uaccess) { + checked_defaults = 2; + continue; + } + } + } + if(badword->use_default_reaction) { + apply_default_reaction = 1; + } else { + switch(badword->reaction) { + case 2: + staticban_user = 1; + if(badword->reaction_time > ban_duration) + ban_duration = badword->reaction_time; + case 1: + ban_user = 1; + case 0: + kick_user = 1; + } + } + } + } + if(apply_default_reaction) { + MYSQL_RES *res; + MYSQL_ROW row, defaults; + loadChannelSettings(chanuser->chan); + printf_mysql_query("SELECT `channel_badword_reaction`, `channel_badword_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id); + res = mysql_use(); + row = mysql_fetch_row(res); + if(!row[0] || !row[1]) { + printf_mysql_query("SELECT `channel_badword_reaction`, `channel_badword_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'"); + res = mysql_use(); + defaults = mysql_fetch_row(res); + } + int reaction = atoi((row[0] ? row[0] : defaults[0])); + int reaction_time = atoi((row[1] ? row[1] : defaults[1])); + switch(reaction) { + case 2: + staticban_user = 1; + if(reaction_time > ban_duration) + ban_duration = reaction_time; + case 1: + ban_user = 1; + case 0: + kick_user = 1; + } + } + if(!kick_user) return SPAMSERV_CHECK_IGNORE; + char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3]; + char *banmask = NULL; + if(staticban_user) { + banmask = generate_banmask(chanuser->user, banmaskBuf); + printf_mysql_query("INSERT INTO `bans` (`ban_channel`, `ban_mask`, `ban_triggered`, `ban_timeout`, `ban_owner`, `ban_reason`) VALUES ('%d', '%s', UNIX_TIMESTAMP(), '%lu', '%d', '%s')", chanuser->chan->channel_id, escape_string(banmask), (unsigned long) (ban_duration ? (time(0) + ban_duration) : 0), 0, escape_string(SPAMSERV_MSG_BADWORD)); + if(ban_duration) { + int banid = (int) mysql_insert_id(get_mysql_conn()); + char nameBuf[MAXLEN]; + char banidBuf[20]; + sprintf(nameBuf, "ban_%d", banid); + sprintf(banidBuf, "%d", banid); + timeq_add_name(nameBuf, ban_duration, module_id, channel_ban_timeout, strdup(banidBuf)); + } + } + if(ban_user) { + if(!banmask) + banmask = generate_banmask(chanuser->user, banmaskBuf); + putsock(client, "MODE %s +b %s", chanuser->chan->name, banmask); + } + putsock(client, "KICK %s %s :%s", chanuser->chan->name, chanuser->user->nick, SPAMSERV_MSG_BADWORD); + return SPAMSERV_CHECK_DEAD; +}