X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/e35380ecabc5414d432bbb67d3f2d78267ee1883..d3252064cfb72aaac72cd105626cf0a8638fc899:/proxyscan/proxyscan.c diff --git a/proxyscan/proxyscan.c b/proxyscan/proxyscan.c index 03b74e06..33d6b836 100644 --- a/proxyscan/proxyscan.c +++ b/proxyscan/proxyscan.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "../core/error.h" #include "../core/events.h" @@ -26,6 +27,7 @@ #include "../localuser/localuserchannel.h" #include "../core/nsmalloc.h" #include "../lib/irc_ipv6.h" +#include "../glines/glines.h" MODULE_VERSION("") @@ -101,6 +103,7 @@ int proxyscandosave(void *sender, int cargc, char **cargv); int proxyscandospew(void *sender, int cargc, char **cargv); int proxyscandoshowkill(void *sender, int cargc, char **cargv); int proxyscandoscan(void *sender, int cargc, char **cargv); +int proxyscandoscanfile(void *sender, int cargc, char **cargv); int proxyscandoaddscan(void *sender, int cargc, char **cargv); int proxyscandodelscan(void *sender, int cargc, char **cargv); int proxyscandoshowcommands(void *sender, int cargc, char **cargv); @@ -136,10 +139,16 @@ int proxyscan_delscantype(int type, int port) { return 0; } +void ignorepipe(int signal_) { + signal(SIGPIPE, ignorepipe); /* HACK */ +} + void _init(void) { sstring *cfgstr; int ipbits[4]; + signal(SIGPIPE, ignorepipe); /* HACK */ + ps_start_ts = time(NULL); ps_ready = 0; ps_commands = NULL; @@ -173,7 +182,7 @@ void _init(void) { freesstring(cfgstr); /* Max concurrent scans */ - cfgstr=getcopyconfigitem("proxyscan","maxscans","200",5); + cfgstr=getcopyconfigitem("proxyscan","maxscans","200",10); maxscans=strtol(cfgstr->content,NULL,10); freesstring(cfgstr); @@ -239,14 +248,16 @@ void _init(void) { addcommandtotree(ps_commands, "status", 0, 0, &proxyscandostatus); addcommandtotree(ps_commands, "listopen", 0, 0, &proxyscandolistopen); addcommandtotree(ps_commands, "save", 0, 0, &proxyscandosave); - addcommandtotree(ps_commands, "spew", 0, 0, &proxyscandospew); - addcommandtotree(ps_commands, "showkill", 0, 0, &proxyscandoshowkill); - addcommandtotree(ps_commands, "scan", 0, 0, &proxyscandoscan); - addcommandtotree(ps_commands, "addscan", 0, 0, &proxyscandoaddscan); - addcommandtotree(ps_commands, "delscan", 0, 0, &proxyscandodelscan); + addcommandtotree(ps_commands, "spew", 0, 1, &proxyscandospew); + addcommandtotree(ps_commands, "showkill", 0, 1, &proxyscandoshowkill); + addcommandtotree(ps_commands, "scan", 0, 1, &proxyscandoscan); + addcommandtotree(ps_commands, "scanfile", 0, 1, &proxyscandoscanfile); + addcommandtotree(ps_commands, "addscan", 0, 1, &proxyscandoaddscan); + addcommandtotree(ps_commands, "delscan", 0, 1, &proxyscandodelscan); /* Default scan types */ proxyscan_addscantype(STYPE_HTTP, 8080); + proxyscan_addscantype(STYPE_HTTP, 8118); proxyscan_addscantype(STYPE_HTTP, 80); proxyscan_addscantype(STYPE_HTTP, 6588); proxyscan_addscantype(STYPE_HTTP, 8000); @@ -257,6 +268,16 @@ void _init(void) { proxyscan_addscantype(STYPE_HTTP, 808); proxyscan_addscantype(STYPE_HTTP, 3332); proxyscan_addscantype(STYPE_HTTP, 2282); + + proxyscan_addscantype(STYPE_HTTP, 1644); + proxyscan_addscantype(STYPE_HTTP, 8081); + proxyscan_addscantype(STYPE_HTTP, 443); + proxyscan_addscantype(STYPE_HTTP, 1337); + proxyscan_addscantype(STYPE_HTTP, 8888); + proxyscan_addscantype(STYPE_HTTP, 8008); + proxyscan_addscantype(STYPE_HTTP, 6515); + proxyscan_addscantype(STYPE_HTTP, 27977); + proxyscan_addscantype(STYPE_SOCKS4, 559); proxyscan_addscantype(STYPE_SOCKS4, 1080); proxyscan_addscantype(STYPE_SOCKS5, 1080); @@ -279,7 +300,14 @@ void _init(void) { proxyscan_addscantype(STYPE_HTTP, 63809); proxyscan_addscantype(STYPE_HTTP, 63000); proxyscan_addscantype(STYPE_SOCKS4, 29992); - + proxyscan_addscantype(STYPE_DIRECT_IRC, 6666); + proxyscan_addscantype(STYPE_DIRECT_IRC, 6667); + proxyscan_addscantype(STYPE_DIRECT_IRC, 6668); + proxyscan_addscantype(STYPE_DIRECT_IRC, 6669); + proxyscan_addscantype(STYPE_DIRECT_IRC, 6670); + proxyscan_addscantype(STYPE_ROUTER, 3128); + proxyscan_addscantype(STYPE_SOCKS5, 27977); + /* Schedule saves */ schedulerecurring(time(NULL)+3600,0,3600,&dumpcachehosts,NULL); @@ -472,10 +500,11 @@ void startscan(patricia_node_t *node, int type, int port, int class) { sp->totalbytesread=0; memset(sp->readbuf, '\0', PSCAN_READBUFSIZE); - sp->fd=createconnectsocket(irc_in_addr_v4_to_int(&((patricia_node_t *)sp->node)->prefix->sin),sp->port); + sp->fd=createconnectsocket(&((patricia_node_t *)sp->node)->prefix->sin,sp->port); sp->state=SSTATE_CONNECTING; if (sp->fd<0) { /* Couldn't set up the socket? */ + derefnode(iptree,sp->node); freescan(sp); return; } @@ -496,6 +525,8 @@ void killsock(scan *sp, int outcome) { int i; cachehost *chp; foundproxy *fpp; + time_t now; + char reason[200]; scansdone++; scansbyclass[sp->class]++; @@ -540,13 +571,24 @@ void killsock(scan *sp, int outcome) { fpp->next=chp->proxies; chp->proxies=fpp; } - - if (!chp->glineid) { + + now=time(NULL); + /* the purpose of this lastgline stuff is to stop gline spam from one scan */ + if (!chp->glineid || (now>=chp->lastgline+SCANTIMEOUT)) { + char buf[512]; + struct irc_in_addr *ip; + + chp->lastgline=now; glinedhosts++; - loggline(chp, sp->node); - irc_send("%s GL * +*@%s 1800 %jd :Open Proxy, see http://www.quakenet.org/openproxies.html - ID: %d", - mynumeric->content,IPtostr(((patricia_node_t *)sp->node)->prefix->sin),(intmax_t)getnettime(), chp->glineid); - Error("proxyscan",ERR_DEBUG,"Found open proxy on host %s",IPtostr(((patricia_node_t *)sp->node)->prefix->sin)); + + loggline(chp, sp->node); + ip = &(((patricia_node_t *)sp->node)->prefix->sin); + snprintf(reason, sizeof(reason), "Open Proxy, see http://www.quakenet.org/openproxies.html - ID: %d", chp->glineid); + glinebyip("*", ip, 128, 43200, reason, GLINE_IGNORE_TRUST, "proxyscan"); + Error("proxyscan",ERR_DEBUG,"Found open proxy on host %s",IPtostr(*ip)); + + snprintf(buf, sizeof(buf), "proxy-gline %lu %s %s %hu %s", time(NULL), IPtostr(*ip), scantostr(sp->type), sp->port, "irc.quakenet.org"); + triggerhook(HOOK_SHADOW_SERVER, (void *)buf); } else { loggline(chp, sp->node); /* Update log only */ } @@ -560,6 +602,8 @@ void killsock(scan *sp, int outcome) { } } + /* deref prefix (referenced in queuescan) */ + derefnode(iptree,sp->node); freescan(sp); /* kick the queue.. */ @@ -614,7 +658,7 @@ void handlescansock(int fd, short events) { switch(sp->type) { case STYPE_HTTP: - sprintf(buf,"CONNECT %s:%d HTTP/1.0\r\n\r\n",myipstr->content,listenport); + sprintf(buf,"CONNECT %s:%d HTTP/1.0\r\n\r\n\r\n",myipstr->content,listenport); if ((write(fd,buf,strlen(buf)))bytesread+=res; sp->totalbytesread+=res; - for (i=0;ibytesread - MAGICSTRINGLENGTH;i++) { - if (!strncmp(sp->readbuf+i, MAGICSTRING, MAGICSTRINGLENGTH)) { - /* Found the magic string */ - /* If the offset is 0, this means it was the first thing we got from the socket, - * so it's an actual IRCD (sheesh). Note that when the buffer is full and moved, - * the thing moved to offset 0 would previously have been tested as offset - * PSCAN_READBUFSIZE/2. - * - * Skip this checking for STYPE_DIRECT scans, which are used to detect trojans setting - * up portforwards (which will therefore show up as ircds, we rely on the port being - * strange enough to avoid false positives */ - if (i==0 && (sp->type != STYPE_DIRECT)) { - killsock(sp, SOUTCOME_CLOSED); - return; + + { + char *magicstring; + int magicstringlength; + + if(sp->type == STYPE_DIRECT_IRC) { + magicstring = MAGICIRCSTRING; + magicstringlength = MAGICIRCSTRINGLENGTH; + } else if(sp->type == STYPE_ROUTER) { + magicstring = MAGICROUTERSTRING; + magicstringlength = MAGICROUTERSTRINGLENGTH; + } else { + magicstring = MAGICSTRING; + magicstringlength = MAGICSTRINGLENGTH; + if(sp->totalbytesread - res == 0) { + buf[0] = '\n'; + write(fd,buf,1); } + } + + for (i=0;ibytesread - magicstringlength;i++) { + if (!strncmp(sp->readbuf+i, magicstring, magicstringlength)) { + /* Found the magic string */ + /* If the offset is 0, this means it was the first thing we got from the socket, + * so it's an actual IRCD (sheesh). Note that when the buffer is full and moved, + * the thing moved to offset 0 would previously have been tested as offset + * PSCAN_READBUFSIZE/2. + * + * Skip this checking for STYPE_DIRECT scans, which are used to detect trojans setting + * up portforwards (which will therefore show up as ircds, we rely on the port being + * strange enough to avoid false positives */ + if (i==0 && (sp->type != STYPE_DIRECT)) { + killsock(sp, SOUTCOME_CLOSED); + return; + } - killsock(sp, SOUTCOME_OPEN); - return; + killsock(sp, SOUTCOME_OPEN); + return; + } } } @@ -888,6 +973,9 @@ int proxyscandosave(void *sender, int cargc, char **cargv) { int proxyscandospew(void *sender, int cargc, char **cargv) { nick *np = (nick *)sender; + if(cargc < 1) + return CMD_USAGE; + /* check our database for the ip supplied */ unsigned long a,b,c,d; if (4 != sscanf(cargv[0],"%lu.%lu.%lu.%lu",&a,&b,&c,&d)) { @@ -902,6 +990,9 @@ int proxyscandospew(void *sender, int cargc, char **cargv) { int proxyscandoshowkill(void *sender, int cargc, char **cargv) { nick *np = (nick *)sender; + if(cargc < 1) + return CMD_USAGE; + /* check our database for the id supplied */ unsigned long a; if (1 != sscanf(cargv[0],"%lu",&a)) { @@ -913,6 +1004,15 @@ int proxyscandoshowkill(void *sender, int cargc, char **cargv) { return CMD_OK; } +void startnickscan(nick *np) { + time_t t = time(NULL); + int i; + for(i=0;iipnode,thescans[i].type,thescans[i].port,SCLASS_NORMAL,t); + } +} + int proxyscandoscan(void *sender, int cargc, char **cargv) { nick *np = (nick *)sender; patricia_node_t *node; @@ -920,23 +1020,114 @@ int proxyscandoscan(void *sender, int cargc, char **cargv) { unsigned char bits; int i; + if(cargc < 1) + return CMD_USAGE; + if (0 == ipmask_parse(cargv[0],&sin, &bits)) { sendnoticetouser(proxyscannick,np,"Usage: scan "); } else { + if (bits != 128 || !irc_in_addr_is_ipv4(&sin) || irc_in_addr_is_loopback(&sin)) { + sendnoticetouser(proxyscannick,np,"You may only scan single IPv4 IP's"); + return CMD_OK; + } + if (bits != 128 || irc_in_addr_is_loopback(&sin)) { + sendnoticetouser(proxyscannick,np,"You may only scan single IP's"); + return CMD_OK; + } + + time_t t; sendnoticetouser(proxyscannick,np,"Forcing scan of %s",IPtostr(sin)); // * Just queue the scans directly here.. plonk them on the priority queue * / node = refnode(iptree, &sin, bits); /* node leaks node here - should only allow to scan a nick? */ + t = time(NULL); for(i=0;i maxno) + maxno = thescans[i].type; + + tscantypes = malloc(sizeof(int) * maxno); + for(i=0;i "); @@ -951,6 +1142,9 @@ int proxyscandoaddscan(void *sender, int cargc, char **cargv) { int proxyscandodelscan(void *sender, int cargc, char **cargv) { nick *np = (nick *)sender; + if(cargc < 1) + return CMD_USAGE; + unsigned int a,b; if (sscanf(cargv[0],"%u %u",&a,&b) != 2) { sendnoticetouser(proxyscannick,np,"Usage: delscan ");