]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_dnsbl.cpp
m_dnsbl stats should count no result as a miss
[user/henk/code/inspircd.git] / src / modules / m_dnsbl.cpp
index 213c2f67e4e812794b66c13905a055d442243bd3..c7631ae789631820ec261bc96b6c26e414788b71 100644 (file)
@@ -33,7 +33,9 @@ class DNSBLConfEntry
                EnumBanaction banaction;
                long duration;
                int bitmask;
-               DNSBLConfEntry(): duration(86400),bitmask(0) {}
+               unsigned long stats_hits, stats_misses;
+               DNSBLConfEntry(): duration(86400),bitmask(0),stats_hits(0), stats_misses(0) {}
+               ~DNSBLConfEntry() { }
 };
 
 
@@ -63,29 +65,14 @@ class DNSBLResolver : public Resolver
                        if(result.length())
                        {
                                unsigned int bitmask=0;
-                               unsigned int octetpos=0;
-                               std::string tmp = result;
+                               in_addr resultip;
 
-                               while(tmp.length()>0)
-                               {
-                                       std::string octet;
-                                       /* Fix by brain, npos is -1, so unsigned int will never match */
-                                       std::string::size_type lastdot = tmp.rfind(".");
-
-                                       if (lastdot == std::string::npos)
-                                       {
-                                               octet=tmp;
-                                               tmp.clear();
-                                       }
-                                       else
-                                       {
-                                               octet=tmp.substr(lastdot+1,tmp.length()-lastdot+1);
-                                               tmp.resize(lastdot);
-                                       }
-
-                                       bitmask += (256 ^ octetpos) * atoi(octet.c_str());
-                                       octetpos += 1;
-                               }
+                               /* Convert the result to an in_addr (we can gaurantee we got ipv4)
+                                * Whoever did the loop that was here before, I AM CONFISCATING
+                                * YOUR CRACKPIPE. you know who you are. -- Brain
+                                */
+                               inet_aton(result.c_str(), &resultip);
+                               bitmask = resultip.s_addr >> 24; /* Last octet (network byte order */
 
                                bitmask &= ConfEntry->bitmask;
 
@@ -101,6 +88,7 @@ class DNSBLResolver : public Resolver
                                        }
 
                                        ServerInstance->WriteOpers("*** Connecting user %s detected as being on a DNS blacklist (%s) with result %d", them->GetFullRealHost(), ConfEntry->name.c_str(), bitmask);
+                                       ConfEntry->stats_hits++;
 
                                        switch (ConfEntry->banaction)
                                        {
@@ -112,16 +100,19 @@ class DNSBLResolver : public Resolver
                                                case DNSBLConfEntry::I_KLINE:
                                                {
                                                        ServerInstance->AddKLine(ConfEntry->duration, ServerInstance->Config->ServerName, reason, std::string("*@") + them->GetIPString());
+                                                       FOREACH_MOD(I_OnAddKLine,OnAddKLine(ConfEntry->duration, NULL, reason, std::string("*@") + them->GetIPString()));
                                                        break;
                                                }
                                                case DNSBLConfEntry::I_GLINE:
                                                {
                                                        ServerInstance->AddGLine(ConfEntry->duration, ServerInstance->Config->ServerName, reason, std::string("*@") + them->GetIPString());
+                                                       FOREACH_MOD(I_OnAddGLine,OnAddGLine(ConfEntry->duration, NULL, reason, std::string("*@") + them->GetIPString()));
                                                        break;
                                                }
                                                case DNSBLConfEntry::I_ZLINE:
                                                {
                                                        ServerInstance->AddZLine(ConfEntry->duration, ServerInstance->Config->ServerName, reason, them->GetIPString());
+                                                       FOREACH_MOD(I_OnAddZLine,OnAddZLine(ConfEntry->duration, NULL, reason, them->GetIPString()));
                                                        break;
                                                }
                                                case DNSBLConfEntry::I_UNKNOWN:
@@ -131,7 +122,11 @@ class DNSBLResolver : public Resolver
                                                break;
                                        }
                                }
+                               else
+                                       ConfEntry->stats_misses++;
                        }
