From 96643d0fe8fdbf460c8d48874e4e45a729141a34 Mon Sep 17 00:00:00 2001 From: pk910 Date: Sun, 23 Oct 2011 17:21:15 +0200 Subject: [PATCH] added digit and caps scanner --- src/bot_NeonSpam.c | 2 + src/bot_NeonSpam.h | 4 ++ src/event_neonspam_chanmsg.c | 111 +++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/src/bot_NeonSpam.c b/src/bot_NeonSpam.c index 911c9b8..a1a2ba8 100644 --- a/src/bot_NeonSpam.c +++ b/src/bot_NeonSpam.c @@ -61,6 +61,8 @@ static struct NeonSpamJoinNode *getNeonSpamJoinNode(struct ChanUser *chanuser); #define SPAMSERV_MSG_JOINFLOOD "Join flooding the channel" #define SPAMSERV_MSG_WARNING "%s is against the channel rules" #define SPAMSERV_MSG_BOTNET "BotNet detected." +#define SPAMSERV_MSG_CAPS "Using too many chars in UPPER CASE" +#define SPAMSERV_MSG_DIGIT "Using too many numeric chars" //EVENTS #include "event_neonspam_join.c" diff --git a/src/bot_NeonSpam.h b/src/bot_NeonSpam.h index e3a32ef..9a7cc63 100644 --- a/src/bot_NeonSpam.h +++ b/src/bot_NeonSpam.h @@ -118,11 +118,15 @@ struct NeonSpamSettings { * are bigger than MAX_FLOOD_TIME * flood_amount */ +#define NEONSPAMNODE_FLAG_CAPSSCAN_WARNED 0x01 +#define NEONSPAMNODE_FLAG_DIGITSCAN_WARNED 0x02 + struct NeonSpamNode { unsigned long lastmsg; //crc32 hash unsigned char spamcount; int floodpenalty; time_t last_penalty_update; + unsigned char flags; }; struct NeonSpamJoinNode { diff --git a/src/event_neonspam_chanmsg.c b/src/event_neonspam_chanmsg.c index b7f124f..fb91aa5 100644 --- a/src/event_neonspam_chanmsg.c +++ b/src/event_neonspam_chanmsg.c @@ -18,6 +18,8 @@ static int neonspam_spamscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message); static int neonspam_floodscan(struct NeonSpamSettings *settings, struct ChanUser *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 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); @@ -91,6 +93,40 @@ static void neonspam_event_chanmsg(struct UserNode *user, struct ChanNode *chan, break; } } + if((settings->flags & SPAMSETTINGS_CAPSSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_CAPSSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_CAPSSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_CAPSEXCINDEX)) { + result = neonspam_capsscan(settings, chanuser, message); + switch(result) { + case SPAMSERV_CHECK_IGNORE: + break; + case SPAMSERV_CHECK_WARN: + warn |= SPAMSETTINGS_CAPSSCAN; + if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_CAPSEXCINDEX)) + needwho = 1; + break; + case SPAMSERV_CHECK_PUNISH: + punish |= SPAMSETTINGS_CAPSSCAN; + if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_CAPSEXCINDEX)) + needwho = 1; + break; + } + } + if((settings->flags & SPAMSETTINGS_DIGITSCAN) && NEONSPAM_CHANMSG_DO_SCANOPS(SPAMSETTINGS_DIGITSCAN_OPS) && NEONSPAM_CHANMSG_DO_SCANVOICE(SPAMSETTINGS_DIGITSCAN_VOICE) && NEONSPAM_CHANMSG_DO_EXCEPT(SPAMSETTINGS_DIGITEXCINDEX)) { + result = neonspam_digitscan(settings, chanuser, message); + switch(result) { + case SPAMSERV_CHECK_IGNORE: + break; + case SPAMSERV_CHECK_WARN: + warn |= SPAMSETTINGS_DIGITSCAN; + if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_DIGITEXCINDEX)) + needwho = 1; + break; + case SPAMSERV_CHECK_PUNISH: + punish |= SPAMSETTINGS_DIGITSCAN; + if(NEONSPAM_CHANMSG_NEED_WHO(SPAMSETTINGS_DIGITEXCINDEX)) + needwho = 1; + break; + } + } //some other checks? if(warn || punish) { @@ -161,12 +197,44 @@ static void neonspam_event_chanmsg_punish(struct ClientSocket *client, struct Ch punishment = atoi(row[0]) + 1; punish_time = atoi(row[1]); } + if(!punishment && (punish & SPAMSETTINGS_CAPSSCAN) && settings->exceptlevel[SPAMSETTINGS_CAPSEXCINDEX] > uaccess) { + printf_mysql_query("SELECT `channel_caps_reaction`, `channel_caps_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id); + res = mysql_use(); + row = mysql_fetch_row(res); + if(!row[0]) { + printf_mysql_query("SELECT `channel_caps_reaction`, `channel_caps_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'"); + res = mysql_use(); + row = mysql_fetch_row(res); + } + sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_CAPS); + punishment = atoi(row[0]) + 1; + punish_time = atoi(row[1]); + } + if(!punishment && (punish & SPAMSETTINGS_DIGITSCAN) && settings->exceptlevel[SPAMSETTINGS_DIGITEXCINDEX] > uaccess) { + printf_mysql_query("SELECT `channel_digit_reaction`, `channel_digit_reaction_duration` FROM `channels` WHERE `channel_id` = '%d'", chanuser->chan->channel_id); + res = mysql_use(); + row = mysql_fetch_row(res); + if(!row[0]) { + printf_mysql_query("SELECT `channel_digit_reaction`, `channel_digit_reaction_duration` FROM `channels` WHERE `channel_name` = 'defaults'"); + res = mysql_use(); + row = mysql_fetch_row(res); + } + sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_DIGIT); + punishment = atoi(row[0]) + 1; + punish_time = atoi(row[1]); + } if(!punishment && (warn & SPAMSETTINGS_SPAMSCAN) && settings->exceptlevel[SPAMSETTINGS_SPAMEXCINDEX] > uaccess) { sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_SPAM); } if(!punishment && (warn & SPAMSETTINGS_FLOODSCAN) && settings->exceptlevel[SPAMSETTINGS_FLOODEXCINDEX] > uaccess) { sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_FLOOD); } + if(!punishment && (warn & SPAMSETTINGS_CAPSSCAN) && settings->exceptlevel[SPAMSETTINGS_CAPSEXCINDEX] > uaccess) { + sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_CAPS); + } + if(!punishment && (warn & SPAMSETTINGS_DIGITSCAN) && settings->exceptlevel[SPAMSETTINGS_DIGITEXCINDEX] > uaccess) { + sprintf(reason, SPAMSERV_MSG_WARNING, SPAMSERV_MSG_DIGIT); + } if(punishment) { char banmaskBuf[NICKLEN+USERLEN+HOSTLEN+3]; char *banmask = NULL; @@ -279,3 +347,46 @@ static int neonspam_botnetscan(struct ClientSocket *client, struct NeonSpamSetti settings->lastmsg_time = time(0); return SPAMSERV_CHECK_IGNORE; } + +static int neonspam_capsscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) { + int caps = 0, msglen = strlen(message); + int i; + if(msglen <= 4) return SPAMSERV_CHECK_IGNORE; + for(i = 0; i < msglen; i++) { + if(isupper(message[i])) caps++; + } + caps = 100*caps/msglen; + if(caps >= settings->percent[SPAMSETTINGS_CAPSPERCENTINDEX]) { + if(!chanuser->spamnode) + createSpamNode(chanuser); + if(chanuser->spamnode->flags & NEONSPAMNODE_FLAG_CAPSSCAN_WARNED) + return SPAMSERV_CHECK_PUNISH; + else { + chanuser->spamnode->flags |= NEONSPAMNODE_FLAG_CAPSSCAN_WARNED; + return SPAMSERV_CHECK_WARN; + } + } + return SPAMSERV_CHECK_IGNORE; +} + +static int neonspam_digitscan(struct NeonSpamSettings *settings, struct ChanUser *chanuser, char *message) { + int digit = 0, msglen = strlen(message); + int i; + if(msglen <= 4) return SPAMSERV_CHECK_IGNORE; + for(i = 0; i < msglen; i++) { + if(isdigit(message[i])) digit++; + } + digit = 100*digit/msglen; + if(digit >= settings->percent[SPAMSETTINGS_DIGITPERCENTINDEX]) { + if(!chanuser->spamnode) + createSpamNode(chanuser); + if(chanuser->spamnode->flags & NEONSPAMNODE_FLAG_DIGITSCAN_WARNED) + return SPAMSERV_CHECK_PUNISH; + else { + chanuser->spamnode->flags |= NEONSPAMNODE_FLAG_DIGITSCAN_WARNED; + return SPAMSERV_CHECK_WARN; + } + } + return SPAMSERV_CHECK_IGNORE; +} + -- 2.20.1