]> jfr.im git - irc/quakenet/newserv.git/blobdiff - trojanscan/trojanscan.c
glines: Include target nick in error message for block command.
[irc/quakenet/newserv.git] / trojanscan / trojanscan.c
index 3fa8e820f76ea48c48a637d6fdc2bba6ef31a977..bfcf02becbb63dd172431004ad87a5b6b3e66567 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Trojanscan version 2
  *
- * Trojanscan  copyright (C) Chris Porter 2002-2007
+ * Trojanscan  copyright (C) Chris Porter 2002-2009
  * Newserv bits copyright (C) David Mansell 2002-2003
  * 
  * TODO: CHECK::
@@ -15,6 +15,8 @@
 #include "../lib/strlfunc.h"
 #include "../lib/version.h"
 #include "../core/nsmalloc.h"
+#include "../glines/glines.h"
+#include <stdint.h>
 
 #define tmalloc(x)     nsmalloc(POOL_TROJANSCAN, x)
 #define tfree(x)       nsfree(POOL_TROJANSCAN, x)
@@ -40,6 +42,8 @@ static char *versionreply;
 static int hooksregistered = 0;
 static void *trojanscan_connect_nick_schedule;
 
+static void *db_ping_schedule;
+
 void _init() {
   trojanscan_cmds = newcommandtree();
 
@@ -128,6 +132,7 @@ void _fini(void) {
 
   for (i=0;i<trojanscan_tailpoolsize;i++)
     freesstring(trojanscan_tailpool[i]);
+
   trojanscan_database_close();
 
   deletecommandfromtree(trojanscan_cmds, "showcommands", &trojanscan_showcommands);
@@ -215,12 +220,12 @@ void trojanscan_connect(void *arg) {
   trojanscan_database.glines = 0;
   trojanscan_database.detections = 0;
     
-  dbhost = getcopyconfigitem("trojanscan", "dbhost", "localhost", HOSTLEN);
-  dbuser = getcopyconfigitem("trojanscan", "dbuser", "", NICKLEN);
-  dbpass = getcopyconfigitem("trojanscan", "dbpass", "", REALLEN);
-  db = getcopyconfigitem("trojanscan", "db", "", NICKLEN);
+  dbhost = getcopyconfigitem("trojanscan", "dbhost", "localhost", 100);
+  dbuser = getcopyconfigitem("trojanscan", "dbuser", "moo", 100);
+  dbpass = getcopyconfigitem("trojanscan", "dbpass", "changeme", 100);
+  db = getcopyconfigitem("trojanscan", "db", "moo", 100);
   
-  dbport = getcopyconfigitem("trojanscan", "dbport", "3306", ACCOUNTLEN);
+  dbport = getcopyconfigitem("trojanscan", "dbport", "3306", 10);
   
   length = snprintf(buf, sizeof(buf) - 1, "%d", TROJANSCAN_DEFAULT_MAXCHANS);
   temp = getcopyconfigitem("trojanscan", "maxchans", buf, length);
@@ -251,6 +256,11 @@ void trojanscan_connect(void *arg) {
 
   if ((trojanscan_cycletime / trojanscan_maxchans) < 1) {
     Error("trojanscan", ERR_FATAL, "Cycletime / maxchans < 1, increase cycletime or decrease maxchans else cycling breaks.");
+    freesstring(dbhost);
+    freesstring(dbuser);
+    freesstring(dbpass);
+    freesstring(db);
+    freesstring(dbport);
     return; /* PPA: module failed to load */
   }
   
@@ -263,6 +273,11 @@ void trojanscan_connect(void *arg) {
 
   if (trojanscan_database_connect(dbhost->content, dbuser->content, dbpass->content, db->content, atoi(dbport->content)) < 0) {
     Error("trojanscan", ERR_FATAL, "Cannot connect to database host!");
+    freesstring(dbhost);
+    freesstring(dbuser);
+    freesstring(dbpass);
+    freesstring(db);
+    freesstring(dbport);
     return; /* PPA: module failed to load */
   }
   
@@ -472,7 +487,7 @@ int trojanscan_strip_codes(char *buf, size_t max, char *original) {
 struct trojanscan_worms *trojanscan_find_worm_by_id(int id) {
   int i;
   for(i=0;i<trojanscan_database.total_worms;i++)
-    if ((trojanscan_database.worms[i].id == id))
+    if (trojanscan_database.worms[i].id == id)
       return &trojanscan_database.worms[i];
   return NULL;
 }
@@ -776,9 +791,9 @@ void trojanscan_privmsg_chan_or_nick(channel *cp, nick *np, char *message, ...)
   va_end(va);
   
   if (cp) {
-    sendmessagetochannel(trojanscan_nick, cp, buf);
+    sendmessagetochannel(trojanscan_nick, cp, "%s", buf);
   } else {
-    sendmessagetouser(trojanscan_nick, np, buf);
+    sendmessagetouser(trojanscan_nick, np, "%s", buf);
   }
 
 }
@@ -1097,7 +1112,7 @@ int trojanscan_nickbanned(trojanscan_clones *np, channel *cp) {
 
   np->clone->ipnode = np->fakeipnode;
 
-  ret = nickbanned(np->clone, cp);
+  ret = nickbanned(np->clone, cp, 0);
 
   np->clone->ipnode = realipnode;
 
@@ -1915,7 +1930,7 @@ void trojanscan_clonehandlemessages(nick *target, int messagetype, void **args)
                 trojanscan_chans[j].watch_clone = NULL;
           } else {
             for(rp=trojanscan_realchanlist;rp;rp=rp->next)
-              if ((rp->clone == &(trojanscan_swarm[i])))
+              if (rp->clone == &(trojanscan_swarm[i]))
                 rp->donotpart = 1;
           }
           derefnode(iptree, trojanscan_swarm[i].fakeipnode);
@@ -1992,38 +2007,12 @@ static void trojanscan_part_watch(int hook, void *arg) {
   trojanscan_process(np, cp, trojanscan_getmtfromhooktype(hook), reason);
 }
 
-static int trojanscan_hostcount(nick *sender, int hostmode, char *mask, int masklen) {
-  int usercount = 0, j;
-  nick *np = NULL; /* sigh at warnings */
-
-  if(hostmode)
-    for (j=0;j<NICKHASHSIZE;j++)
-      for (np=nicktable[j];np;np=np->next)
-        if (np->ipnode==sender->ipnode)
-          usercount++;
-
-  if(usercount > TROJANSCAN_MAX_HOST_GLINE) {
-    hostmode = 0;
-    usercount = 0;
-  }
-
-  if(!hostmode)
-    for (j=0;j<NICKHASHSIZE;j++)
-      for (np=nicktable[j];np;np=np->next)
-        if (np->ipnode==sender->ipnode && !ircd_strcmp(np->ident, sender->ident))
-          usercount++;
-
-  if(mask)
-    snprintf(mask, masklen, "%s@%s", hostmode?"*":sender->ident, IPtostr(sender->p_ipaddr));
-
-  return usercount;
-}
-
 void trojanscan_phrasematch(channel *chp, nick *sender, trojanscan_phrases *phrase, char messagetype, char *matchbuf) {
   char glinemask[HOSTLEN + USERLEN + NICKLEN + 4], enick[TROJANSCAN_QUERY_TEMP_BUF_SIZE], eident[TROJANSCAN_QUERY_TEMP_BUF_SIZE], ehost[TROJANSCAN_QUERY_TEMP_BUF_SIZE];
   unsigned int frequency;
   int glining = 0, usercount;
   struct trojanscan_worms *worm = phrase->worm;
+  char reason[200];
 
   trojanscan_database.detections++;
   
@@ -2033,7 +2022,7 @@ void trojanscan_phrasematch(channel *chp, nick *sender, trojanscan_phrases *phra
   } else if(worm->glinehost || worm->glineuser) {
     glining = 1;
 
-    usercount = trojanscan_hostcount(sender, worm->glinehost, glinemask, sizeof(glinemask));
+    usercount = glinebynick(sender, 0, NULL, GLINE_SIMULATE, "trojanscan");
   }
   
   if (!usercount) {
@@ -2080,7 +2069,8 @@ void trojanscan_phrasematch(channel *chp, nick *sender, trojanscan_phrases *phra
     trojanscan_database_query("INSERT INTO hits (nickname, ident, host, phrase, messagetype, glined) VALUES ('%s', '%s', '%s', %d, '%c', %d)", enick, eident, ehost, phrase->id, messagetype, glining);
     trojanscan_database.glines++;
     
-    irc_send("%s GL * +%s %d %jd :You (%s!%s@%s) are infected with a trojan (%s/%d), see %s%d for details - banned for %d hours\r\n", mynumeric->content, glinemask, glinetime * 3600, (intmax_t)time(NULL), sender->nick, sender->ident, sender->host->name->content, worm->name->content, phrase->id, TROJANSCAN_URL_PREFIX, worm->id, glinetime);
+    snprintf(reason, sizeof(reason), "You (%s!%s@%s) are infected with a trojan (%s/%d), see %s%d for details - banned for %d hours", sender->nick, sender->ident, sender->host->name->content, worm->name->content, phrase->id, TROJANSCAN_URL_PREFIX, worm->id, glinetime);
+    glinebynick(sender, glinetime * 3600, reason, 0, "trojanscan");
 
     trojanscan_mainchanmsg("g: *!%s t: %c u: %s!%s@%s%s%s c: %d w: %s%s p: %d f: %d%s%s", glinemask, messagetype, sender->nick, sender->ident, sender->host->name->content, messagetype=='N'||messagetype=='M'||messagetype=='P'?" #: ":"", messagetype=='N'||messagetype=='M'||messagetype=='P'?chp->index->name->content:"", usercount, worm->name->content, worm->epidemic?"(E)":"", phrase->id, frequency, matchbuf[0]?" --: ":"", matchbuf[0]?matchbuf:"");
   }
@@ -2383,6 +2373,16 @@ host *trojanscan_selecthost(void) {
   return NULL;
 }
 
+static int specialuseronhost(host *hp) {
+  nick *np;
+
+  for(np=hp->nicks;np;np=np->nextbyhost)
+    if(IsOper(np) || IsService(np) || IsXOper(np) || NickOnServiceServer(np))
+      return 1;
+
+  return 0;
+}
+
 void trojanscan_generatehost(char *buf, int maxsize, patricia_node_t **fakeip) {
   struct irc_in_addr ipaddress;
 
@@ -2394,7 +2394,7 @@ void trojanscan_generatehost(char *buf, int maxsize, patricia_node_t **fakeip) {
 
     do {
       hp = trojanscan_selecthost();
-      if(hp && (hp->clonecount <= TROJANSCAN_MAX_CLONE_COUNT) && !trojanscan_isip(hp->name->content)) {
+      if(hp && (hp->clonecount <= TROJANSCAN_MAX_CLONE_COUNT) && !trojanscan_isip(hp->name->content) && !specialuseronhost(hp)) {
         strlcpy(buf, hp->name->content, maxsize + 1);
         if(hp->nicks) {
           *fakeip = hp->nicks->ipnode;
@@ -2491,7 +2491,21 @@ void trojanscan_generaterealname(char *buf, int maxsize) {
     strlcpy(buf, np->realname->name->content, maxsize + 1);
 }
 
+static void db_ping(void *arg) {
+  if (!(trojanscan_database_query("SELECT 1"))) {
+    trojanscan_database_res *res;
+    if ((res = trojanscan_database_store_result(&trojanscan_sql))) {
+      trojanscan_database_free_result(res);
+    }
+  } 
+
+  db_ping_schedule = scheduleoneshot(time(NULL) + 60, &db_ping, NULL);
+}
+
 void trojanscan_database_close(void) {
+  if(db_ping_schedule)
+    deleteschedule(db_ping_schedule, db_ping, NULL);
+
   mysql_close(&trojanscan_sql);
 }
 
@@ -2499,6 +2513,10 @@ int trojanscan_database_connect(char *dbhost, char *dbuser, char *dbpass, char *
   mysql_init(&trojanscan_sql);
   if (!mysql_real_connect(&trojanscan_sql, dbhost, dbuser, dbpass, db, port, NULL, 0))
     return -1;
+
+
+  db_ping_schedule = scheduleoneshot(time(NULL) + 60, &db_ping, NULL);
+
   return 0;
 }