]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_dnsbl.cpp
Fix mistakenly using Clang instead of GCC on older FreeBSD versions.
[user/henk/code/inspircd.git] / src / modules / m_dnsbl.cpp
index 2160b02dc68fcbd51a47d14b126b3ef582f74f0b..d4101686a03c1daaba9115da2a8244e2898838d0 100644 (file)
 #include "inspircd.h"
 #include "xline.h"
 
-#ifndef WINDOWS
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif
-
 /* $ModDesc: Provides handling of DNS blacklists */
 
 /* Class holding data for a single entry */
-class DNSBLConfEntry
+class DNSBLConfEntry : public refcountbase
 {
        public:
                enum EnumBanaction { I_UNKNOWN, I_KILL, I_ZLINE, I_KLINE, I_GLINE, I_MARK };
@@ -58,11 +51,11 @@ class DNSBLResolver : public Resolver
        std::string theiruid;
        LocalStringExt& nameExt;
        LocalIntExt& countExt;
-       DNSBLConfEntry *ConfEntry;
+       reference<DNSBLConfEntry> ConfEntry;
 
  public:
 
-       DNSBLResolver(Module *me, LocalStringExt& match, LocalIntExt& ctr, const std::string &hostname, LocalUser* u, DNSBLConfEntry *conf, bool &cached)
+       DNSBLResolver(Module *me, LocalStringExt& match, LocalIntExt& ctr, const std::string &hostname, LocalUser* u, reference<DNSBLConfEntry> conf, bool &cached)
                : Resolver(hostname, DNS_QUERY_A, cached, me), theiruid(u->uuid), nameExt(match), countExt(ctr), ConfEntry(conf)
        {
        }
@@ -116,7 +109,7 @@ class DNSBLResolver : public Resolver
                                        {
                                                case DNSBLConfEntry::I_KILL:
                                                {
-                                                       ServerInstance->Users->QuitUser(them, std::string("Killed (") + reason + ")");
+                                                       ServerInstance->Users->QuitUser(them, "Killed (" + reason + ")");
                                                        break;
                                                }
                                                case DNSBLConfEntry::I_MARK:
@@ -142,12 +135,16 @@ class DNSBLResolver : public Resolver
                                                                        "*", them->GetIPString());
                                                        if (ServerInstance->XLines->AddLine(kl,NULL))
                                                        {
-                                                               ServerInstance->SNO->WriteGlobalSno('x',"K:line added due to DNSBL match on *@%s to expire on %s: %s", 
-                                                                       them->GetIPString(), ServerInstance->TimeString(kl->expiry).c_str(), reason.c_str());
+                                                               std::string timestr = ServerInstance->TimeString(kl->expiry);
+                                                               ServerInstance->SNO->WriteGlobalSno('x',"K:line added due to DNSBL match on *@%s to expire on %s: %s",
+                                                                       them->GetIPString(), timestr.c_str(), reason.c_str());
                                                                ServerInstance->XLines->ApplyLines();
                                                        }
                                                        else
+                                                       {
                                                                delete kl;
+                                                               return;
+                                                       }
                                                        break;
                                                }
                                                case DNSBLConfEntry::I_GLINE:
@@ -156,12 +153,16 @@ class DNSBLResolver : public Resolver
                                                                        "*", them->GetIPString());
                                                        if (ServerInstance->XLines->AddLine(gl,NULL))
                                                        {
-                                                               ServerInstance->SNO->WriteGlobalSno('x',"G:line added due to DNSBL match on *@%s to expire on %s: %s", 
-                                                                       them->GetIPString(), ServerInstance->TimeString(gl->expiry).c_str(), reason.c_str());
+                                                               std::string timestr = ServerInstance->TimeString(gl->expiry);
+                                                               ServerInstance->SNO->WriteGlobalSno('x',"G:line added due to DNSBL match on *@%s to expire on %s: %s",
+                                                                       them->GetIPString(), timestr.c_str(), reason.c_str());
                                                                ServerInstance->XLines->ApplyLines();
                                                        }
                                                        else
+                                                       {
                                                                delete gl;
+                                                               return;
+                                                       }
                                                        break;
                                                }
                                                case DNSBLConfEntry::I_ZLINE:
