From 110f5794640cfa475474a1f567c8b36c5b744f3f Mon Sep 17 00:00:00 2001 From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Date: Sun, 23 May 2021 15:18:32 +0100 Subject: [PATCH] IPIntel Configuration --- code/controllers/configuration.dm | 28 --------------- .../configuration/configuration_core.dm | 4 +++ .../sections/ipintel_configuration.dm | 34 +++++++++++++++++++ code/modules/admin/IsBanned.dm | 2 +- code/modules/admin/ipintel.dm | 28 ++++++++------- code/modules/client/client_procs.dm | 13 +++---- config/example/config.toml | 6 ++-- paradise.dme | 1 + 8 files changed, 66 insertions(+), 50 deletions(-) create mode 100644 code/controllers/configuration/sections/ipintel_configuration.dm diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 7c1e51134c9..aab334af825 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -47,16 +47,6 @@ var/shuttle_refuel_delay = 12000 - //IP Intel vars - var/ipintel_email - var/ipintel_rating_bad = 1 - var/ipintel_save_good = 12 - var/ipintel_save_bad = 1 - var/ipintel_domain = "check.getipintel.net" - var/ipintel_maxplaytime = 0 - var/ipintel_whitelist = 0 - var/ipintel_detailsurl = "https://iphub.info/?ip=" - var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt var/simultaneous_pm_warning_timeout = 100 @@ -147,24 +137,6 @@ if("list_afk_minimum") config.list_afk_minimum = text2num(value) - if("ipintel_email") - if(value != "ch@nge.me") - config.ipintel_email = value - if("ipintel_rating_bad") - config.ipintel_rating_bad = text2num(value) - if("ipintel_domain") - config.ipintel_domain = value - if("ipintel_save_good") - config.ipintel_save_good = text2num(value) - if("ipintel_save_bad") - config.ipintel_save_bad = text2num(value) - if("ipintel_maxplaytime") - config.ipintel_maxplaytime = text2num(value) - if("ipintel_whitelist") - config.ipintel_whitelist = 1 - if("ipintel_detailsurl") - config.ipintel_detailsurl = value - if("pregame_timestart") config.pregame_timestart = text2num(value) diff --git a/code/controllers/configuration/configuration_core.dm b/code/controllers/configuration/configuration_core.dm index 18d2923e763..b029a642d98 100644 --- a/code/controllers/configuration/configuration_core.dm +++ b/code/controllers/configuration/configuration_core.dm @@ -21,6 +21,8 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new()) var/datum/configuration_section/gamemode_configuration/gamemode /// Holder for the gateway configuration datum var/datum/configuration_section/gateway_configuration/gateway + /// Holder for the IPIntel configuration datum + var/datum/configuration_section/ipintel_configuration/ipintel /// Holder for the job configuration datum var/datum/configuration_section/job_configuration/jobs /// Holder for the logging configuration datum @@ -61,6 +63,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new()) event = new() gamemode = new() gateway = new() + ipintel = new() jobs = new() logging = new() mc = new() @@ -87,6 +90,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new()) event.load_data(raw_config_data["event_configuration"]) gamemode.load_data(raw_config_data["gamemode_configuration"]) gateway.load_data(raw_config_data["gateway_configuration"]) + ipintel.load_data(raw_config_data["ipintel_configuration"]) jobs.load_data(raw_config_data["job_configuration"]) logging.load_data(raw_config_data["logging_configuration"]) mc.load_data(raw_config_data["mc_configuration"]) diff --git a/code/controllers/configuration/sections/ipintel_configuration.dm b/code/controllers/configuration/sections/ipintel_configuration.dm new file mode 100644 index 00000000000..42bd988b818 --- /dev/null +++ b/code/controllers/configuration/sections/ipintel_configuration.dm @@ -0,0 +1,34 @@ +/// Config holder for all things relating to IPIntel +/datum/configuration_section/ipintel_configuration + /// Is IPIntel enabled + var/enabled = FALSE + /// Arew we in whitelist mode (Auto-kick people who are on proxies/VPNs) + var/whitelist_mode = TRUE + /// 0-1 float for percentage threshold to kick people out + var/bad_rating = 0.9 + /// IPIntel contact email. Required. + var/contact_email = null + /// How many hours to save good matches for. Cached due to rate limits + var/hours_save_good = 72 + /// How many hours to save bad matches for. Cached due to rate limits + var/hours_save_bad = 24 + /// IPIntel Domain. Do not prefix with a protocol + var/ipintel_domain = "check.getipintel.net" + /// Do not proxy-check players with more hours than the below threshold + var/playtime_ignore_threshold = 10 + /// Details URL for more info on an IP, including ASN. IP is tacked straight on the end. + var/details_url = "https://iphub.info/?ip=" + +/datum/configuration_section/ipintel_configuration/load_data(list/data) + // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line + CONFIG_LOAD_BOOL(enabled, data["ipintel_enabled"]) + CONFIG_LOAD_BOOL(whitelist_mode, data["whitelist_mode"]) + + CONFIG_LOAD_NUM(bad_rating, data["bad_rating"]) + CONFIG_LOAD_NUM(hours_save_good, data["hours_save_good"]) + CONFIG_LOAD_NUM(hours_save_bad, data["hours_save_bad"]) + CONFIG_LOAD_NUM(playtime_ignore_threshold, data["playtime_ignore_threshold"]) + + CONFIG_LOAD_STR(contact_email, data["contact_email"]) + CONFIG_LOAD_STR(ipintel_domain, data["ipintel_domain"]) + CONFIG_LOAD_STR(details_url, data["details_url"]) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index f17a6c443a0..03e70a21408 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -35,7 +35,7 @@ return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a BYOND account.") //check if the IP address is a known proxy/vpn, and the user is not whitelisted - if(check_ipintel && config.ipintel_email && config.ipintel_whitelist && ipintel_is_banned(key, address)) + if(check_ipintel && GLOB.configuration.ipintel.contact_email && GLOB.configuration.ipintel.whitelist_mode && ipintel_is_banned(key, address)) log_adminwarn("Failed Login: [key] [computer_id] [address] - Proxy/VPN") var/mistakemessage = "" if(GLOB?.configuration?.url.banappeals_url) diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm index b0d411a2727..3d02ba78db5 100644 --- a/code/modules/admin/ipintel.dm +++ b/code/modules/admin/ipintel.dm @@ -14,18 +14,18 @@ . = FALSE if(intel < 0) return - if(intel <= config.ipintel_rating_bad) - if(world.realtime < cacherealtime + (config.ipintel_save_good HOURS)) + if(intel <= GLOB.configuration.ipintel.bad_rating) + if(world.realtime < cacherealtime + (GLOB.configuration.ipintel.hours_save_good HOURS)) return TRUE else - if(world.realtime < cacherealtime + (config.ipintel_save_bad HOURS)) + if(world.realtime < cacherealtime + (GLOB.configuration.ipintel.hours_save_bad HOURS)) return TRUE /proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE) var/datum/ipintel/res = new() res.ip = ip . = res - if(!ip || !config.ipintel_email || !SSipintel.enabled) + if(!ip || !GLOB.configuration.ipintel.contact_email || !GLOB.configuration.ipintel.enabled || !SSipintel.enabled) return if(!bypasscache) var/datum/ipintel/cachedintel = SSipintel.cache[ip] @@ -50,9 +50,9 @@ )) "}, list( "ip" = ip, - "rating_bad" = config.ipintel_rating_bad, - "save_good" = config.ipintel_save_good, - "save_bad" = config.ipintel_save_bad, + "rating_bad" = GLOB.configuration.ipintel.bad_rating, + "save_good" = GLOB.configuration.ipintel.hours_save_good, + "save_bad" = GLOB.configuration.ipintel.hours_save_bad, )) if(!query_get_ip_intel.warn_execute()) qdel(query_get_ip_intel) @@ -93,7 +93,7 @@ return // Do not refactor this to use SShttp, because that requires the subsystem to be firing for requests to be made, and this will be triggered before the MC has finished loading - var/list/http[] = world.Export("http://[config.ipintel_domain]/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json&flags=b") + var/list/http[] = world.Export("http://[GLOB.configuration.ipintel.ipintel_domain]/check.php?ip=[ip]&contact=[GLOB.configuration.ipintel.contact_email]&format=json&flags=b") if(http) var/status = text2num(http["STATUS"]) @@ -146,9 +146,11 @@ /proc/ipintel_is_banned(t_ckey, t_ip) - if(!config.ipintel_email) + if(!GLOB.configuration.ipintel.contact_email) return FALSE - if(!config.ipintel_whitelist) + if(!GLOB.configuration.ipintel.enabled) + return FALSE + if(!GLOB.configuration.ipintel.whitelist_mode) return FALSE if(!SSdbcore.IsConnected()) return FALSE @@ -159,11 +161,11 @@ return TRUE /proc/ipintel_badip_check(target_ip) - var/rating_bad = config.ipintel_rating_bad + var/rating_bad = GLOB.configuration.ipintel.bad_rating if(!rating_bad) log_debug("ipintel_badip_check reports misconfigured rating_bad directive") return FALSE - var/valid_hours = config.ipintel_save_bad + var/valid_hours = GLOB.configuration.ipintel.hours_save_bad if(!valid_hours) log_debug("ipintel_badip_check reports misconfigured ipintel_save_bad directive") return FALSE @@ -187,7 +189,7 @@ return TRUE /proc/vpn_whitelist_check(target_ckey) - if(!config.ipintel_whitelist) + if(!GLOB.configuration.ipintel.whitelist_mode) return FALSE var/datum/db_query/query_whitelist_check = SSdbcore.NewQuery("SELECT * FROM [format_table_name("vpn_whitelist")] WHERE ckey=:ckey", list( "ckey" = target_ckey diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index b16ca3284bc..1efd85dd1e3 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -592,10 +592,10 @@ /client/proc/check_ip_intel() set waitfor = 0 //we sleep when getting the intel, no need to hold up the client connection while we sleep - if(config.ipintel_email) - if(config.ipintel_maxplaytime && GLOB.configuration.jobs.enable_exp_tracking) + if(GLOB.configuration.ipintel.enabled) + if(GLOB.configuration.ipintel.playtime_ignore_threshold && GLOB.configuration.jobs.enable_exp_tracking) var/living_hours = get_exp_type_num(EXP_TYPE_LIVING) / 60 - if(living_hours >= config.ipintel_maxplaytime) + if(living_hours >= GLOB.configuration.ipintel.playtime_ignore_threshold) return if(is_connecting_from_localhost()) @@ -611,9 +611,10 @@ verify_ip_intel() /client/proc/verify_ip_intel() - if(ip_intel >= config.ipintel_rating_bad) - var/detailsurl = config.ipintel_detailsurl ? "(IP Info)" : "" - if(config.ipintel_whitelist) + if(ip_intel >= GLOB.configuration.ipintel.bad_rating) + var/detailsurl = GLOB.configuration.ipintel.details_url ? "(IP Info)" : "" + if(GLOB.configuration.ipintel.whitelist_mode) + // TODO: move this check to world.IsBanned() spawn(40) // This is necessary because without it, they won't see the message, and addtimer cannot be used because the timer system may not have initialized yet message_admins("IPIntel: [key_name_admin(src)] on IP [address] was rejected. [detailsurl]") var/blockmsg = "Error: proxy/VPN detected. Proxy/VPN use is not allowed here. Deactivate it before you reconnect." diff --git a/config/example/config.toml b/config/example/config.toml index 519a5c5c057..6be4ab1fc30 100644 --- a/config/example/config.toml +++ b/config/example/config.toml @@ -378,12 +378,14 @@ random_ai_lawset = true [ipintel_configuration] -# This section contains all the information for IPIntel (The AntiVPN system) +# This section contains all the information for IPIntel (The Anti VPN system) # Enable or disable IPIntel entirely ipintel_enabled = false +# Whitelist mode. If true, people on proxies/VPNs will need whitelisting if they arent past the threshold below. If false, admins are merely warned with no automatic action +whitelist_mode = true # Threshold to kick people out (0-1 percentage float) -bad_rading = 0.98 +bad_rating = 0.98 # Contact email (required, leaving blank disables this) contact_email = "ch@nge.me" # How many hours to save good matches for (IPIntel has rate limits) diff --git a/paradise.dme b/paradise.dme index 3f836906e04..ba08f990e36 100644 --- a/paradise.dme +++ b/paradise.dme @@ -193,6 +193,7 @@ #include "code\controllers\configuration\sections\event_configuration.dm" #include "code\controllers\configuration\sections\gamemode_configuration.dm" #include "code\controllers\configuration\sections\gateway_configuration.dm" +#include "code\controllers\configuration\sections\ipintel_configuration.dm" #include "code\controllers\configuration\sections\job_configuration.dm" #include "code\controllers\configuration\sections\logging_configuration.dm" #include "code\controllers\configuration\sections\mc_configuration.dm"