/*
* 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::
#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)
static int hooksregistered = 0;
static void *trojanscan_connect_nick_schedule;
+static void *db_ping_schedule;
+
void _init() {
trojanscan_cmds = newcommandtree();
for (i=0;i<trojanscan_tailpoolsize;i++)
freesstring(trojanscan_tailpool[i]);
+
trojanscan_database_close();
deletecommandfromtree(trojanscan_cmds, "showcommands", &trojanscan_showcommands);
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);
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 */
}
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 */
}
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;
}
for(i=0;i<TROJANSCAN_CLONE_TOTAL;i++) {
if(trojanscan_swarm[i].clone->nick && !ircd_strcmp(trojanscan_swarm[i].clone->nick, np2->nick)) {
trojanscan_reply(np, "Nickname : %s", np2->nick);
- trojanscan_reply(np, "Swarm : yes", trojanscan_swarm[i].clone->nick);
+ trojanscan_reply(np, "Swarm : yes");
return CMD_OK;
}
}
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);
}
}
np->clone->ipnode = np->fakeipnode;
- ret = nickbanned(np->clone, cp);
+ ret = nickbanned(np->clone, cp, 0);
np->clone->ipnode = realipnode;
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);
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++;
} 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) {
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 %d :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, 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:"");
}
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;
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;
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);
}
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;
}