@@ -170,12 +171,16 @@ class DNSBLResolver : public Resolver
                                                                        them->GetIPString());
                                                        if (ServerInstance->XLines->AddLine(zl,NULL))
                                                        {
-                                                               ServerInstance->SNO->WriteGlobalSno('x',"Z:line added due to DNSBL match on *@%s to expire on %s: %s", 
-                                                                       them->GetIPString(), ServerInstance->TimeString(zl->expiry).c_str(), reason.c_str());
+                                                               std::string timestr = ServerInstance->TimeString(zl->expiry);
+                                                               ServerInstance->SNO->WriteGlobalSno('x',"Z:line added due to DNSBL match on *@%s to expire on %s: %s",
+                                                                       them->GetIPString(), timestr.c_str(), reason.c_str());
                                                                ServerInstance->XLines->ApplyLines();
                                                        }
                                                        else
+                                                       {
                                                                delete zl;
+                                                               return;
+                                                       }
                                                        break;
                                                }
                                                case DNSBLConfEntry::I_UNKNOWN:
@@ -185,7 +190,7 @@ class DNSBLResolver : public Resolver
                                                break;
                                        }
 
-                                       ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s detected as being on a DNS blacklist (%s) with result %d", them->GetFullRealHost().c_str(), ConfEntry->domain.c_str(), (ConfEntry->type==DNSBLConfEntry::A_BITMASK) ? bitmask : record);
+                                       ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s%s detected as being on a DNS blacklist (%s) with result %d", them->nick.empty() ? "<unknown>" : "", them->GetFullRealHost().c_str(), ConfEntry->domain.c_str(), (ConfEntry->type==DNSBLConfEntry::A_BITMASK) ? bitmask : record);
                                }
                                else
                                        ConfEntry->stats_misses++;
@@ -213,7 +218,7 @@ class DNSBLResolver : public Resolver
 
 class ModuleDNSBL : public Module
 {
-       std::vector<DNSBLConfEntry *> DNSBLConfEntries;
+       std::vector<reference<DNSBLConfEntry> > DNSBLConfEntries;
        LocalStringExt nameExt;
        LocalIntExt countExt;
 
@@ -243,13 +248,8 @@ class ModuleDNSBL : public Module
                ReadConf();
                ServerInstance->Modules->AddService(nameExt);
                ServerInstance->Modules->AddService(countExt);
-               Implementation eventlist[] = { I_OnRehash, I_OnUserInit, I_OnStats, I_OnSetConnectClass, I_OnCheckReady };
-               ServerInstance->Modules->Attach(eventlist, this, 5);
-       }
-
-       virtual ~ModuleDNSBL()
-       {
-               ClearEntries();
+               Implementation eventlist[] = { I_OnRehash, I_OnSetUserIP, I_OnStats, I_OnSetConnectClass, I_OnCheckReady };
+               ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
        }
 
        Version GetVersion()
@@ -257,26 +257,17 @@ class ModuleDNSBL : public Module
                return Version("Provides handling of DNS blacklists", VF_VENDOR);
        }
 
-       /** Clear entries and free the mem it was using
-        */
-       void ClearEntries()
-       {
-               for (std::vector<DNSBLConfEntry *>::iterator i = DNSBLConfEntries.begin(); i != DNSBLConfEntries.end(); i++)
-                       delete *i;
-               DNSBLConfEntries.clear();
-       }
-
        /** Fill our conf vector with data
         */
        void ReadConf()
        {
-               ClearEntries();
+               DNSBLConfEntries.clear();
 
                ConfigTagList dnsbls = ServerInstance->Config->ConfTags("dnsbl");
                for(ConfigIter i = dnsbls.first; i != dnsbls.second; ++i)
                {
                        ConfigTag* tag = i->second;
-                       DNSBLConfEntry *e = new DNSBLConfEntry();
+                       reference<DNSBLConfEntry> e = new DNSBLConfEntry();
 
                        e->name = tag->getString("name");
                        e->ident = tag->getString("ident");
@@ -307,39 +298,41 @@ class ModuleDNSBL : public Module
                        /* yeah, logic here is a little messy */
                        if ((e->bitmask <= 0) && (DNSBLConfEntry::A_BITMASK == e->type))
                        {
-                               ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): invalid bitmask",tag->getTagLocation().c_str());
+                               std::string location = tag->getTagLocation();
+                               ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): invalid bitmask", location.c_str());
                        }
                        else if (e->name.empty())
                        {
-                               ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): Invalid name",tag->getTagLocation().c_str());
+                               std::string location = tag->getTagLocation();
+                               ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): Invalid name", location.c_str());
                        }
                        else if (e->domain.empty())
                        {
-                               ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): Invalid domain",tag->getTagLocation().c_str());
+                               std::string location = tag->getTagLocation();
+                               ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): Invalid domain", location.c_str());
                        }
                        else if (e->banaction == DNSBLConfEntry::I_UNKNOWN)
                        {
-                               ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): Invalid banaction",tag->getTagLocation().c_str());
+                               std::string location = tag->getTagLocation();
+                               ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): Invalid banaction", location.c_str());
                        }
                        else if (e->duration <= 0)
                        {
-                               ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): Invalid duration",tag->getTagLocation().c_str());
+                               std::string location = tag->getTagLocation();
+                               ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): Invalid duration", location.c_str());
                        }
                        else
                        {
                                if (e->reason.empty())
                                {
-                                       ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): empty reason, using defaults",tag->getTagLocation().c_str());
+                                       std::string location = tag->getTagLocation();
+                                       ServerInstance->SNO->WriteGlobalSno('a', "DNSBL(%s): empty reason, using defaults", location.c_str());
                                        e->reason = "Your IP has been blacklisted.";
                                }
 
                                /* add it, all is ok */
                                DNSBLConfEntries.push_back(e);
