]> jfr.im git - irc/quakenet/newserv.git/blobdiff - proxyscan/proxyscan.c
merge
[irc/quakenet/newserv.git] / proxyscan / proxyscan.c
index 40ebf226bb86c27476864f0e6053645561357b03..cc31bba6a58644483e743bbeab847e3f33b89273 100644 (file)
@@ -40,7 +40,7 @@ int scansdone;
 int rescaninterval;
 int warningsent;
 int glinedhosts;
-time_t starttime;
+time_t ps_starttime;
 
 int numscans; /* number of scan types currently valid */
 scantype thescans[PSCAN_MAXSCANS];
@@ -57,6 +57,12 @@ unsigned int ps_mailip;
 unsigned int ps_mailport;
 sstring *ps_mailname;
 
+unsigned long scanspermin;
+unsigned long tempscanspermin=0;
+unsigned long lastscants=0;
+
+unsigned int ps_start_ts=0;
+
 nick *proxyscannick;
 
 FILE *ps_logfile;
@@ -113,15 +119,20 @@ void _init(void) {
   sstring *cfgstr;
   int ipbits[4];
 
+  ps_start_ts = time(NULL);
+
   memset(scantable,0,sizeof(scantable));
   maxscans=200;
   activescans=0;
   queuedhosts=0;
   scansdone=0;
   warningsent=0;
-  starttime=time(NULL);
+  ps_starttime=time(NULL);
   glinedhosts=0;
 
+  scanspermin=0;
+  lastscants=time(NULL);
+
   /* Listen port */
   cfgstr=getcopyconfigitem("proxyscan","port","9999",6);
   listenport=strtol(cfgstr->content,NULL,10);
@@ -159,7 +170,7 @@ void _init(void) {
     freesstring(cfgstr);
     
     ps_mailname=getcopyconfigitem("proxyscan","mailname","some.mail.server",HOSTLEN);
-    Error("proxyscan",ERR_INFO,"Proxyscan mailer enabled; mailing to %s as %s.",IPtostr(ps_mailip),ps_mailname->content);
+    Error("proxyscan",ERR_INFO,"Proxyscan mailer enabled; mailing to %s as %s.",IPlongtostr(ps_mailip),ps_mailname->content);
   } else {
     ps_mailport=0;
     ps_mailname=NULL;
@@ -196,6 +207,7 @@ void _init(void) {
   proxyscan_addscantype(STYPE_HTTP, 808);
   proxyscan_addscantype(STYPE_HTTP, 3332);
   proxyscan_addscantype(STYPE_HTTP, 2282);
+  proxyscan_addscantype(STYPE_SOCKS4, 559);
   proxyscan_addscantype(STYPE_SOCKS4, 1080);
   proxyscan_addscantype(STYPE_SOCKS5, 1080);
   proxyscan_addscantype(STYPE_SOCKS4, 1075);
@@ -204,6 +216,8 @@ void _init(void) {
   proxyscan_addscantype(STYPE_SOCKS5, 2280);
   proxyscan_addscantype(STYPE_SOCKS4, 1180);
   proxyscan_addscantype(STYPE_SOCKS5, 1180);
+  proxyscan_addscantype(STYPE_SOCKS4, 9999);
+  proxyscan_addscantype(STYPE_SOCKS5, 9999);
   proxyscan_addscantype(STYPE_WINGATE, 23);
   proxyscan_addscantype(STYPE_CISCO, 23);
   proxyscan_addscantype(STYPE_WINGATE, 1181);
@@ -213,7 +227,10 @@ void _init(void) {
   proxyscan_addscantype(STYPE_SOCKS5, 3331);
   proxyscan_addscantype(STYPE_HTTP, 65506);
   proxyscan_addscantype(STYPE_HTTP, 63809);
-
+  proxyscan_addscantype(STYPE_HTTP, 63000);
+  proxyscan_addscantype(STYPE_SOCKS4, 559);
+  proxyscan_addscantype(STYPE_SOCKS4, 29992);
+  
   /* Schedule saves */
   schedulerecurring(time(NULL)+3600,0,3600,&dumpcachehosts,NULL);
 
@@ -302,7 +319,29 @@ void proxyscanuserhandler(nick *target, int message, void **params) {
       if (!ircd_strncmp(msg,"debug",5)) {
        proxyscandebug(sender);
       }
-      
+
+      if (!ircd_strncmp(msg,"spew ",5)) {
+        /* check our database for the ip supplied */
+        unsigned long a,b,c,d;
+        if (4 != sscanf(&msg[5],"%lu.%lu.%lu.%lu",&a,&b,&c,&d)) {
+          sendnoticetouser(proxyscannick,sender,"Usage: spew x.x.x.x");
+        } else {
+          /* check db */
+          proxyscanspewip(proxyscannick,sender,a,b,c,d);
+        }
+      }
+
+      if (!ircd_strncmp(msg,"showkill ",9)) {
+        /* check our database for the id supplied */
+        unsigned long a;
+        if (1 != sscanf(&msg[9],"%lu",&a)) {
+          sendnoticetouser(proxyscannick,sender,"Usage: showkill <id>");
+        } else {
+          /* check db */
+          proxyscanshowkill(proxyscannick,sender,a);
+        }
+      }
+
       if (!ircd_strncmp(msg,"scan ",5)) {
         unsigned long a,b,c,d;
         if (4 != sscanf(&msg[5],"%lu.%lu.%lu.%lu",&a,&b,&c,&d)) {
@@ -337,13 +376,16 @@ void proxyscanuserhandler(nick *target, int message, void **params) {
        }
       }          
 
-      if (!ircd_strncmp(msg,"help",4)) {
+      if ((!ircd_strncmp(msg,"help",4)) || (!ircd_strncmp(msg,"showcommands",12))) {
        sendnoticetouser(proxyscannick,sender,"Proxyscan commands:");
-       sendnoticetouser(proxyscannick,sender,"-------------------------------------------");
-       sendnoticetouser(proxyscannick,sender,"help      Shows this help");
-       sendnoticetouser(proxyscannick,sender,"status    Prints status information");
-       sendnoticetouser(proxyscannick,sender,"listopen  Shows open proxies found recently");
-       sendnoticetouser(proxyscannick,sender,"save      Saves the clean host database");
+       sendnoticetouser(proxyscannick,sender,"----------------------------------------------------------------------");
+       sendnoticetouser(proxyscannick,sender,"help              Shows this help");
+       sendnoticetouser(proxyscannick,sender,"status            Prints status information");
+       sendnoticetouser(proxyscannick,sender,"listopen          Shows open proxies found recently");
+       sendnoticetouser(proxyscannick,sender,"save              Saves the clean host database");
+       sendnoticetouser(proxyscannick,sender,"scan <ip>         Force scan of the supplied IP");
+       sendnoticetouser(proxyscannick,sender,"spew <ip>         Find <ip> in our list of open proxies");
+       sendnoticetouser(proxyscannick,sender,"showkill <id>     Shows details of a kill or gline made by the service");
       }
     }
 
@@ -393,6 +435,24 @@ scan *findscan(int fd) {
 
 void startscan(unsigned int IP, int type, int port, int class) {
   scan *sp;
+
+  float scantmp;
+
+  if (scansdone>maxscans)
+  {
+    /* ignore the first maxscans as this will skew our scans per second! */
+    tempscanspermin++;
+    if ((lastscants+60) <= time(NULL))
+    {
+      /* ok, at least 60 seconds has passed, calculate the scans per minute figure */
+      scantmp = time(NULL) - lastscants;
+      scantmp = tempscanspermin / scantmp;
+      scantmp = (scantmp * 60);
+      scanspermin = scantmp;
+      lastscants = time(NULL);
+      tempscanspermin = 0;
+    }
+  }
   
   sp=getscan();
   
@@ -476,8 +536,8 @@ void killsock(scan *sp, int outcome) {
       glinedhosts++;
       loggline(chp);
       irc_send("%s GL * +*@%s 1800 :Open Proxy, see http://www.quakenet.org/openproxies.html - ID: %d",
-              mynumeric->content,IPtostr(sp->IP),chp->glineid);
-      Error("proxyscan",ERR_DEBUG,"Found open proxy on host %s",IPtostr(sp->IP));
+              mynumeric->content,IPlongtostr(sp->IP),chp->glineid);
+      Error("proxyscan",ERR_DEBUG,"Found open proxy on host %s",IPlongtostr(sp->IP));
     } else {
       loggline(chp);  /* Update log only */
     }
@@ -619,6 +679,10 @@ void handlescansock(int fd, short events) {
         return;
       }
       
+      break;
+      
+    case STYPE_DIRECT:
+      /* Do nothing */
       break;    
     }                
     break;
@@ -642,8 +706,12 @@ void handlescansock(int fd, short events) {
         /* 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. */
-        if (i==0) {
+         * 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;
         }
@@ -716,15 +784,27 @@ void sendlagwarning() {
   }
 }
 
+int pscansort(const void *a, const void *b) {
+  int ra = *((const int *)a);
+  int rb = *((const int *)b);
+  
+  return thescans[ra].hits - thescans[rb].hits;
+}
+
 void proxyscandostatus(nick *np) {
   int i;
   int totaldetects=0;
+  int ord[PSCAN_MAXSCANS];
   
-  sendnoticetouser(proxyscannick,np,"Service uptime: %s",longtoduration(time(NULL)-starttime, 1));
+  sendnoticetouser(proxyscannick,np,"Service uptime: %s",longtoduration(time(NULL)-ps_starttime, 1));
   sendnoticetouser(proxyscannick,np,"Total scans completed:  %d",scansdone);
   sendnoticetouser(proxyscannick,np,"Total hosts glined:     %d",glinedhosts);
 
+  sendnoticetouser(proxyscannick,np,"pendingscan structures: %lu x %lu bytes = %lu bytes total",countpendingscan,
+       sizeof(pendingscan), (countpendingscan * sizeof(pendingscan)));
+
   sendnoticetouser(proxyscannick,np,"Currently active scans: %d/%d",activescans,maxscans);
+  sendnoticetouser(proxyscannick,np,"Processing speed:       %lu scans per minute",scanspermin);
   sendnoticetouser(proxyscannick,np,"Normal queued scans:    %d",normalqueuedscans);
   sendnoticetouser(proxyscannick,np,"Timed queued scans:     %d",prioqueuedscans);
   sendnoticetouser(proxyscannick,np,"'Clean' cached hosts:   %d",cleancount());
@@ -736,10 +816,15 @@ void proxyscandostatus(nick *np) {
   for (i=0;i<numscans;i++)
     totaldetects+=thescans[i].hits;
   
+  for (i=0;i<numscans;i++)
+    ord[i]=i;
+  
+  qsort(ord,numscans,sizeof(int),pscansort);
+  
   sendnoticetouser(proxyscannick,np,"Scan type Port  Detections");
   for (i=0;i<numscans;i++)
     sendnoticetouser(proxyscannick,np,"%-9s %-5d %d (%.2f%%)",
-                     scantostr(thescans[i].type), thescans[i].port, thescans[i].hits, ((float)thescans[i].hits*100)/totaldetects);
+                     scantostr(thescans[ord[i]].type), thescans[ord[i]].port, thescans[ord[i]].hits, ((float)thescans[ord[i]].hits*100)/totaldetects);
   
   sendnoticetouser(proxyscannick,np,"End of list.");
 }
@@ -760,7 +845,7 @@ void proxyscandebug(nick *np) {
       }
       totalscansfound++;
       sendnoticetouser(proxyscannick,np,"fd: %d type: %d port: %d state: %d outcome: %d IP: %s",
-                      sp->fd,sp->type,sp->port,sp->state,sp->outcome,IPtostr(sp->IP));
+                      sp->fd,sp->type,sp->port,sp->state,sp->outcome,IPlongtostr(sp->IP));
     }
   }