+                       else
+                               ConfEntry->stats_misses++;
                }
        }
 
@@ -183,7 +178,7 @@ class ModuleDNSBL : public Module
 
        void Implements(char* List)
        {
-               List[I_OnRehash] = List[I_OnUserRegister] = 1;
+               List[I_OnRehash] = List[I_OnUserRegister] = List[I_OnStats] = 1;
        }
 
        /** Clear entries and free the mem it was using
@@ -191,11 +186,9 @@ class ModuleDNSBL : public Module
        void ClearEntries()
        {
                std::vector<DNSBLConfEntry *>::iterator i;
-               while ((i = DNSBLConfEntries.begin()) != DNSBLConfEntries.end())
-               {
-                       DNSBLConfEntries.erase(i);
+               for (std::vector<DNSBLConfEntry *>::iterator i = DNSBLConfEntries.begin(); i != DNSBLConfEntries.end(); i++)
                        delete *i;
-               }
+               DNSBLConfEntries.clear();
        }
 
        /** Fill our conf vector with data
@@ -270,13 +263,30 @@ class ModuleDNSBL : public Module
                        unsigned char a, b, c, d;
                        char reversedipbuf[128];
                        std::string reversedip;
+                       bool success = false;
 
                        if (!inet_aton(user->GetIPString(), &in))
                        {
-                               ServerInstance->WriteOpers("Invalid IP address in m_dnsbl! Bailing check");
-                               return 0;
+#ifdef IPV6
+                               /* We could have an ipv6 address here */
+                               std::string x = user->GetIPString();
+                               /* Is it a 4in6 address? (Compensate for this kernel kludge that people love) */
+                               if (x.find("0::ffff:") == 0)
+                               {
+                                       x.erase(x.begin(), x.begin() + 8);
+                                       if (inet_aton(x.c_str(), &in))
+                                               success = true;
+                               }
+#endif
+                       }
+                       else
+                       {
+                               success = true;
                        }
 
+                       if (!success)
+                               return 0;
+
                        d = (unsigned char) (in.s_addr >> 24) & 0xFF;
                        c = (unsigned char) (in.s_addr >> 16) & 0xFF;
                        b = (unsigned char) (in.s_addr >> 8) & 0xFF;
@@ -289,7 +299,7 @@ class ModuleDNSBL : public Module
                        for (std::vector<DNSBLConfEntry *>::iterator i = DNSBLConfEntries.begin(); i != DNSBLConfEntries.end(); i++)
                        {
                                // Fill hostname with a dnsbl style host (d.c.b.a.domain.tld)
-                               std::string hostname=reversedip+"."+ (*i)->domain;
+                               std::string hostname = reversedip + "." + (*i)->domain;
 
                                /* now we'd need to fire off lookups for `hostname'. */
                                bool cached;
@@ -301,6 +311,28 @@ class ModuleDNSBL : public Module
                /* don't do anything with this hot potato */
                return 0;
        }
+       
+       virtual int OnStats(char symbol, userrec* user, string_list &results)
+       {
+               if (symbol != 'd')
+                       return 0;
+               
+               unsigned long total_hits = 0, total_misses = 0;
+
+               for (std::vector<DNSBLConfEntry*>::iterator i = DNSBLConfEntries.begin(); i != DNSBLConfEntries.end(); i++)
+               {
+                       total_hits += (*i)->stats_hits;
+                       total_misses += (*i)->stats_misses;
+                       
+                       results.push_back(std::string(ServerInstance->Config->ServerName) + " 304 " + user->nick + " :DNSBLSTATS DNSbl \"" + (*i)->name + "\" had " +
+                                       ConvToStr((*i)->stats_hits) + " hits and " + ConvToStr((*i)->stats_misses) + " misses");
+               }
+               
+               results.push_back(std::string(ServerInstance->Config->ServerName) + " 304 " + user->nick + " :DNSBLSTATS Total hits: " + ConvToStr(total_hits));
+               results.push_back(std::string(ServerInstance->Config->ServerName) + " 304 " + user->nick + " :DNSBLSTATS Total misses: " + ConvToStr(total_misses));
+               
+               return 0;
+       }
 };
 
 // stuff down here is the module-factory stuff.