]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_dnsbl.cpp
Call events properly on KLINE, GLINE and ZLINE for DNSBL module. This fixes bans...
[user/henk/code/inspircd.git] / src / modules / m_dnsbl.cpp
index 1760f5a8376379745594b73d96318c8d192b7259..ab4c2e76d6e2950cfc1e1a8edea51ddde6b6b547 100644 (file)
@@ -46,21 +46,19 @@ class DNSBLResolver : public Resolver
        DNSBLConfEntry *ConfEntry;
 
     public:
-       DNSBLResolver(Module *me, InspIRCd *ServerInstance, const std::string &hostname, userrec* u, int userfd, DNSBLConfEntry *conf)
-               : Resolver(ServerInstance, hostname, DNS_QUERY_A, me)
+       DNSBLResolver(Module *me, InspIRCd *ServerInstance, const std::string &hostname, userrec* u, int userfd, DNSBLConfEntry *conf, bool &cached)
+               : Resolver(ServerInstance, hostname, DNS_QUERY_A, cached, me)
        {
                theirfd = userfd;
                them = u;
                ConfEntry = conf;
        }
 
-       virtual void OnLookupComplete(const std::string &result)
+       virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
        {
                /* Check the user still exists */
                if ((them) && (them == ServerInstance->SE->GetRef(theirfd)))
                {
-                       ServerInstance->Log(DEBUG, "m_dnsbl:  %s got a result from dnsbl %s", them->nick, ConfEntry->name.c_str());
-
                        // Now we calculate the bitmask: 256*(256*(256*a+b)+c)+d
                        if(result.length())
                        {
@@ -71,7 +69,8 @@ class DNSBLResolver : public Resolver
                                while(tmp.length()>0)
                                {
                                        std::string octet;
-                                       unsigned int lastdot = tmp.rfind(".");
+                                       /* Fix by brain, npos is -1, so unsigned int will never match */
+                                       std::string::size_type lastdot = tmp.rfind(".");
 
                                        if (lastdot == std::string::npos)
                                        {
@@ -93,10 +92,12 @@ class DNSBLResolver : public Resolver
                                if (bitmask != 0)
                                {
                                        std::string reason = ConfEntry->reason;
-
-                                       while (int pos = reason.find("%ip%") != std::string::npos)
+                                       std::string::size_type x = reason.find("%ip%");
+                                       while (x != std::string::npos)
                                        {
-                                               reason.replace(pos, 4, them->GetIPString());
+                                               reason.erase(x, 4);
+                                               reason.insert(x, them->GetIPString());
+                                               x = reason.find("%ip%");
                                        }
 
                                        ServerInstance->WriteOpers("*** Connecting user %s detected as being on a DNS blacklist (%s) with result %d", them->GetFullRealHost(), ConfEntry->name.c_str(), bitmask);
@@ -105,22 +106,25 @@ class DNSBLResolver : public Resolver
                                        {
                                                case DNSBLConfEntry::I_KILL:
                                                {
-                                                       them->QuitUser(ServerInstance, them, std::string("Killed (") + reason + ")");
+                                                       userrec::QuitUser(ServerInstance, them, std::string("Killed (") + reason + ")");
                                                        break;
                                                }
                                                case DNSBLConfEntry::I_KLINE:
                                                {
                                                        ServerInstance->AddKLine(ConfEntry->duration, ServerInstance->Config->ServerName, reason, std::string("*@") + them->GetIPString());
+                                                       FOREACH_MOD(I_OnAddKLine,OnAddKLine(ServerInstance->Duration(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(ServerInstance->Duration(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(ServerInstance->Duration(ConfEntry->duration), NULL, reason, them->GetIPString()));
                                                        break;
                                                }
                                                case DNSBLConfEntry::I_UNKNOWN:
@@ -136,19 +140,8 @@ class DNSBLResolver : public Resolver
 
        virtual void OnError(ResolverError e, const std::string &errormessage)
        {
-               /*
-               this just means they don't appear in the respective dnsbl
-               if ((them) && (them == ServerInstance->SE->GetRef(theirfd)))
-               {
-               }
-               */
-               /* Check the user still exists */
-               if ((them) && (them == ServerInstance->SE->GetRef(theirfd)))
-               {
-                       ServerInstance->Log(DEBUG, "m_dnsbl:  %s got an error while resolving for dnsbl %s", them->nick, ConfEntry->name.c_str());
-               }
        }
+
        virtual ~DNSBLResolver()
        {
        }
@@ -158,7 +151,7 @@ class ModuleDNSBL : public Module
 {
  private:
        std::vector<DNSBLConfEntry *> DNSBLConfEntries;
-       
+
        /*
         *      Convert a string to EnumBanaction
         */
@@ -172,7 +165,7 @@ class ModuleDNSBL : public Module
                        return DNSBLConfEntry::I_ZLINE;
                if(action.compare("GLINE")==0)
                        return DNSBLConfEntry::I_GLINE;
-       
+
                return DNSBLConfEntry::I_UNKNOWN;
        }
  public:
@@ -180,14 +173,15 @@ class ModuleDNSBL : public Module
        {
                ReadConf();
        }
-       
+
        virtual ~ModuleDNSBL()
        {
+               ClearEntries();
        }
-       
+
        virtual Version GetVersion()
        {
-               return Version(2, 0, 0, 0, 0, API_VERSION);
+               return Version(2, 0, 0, 1, VF_VENDOR, API_VERSION);
        }
 
        void Implements(char* List)
@@ -195,13 +189,24 @@ class ModuleDNSBL : public Module
                List[I_OnRehash] = List[I_OnUserRegister] = 1;
        }
 
-       /*
-        * Fill our conf vector with data
-        */     
+       /** Clear entries and free the mem it was using
+        */
+       void ClearEntries()
+       {
+               std::vector<DNSBLConfEntry *>::iterator i;
+               while ((i = DNSBLConfEntries.begin()) != DNSBLConfEntries.end())
+               {
+                       DNSBLConfEntries.erase(i);
+                       delete *i;
+               }
+       }
+
+       /** Fill our conf vector with data
+        */
        virtual void ReadConf()
        {
                ConfigReader *MyConf = new ConfigReader(ServerInstance);
-               DNSBLConfEntries.clear();
+               ClearEntries();
 
                for (int i=0; i< MyConf->Enumerate("dnsbl"); i++)
                {
@@ -241,8 +246,7 @@ class ModuleDNSBL : public Module
 
                                /* add it, all is ok */
                                DNSBLConfEntries.push_back(e);
-                               delete MyConf;
-                               return;
+                               continue;
                        }
 
                        /* delete and drop it, error somewhere */
@@ -251,9 +255,8 @@ class ModuleDNSBL : public Module
 
                delete MyConf;
        }
-       
-       
-       virtual void OnRehash(const std::string &parameter)
+
+       virtual void OnRehash(userrec* user, const std::string &parameter)
        {
                ReadConf();
        }
@@ -270,12 +273,29 @@ 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;
@@ -285,41 +305,16 @@ class ModuleDNSBL : public Module
                        snprintf(reversedipbuf, 128, "%d.%d.%d.%d", d, c, b, a);
                        reversedip = std::string(reversedipbuf);
 
-/*
-       this is satmd's old code
-                       std::string reversedip;
-                       std::string userip = user->GetIPString();
-                       std::string tempip = userip;
-
-                       // reversedip will created in there
-                       while (tempip.length()>0)
-                       {
-                               unsigned int lastdot=tempip.rfind(".");
-                               if (lastdot == std::string::npos)
-                               {
-                                       reversedip+=tempip;
-                                       tempip.clear();
-                               }
-                               else
-                               {
-                                       reversedip += tempip.substr(lastdot+1,tempip.length()-lastdot+1);
-                                       reversedip += ".";
-                                       tempip.resize(lastdot);
-                               }
-                       }
-*/
-               
                        // For each DNSBL, we will run through this lookup
                        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;
-
-                               ServerInstance->Log(DEBUG, "m_dnsbl: sending %s for resolution", hostname.c_str());
+                               std::string hostname = reversedip + "." + (*i)->domain;
 
                                /* now we'd need to fire off lookups for `hostname'. */
-                               DNSBLResolver *r = new DNSBLResolver(this, ServerInstance, hostname, user, user->GetFd(), *i);
-                               ServerInstance->AddResolver(r);
+                               bool cached;
+                               DNSBLResolver *r = new DNSBLResolver(this, ServerInstance, hostname, user, user->GetFd(), *i, cached);
+                               ServerInstance->AddResolver(r, cached);
                        }
                }
 
@@ -336,16 +331,16 @@ class ModuleDNSBLFactory : public ModuleFactory
        ModuleDNSBLFactory()
        {
        }
-       
+
        ~ModuleDNSBLFactory()
        {
        }
-       
+
        virtual Module *CreateModule(InspIRCd *Me)
        {
                return new ModuleDNSBL(Me);
        }
-       
+
 };
 
 
@@ -353,4 +348,3 @@ extern "C" void * init_module( void )
 {
        return new ModuleDNSBLFactory;
 }
-