]> jfr.im git - irc/quakenet/newserv.git/blobdiff - proxyscan/proxyscan.c
merge
[irc/quakenet/newserv.git] / proxyscan / proxyscan.c
index 03b74e06bed8bbfdef521c8f5907a8c19a47df9f..8e2190a77480969db9d3cb91805b9962885a82cf 100644 (file)
@@ -247,6 +247,7 @@ void _init(void) {
 
   /* 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);
@@ -279,6 +280,12 @@ 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);
  
   /* Schedule saves */
   schedulerecurring(time(NULL)+3600,0,3600,&dumpcachehosts,NULL);
@@ -476,6 +483,7 @@ void startscan(patricia_node_t *node, int type, int port, int class) {
   sp->state=SSTATE_CONNECTING;
   if (sp->fd<0) {
     /* Couldn't set up the socket? */
+    derefnode(iptree,sp->node);
     freescan(sp);
     return;
   }
@@ -496,6 +504,7 @@ void killsock(scan *sp, int outcome) {
   int i;
   cachehost *chp;
   foundproxy *fpp;
+  time_t now;
 
   scansdone++;
   scansbyclass[sp->class]++;
@@ -540,10 +549,13 @@ 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)) {
+      chp->lastgline=now;
       glinedhosts++;
-      loggline(chp, sp->node);
+      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));
@@ -560,6 +572,8 @@ void killsock(scan *sp, int outcome) {
     }
   }
 
+  /* deref prefix (referenced in queuescan) */
+  derefnode(iptree,sp->node);
   freescan(sp);
 
   /* kick the queue.. */
@@ -693,6 +707,26 @@ void handlescansock(int fd, short events) {
     case STYPE_DIRECT:
       /* Do nothing */
       break;    
+
+    case STYPE_DIRECT_IRC:
+      sprintf(buf,"PRIVMSG\r\n");
+      if ((write(fd,buf,strlen(buf)))<strlen(buf)) {
+       killsock(sp, SOUTCOME_CLOSED);
+        return;
+      }
+      
+      /* Do nothing */
+      break;    
+
+    case STYPE_ROUTER:
+      sprintf(buf,"GET /nonexistent HTTP/1.0\r\n\r\n");
+      if ((write(fd,buf,strlen(buf)))<strlen(buf)) {
+       killsock(sp, SOUTCOME_CLOSED);
+        return;
+      }
+      
+      /* Do nothing */
+      break;    
     }                
     break;
     
@@ -709,24 +743,41 @@ void handlescansock(int fd, short events) {
     
     sp->bytesread+=res;
     sp->totalbytesread+=res;
-    for (i=0;i<sp->bytesread - 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);
+
+    {
+      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;
+      }
+
+      for (i=0;i<sp->bytesread - 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;
       }
     }
     
@@ -913,6 +964,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;i<numscans;i++) {
+    /* @@@TODO: we allow a forced scan to scan the same IP multiple times atm */
+    queuescan(np->ipnode,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;
@@ -923,12 +983,19 @@ int proxyscandoscan(void *sender, int cargc, char **cargv) {
   if (0 == ipmask_parse(cargv[0],&sin, &bits)) {
     sendnoticetouser(proxyscannick,np,"Usage: scan <ip>");
   } 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;
+    }
+
+    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<numscans;i++) {
       /* @@@TODO: we allow a forced scan to scan the same IP multiple times atm */
-      queuescan(node,thescans[i].type,thescans[i].port,SCLASS_NORMAL,time(NULL));
+      queuescan(node,thescans[i].type,thescans[i].port,SCLASS_NORMAL,t);
     }
   }
   return CMD_OK;