diff --git a/SQL/migrate-2023/V008__rework_connection_logging.sql b/SQL/migrate-2023/V008__rework_connection_logging.sql new file mode 100644 index 00000000000..a5dd077bacf --- /dev/null +++ b/SQL/migrate-2023/V008__rework_connection_logging.sql @@ -0,0 +1,9 @@ +-- +-- Rework Connection Logging +-- +ALTER TABLE `ss13_connection_log` + CHANGE COLUMN `ckey` `ckey` VARCHAR(32) NULL COLLATE 'utf8mb4_unicode_ci' AFTER `id`, + CHANGE COLUMN `ip` `ip` VARCHAR(18) NULL COLLATE 'utf8mb4_unicode_ci' AFTER `serverip`, + CHANGE COLUMN `computerid` `computerid` VARCHAR(32) NULL COLLATE 'utf8mb4_unicode_ci' AFTER `ip`, + ADD COLUMN `status` VARCHAR(50) NULL DEFAULT NULL AFTER `game_id`; + diff --git a/code/modules/admin/DB ban/ban_mirroring.dm b/code/modules/admin/DB ban/ban_mirroring.dm index 8be927c4886..490086cbec6 100644 --- a/code/modules/admin/DB ban/ban_mirroring.dm +++ b/code/modules/admin/DB ban/ban_mirroring.dm @@ -309,7 +309,7 @@ if (dset[3] == C.computer_id) new_info &= ~BAD_CID - var/list/bdata = world.IsBanned(dset[1], dset[2], dset[3], 1, real_bans_only = TRUE) + var/list/bdata = world.IsBanned(dset[1], dset[2], dset[3], 1, real_bans_only = TRUE, log_connection = FALSE) if (bdata && bdata.len && !isnull(bdata["id"])) ding_bannu = bdata["id"] break diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 6deaa87da86..2f4ebae0409 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -2,12 +2,42 @@ #define STICKYBAN_MAX_EXISTING_USER_MATCHES 3 //ie, users who were connected before the ban triggered #define STICKYBAN_MAX_ADMIN_MATCHES 1 +#define ACCESS_STATUS_PERMITTED "permitted" +#define ACCESS_STATUS_ADMINPERMITTED "admin permitted" +#define ACCESS_STATUS_GUESTDENIED "guests denied" +#define ACCESS_STATUS_NOIP "no ip" +#define ACCESS_STATUS_NOCID "no cid" +#define ACCESS_STATUS_BANNED "banned" +#define ACCESS_STATUS_STICKYBANNED "sticky banned" + + +#define LOG_CLIENT_CONNECTION(STATUS) if (log_connection) {log_connection(ckey(key), address, computer_id, byond_version, byond_build, game_id, STATUS)} + +/world/proc/log_connection(ckey, ip, computerid, byond_version, byond_build, game_id, access_status) + if(!establish_db_connection(GLOB.dbcon)) + log_access("Unable to Establish DB Connection for connection logging") + return + + //Logging player access + var/DBQuery/query_accesslog = GLOB.dbcon.NewQuery("INSERT INTO `ss13_connection_log`(`datetime`,`serverip`,`ckey`,`ip`,`computerid`,`byond_version`,`byond_build`,`game_id`, `status`) VALUES(Now(), :serverip:, :ckey:, :ip:, :computerid:, :byond_version:, :byond_build:, :game_id:, :status:);") + query_accesslog.Execute(list( + "serverip"="[world.internet_address]:[world.port]", + "ckey"=ckey, + "ip"=ip, + "computerid"=computerid, + "byond_version"=byond_version, + "byond_build"=byond_build, + "game_id"=game_id, + "status"=access_status)) + + //Blocks an attempt to connect before even creating our client datum thing. -/world/IsBanned(key, address, computer_id, type, real_bans_only = FALSE) +/world/IsBanned(key, address, computer_id, type, real_bans_only = FALSE, log_connection = TRUE) if (type == "world") return ..() if(ckey(key) in admin_datums) + LOG_CLIENT_CONNECTION(ACCESS_STATUS_ADMINPERMITTED) return ..() var/ckey = ckey(key) @@ -26,8 +56,8 @@ if(!(GLOB.config.guests_allowed || GLOB.config.external_auth) && IsGuestKey(key)) log_access("Failed Login: [key] - Guests not allowed",ckey=key_name(key)) message_admins("Failed Login: [key] - Guests not allowed") + LOG_CLIENT_CONNECTION(ACCESS_STATUS_GUESTDENIED) return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.") - if(GLOB.config.ban_legacy_system) //Ban Checking . = CheckBan(ckey, computer_id, address) @@ -39,15 +69,16 @@ return ..() //default pager ban stuff else - if (!address) log_access("Failed Login: [key] null-[computer_id] - Denied access: No IP address broadcast.",ckey=key_name(key)) message_admins("[key] tried to connect without an IP address.") + LOG_CLIENT_CONNECTION(ACCESS_STATUS_NOIP) return list("reason" = "Temporary ban", "desc" = "Your connection did not broadcast an IP address to check.") if (!computer_id) log_access("Failed Login: [key] [address]-null - Denied access: No computer ID broadcast.",ckey=key_name(key)) message_admins("[key] tried to connect without a computer ID.") + LOG_CLIENT_CONNECTION(ACCESS_STATUS_NOCID) return list("reason" = "Temporary ban", "desc" = "Your connection did not broadcast an computer ID to check.") @@ -95,6 +126,7 @@ if (GLOB.config.forum_passphrase) desc += "\nTo register on the forums, please use the following passphrase: [GLOB.config.forum_passphrase]" + LOG_CLIENT_CONNECTION(ACCESS_STATUS_BANNED) return list("reason"="[bantype]", "desc"="[desc]", "id" = ban_id) var/list/ban = ..() //default pager ban stuff @@ -206,10 +238,22 @@ var/desc = "\nReason:(StickyBan) You, or another user of this computer or connection ([bannedckey]) is banned from playing here. The ban reason is:\n[ban["message"]]\nThis ban was applied by [ban["admin"]]\nThis is a BanEvasion Detection System ban, if you think this ban is a mistake, please wait EXACTLY 6 seconds, then try again before filing an appeal.\n" . = list("reason" = "Stickyban", "desc" = desc) log_access("Failed Login: [key] [computer_id] [address] - StickyBanned [ban["message"]] Target Username: [bannedckey] Placed by [ban["admin"]]") + LOG_CLIENT_CONNECTION(ACCESS_STATUS_STICKYBANNED) + LOG_CLIENT_CONNECTION(ACCESS_STATUS_PERMITTED) return . +#undef ACCESS_STATUS_ADMINPERMITTED +#undef ACCESS_STATUS_PERMITTED +#undef ACCESS_STATUS_GUESTDENIED +#undef ACCESS_STATUS_NOIP +#undef ACCESS_STATUS_NOCID +#undef ACCESS_STATUS_BANNED +#undef ACCESS_STATUS_STICKYBANNED + +#undef LOG_CLIENT_CONNECTION + #undef STICKYBAN_MAX_MATCHES #undef STICKYBAN_MAX_EXISTING_USER_MATCHES #undef STICKYBAN_MAX_ADMIN_MATCHES diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 99f35f850d0..86bdd3ebd68 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -590,11 +590,6 @@ var/list/localhost_addresses = list( if (!account_join_date) account_join_date = "Error" - //Logging player access - var/DBQuery/query_accesslog = GLOB.dbcon.NewQuery("INSERT INTO `ss13_connection_log`(`datetime`,`serverip`,`ckey`,`ip`,`computerid`,`byond_version`,`byond_build`,`game_id`) VALUES(Now(), :serverip:, :ckey:, :ip:, :computerid:, :byond_version:, :byond_build:, :game_id:);") - query_accesslog.Execute(list("serverip"="[world.internet_address]:[world.port]","ckey"=ckey(key),"ip"=src.address,"computerid"=src.computer_id,"byond_version"=byond_version,"byond_build"=byond_build,"game_id"=game_id)) - - #undef UPLOAD_LIMIT #undef MIN_CLIENT_VERSION diff --git a/code/modules/mob/abstract/unauthed/login.dm b/code/modules/mob/abstract/unauthed/login.dm index ba305eac1a5..b3ba68da5f9 100644 --- a/code/modules/mob/abstract/unauthed/login.dm +++ b/code/modules/mob/abstract/unauthed/login.dm @@ -43,7 +43,7 @@ c.authed = TRUE // We declare client as authed now c.prefs = null //Null them so we can load them from the db again for the correct ckey // Check for bans - var/list/ban_data = world.IsBanned(ckey(newkey), c.address, c.computer_id, 1, TRUE) + var/list/ban_data = world.IsBanned(ckey(newkey), c.address, c.computer_id, 1, real_bans_only = TRUE, log_connection = TRUE) if(ban_data) to_chat_immediate(c, "You are banned for this server.") to_chat_immediate(c, "Reason: [ban_data["reason"]]") diff --git a/html/changelogs/arrow768-connection-logging-overhaul.yml b/html/changelogs/arrow768-connection-logging-overhaul.yml new file mode 100644 index 00000000000..9747f3ff05a --- /dev/null +++ b/html/changelogs/arrow768-connection-logging-overhaul.yml @@ -0,0 +1,42 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: arrow768 + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - backend: "Changes how the connections are logged to the database." +