From 2ea75dfbdb307fdf22f1ce99f141339bde53950e Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Tue, 17 Aug 2021 15:24:25 +0200 Subject: [PATCH] Add geoip_base module, which sets "geo_country" if a geo provider module is able to lookup the IP and return a country. Also consistently use geoip_ and GEOIP_ prefixes. --- doc/conf/modules.default.conf | 1 + include/h.h | 2 +- include/modules.h | 2 +- src/modules/Makefile.in | 7 ++- src/modules/geoip_base.c | 92 +++++++++++++++++++++++++++++++++++ src/modules/geoip_classic.c | 12 +++-- src/user.c | 6 +-- 7 files changed, 111 insertions(+), 11 deletions(-) create mode 100644 src/modules/geoip_base.c diff --git a/doc/conf/modules.default.conf b/doc/conf/modules.default.conf index 191512b8c..900f60bc9 100644 --- a/doc/conf/modules.default.conf +++ b/doc/conf/modules.default.conf @@ -241,3 +241,4 @@ loadmodule "userhost-tag"; /* unrealircd.org/userhost tag for ircops */ loadmodule "json-log-tag"; /* unrealircd.org/json-log tag and CAP for ircops */ loadmodule "targetfloodprot"; /* set::anti-flood::target-flood protection */ loadmodule "watch-backend"; /* used by watch and other modules */ +loadmodule "geoip_base"; /* needed for ALL geoip functions */ diff --git a/include/h.h b/include/h.h index 6d841963d..eb9ccabfd 100644 --- a/include/h.h +++ b/include/h.h @@ -1129,4 +1129,4 @@ extern char *timestamp_iso8601(time_t v); /* end of logging */ extern void add_fake_lag(Client *client, long msec); extern char *prefix_with_extban(char *remainder, BanContext *b, Extban *extban, char *buf, size_t buflen); -extern char *geo_lookup(char *ip); +extern char *geoip_lookup_country(char *ip); diff --git a/include/modules.h b/include/modules.h index 308b4d117..fc2477efc 100644 --- a/include/modules.h +++ b/include/modules.h @@ -2272,7 +2272,7 @@ _UNREAL_ERROR(_hook_error_incompatible, "Incompatible hook function. Check argum #define CALLBACKTYPE_CLOAK_EX 3 #define CALLBACKTYPE_BLACKLIST_CHECK 4 #define CALLBACKTYPE_REPUTATION_STARTTIME 5 -#define CALLBACKTYPE_GEO_LOOKUP 6 +#define CALLBACKTYPE_GEOIP_LOOKUP 6 /* To add a new efunction, only if you are an UnrealIRCd coder: * 1) Add a new entry here diff --git a/src/modules/Makefile.in b/src/modules/Makefile.in index 036fa343a..bc67ad118 100644 --- a/src/modules/Makefile.in +++ b/src/modules/Makefile.in @@ -76,7 +76,8 @@ R_MODULES= \ ident_lookup.so history.so chathistory.so \ targetfloodprot.so clienttagdeny.so watch-backend.so \ monitor.so slog.so tls_cipher.so \ - unreal_server_compat.so $(GEOIP_CLASSIC_OBJECTS) + unreal_server_compat.so \ + geoip_base.so $(GEOIP_CLASSIC_OBJECTS) MODULES=cloak.so $(R_MODULES) MODULEFLAGS=@MODULEFLAGS@ @@ -679,6 +680,10 @@ unreal_server_compat.so: unreal_server_compat.c $(INCLUDES) $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ -o unreal_server_compat.so unreal_server_compat.c +geoip_base.so: geoip_base.c $(INCLUDES) + $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ + -o geoip_base.so geoip_base.c + geoip_classic.so: geoip_classic.c $(INCLUDES) $(CC) $(CFLAGS) $(MODULEFLAGS) $(GEOIP_CLASSIC_CFLAGS) $(GEOIP_CLASSIC_LIBS) -DDYNAMIC_LINKING \ -o geoip_classic.so geoip_classic.c diff --git a/src/modules/geoip_base.c b/src/modules/geoip_base.c new file mode 100644 index 000000000..790c3af12 --- /dev/null +++ b/src/modules/geoip_base.c @@ -0,0 +1,92 @@ +/* + * GEOIP Base module, needed for all geoip functions + * as this stores the geo information in ModData. + * (C) Copyright 2021-.. Syzop and The UnrealIRCd Team + * License: GPLv2 + */ + +#include "unrealircd.h" + +ModuleHeader MOD_HEADER + = { + "geoip_base", + "5.0", + "Base module for geoip", + "UnrealIRCd Team", + "unrealircd-6", + }; + +/* Forward declarations */ +void geoip_base_free(ModData *m); +char *geoip_base_serialize(ModData *m); +void geoip_base_unserialize(char *str, ModData *m); +int geoip_base_handshake(Client *client); +int geoip_base_connect(Client *client); +int geoip_base_whois(Client *client, Client *target); + +ModDataInfo *geoip_base_md; /* Module Data structure which we acquire */ + +MOD_INIT() +{ +ModDataInfo mreq; + + MARK_AS_OFFICIAL_MODULE(modinfo); + + memset(&mreq, 0, sizeof(mreq)); + mreq.name = "geoip_base"; + mreq.free = geoip_base_free; + mreq.serialize = geoip_base_serialize; + mreq.unserialize = geoip_base_unserialize; + mreq.sync = MODDATA_SYNC_EARLY; + mreq.type = MODDATATYPE_CLIENT; + geoip_base_md = ModDataAdd(modinfo->handle, mreq); + if (!geoip_base_md) + abort(); + + HookAdd(modinfo->handle, HOOKTYPE_HANDSHAKE, 0, geoip_base_handshake); + HookAdd(modinfo->handle, HOOKTYPE_SERVER_HANDSHAKE_OUT, 0, geoip_base_handshake); + + return MOD_SUCCESS; +} + +MOD_LOAD() +{ + return MOD_SUCCESS; +} + + +MOD_UNLOAD() +{ + return MOD_SUCCESS; +} + +int geoip_base_handshake(Client *client) +{ + if (client->ip) + { + char *country = geoip_lookup_country(client->ip); + + if (!country) + return 0; + + moddata_client_set(client, "geoip_country", country); + } + return 0; +} + +void geoip_base_free(ModData *m) +{ + safe_free(m->str); +} + +char *geoip_base_serialize(ModData *m) +{ + if (!m->str) + return NULL; + return m->str; +} + +void geoip_base_unserialize(char *str, ModData *m) +{ + safe_strdup(m->str, str); +} diff --git a/src/modules/geoip_classic.c b/src/modules/geoip_classic.c index 231c2293f..fcc1e8434 100644 --- a/src/modules/geoip_classic.c +++ b/src/modules/geoip_classic.c @@ -20,15 +20,17 @@ char *db_file = NULL; GeoIP *gi = NULL; /* Forward declarations */ -char *geo_lookup_classic(char *ip); +char *geoip_lookup_classic(char *ip); MOD_TEST() { MARK_AS_OFFICIAL_MODULE(modinfo); - if (!CallbackAddPCharEx(modinfo->handle, CALLBACKTYPE_GEO_LOOKUP, geo_lookup_classic)) + if (!CallbackAddPCharEx(modinfo->handle, CALLBACKTYPE_GEOIP_LOOKUP, geoip_lookup_classic)) { - config_error("geoip_classic: Could not install GEO_LOOKUP callback. " - "Maybe another geoip module is already loaded? You can only load one!"); + unreal_log(ULOG_ERROR, "geoip_classic", "GEOIP_ADD_CALLBACK_FAILED", NULL, + "geoip_classic: Could not install GEOIP_LOOKUP callback. " + "Most likely another eoip module is already loaded. " + "You can only load one!"); return MOD_FAILED; } return MOD_SUCCESS; @@ -65,7 +67,7 @@ MOD_UNLOAD() return MOD_SUCCESS; } -char *geo_lookup_classic(char *ip) +char *geoip_lookup_classic(char *ip) { static char buf[256]; const char *r; diff --git a/src/user.c b/src/user.c index 380405e47..52f4f066e 100644 --- a/src/user.c +++ b/src/user.c @@ -1094,9 +1094,9 @@ MODVAR char *floodoption_names[] = { * @param ip The IP to lookup * @returns The country code, or NULL. */ -char *geo_lookup(char *ip) +char *geoip_lookup_country(char *ip) { - if (!RCallbacks[CALLBACKTYPE_GEO_LOOKUP]) + if (!RCallbacks[CALLBACKTYPE_GEOIP_LOOKUP]) return NULL; - return RCallbacks[CALLBACKTYPE_GEO_LOOKUP]->func.pcharfunc(ip); + return RCallbacks[CALLBACKTYPE_GEOIP_LOOKUP]->func.pcharfunc(ip); }