]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/extra/m_geoip.cpp
Add SHUN as a /filter action
[user/henk/code/inspircd.git] / src / modules / extra / m_geoip.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
6  *
7  * This file is part of InspIRCd.  InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /// $CompilerFlags: find_compiler_flags("geoip" "")
21 /// $LinkerFlags: find_linker_flags("geoip" "-lGeoIP")
22
23 /// $PackageInfo: require_system("centos" "7.0") GeoIP-devel pkgconfig
24 /// $PackageInfo: require_system("darwin") geoip pkg-config
25 /// $PackageInfo: require_system("debian") libgeoip-dev pkg-config
26 /// $PackageInfo: require_system("ubuntu") libgeoip-dev pkg-config
27
28 #include "inspircd.h"
29 #include "xline.h"
30
31 // Fix warnings about the use of commas at end of enumerator lists on C++03.
32 #if defined __clang__
33 # pragma clang diagnostic ignored "-Wc++11-extensions"
34 #elif defined __GNUC__
35 # pragma GCC diagnostic ignored "-pedantic"
36 #endif
37
38 #include <GeoIP.h>
39
40 #ifdef _WIN32
41 # pragma comment(lib, "GeoIP.lib")
42 #endif
43
44 class ModuleGeoIP : public Module
45 {
46         LocalStringExt ext;
47         GeoIP* gi;
48
49         std::string* SetExt(LocalUser* user)
50         {
51                 const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString().c_str());
52                 if (!c)
53                         c = "UNK";
54
55                 std::string* cc = new std::string(c);
56                 ext.set(user, cc);
57                 return cc;
58         }
59
60  public:
61         ModuleGeoIP()
62                 : ext("geoip_cc", ExtensionItem::EXT_USER, this)
63                 , gi(NULL)
64         {
65         }
66
67         void init() CXX11_OVERRIDE
68         {
69                 gi = GeoIP_new(GEOIP_STANDARD);
70                 if (gi == NULL)
71                                 throw ModuleException("Unable to initialize geoip, are you missing GeoIP.dat?");
72
73                 const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers();
74                 for (UserManager::LocalList::const_iterator i = list.begin(); i != list.end(); ++i)
75                 {
76                         LocalUser* user = *i;
77                         if ((user->registered == REG_ALL) && (!ext.get(user)))
78                         {
79                                 SetExt(user);
80                         }
81                 }
82         }
83
84         ~ModuleGeoIP()
85         {
86                 if (gi)
87                         GeoIP_delete(gi);
88         }
89
90         Version GetVersion() CXX11_OVERRIDE
91         {
92                 return Version("Provides a way to assign users to connect classes by country using GeoIP lookup", VF_VENDOR);
93         }
94
95         ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass) CXX11_OVERRIDE
96         {
97                 std::string* cc = ext.get(user);
98                 if (!cc)
99                         cc = SetExt(user);
100
101                 std::string geoip = myclass->config->getString("geoip");
102                 if (geoip.empty())
103                         return MOD_RES_PASSTHRU;
104                 irc::commasepstream list(geoip);
105                 std::string country;
106                 while (list.GetToken(country))
107                         if (country == *cc)
108                                 return MOD_RES_PASSTHRU;
109                 return MOD_RES_DENY;
110         }
111
112         ModResult OnStats(Stats::Context& stats) CXX11_OVERRIDE
113         {
114                 if (stats.GetSymbol() != 'G')
115                         return MOD_RES_PASSTHRU;
116
117                 unsigned int unknown = 0;
118                 std::map<std::string, unsigned int> results;
119
120                 const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers();
121                 for (UserManager::LocalList::const_iterator i = list.begin(); i != list.end(); ++i)
122                 {
123                         std::string* cc = ext.get(*i);
124                         if (cc)
125                                 results[*cc]++;
126                         else
127                                 unknown++;
128                 }
129
130                 for (std::map<std::string, unsigned int>::const_iterator i = results.begin(); i != results.end(); ++i)
131                 {
132                         stats.AddRow(801, "GeoIPSTATS " + i->first + " " + ConvToStr(i->second));
133                 }
134
135                 if (unknown)
136                         stats.AddRow(801, "GeoIPSTATS Unknown " + ConvToStr(unknown));
137
138                 return MOD_RES_DENY;
139         }
140 };
141
142 MODULE_INIT(ModuleGeoIP)