From 0844f7243fd8ecd3570d8f2d96fba27c9beda32f Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Fri, 12 Jul 2024 10:58:25 +0200 Subject: [PATCH] Add ASN as extended server ban, mask item, secgroup. Eg: GLINE ~asn:64496 0 Bye! This also automatically adds it as a security group and mask item: ban user { mask { asn 64496; } reason "Testing ASN ban"; } And yeah, it is a normal extban too (in +b and +I). Users usually don't know the AS Number of other users, though, unless you change the default configuration (at the cost of privacy). Updated release notes a bit... more will follow. --- doc/RELEASE-NOTES.md | 14 ++++ doc/conf/modules.default.conf | 1 + src/modules/extbans/Makefile.in | 2 +- src/modules/extbans/asn.c | 143 ++++++++++++++++++++++++++++++++ src/user.c | 1 + 5 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 src/modules/extbans/asn.c diff --git a/doc/RELEASE-NOTES.md b/doc/RELEASE-NOTES.md index 0847e7523..46650ea0f 100644 --- a/doc/RELEASE-NOTES.md +++ b/doc/RELEASE-NOTES.md @@ -11,6 +11,20 @@ in progress and may not always be a stable version. [Mask item](https://www.unrealircd.org/docs/Mask_item). This means you can use all the power of mask items and security groups and multiple matching criteria. +* The GeoIP module now contains info about + [Autonomous system numbers](https://en.wikipedia.org/wiki/Autonomous_system_(Internet)) + and this is exposed in: + * [Extended server ban](https://www.unrealircd.org/docs/Extended_server_bans) + so you can do things like `GLINE ~asn:64496 0 This ISP is banned`. + * In security groups and Mask items so you can do like: + ``` + ban user { + mask { asn { 64496; 64497; 64498; } } + reason "Your ISP is banned."; + } + ``` + * It is shown in the user connecting notice, WHOIS (for IRCOps) and + expanded in JSON data such as JSON Logging and JSON-RPC. * New option [set::tls::certificate-expiry-notification](https://www.unrealircd.org/docs/Set_block#set::tls::certificate-expiry-notification): since UnrealIRCd 5.0.8 we warn if a SSL/TLS certificate is (nearly) expired. This new option allows turning it off, it is (still) on by default. diff --git a/doc/conf/modules.default.conf b/doc/conf/modules.default.conf index 952b7bde9..3dd81306a 100644 --- a/doc/conf/modules.default.conf +++ b/doc/conf/modules.default.conf @@ -221,6 +221,7 @@ loadmodule "extbans/securitygroup"; /* +b ~security-group (old ~G mode, security loadmodule "extbans/country"; /* +b ~country (country/geoip) */ loadmodule "extbans/msgbypass"; /* +e ~msgbypass (old ~m mode, bypass message restrictions) */ loadmodule "extbans/flood"; /* +e ~flood (flood exemption for chanmode +f/+F) */ +loadmodule "extbans/asn"; /* +b ~asn (country/asn) */ /*** IRCv3 extensions ***/ diff --git a/src/modules/extbans/Makefile.in b/src/modules/extbans/Makefile.in index 827cba143..c73ab6bf3 100644 --- a/src/modules/extbans/Makefile.in +++ b/src/modules/extbans/Makefile.in @@ -35,7 +35,7 @@ R_MODULES= \ join.so quiet.so nickchange.so inchannel.so realname.so \ account.so operclass.so certfp.so textban.so msgbypass.so \ timedban.so partmsg.so securitygroup.so \ - country.so flood.so + country.so asn.so flood.so MODULES=$(R_MODULES) MODULEFLAGS=@MODULEFLAGS@ diff --git a/src/modules/extbans/asn.c b/src/modules/extbans/asn.c new file mode 100644 index 000000000..e91fd068d --- /dev/null +++ b/src/modules/extbans/asn.c @@ -0,0 +1,143 @@ +/* + * Extended ban to ban/exempt by asn/geoip info (+b ~asn:64496) + * (C) Copyright 2024 The UnrealIRCd Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "unrealircd.h" + +ModuleHeader MOD_HEADER += { + "extbans/asn", + "6.0", + "ExtBan ~asn - Ban/exempt by ASN (geoip)", + "UnrealIRCd Team", + "unrealircd-6", +}; + +/* Forward declarations */ +int extban_asn_is_ok(BanContext *b); +const char *extban_asn_conv_param(BanContext *b, Extban *extban); +int extban_asn_is_banned(BanContext *b); + +Extban *register_asn_extban(ModuleInfo *modinfo) +{ + ExtbanInfo req; + + memset(&req, 0, sizeof(req)); + req.letter = 'A'; + req.name = "asn"; + req.is_ok = extban_asn_is_ok; + req.conv_param = extban_asn_conv_param; + req.is_banned = extban_asn_is_banned; + req.is_banned_events = BANCHK_ALL|BANCHK_TKL; + req.options = EXTBOPT_INVEX|EXTBOPT_TKL; + return ExtbanAdd(modinfo->handle, req); +} + +/* Called upon module test */ +MOD_TEST() +{ + if (!register_asn_extban(modinfo)) + { + config_error("could not register extended ban type"); + return MOD_FAILED; + } + + return MOD_SUCCESS; +} + +/* Called upon module init */ +MOD_INIT() +{ + if (!register_asn_extban(modinfo)) + { + config_error("could not register extended ban type"); + return MOD_FAILED; + } + + MARK_AS_OFFICIAL_MODULE(modinfo); + + return MOD_SUCCESS; +} + +/* Called upon module load */ +MOD_LOAD() +{ + return MOD_SUCCESS; +} + +/* Called upon unload */ +MOD_UNLOAD() +{ + return MOD_SUCCESS; +} + +int extban_asn_usage(Client *client) +{ + sendnotice(client, "ERROR: ExtBan ~asn expects the AS number (all digits). " + "For example: +b ~asn:64496"); + return EX_DENY; +} + +int extban_asn_is_ok(BanContext *b) +{ + if (b->is_ok_check == EXCHK_PARAM) + { + const char *p; + + if (!strcmp(b->banstr, "*")) + return EX_ALLOW; + + if (!*b->banstr) + return extban_asn_usage(b->client); + + for (p = b->banstr; *p; p++) + if (!isdigit(*p)) + return extban_asn_usage(b->client); + + return EX_ALLOW; + } + return EX_ALLOW; +} + +/* Obtain targeted asn from the ban string */ +const char *extban_asn_conv_param(BanContext *b, Extban *extban) +{ + static char retbuf[32]; + unsigned int asn; + char *p=NULL; + + if (!isdigit(b->banstr[0])) + return NULL; + + asn = strtoul(b->banstr, &p, 10); + if (!BadPtr(p)) + return NULL; /* contains invalid characters */ + + snprintf(retbuf, sizeof(retbuf), "%u", asn); + return retbuf; +} + +int extban_asn_is_banned(BanContext *b) +{ + unsigned int banned_asn = strtoul(b->banstr, NULL, 10); + GeoIPResult *geo = geoip_client(b->client); + + if (geo) + return banned_asn == geo->asn; + + return banned_asn == 0; /* ASN 0 is for unknown */ +} diff --git a/src/user.c b/src/user.c index b8d5203a2..0af742ad7 100644 --- a/src/user.c +++ b/src/user.c @@ -961,6 +961,7 @@ void free_geoip_result(GeoIPResult *r) return; safe_free(r->country_code); safe_free(r->country_name); + safe_free(r->asname); safe_free(r); }