Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add m_geomaxlite and deleted m_whoisgeolite. #285

Merged
merged 6 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions 4/m_geomaxlite.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* InspIRCd -- Internet Relay Chat Daemon
*
* Copyright (C) 2024 reverse
*
* This file contains a third-party module for InspIRCd. You can
* redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation, version 2.
*
* 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, see <http://www.gnu.org/licenses/>.
*/

/// $ModAuthor: reverse <[email protected]>
/// $ModDesc: Adds city and country information to WHOIS using a local MaxMind GeoLite2 database with user mode +y.
/// $ModConfig: <geomaxlite dbpath="path/geodata/GeoLite2-City.mmdb">
/// $ModDepends: core 4

/// $CompilerFlags: find_compiler_flags("libmaxminddb")
/// $LinkerFlags: find_linker_flags("libmaxminddb")

/// $PackageInfo: require_system("alpine") libmaxminddb-dev pkgconf
/// $PackageInfo: require_system("arch") pkgconf libmaxminddb
/// $PackageInfo: require_system("darwin") libmaxminddb pkg-config
/// $PackageInfo: require_system("debian~") libmaxminddb-dev pkg-config
/// $PackageInfo: require_system("rhel~") pkg-config libmaxminddb-devel

#include "inspircd.h"
#include "modules/whois.h"
#include "extension.h"
#include <maxminddb.h>

class ModuleGeoMaxLite final
: public Module
, public Whois::EventListener
{
private:
// MaxMind DB handle
MMDB_s mmdb;

// Path to the MaxMind database file
std::string dbpath;

// Extension item to store a user's city/country info
StringExtItem country_item;

// +y user mode for enabling GeoMaxLite lookups
SimpleUserMode geomaxlite_mode;

public:
ModuleGeoMaxLite()
: Module(VF_OPTCOMMON, "Adds city and country information to WHOIS using a local MaxMind GeoLite2 database.")
, Whois::EventListener(this)
, country_item(this, "geomaxlite-country", ExtensionType::USER, true)
, geomaxlite_mode(this, "geomaxlite", 'y', false)
{
}

void ReadConfig(ConfigStatus& status) override
{
// Read the <geomaxlite> block from the config
auto& tag = ServerInstance->Config->ConfValue("geomaxlite");
dbpath = ServerInstance->Config->Paths.PrependConfig(
tag->getString("dbpath", "data/GeoLite2-City.mmdb"));

int status_open = MMDB_open(dbpath.c_str(), MMDB_MODE_MMAP, &mmdb);
if (status_open != MMDB_SUCCESS)
{
// If the database can't be opened, throw a module exception
std::string error_msg = "GeoMaxLite: Failed to open GeoLite2 database: "
+ std::string(MMDB_strerror(status_open));
throw ModuleException(this, error_msg.c_str());
}
}

void OnWhois(Whois::Context& whois) override
{
User* target = whois.GetTarget();

// Only display city/country data if the target user has +y (geomaxlite) set
if (!target->IsModeSet(geomaxlite_mode))
return;

const std::string* info = country_item.Get(target);
if (info && !info->empty())
{
whois.SendLine(RPL_WHOISSPECIAL, "is connecting from " + *info);
}
else
{
whois.SendLine(RPL_WHOISSPECIAL, "City: Unknown, Country: Unknown");
}
}

void OnChangeRemoteAddress(LocalUser* user) override
{
// If the address is not an IP, unset any stored geo info
if (!user->client_sa.is_ip())
{
country_item.Unset(user);
return;
}

int gai_error = 0;
const struct sockaddr* addr = &user->client_sa.sa;
MMDB_lookup_result_s result = MMDB_lookup_sockaddr(&mmdb, addr, &gai_error);

// Unset if we got a lookup error or didn't find anything
if (gai_error != 0 || !result.found_entry)
{
country_item.Unset(user);
return;
}

// Fetch city and country strings (in English)
MMDB_entry_data_s city_data = {};
MMDB_entry_data_s country_data = {};

int status_city = MMDB_get_value(&result.entry, &city_data, "city", "names", "en", nullptr);
int status_country = MMDB_get_value(&result.entry, &country_data, "country", "names", "en", nullptr);

std::string city = (status_city == MMDB_SUCCESS && city_data.has_data)
? std::string(city_data.utf8_string, city_data.data_size)
: "Unknown";

std::string country = (status_country == MMDB_SUCCESS && country_data.has_data)
? std::string(country_data.utf8_string, country_data.data_size)
: "Unknown";

// Store
country_item.Set(user, "City: " + city + ", Country: " + country);
}

~ModuleGeoMaxLite() override
{
// Close the MaxMind DB on unload
MMDB_close(&mmdb);
}
};

MODULE_INIT(ModuleGeoMaxLite)
116 changes: 0 additions & 116 deletions 4/m_whoisgeolite.cpp

This file was deleted.

Loading