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:
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user