-                               continue;
                        }
-
-                       /* delete and drop it, error somewhere */
-                       delete e;
                }
        }
 
@@ -348,18 +341,23 @@ class ModuleDNSBL : public Module
                ReadConf();
        }
 
-       void OnUserInit(LocalUser* user)
+       void OnSetUserIP(LocalUser* user)
        {
-               if (user->exempt)
+               if ((user->exempt) || (user->client_sa.sa.sa_family != AF_INET))
                        return;
 
+               if (user->MyClass)
+               {
+                       if (!user->MyClass->config->getBool("usednsbl", true))
+                               return;
+               }
+               else
+                       ServerInstance->Logs->Log("m_dnsbl", DEBUG, "User has no connect class in OnSetUserIP");
+
                unsigned char a, b, c, d;
                char reversedipbuf[128];
                std::string reversedip;
 
-               if (user->client_sa.sa.sa_family != AF_INET)
-                       return;
-
                d = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 24) & 0xFF;
                c = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 16) & 0xFF;
                b = (unsigned char) (user->client_sa.in4.sin_addr.s_addr >> 8) & 0xFF;
@@ -368,6 +366,8 @@ class ModuleDNSBL : public Module
                snprintf(reversedipbuf, 128, "%d.%d.%d.%d", d, c, b, a);
                reversedip = std::string(reversedipbuf);
 
+               countExt.set(user, DNSBLConfEntries.size());
+
                // For each DNSBL, we will run through this lookup
                unsigned int i = 0;
                while (i < DNSBLConfEntries.size())
@@ -379,9 +379,10 @@ class ModuleDNSBL : public Module
                        bool cached;
                        DNSBLResolver *r = new DNSBLResolver(this, nameExt, countExt, hostname, user, DNSBLConfEntries[i], cached);
                        ServerInstance->AddResolver(r, cached);
+                       if (user->quitting)
+                               break;
                        i++;
                }
-               countExt.set(user, i);
        }
 
        ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass)
@@ -410,17 +411,17 @@ class ModuleDNSBL : public Module
 
                unsigned long total_hits = 0, total_misses = 0;
 
-               for (std::vector<DNSBLConfEntry*>::iterator i = DNSBLConfEntries.begin(); i != DNSBLConfEntries.end(); i++)
+               for (std::vector<reference<DNSBLConfEntry> >::const_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.c_str()) + " 304 " + user->nick + " :DNSBLSTATS DNSbl \"" + (*i)->name + "\" had " +
+                       results.push_back(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.c_str()) + " 304 " + user->nick + " :DNSBLSTATS Total hits: " + ConvToStr(total_hits));
-               results.push_back(std::string(ServerInstance->Config->ServerName.c_str()) + " 304 " + user->nick + " :DNSBLSTATS Total misses: " + ConvToStr(total_misses));
+               results.push_back(ServerInstance->Config->ServerName + " 304 " + user->nick + " :DNSBLSTATS Total hits: " + ConvToStr(total_hits));
+               results.push_back(ServerInstance->Config->ServerName + " 304 " + user->nick + " :DNSBLSTATS Total misses: " + ConvToStr(total_misses));
 
                return MOD_RES_PASSTHRU;
        }