1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-09 09:23:13 +02:00

geoip_base: add configuration, check all users on load

geoip_classic: change config format
This commit is contained in:
k4be
2021-08-26 18:08:56 +02:00
parent 52904ded83
commit bebeeac0db
2 changed files with 141 additions and 69 deletions
+91 -3
View File
@@ -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;
}
+50 -66
View File
@@ -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);
}