X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/6a7c5b7fc2ab7fa46c8d0fade5cfa9dc7f4077e1..9172b03e94b4a23862c5ffeab84d2bcec001cb64:/trojanscan/trojanscan.c diff --git a/trojanscan/trojanscan.c b/trojanscan/trojanscan.c index 1813d1fc..e0d655af 100644 --- a/trojanscan/trojanscan.c +++ b/trojanscan/trojanscan.c @@ -15,6 +15,8 @@ #include "../lib/strlfunc.h" #include "../lib/version.h" #include "../core/nsmalloc.h" +#include "../glines/glines.h" +#include "../patrol/patrol.h" #include #define tmalloc(x) nsmalloc(POOL_TROJANSCAN, x) @@ -41,6 +43,8 @@ static char *versionreply; static int hooksregistered = 0; static void *trojanscan_connect_nick_schedule; +static void *db_ping_schedule; + void _init() { trojanscan_cmds = newcommandtree(); @@ -86,11 +90,8 @@ void _fini(void) { if(trojanscan_schedule) deleteschedule(trojanscan_schedule, &trojanscan_dojoin, NULL); - if(trojanscan_poolschedule) - deleteschedule(trojanscan_poolschedule, &trojanscan_repool, NULL); - if(trojanscan_cloneschedule) - deleteschedule(trojanscan_poolschedule, &trojanscan_registerclones, NULL); + deleteschedule(trojanscan_cloneschedule, &trojanscan_registerclones, NULL); if(hooksregistered) deregisterhook(HOOK_CHANNEL_PART, trojanscan_part_watch); @@ -118,17 +119,11 @@ void _fini(void) { for (i=0;icontent); freesstring(temp); - length = snprintf(buf, sizeof(buf) - 1, "%d", TROJANSCAN_MINIMUM_HOSTS_BEFORE_POOL); - temp = getcopyconfigitem("trojanscan", "minpoolhosts", buf, length); - trojanscan_min_hosts = atoi(temp->content); - freesstring(temp); - 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 */ } @@ -264,6 +255,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 */ } @@ -473,7 +469,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;iremaining) && (!rc->sitting)) { if (rc->clone) { deregisterlocaluser(rc->clone, NULL); - derefnode(iptree, rc->fakeipnode); rc->clone = NULL; } trojanscan_generateclone((void *)((long)rc->index)); @@ -1091,20 +1043,6 @@ struct trojanscan_clones *trojanscan_selectclone(char type) { } -/* hack hack hack */ -int trojanscan_nickbanned(trojanscan_clones *np, channel *cp) { - int ret; - patricia_node_t *realipnode = np->clone->ipnode; - - np->clone->ipnode = np->fakeipnode; - - ret = nickbanned(np->clone, cp, 0); - - np->clone->ipnode = realipnode; - - return ret; -} - struct trojanscan_realchannels *trojanscan_allocaterc(char *chan) { struct trojanscan_realchannels *rc; struct trojanscan_clones *clonep; @@ -1145,7 +1083,7 @@ struct trojanscan_realchannels *trojanscan_allocaterc(char *chan) { trojanscan_errorcode = 6; return NULL; } - if(!trojanscan_nickbanned(clonep, cp)) + if(!nickbanned(clonep->clone, cp, 0)) break; } while (--attempts_left > 0); @@ -1480,7 +1418,7 @@ void trojanscan_watch_clone_update(struct trojanscan_prechannels *hp, int count) lp->watch_clone = trojanscan_selectclone(TROJANSCAN_WATCH_CLONES); if(!lp->watch_clone) break; - if(!trojanscan_nickbanned(lp->watch_clone, cp)) { + if(!nickbanned(lp->watch_clone->clone, cp, 0)) { if(localjoinchannel(lp->watch_clone->clone, cp)) lp->watch_clone = NULL; break; @@ -1606,21 +1544,9 @@ void trojanscan_dopart(void *arg) { void trojanscan_donickchange(void *arg) { /* just incase I choose to make this schedule at some point */ struct trojanscan_clones *clone = (trojanscan_clones *)arg; - if (clone && clone->clone) { - char c_nick[NICKLEN+1]; - int loops = 0; - /* PPA: unlikely to be infinite */ - do { - if ((loops++ < 10) && trojanscan_hostmode) { - trojanscan_generatenick(c_nick, NICKLEN); - } else { - trojanscan_gennick(c_nick, trojanscan_minmaxrand(7, TROJANSCAN_MMIN(13, NICKLEN))); - } - } while (c_nick[0] && (getnickbynick(c_nick) != NULL)); - renamelocaluser(clone->clone, c_nick); - } - + if (clone && clone->clone) + patrol_nickchange(clone->clone); } int trojanscan_keysort(const void *v1, const void *v2) { @@ -1916,10 +1842,9 @@ 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); trojanscan_swarm[i].clone = NULL; trojanscan_swarm[i].remaining = 0; /* bah */ break; @@ -1993,36 +1918,13 @@ 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) - usercount = sender->ipnode->usercount; - - if(usercount > TROJANSCAN_MAX_HOST_GLINE) { - hostmode = 0; - usercount = 0; - } - - /* should really go through the ipnode I guess */ - if(!hostmode) - for (j=0;jnext) - 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]; + glinebuf gbuf; trojanscan_database.detections++; @@ -2032,7 +1934,11 @@ 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)); + glinebufinit(&gbuf, 0); + glinebufaddbynick(&gbuf, sender, 0, "trojanscan", NULL, getnettime(), getnettime(), getnettime()); + glinebufcounthits(&gbuf, &usercount, NULL); + strncpy(glinemask, gbuf.glines ? glinetostring(gbuf.glines) : "", sizeof(glinemask)); + glinebufabort(&gbuf); } if (!usercount) { @@ -2041,12 +1947,12 @@ void trojanscan_phrasematch(channel *chp, nick *sender, trojanscan_phrases *phra } if (glining && (usercount > trojanscan_maxusers)) { - trojanscan_mainchanmsg("w: not glining %s!%s@%s due to too many users (%d) with mask: *!%s -- worm: %s)", sender->nick, sender->ident, sender->host->name->content, usercount, glinemask, worm->name->content); + trojanscan_mainchanmsg("w: not glining %s!%s@%s due to too many users (%d) with mask: %s -- worm: %s)", sender->nick, sender->ident, sender->host->name->content, usercount, glinemask, worm->name->content); return; } if (glining && !worm->datalen) { - trojanscan_mainchanmsg("w: not glining %s!%s@%s due to too lack of removal data with mask: *!%s (%d users) -- worm: %s)", sender->nick, sender->ident, sender->host->name->content, glinemask, usercount, worm->name->content); + trojanscan_mainchanmsg("w: not glining %s!%s@%s due to too lack of removal data with mask: %s (%d users) -- worm: %s)", sender->nick, sender->ident, sender->host->name->content, glinemask, usercount, worm->name->content); return; } @@ -2079,9 +1985,10 @@ 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:""); + 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:""); } } @@ -2097,7 +2004,7 @@ void trojanscan_rejoin_channel(void *arg) { rj->rp->donotpart = 1; /* we were the last user on the channel, so we need to be VERY careful freeing it */ } else { if(!rj->rp->donotpart && !rj->rp->kickedout) { /* check we're allowed to join channels (not killed), and we're the last one to join */ - if (trojanscan_nickbanned(rj->clone, cp)) { + if (nickbanned(rj->clone->clone, cp, 0)) { rj->rp->donotpart = 1; } else { localjoinchannel(rj->clone->clone, cp); @@ -2179,184 +2086,6 @@ int trojanscan_minmaxrand(float min, float max) { return (int)((max-min+1)*rand()/(RAND_MAX+min))+min; } -char *trojanscan_iptostr(char *buf, int buflen, unsigned int ip) { - snprintf(buf, buflen, "%d.%d.%d.%d", ip >> 24, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255); - return buf; -} - -char trojanscan_genchar(int ty) { - /* hostname and realname characters*/ - if (!ty) { - if (!(trojanscan_minmaxrand(0, 40) % 10)) { - return trojanscan_minmaxrand(48, 57); - } else { - return trojanscan_minmaxrand(97, 122); - } - /* ident characters - without numbers*/ - } else if (ty == 1) { - return trojanscan_minmaxrand(97, 122); - /* ident characters - with numbers*/ - } else if (ty == 2) { - ty = trojanscan_minmaxrand(97, 125); - if (ty > 122) return trojanscan_minmaxrand(48, 57); - return ty; - /* nick characters - with and without numbers*/ - } else if (ty == 3 || ty == 4) { - if (!(trojanscan_minmaxrand(0, 59) % 16)) { - char weirdos[6] = { '\\', '|', '[', '{', ']', '}' }; - return weirdos[trojanscan_minmaxrand(0, 5)]; - } - if (ty == 4) { - ty = trojanscan_minmaxrand(65, 93); - if (ty > 90) return trojanscan_minmaxrand(48, 57); - } else { - ty = trojanscan_minmaxrand(65, 90); - } - if (!(trojanscan_minmaxrand(0, 40) % 8)) return ty; - return ty + 32; - /* moron check */ - } else { - return ' '; - } -} - -void trojanscan_gennick(char *ptc, char size) { - int i; - for (i=0;i 5) && (i < (size-4))) { - if ((ptc[i-1] != '.') && (ptc[i-1] != '-')) { - cur = trojanscan_minmaxrand(1,size / dots); - if (cur < 3) { - if (cur == 1) { - ptc[i] = '.'; - dotexist = 1; - } else { - ptc[i] = '-'; - } - } - } - } - } - } - ptc[i] = '\0'; - - memset(&ipaddress, 0, sizeof(ipaddress)); - ((unsigned short *)(ipaddress.in6_16))[5] = 65535; - ((unsigned short *)(ipaddress.in6_16))[6] = trojanscan_minmaxrand(0, 65535); - ((unsigned short *)(ipaddress.in6_16))[7] = trojanscan_minmaxrand(0, 65535); - - *fakeipnode = refnode(iptree, &ipaddress, PATRICIA_MAXBITS); -} - -void trojanscan_genreal(char *ptc, char size) { - int spaces = trojanscan_minmaxrand(2, 4), i; - for (i=0;i 5) && (i < (size-4))) { - if (ptc[i-1] != ' ') { - if (trojanscan_minmaxrand(1,size / spaces) == 1) ptc[i] = ' '; - } - } - } - ptc[i] = '\0'; -} - -int trojanscan_is_not_octet(char *begin, int length) { - int i; - if(length > 3) - return 0; - for(i=0;i= '0') && (*begin <= '9'))) - return 0; - begin++; - } - return 1; -} - -int trojanscan_generatepool(void) { - int i, k = 0, j = 0, loops = 0; - char *p, *pp; - nick *np; - - for (i=0;inext) - j++; - - if(j < trojanscan_min_hosts) - return 0; - - if(TROJANSCAN_HOST_MODE == TROJANSCAN_STEAL_HOST) - return TROJANSCAN_MINPOOLSIZE; - - i = 0; - do { - for (j=trojanscan_minmaxrand(0, NICKHASHSIZE-1);jhost->name->content, pp=p;*p;) { - if (*++p == '.') { - if (!trojanscan_is_not_octet(pp, p-pp)) { - if (i < TROJANSCAN_POOLSIZE) { - if (i < trojanscan_hostpoolsize) - freesstring(trojanscan_hostpool[i]); - trojanscan_hostpool[i] = getsstring(pp, p-pp); - i++; - } else { - if (k >= TROJANSCAN_POOLSIZE) - break; - } - } - pp=++p; - } - } - if (!trojanscan_is_not_octet(pp, p-pp)) { - if (k < TROJANSCAN_POOLSIZE) { - if (k < trojanscan_tailpoolsize) - freesstring(trojanscan_tailpool[k]); - trojanscan_tailpool[k] = getsstring(pp, p-pp); - k++; - } else { - if (i >= TROJANSCAN_POOLSIZE) - break; - } - } - } - } - loops++; - } while ((loops < 5) && ((i < TROJANSCAN_POOLSIZE) || (k < TROJANSCAN_POOLSIZE))); - - trojanscan_hostpoolsize = i; - trojanscan_tailpoolsize = k; - return i; -} - nick *trojanscan_selectuser(void) { int target = trojanscan_minmaxrand(0, 500), loops = 150, j; nick *np; @@ -2369,138 +2098,21 @@ nick *trojanscan_selectuser(void) { return NULL; } -host *trojanscan_selecthost(void) { - int target = trojanscan_minmaxrand(0, 500), loops = 150, j; - host *hp; - do { - for (j=trojanscan_minmaxrand(0, HOSTHASHSIZE-1);jnext) - if (!--target) - return hp; - } while(--loops > 0); - - 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; - - if(TROJANSCAN_HOST_MODE == TROJANSCAN_STEAL_HOST) { - host *hp; - int loops = 20; - - buf[0] = '\0'; - - do { - hp = trojanscan_selecthost(); - 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; - patricia_ref_prefix(hp->nicks->ipnode->prefix); - } else { - memset(&ipaddress, 0, sizeof(ipaddress)); - ((unsigned short *)(ipaddress.in6_16))[5] = 65535; - ((unsigned short *)(ipaddress.in6_16))[6] = trojanscan_minmaxrand(0, 65535); - ((unsigned short *)(ipaddress.in6_16))[7] = trojanscan_minmaxrand(0, 65535); - - *fakeip = refnode(iptree, &ipaddress, PATRICIA_MAXBITS); - } - break; - } - } while(--loops > 0); - } else { - char *cpos; - int pieces = trojanscan_minmaxrand(2, 4), totallen = 0, a = 0, i; - int *choices = tmalloc(sizeof(int) * (pieces + 1)); - int *lengths = tmalloc(sizeof(int) * (pieces + 1)); - - choices[pieces] = trojanscan_minmaxrand(0, trojanscan_tailpoolsize-1); - lengths[pieces] = strlen(trojanscan_tailpool[choices[pieces]]->content) + 1; - totallen += lengths[pieces]; - - for (i=0;icontent) + 1; - if (totallen+lengths[i] > maxsize) { - choices[i] = choices[pieces]; - lengths[i] = lengths[pieces]; - pieces-=(pieces-i); - break; - } - totallen += lengths[i]; - } - - for (i=0;icontent; *cpos;) - buf[a++] = *cpos++; - buf[a++] = '.'; - } - - for (cpos=trojanscan_tailpool[choices[i]]->content; *cpos;) { - buf[a++] = *cpos++; - } - - buf[a] = '\0'; - tfree(choices); - tfree(lengths); - - memset(&ipaddress, 0, sizeof(ipaddress)); - ((unsigned short *)(ipaddress.in6_16))[5] = 65535; - ((unsigned short *)(ipaddress.in6_16))[6] = trojanscan_minmaxrand(0, 65535); - ((unsigned short *)(ipaddress.in6_16))[7] = trojanscan_minmaxrand(0, 65535); - - *fakeip = refnode(iptree, &ipaddress, PATRICIA_MAXBITS); - } -} - -void trojanscan_generatenick(char *buf, int maxsize) { - int bits = trojanscan_minmaxrand(2, 3), loops = 0, wanttocopy, len = 0, i, d = 0, newmaxsize = maxsize - trojanscan_minmaxrand(0, 7); - nick *np; - - if(newmaxsize > 2) - maxsize = newmaxsize; - - do { - np = trojanscan_selectuser(); - if(np) { - wanttocopy = trojanscan_minmaxrand(1, (strlen(np->nick) / 2) + 3); - for(i=0;((inick[i]; - if(++d > bits) { - buf[len] = '\0'; - return; - } +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); } - } while (++loops < 10); - buf[0] = '\0'; -} - -void trojanscan_generateident(char *buf, int maxsize) { - nick *np = trojanscan_selectuser(); - buf[0] = '\0'; - if(np) - strlcpy(buf, np->ident, maxsize + 1); -} + } -void trojanscan_generaterealname(char *buf, int maxsize) { - nick *np = trojanscan_selectuser(); - buf[0] = '\0'; - if(np) - strlcpy(buf, np->realname->name->content, maxsize + 1); + 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); } @@ -2508,6 +2120,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; }