summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2018-04-06 17:53:14 +0100
committerPeter Powell <petpow@saberuk.com>2018-04-06 18:05:15 +0100
commitd04db003df83ddfdc2b5b9ae0e360335d88ae769 (patch)
treef1ddd01cbfbb5690b710ec6f67164dcbfe4f5acf
parent9ea8191a050aa2262289a11edde115de1bcb0d71 (diff)
Implement support for banning users from channels by country code.
-rw-r--r--docs/conf/modules.conf.example4
-rw-r--r--src/modules/extra/m_geoip.cpp57
2 files changed, 53 insertions, 8 deletions
diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example
index f8cb7ddfa..f46526dfc 100644
--- a/docs/conf/modules.conf.example
+++ b/docs/conf/modules.conf.example
@@ -833,6 +833,10 @@
#
# <connect deny="*" geoip="TR,RU">
#
+# If enabled you can also ban people from channnels by country code
+# using the G: extban (e.g. /mode #channel +b G:US).
+# <geoip extban="yes">
+#
# 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
diff --git a/src/modules/extra/m_geoip.cpp b/src/modules/extra/m_geoip.cpp
index 1f77afa76..c03800f43 100644
--- a/src/modules/extra/m_geoip.cpp
+++ b/src/modules/extra/m_geoip.cpp
@@ -41,25 +41,33 @@
# pragma comment(lib, "GeoIP.lib")
#endif
-class ModuleGeoIP : public Module
+enum
{
- LocalStringExt ext;
+ // InspIRCd-specific.
+ RPL_WHOISCOUNTRY = 344
+};
+
+class ModuleGeoIP : public Module, public Whois::EventListener
+{
+ StringExtItem ext;
+ bool extban;
GeoIP* gi;
- std::string* SetExt(LocalUser* user)
+ std::string* SetExt(User* user)
{
const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString().c_str());
if (!c)
c = "UNK";
- std::string* cc = new std::string(c);
- ext.set(user, cc);
- return cc;
+ ext.set(user, c);
+ return ext.get(user);
}
public:
ModuleGeoIP()
- : ext("geoip_cc", ExtensionItem::EXT_USER, this)
+ : Whois::EventListener(this)
+ , ext("geoip_cc", ExtensionItem::EXT_USER, this)
+ , extban(true)
, gi(NULL)
{
}
@@ -87,9 +95,29 @@ class ModuleGeoIP : public Module
GeoIP_delete(gi);
}
+ void ReadConfig(ConfigStatus&)
+ {
+ ConfigTag* tag = ServerInstance->Config->ConfValue("geoip");
+ extban = tag->getBool("extban");
+ }
+
Version GetVersion() CXX11_OVERRIDE
{
- return Version("Provides a way to assign users to connect classes by country using GeoIP lookup", VF_VENDOR);
+ return Version("Provides a way to assign users to connect classes by country using GeoIP lookup", VF_OPTCOMMON|VF_VENDOR);
+ }
+
+ ModResult OnCheckBan(User *user, Channel *c, const std::string& mask)
+ {
+ if ((mask.length() > 2) && (mask[0] == 'G') && (mask[1] == ':'))
+ {
+ std::string* cc = ext.get(user);
+ if (!cc)
+ cc = SetExt(user);
+
+ if (InspIRCd::Match(*cc, mask.substr(2)))
+ return MOD_RES_DENY;
+ }
+ return MOD_RES_PASSTHRU;
}
ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass) CXX11_OVERRIDE
@@ -109,6 +137,19 @@ class ModuleGeoIP : public Module
return MOD_RES_DENY;
}
+ void OnWhois(Whois::Context& whois) CXX11_OVERRIDE
+ {
+ // If the extban is disabled we don't expose users location.
+ if (!extban)
+ return;
+
+ std::string* cc = ext.get(whois.GetTarget());
+ if (!cc)
+ cc = SetExt(whois.GetTarget());
+
+ whois.SendLine(RPL_WHOISCOUNTRY, *cc, "is located in this country");
+ }
+
ModResult OnStats(Stats::Context& stats) CXX11_OVERRIDE
{
if (stats.GetSymbol() != 'G')