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"