diff options
-rw-r--r-- | docs/modules.conf.example | 25 | ||||
-rw-r--r-- | src/modules/extra/m_geoip.cpp | 68 |
2 files changed, 41 insertions, 52 deletions
diff --git a/docs/modules.conf.example b/docs/modules.conf.example index 532073a18..cc120af61 100644 --- a/docs/modules.conf.example +++ b/docs/modules.conf.example @@ -782,7 +782,7 @@ #<module name="m_gecosban.so"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# -# GeoIP module: Allows the server admin to ban users by country code. +# GeoIP module: Allows the server admin to match users by country code. # This modules is in extras. Re-run configure with: ./configure --enable-extras=m_geoip.cpp # and run make install, then uncomment this module to enable it. # This module requires GeoIP to be installed on your system, @@ -790,18 +790,17 @@ # or check the InspIRCd wiki page for this module. #<module name="m_geoip.so"> # -#-#-#-#-#-#-#-#-#-#-#-# GEOIP CONFIGURATION #-#-#-#-#-#-#-#-#-#-#-#-# -# # -# <geoip banunknown="false"> # -# # -# Set this value to true or yes to block unknown IP ranges which are # -# not in the database (usually LAN addresses, localhost, etc) # -# # -# <geoban country="TR" reason="This country not permitted"> # -# # -# Use one or more of these tags to ban countries by country code. # -# The country code must be in capitals and should be an ISO country # -# code such as TR, GB, or US. # +# The actual allow/ban actions are done by connect classes, not by the +# GeoIP module. An example connect class to ban people from russia or +# turkey: +# +# <connect deny="*" geoip="TR,RU"> +# +# The country code must be in capitals and should be an ISO country +# code such as TR, GB, or US. Unknown IPs (localhost, LAN IPs, etc) +# will be assigned the country code "UNK". Since connect classes are +# matched from top down, your deny classes must be above your allow +# classes for them to match. #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Globops module: gives /GLOBOPS and SNOMASK +g diff --git a/src/modules/extra/m_geoip.cpp b/src/modules/extra/m_geoip.cpp index 4632da22b..cdd269003 100644 --- a/src/modules/extra/m_geoip.cpp +++ b/src/modules/extra/m_geoip.cpp @@ -21,62 +21,52 @@ class ModuleGeoIP : public Module { - GeoIP * gi; - - bool banunknown; - - std::map<std::string, std::string> GeoBans; - + LocalStringExt ext; + GeoIP* gi; public: - ModuleGeoIP() { - OnRehash(NULL); - Implementation eventlist[] = { I_OnRehash, I_OnUserRegister }; - ServerInstance->Modules->Attach(eventlist, this, 2); - + ModuleGeoIP() : ext("geoip_cc", this) + { gi = GeoIP_new(GEOIP_STANDARD); } - virtual ~ModuleGeoIP() + void init() { + ServerInstance->Modules->AddService(ext); + Implementation eventlist[] = { I_OnSetConnectClass }; + ServerInstance->Modules->Attach(eventlist, this, 1); } - virtual Version GetVersion() + ~ModuleGeoIP() { - return Version("Provides a way to restrict users by country using GeoIP lookup", VF_VENDOR); + GeoIP_delete(gi); } - virtual void OnRehash(User* user) + Version GetVersion() { - GeoBans.clear(); - - ConfigReader conf; - - banunknown = conf.ReadFlag("geoip", "banunknown", 0); - - for (int i = 0; i < conf.Enumerate("geoban"); ++i) - { - std::string countrycode = conf.ReadValue("geoban", "country", i); - std::string reason = conf.ReadValue("geoban", "reason", i); - GeoBans[countrycode] = reason; - } + return Version("Provides a way to assign users to connect classes by country using GeoIP lookup", VF_VENDOR); } - virtual ModResult OnUserRegister(LocalUser* user) + ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass) { - const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString()); - if (c) - { - std::map<std::string, std::string>::iterator x = GeoBans.find(c); - if (x != GeoBans.end()) - ServerInstance->Users->QuitUser(user, x->second); - } - else + std::string* cc = ext.get(user); + if (!cc) { - if (banunknown) - ServerInstance->Users->QuitUser(user, "Could not identify your country of origin. Access denied."); + const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString()); + if (!c) + c = "UNK"; + cc = new std::string(c); + ext.set(user, cc); } - return MOD_RES_PASSTHRU; + std::string geoip = myclass->config->getString("geoip"); + if (geoip.empty()) + return MOD_RES_PASSTHRU; + irc::commasepstream list(geoip); + std::string country; + while (list.GetToken(country)) + if (country == *cc) + return MOD_RES_PASSTHRU; + return MOD_RES_DENY; } }; |