/* * Copyright (C) 2004-2005 BarkerJr * * This module is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Anope; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "module.h" #define VERSION "1.0.1" /* * ircd_ctcpping * by BarkerJr * * This module has been written to block Bottler bots which reply to CTCP PING. * Bottlers reply to two-part pings (1102439028 1234) with only * the first part, but also mising the last digit (110243902). * * It has been tested on SolidIRCd 3.4.6 (based on Bahamut) and Anope 1.7.7svn. */ /* Akill Reason. According to the Bottler forum, the default reason should * cause the bot to remove the server from its list. */ #define REASON "no bottler clients please" /* Akill time in seconds (if applicable). Minimum is 60. Maximum is 2147483647. * 604800 = 1 week */ #define AKILL_TIME 604800 /* PingServ information */ #define s_PingServ "PingServ" #define PINGSERV_FULL "Ping Server" /* Run in gebug mode */ #undef DEBUG_MODE /* End of configuration */ #if AKILL_TIME < 60 #define AKILL_TIME 60 #elif AKILL_TIME > 2147483647 #define AKILL_TIME 2147483647 #endif #ifdef IRC_ULTIMATE3 #define CONNECT_NOTICE "CLIENT" #elif defined (IRC_RAGE2) #define CONNECT_NOTICE "SNICK" #else #define CONNECT_NOTICE send_token("NICK", "&") #endif #if defined (IRC_SOLID) || defined (IRC_BAHAMUT) #define USE_IP #endif int gotNotice(char*, int, char**); int gotConnect(char*, int, char**); int AnopeInit(int argc, char **argv) { Message *msg; int reply; msg = createMessage(send_token("NOTICE", "B"), gotNotice); reply = moduleAddMessage(msg, MOD_TAIL); if (reply != MOD_ERR_OK) { alog("ircd_ctcpping error adding message \"%s\": %i", send_token("NOTICE", "B"), reply); return MOD_STOP; } msg = createMessage(CONNECT_NOTICE, gotConnect); reply = moduleAddMessage(msg, MOD_TAIL); if (reply != MOD_ERR_OK) { alog("ircd_ctcpping error adding message \"%s\": %i", CONNECT_NOTICE, reply); return MOD_STOP; } anope_cmd_bot_nick(s_PingServ, ServiceUser, ServiceHost, PINGSERV_FULL, "+i"); moduleAddAuthor("BarkerJr"); moduleAddVersion(VERSION); alog("ircd_ctcpping v%s by BarkerJr loaded", VERSION); #if AKILL_TIME < 3600 alog("ircd_ctcpping akills expire after %u minutes", AKILL_TIME / 60); #elif AKILL_TIME == 3600 alog("ircd_ctcpping akills expire after 1 hour"); #elif AKILL_TIME < 86400 alog("ircd_ctcpping akills expire after %.1f hours", AKILL_TIME / 3600.0); #elif AKILL_TIME == 86400 alog("ircd_ctcpping akills expire after 1 day"); #else alog("ircd_ctcpping akills expire after %.1f days", AKILL_TIME / 86400.0); #endif return MOD_CONT; } void AnopeFini(void) { anope_cmd_quit(s_PingServ, "Help! I'm being unloaded!"); } int gotNotice(char *source, int ac, char **av) { if (*av[0] == '#') return MOD_CONT; /* Channel Notice */ if (strcmp(av[0], s_PingServ)) return MOD_CONT; /* Not for me */ if (strcmp(av[1], "\1PING BottlerTes\1")) return MOD_CONT; /* Not a Bottler */ { User *u; if (!(u = finduser(source))) return MOD_CONT; /* Not a user */ { char *mask; char *host; #ifdef USE_IP if (!(host = moduleGetData(&u->moduleData, "ip"))) #endif host = u->host; if (!(mask = (char *)malloc(strlen(host) + 3))) /* Out of memory */ { alog("ircd_ctcpping error allocating memory to akill %s", u->nick); return MOD_CONT; } sprintf(mask, "*@%s", host); #ifdef DEBUG_MODE alog("%s: Sending akill for %s", s_PingServ, mask); #endif add_akill(NULL, mask, s_PingServ, time(NULL) + AKILL_TIME, REASON); free(mask); alog("%s: Akilling %s!%s@%s [%s] for malformed CTCP \"PING\" reply (Bottler)", s_PingServ, u->nick, u->username, u->host, u->realname); } } return MOD_STOP; } int gotConnect(char *source, int ac, char **av) { if (ac < 2) return MOD_CONT; #ifndef IRC_ULTIMATE3 if (*source) return MOD_CONT; #endif #ifdef USE_IP { User *u; if (!(u = finduser(av[0]))) return MOD_CONT; /* Not a user */ { int reply; char ipbuf[16]; struct in_addr addr; addr.s_addr = htonl(strtoul(av[8], NULL, 10)); ntoa(addr, ipbuf, sizeof(ipbuf)); #ifdef DEBUG_MODE alog("ircd_ctcpping storing %s for %s", ipbuf, av[0]); #endif reply = moduleAddData(&u->moduleData, "ip", ipbuf); if (reply != MOD_ERR_OK) alog("ircd_ctcpping error storing IP for %s: %i", av[0], reply); } } #endif anope_cmd_privmsg2(s_PingServ, av[0], "\1PING BottlerTest PleaseIgnore\1"); return MOD_CONT; }