From bebeeac0db71ac9df65272172c56d8e8339ca222 Mon Sep 17 00:00:00 2001 From: k4be Date: Thu, 26 Aug 2021 18:08:56 +0200 Subject: [PATCH] geoip_base: add configuration, check all users on load geoip_classic: change config format --- src/modules/geoip_base.c | 94 ++++++++++++++++++++++++++++- src/modules/geoip_classic.c | 116 ++++++++++++++++-------------------- 2 files changed, 141 insertions(+), 69 deletions(-) diff --git a/src/modules/geoip_base.c b/src/modules/geoip_base.c index 7e69e41fc..099d8ab7f 100644 --- a/src/modules/geoip_base.c +++ b/src/modules/geoip_base.c @@ -16,6 +16,11 @@ ModuleHeader MOD_HEADER "unrealircd-6", }; +struct geoip_base_config_s { + int whois_for_anyone; + int check_on_load; +}; + /* Forward declarations */ void geoip_base_free(ModData *m); char *geoip_base_serialize(ModData *m); @@ -24,7 +29,12 @@ int geoip_base_handshake(Client *client); int geoip_base_whois(Client *client, Client *target); int geoip_connect_extinfo(Client *client, NameValuePrioList **list); int geoip_whois(Client *client, Client *target); +int geoip_base_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs); +int geoip_base_configrun(ConfigFile *cf, ConfigEntry *ce, int type); +EVENT(geoip_base_set_existing_users_evt); + ModDataInfo *geoip_md; /* Module Data structure which we acquire */ +struct geoip_base_config_s geoip_base_config; /* We can use GEOIPDATA() and GEOIPDATARAW() for fast access. * People wanting to get this information from outside this module @@ -34,9 +44,68 @@ ModDataInfo *geoip_md; /* Module Data structure which we acquire */ #define GEOIPDATARAW(x) (moddata_client((x), geoip_md).ptr) #define GEOIPDATA(x) ((GeoIPResult *)moddata_client((x), geoip_md).ptr) +int geoip_base_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs) +{ + ConfigEntry *cep; + int errors = 0; + int i; + + if (type != CONFIG_SET) + return 0; + + if (!ce || !ce->name) + return 0; + + if (strcmp(ce->name, "geoip")) + return 0; + + for (cep = ce->items; cep; cep = cep->next) + { + if (!strcmp(cep->name, "whois-for-anyone") || !strcmp(cep->name, "check-on-load")) + { + CheckNull(cep); + continue; + } + config_warn("%s:%i: unknown item geoip::%s", cep->file->filename, cep->line_number, cep->name); + } + + *errs = errors; + return errors ? -1 : 1; +} + +int geoip_base_configrun(ConfigFile *cf, ConfigEntry *ce, int type) +{ + ConfigEntry *cep; + + if (type != CONFIG_SET) + return 0; + + if (!ce || !ce->name) + return 0; + + if (strcmp(ce->name, "geoip")) + return 0; + + for (cep = ce->items; cep; cep = cep->next) + { + if (!strcmp(cep->name, "whois-for-anyone")) + geoip_base_config.whois_for_anyone = config_checkval(cep->value, CFG_YESNO); + if (!strcmp(cep->name, "check-on-load")) + geoip_base_config.check_on_load = config_checkval(cep->value, CFG_YESNO); + } + return 1; +} + +MOD_TEST() +{ + MARK_AS_OFFICIAL_MODULE(modinfo); + HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, geoip_base_configtest); + return MOD_SUCCESS; +} + MOD_INIT() { -ModDataInfo mreq; + ModDataInfo mreq; MARK_AS_OFFICIAL_MODULE(modinfo); @@ -51,6 +120,7 @@ ModDataInfo mreq; if (!geoip_md) abort(); + HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, geoip_base_configrun); HookAdd(modinfo->handle, HOOKTYPE_HANDSHAKE, 0, geoip_base_handshake); HookAdd(modinfo->handle, HOOKTYPE_SERVER_HANDSHAKE_OUT, 0, geoip_base_handshake); HookAdd(modinfo->handle, HOOKTYPE_CONNECT_EXTINFO, 1, geoip_connect_extinfo); /* (prio: near-first) */ @@ -58,11 +128,20 @@ ModDataInfo mreq; HookAdd(modinfo->handle, HOOKTYPE_REMOTE_CONNECT, 0, geoip_base_handshake); /* remote user */ HookAdd(modinfo->handle, HOOKTYPE_WHOIS, 0, geoip_whois); + /* set defaults */ + geoip_base_config.whois_for_anyone = 0; + geoip_base_config.check_on_load = 1; + return MOD_SUCCESS; } MOD_LOAD() { + /* add info for all users upon module loading if enabled, but delay it a bit for data provider module to load */ + if (geoip_base_config.check_on_load) + { + EventAdd(modinfo->handle, "geoip_base_set_existing_users", geoip_base_set_existing_users_evt, NULL, 1000, 1); + } return MOD_SUCCESS; } @@ -83,7 +162,6 @@ int geoip_base_handshake(Client *client) if (GEOIPDATA(client)) { - /* Can this even happen? Ah well.. */ free_geoip_result(GEOIPDATA(client)); GEOIPDATARAW(client) = NULL; } @@ -153,6 +231,15 @@ void geoip_base_unserialize(char *str, ModData *m) m->ptr = res; } +EVENT(geoip_base_set_existing_users_evt){ + Client *client; + list_for_each_entry(client, &client_list, client_node){ + if (!IsUser(client)) + continue; + geoip_base_handshake(client); + } +} + int geoip_connect_extinfo(Client *client, NameValuePrioList **list) { GeoIPResult *geo = GEOIPDATA(client); @@ -165,7 +252,7 @@ int geoip_whois(Client *client, Client *target) { GeoIPResult *geo; - if (!IsOper(client)) + if (!geoip_base_config.whois_for_anyone && !IsOper(client)) return 0; geo = GEOIPDATA(target); @@ -175,3 +262,4 @@ int geoip_whois(Client *client, Client *target) sendnumeric(client, RPL_WHOISCOUNTRY, target->name, geo->country_code, geo->country_name); return 0; } + diff --git a/src/modules/geoip_classic.c b/src/modules/geoip_classic.c index 356bf4560..5a71668c3 100644 --- a/src/modules/geoip_classic.c +++ b/src/modules/geoip_classic.c @@ -39,68 +39,62 @@ GeoIPResult *geoip_lookup_classic(char *ip); int geoip_classic_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs) { - ConfigEntry *cep, *cep2; + ConfigEntry *cep; int errors = 0; int i; - if (type != CONFIG_MAIN) + if (type != CONFIG_SET) return 0; if (!ce || !ce->name) return 0; - if (strcmp(ce->name, "geoip")) + if (strcmp(ce->name, "geoip-classic")) return 0; + geoip_classic_config.have_config = 1; + for (cep = ce->items; cep; cep = cep->next) { - if (strcmp(cep->name, "classic")) - continue; - - geoip_classic_config.have_config = 1; - - for (cep2 = cep->items; cep2; cep2 = cep2->next) + if (!strcmp(cep->name, "ipv4-database")) { - if (!strcmp(cep2->name, "ipv4-database")) + if (geoip_classic_config.have_ipv4_database) { - if (geoip_classic_config.have_ipv4_database) - { - config_error("%s:%i: duplicate item geoip::classic::%s", cep2->file->filename, cep2->line_number, cep2->name); - continue; - } - char *filename = strdup(cep2->value); - convert_to_absolute_path(&filename, PERMDATADIR); - if(access(filename, R_OK)){ - config_error("%s:%i: geoip::classic::%s: cannot open file \"%s\" for reading", cep2->file->filename, cep2->line_number, cep2->name, cep2->value); - errors++; - safe_free(filename); - continue; - } - safe_free(filename); - geoip_classic_config.have_ipv4_database = 1; + config_error("%s:%i: duplicate item set::geoip-classic::%s", cep->file->filename, cep->line_number, cep->name); continue; } - if (!strcmp(cep2->name, "ipv6-database")) - { - if (geoip_classic_config.have_ipv6_database) - { - config_error("%s:%i: duplicate item geoip::classic::%s", cep2->file->filename, cep2->line_number, cep2->name); - continue; - } - char *filename = strdup(cep2->value); - convert_to_absolute_path(&filename, PERMDATADIR); - if(access(filename, R_OK)){ - config_error("%s:%i: geoip::classic::%s: cannot open file \"%s\" for reading", cep2->file->filename, cep2->line_number, cep2->name, cep2->value); - errors++; - safe_free(filename); - continue; - } + char *filename = strdup(cep->value); + convert_to_absolute_path(&filename, PERMDATADIR); + if(access(filename, R_OK)){ + config_error("%s:%i: set::geoip-classic::%s: cannot open file \"%s\" for reading", cep->file->filename, cep->line_number, cep->name, cep->value); + errors++; safe_free(filename); - geoip_classic_config.have_ipv6_database = 1; continue; } - config_warn("%s:%i: unknown item geoip::classic::%s", cep2->file->filename, cep2->line_number, cep2->name); + safe_free(filename); + geoip_classic_config.have_ipv4_database = 1; + continue; } + if (!strcmp(cep->name, "ipv6-database")) + { + if (geoip_classic_config.have_ipv6_database) + { + config_error("%s:%i: duplicate item set::geoip-classic::%s", cep->file->filename, cep->line_number, cep->name); + continue; + } + char *filename = strdup(cep->value); + convert_to_absolute_path(&filename, PERMDATADIR); + if(access(filename, R_OK)){ + config_error("%s:%i: set::geoip-classic::%s: cannot open file \"%s\" for reading", cep->file->filename, cep->line_number, cep->name, cep->value); + errors++; + safe_free(filename); + continue; + } + safe_free(filename); + geoip_classic_config.have_ipv6_database = 1; + continue; + } + config_warn("%s:%i: unknown item set::geoip-classic::%s", cep->file->filename, cep->line_number, cep->name); } *errs = errors; @@ -110,46 +104,35 @@ int geoip_classic_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *err int geoip_classic_configposttest(int *errs) { int errors = 0; - if (geoip_classic_config.have_config) + if (geoip_classic_config.have_config && !geoip_classic_config.have_ipv4_database && !geoip_classic_config.have_ipv6_database) { - if (!geoip_classic_config.have_ipv4_database && !geoip_classic_config.have_ipv6_database) - { - config_error("geoip_classic: no database files specified! Remove geoip::classic to use defaults"); - errors++; - goto end; - } - geoip_classic_free(); + config_error("geoip_classic: no database files specified! Remove set::geoip-classic to use defaults"); + errors++; } -end: + *errs = errors; return errors ? -1 : 1; } int geoip_classic_configrun(ConfigFile *cf, ConfigEntry *ce, int type) { - ConfigEntry *cep, *cep2; + ConfigEntry *cep; - if (type != CONFIG_MAIN) + if (type != CONFIG_SET) return 0; if (!ce || !ce->name) return 0; - if (strcmp(ce->name, "geoip")) + if (strcmp(ce->name, "geoip-classic")) return 0; for (cep = ce->items; cep; cep = cep->next) { - if (strcmp(cep->name, "classic")) - continue; - - for (cep2 = cep->items; cep2; cep2 = cep2->next) - { - if (!strcmp(cep2->name, "ipv4-database")) - safe_strdup(geoip_classic_config.v4_db_file, cep2->value); - if (!strcmp(cep2->name, "ipv6-database")) - safe_strdup(geoip_classic_config.v6_db_file, cep2->value); - } + if (!strcmp(cep->name, "ipv4-database")) + safe_strdup(geoip_classic_config.v4_db_file, cep->value); + if (!strcmp(cep->name, "ipv6-database")) + safe_strdup(geoip_classic_config.v6_db_file, cep->value); } return 1; } @@ -177,6 +160,7 @@ MOD_TEST() MOD_INIT() { MARK_AS_OFFICIAL_MODULE(modinfo); + geoip_classic_free(); HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, geoip_classic_configrun); return MOD_SUCCESS; } @@ -246,6 +230,8 @@ void geoip_classic_free(void) GeoIP_delete(gi4); if (gi6) GeoIP_delete(gi6); + gi4 = NULL; + gi6 = NULL; safe_free(geoip_classic_config.v4_db_file); safe_free(geoip_classic_config.v6_db_file); } @@ -263,14 +249,12 @@ GeoIPResult *geoip_lookup_classic(char *ip) { if (!gi6) return NULL; - country_code = GeoIP_country_code_by_name_v6(gi6, ip); country_name = GeoIP_country_name_by_name_v6(gi6, ip); } else { if (!gi4 || !strcmp(ip, "255.255.255.255")) return NULL; - country_code = GeoIP_country_code_by_name(gi4, ip); country_name = GeoIP_country_name_by_name(gi4, ip); }