]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_connectban.cpp
Fix incorrect forward-port of patch
[user/henk/code/inspircd.git] / src / modules / m_connectban.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
6  * See: http://wiki.inspircd.org/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #include "inspircd.h"
15 #include "xline.h"
16
17 /* $ModDesc: Throttles the connections of any users who try connect flood */
18
19 class ModuleConnectBan : public Module
20 {
21  private:
22         clonemap connects;
23         unsigned int threshold;
24         unsigned int banduration;
25         unsigned int ipv4_cidr;
26         unsigned int ipv6_cidr;
27  public:
28         ModuleConnectBan()      {
29                 Implementation eventlist[] = { I_OnUserConnect, I_OnGarbageCollect, I_OnRehash };
30                 ServerInstance->Modules->Attach(eventlist, this, 3);
31                 OnRehash(NULL);
32         }
33
34         virtual ~ModuleConnectBan()
35         {
36         }
37
38         virtual Version GetVersion()
39         {
40                 return Version("Throttles the connections of any users who try connect flood", VF_VENDOR);
41         }
42
43         virtual void OnRehash(User* user)
44         {
45                 ConfigReader Conf;
46                 std::string duration;
47
48                 ipv4_cidr = Conf.ReadInteger("connectban", "ipv4cidr", 0, true);
49                 if (ipv4_cidr == 0)
50                         ipv4_cidr = 32;
51
52                 ipv6_cidr = Conf.ReadInteger("connectban", "ipv6cidr", 0, true);
53                 if (ipv6_cidr == 0)
54                         ipv6_cidr = 128;
55
56                 threshold = Conf.ReadInteger("connectban", "threshold", 0, true);
57
58                 if (threshold == 0)
59                         threshold = 10;
60
61                 duration = Conf.ReadValue("connectban", "duration", 0, true);
62
63                 if (duration.empty())
64                         duration = "10m";
65
66                 banduration = ServerInstance->Duration(duration);
67         }
68
69         virtual void OnUserConnect(LocalUser *u)
70         {
71                 int range = 32;
72                 clonemap::iterator i;
73
74                 switch (u->client_sa.sa.sa_family)
75                 {
76                         case AF_INET6:
77                                 range = ipv6_cidr;
78                         break;
79                         case AF_INET:
80                                 range = ipv4_cidr;
81                         break;
82                 }
83
84                 irc::sockets::cidr_mask mask(u->client_sa, range);
85                 i = connects.find(mask);
86
87                 if (i != connects.end())
88                 {
89                         i->second++;
90
91                         if (i->second >= threshold)
92                         {
93                                 // Create zline for set duration.
94                                 ZLine* zl = new ZLine(ServerInstance->Time(), banduration, ServerInstance->Config->ServerName, "Your IP range has been attempting to connect too many times in too short a duration. Wait a while, and you will be able to connect.", mask.str());
95                                 if (ServerInstance->XLines->AddLine(zl,NULL))
96                                         ServerInstance->XLines->ApplyLines();
97                                 else
98                                         delete zl;
99
100                                 ServerInstance->SNO->WriteGlobalSno('x',"Module m_connectban added Z:line on *@%s to expire on %s: Connect flooding", 
101                                         mask.str().c_str(), ServerInstance->TimeString(zl->expiry).c_str());
102                                 ServerInstance->SNO->WriteGlobalSno('a', "Connect flooding from IP range %s (%d)", mask.str().c_str(), threshold);
103                                 connects.erase(i);
104                         }
105                 }
106                 else
107                 {
108                         connects[mask] = 1;
109                 }
110         }
111
112         virtual void OnGarbageCollect()
113         {
114                 ServerInstance->Logs->Log("m_connectban",DEBUG, "Clearing map.");
115                 connects.clear();
116         }
117 };
118
119 MODULE_INIT(ModuleConnectBan)