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

[s] update the thing #6846

Closed
wants to merge 4 commits into from
Closed
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
5 changes: 3 additions & 2 deletions code/controllers/configuration/entries/general.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
/datum/config_entry/string/invoke_youtubedl
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN


/datum/config_entry/number/client_warn_version
default = null
min_val = 500

/datum/config_entry/number/client_warn_version
/datum/config_entry/number/client_warn_build
default = null
min_val = 500
min_val = 0

/datum/config_entry/string/client_warn_message
default = "Your version of byond may have issues or be blocked from accessing this server in the future."
Expand Down
37 changes: 24 additions & 13 deletions code/modules/client/client_procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@
If you have any questions about this stuff feel free to ask. ~Carn
*/

/client/Topic(href, href_list, hsrc)
if(!usr || usr != mob) //stops us calling Topic for somebody else's client. Also helps prevent usr=null
//the undocumented 4th argument is for ?[0x\ref] style topic links. hsrc is set to the reference and anything after the ] gets put into hsrc_command
/client/Topic(href, href_list, hsrc, hsrc_command)
if(!usr || usr != mob) // stops us calling Topic for somebody else's client. Also helps prevent usr=null
return

// Rate limiting
Expand All @@ -68,11 +69,11 @@
msg += " Administrators have been informed."
log_game("[key_name(src)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
to_chat(src, "<span class='danger'>[msg]</span>")
to_chat(src, SPAN_DANGER("[msg]"))
return

var/stl = config_legacy.second_topic_limit //CONFIG_GET(number/second_topic_limit)
if (!holder && stl)
if (!holder && stl && href_list["window_id"] != "statbrowser")
var/second = round(world.time, 10)
if (!topiclimiter)
topiclimiter = new(LIMITER_SIZE)
Expand All @@ -81,14 +82,16 @@
topiclimiter[SECOND_COUNT] = 0
topiclimiter[SECOND_COUNT] += 1
if (topiclimiter[SECOND_COUNT] > stl)
to_chat(src, "<span class='danger'>Your previous action was ignored because you've done too many in a second</span>")
to_chat(src, SPAN_DANGER("Your previous action was ignored because you've done too many in a second"))
return

// Tgui Topic middleware
if(tgui_topic(href_list))
if(CONFIG_GET(flag/emergency_tgui_logging))
log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]")
return
if(href_list["reload_tguipanel"])
nuke_chat()

//? Normal HREF handling go below

Expand Down Expand Up @@ -173,14 +176,16 @@
/client/New(TopicData)
//* pre-connect-ish *//

// Byond only populates whether or not you can profile at connect. You have to give someone this
// before their client loads/whatever. This cannot be behind a spawn(). We will remove it from non-admins later.
world.SetConfig("APP/admin", ckey, "role=admin")
// Block client.Topic() calls from connect.
TopicData = null

// Kick invalid connections.
if(connection != "seeker" && connection != "web")
return null

// Byond only populates whether or not you can profile at connect. You have to give someone this
// before their client loads/whatever. This cannot be behind a spawn(). We will remove it from non-admins later.
world.SetConfig("APP/admin", ckey, "role=admin")
//! legacy: kick out guests !//
if(!config_legacy.guests_allowed && is_guest() && !is_localhost())
security_kick(
Expand Down Expand Up @@ -298,6 +303,8 @@
INVOKE_ASYNC(SSipintel, TYPE_PROC_REF(/datum/controller/subsystem/ipintel, vpn_connection_check), address, ckey)
// run onboarding gauntlet
INVOKE_ASYNC(src, PROC_REF(onboarding))
if (!security_checks())
return // GET OUT (assume client is dead)

//* Initialize Input *//
if(SSinput.initialized)
Expand Down Expand Up @@ -465,12 +472,13 @@
// here because it's similar to below

/client/proc/add_system_note(system_ckey, message)
notes_add(ckey, message)
notes_add(ckey, message) // TODO: move me to sql
/*
var/sql_system_ckey = sanitizeSQL(system_ckey)
var/sql_ckey = sanitizeSQL(ckey)
//check to see if we noted them in the last day.
var/datum/DBQuery/query_get_notes = SSdbcore.NewQuery("SELECT id FROM [format_table_name("messages")] WHERE type = 'note' AND targetckey = '[sql_ckey]' AND adminckey = '[sql_system_ckey]' AND timestamp + INTERVAL 1 DAY < NOW() AND deleted = 0 AND expire_timestamp > NOW()")
var/datum/db_query/query_get_notes = SSdbcore.NewQuery(
"SELECT id FROM [format_table_name("messages")] WHERE type = 'note' AND targetckey = :targetckey AND adminckey = :adminckey AND timestamp + INTERVAL 1 DAY < NOW() AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)",
list("targetckey" = ckey, "adminckey" = system_ckey)
)
if(!query_get_notes.Execute())
qdel(query_get_notes)
return
Expand All @@ -479,7 +487,10 @@
return
qdel(query_get_notes)
//regardless of above, make sure their last note is not from us, as no point in repeating the same note over and over.
query_get_notes = SSdbcore.NewQuery("SELECT adminckey FROM [format_table_name("messages")] WHERE targetckey = '[sql_ckey]' AND deleted = 0 AND expire_timestamp > NOW() ORDER BY timestamp DESC LIMIT 1")
query_get_notes = SSdbcore.NewQuery(
"SELECT adminckey FROM [format_table_name("messages")] WHERE targetckey = :targetckey AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL) ORDER BY timestamp DESC LIMIT 1",
list("targetckey" = ckey)
)
if(!query_get_notes.Execute())
qdel(query_get_notes)
return
Expand Down
2 changes: 1 addition & 1 deletion code/modules/client/onboarding/_onboarding.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
* client should already be logged to DB at this point.
*/
/client/proc/onboarding()
security_checks()
// security_checks()
panic_bunker()
age_verification()
71 changes: 41 additions & 30 deletions code/modules/client/onboarding/security_checks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,61 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
"1407" = "a bug preventing client display overrides from working leads to clients being able to see things/mobs they shouldn't be able to see",
"1408" = "a bug preventing client display overrides from working leads to clients being able to see things/mobs they shouldn't be able to see",
"1428" = "a bug causing right-click menus to show too many verbs that's been fixed in version 1429",
"1622" = "Bug breaking rendering can lead to wallhacks.",
))

/client/proc/security_checks()
set waitfor = FALSE
security_checks_impl()
// set waitfor = FALSE
// lock up login
return security_checks_impl()

/client/proc/security_checks_impl()
if(byond_version < 513)
security_kick("BYOND 512 and prior clients are too outdated.", tell_user = TRUE)
return FALSE
if(!byond_build || byond_build < 1386)
message_admins("[src] detected as BYOND version spoof. Kicking.")
security_note("likely spoofed byond version")
security_kick("likely spoofed byond version")
return FALSE
if(num2text(byond_build, 999) in GLOB.blacklisted_builds)
security_kick("[byond_build] is blacklisted due to [GLOB.blacklisted_builds[num2text(byond_build)]]. Please update your BYOND version.", tell_user = TRUE)
return FALSE
var/cev = CONFIG_GET(number/client_error_version)
var/ceb = CONFIG_GET(number/client_error_build)
var/cwv = CONFIG_GET(number/client_warn_version)
if (byond_version < cev || (byond_version == cev && byond_build < ceb)) //Out of date client.
to_chat(src, "<span class='danger'><b>Your version of BYOND is too old:</b></span>")
to_chat(src, CONFIG_GET(string/client_error_message))
to_chat(src, "Your version: [byond_version].[byond_build]")
to_chat(src, "Required version: [cev].[ceb] or later")
to_chat(src, "Visit <a href=\"https://secure.byond.com/download\">BYOND's website</a> to get the latest version of BYOND.")
// supplimentary checks for 512 n up. version check is down there
if(byond_version >= 512)
if (!byond_build || byond_build < 1386)
message_admins(SPAN_ADMINNOTICE("[key_name(src)] has been detected as spoofing their byond version. Connection rejected."))
add_system_note("Spoofed-Byond-Version", "Detected as using a spoofed byond version.")
log_suspicious_login("Failed Login: [key] - Spoofed byond version")
qdel(src)
return FALSE
if (num2text(byond_build) in GLOB.blacklisted_builds)
to_chat_immediate(src, SPAN_USERDANGER("Your version of byond is blacklisted."))
to_chat_immediate(src, SPAN_DANGER("Byond build [byond_build] ([byond_version].[byond_build]) has been blacklisted for the following reason: [GLOB.blacklisted_builds[num2text(byond_build)]]."))
to_chat_immediate(src, SPAN_DANGER("Please download a new version of byond. If [byond_build] is the latest, you can go to <a href=\"https://secure.byond.com/download/build\">BYOND's website</a> to download other versions."))
if(is_staff())
to_chat_immediate(src, "As an admin, you are being allowed to continue using this version, but please consider changing byond versions")
else
qdel(src)
return FALSE

var/breaking_version = CONFIG_GET(number/client_error_version)
var/breaking_build = CONFIG_GET(number/client_error_build)
var/warn_version = CONFIG_GET(number/client_warn_version)
var/warn_build = CONFIG_GET(number/client_warn_build)

if (byond_version < breaking_version || (byond_version == breaking_version && byond_build < breaking_build)) //Out of date client.
to_chat_immediate(src, SPAN_DANGER("<b>Your version of BYOND is too old:</b>"))
to_chat_immediate(src, CONFIG_GET(string/client_error_message))
to_chat_immediate(src, "Your version: [byond_version].[byond_build]")
to_chat_immediate(src, "Required version: [breaking_version].[breaking_build] or later")
to_chat_immediate(src, "Visit <a href=\"https://secure.byond.com/download\">BYOND's website</a> to get the latest version of BYOND.")
Comment on lines +15 to +42
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other than the spoofing, is there a reason this is not using security procs / browse()?

it's not a critical security issue for someone to have wallhacks for a second before they're booted and logged
our old chat looks like absolute ass and it's a big UI/UX issue to have people be DC'd and forced to eyestrain to see why
also, all of these should log somewhere

if (is_staff())
to_chat(src, "Because you are an admin, you are being allowed to walk past this limitation, But it is still STRONGLY suggested you upgrade")
to_chat_immediate(src, "Because you are an admin, you are being allowed to walk past this limitation, But it is still STRONGLY suggested you upgrade")
else
disconnection_message("Your BYOND version ([byond_version].[byond_build]) is too old. Visit <a href=\"https://secure.byond.com/download\">BYOND's website</a> to get the latest version of BYOND.")
qdel(src)
return FALSE
else if (byond_version < cwv) //We have words for this client.
else if (byond_version < warn_version || (byond_version == warn_version && byond_build < warn_build)) //We have words for this client.
if(CONFIG_GET(flag/client_warn_popup))
var/msg = "<b>Your version of byond may be getting out of date:</b><br>"
msg += CONFIG_GET(string/client_warn_message) + "<br><br>"
msg += "Your version: [byond_version]<br>"
msg += "Required version to remove this message: [cwv] or later<br>"
msg += "Your version: [byond_version].[byond_build]<br>"
msg += "Required version to remove this message: [warn_version].[warn_build] or later<br>"
msg += "Visit <a href=\"https://secure.byond.com/download\">BYOND's website</a> to get the latest version of BYOND.<br>"
src << browse(msg, "window=warning_popup")
else
to_chat(src, "<span class='danger'><b>Your version of byond may be getting out of date:</b></span>")
to_chat(src, SPAN_DANGER("<b>Your version of byond may be getting out of date:</b>"))
to_chat(src, CONFIG_GET(string/client_warn_message))
to_chat(src, "Your version: [byond_version]")
to_chat(src, "Required version to remove this message: [cwv] or later")
to_chat(src, "Your version: [byond_version].[byond_build]")
to_chat(src, "Required version to remove this message: [warn_version].[warn_build] or later")
to_chat(src, "Visit <a href=\"https://secure.byond.com/download\">BYOND's website</a> to get the latest version of BYOND.")
return TRUE
4 changes: 2 additions & 2 deletions code/modules/client/security.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
message_admins("client security: noting [key_name(src)] for [message]")
add_system_note("client-security", message)
if(tell_user)
to_chat(src, SPAN_BOLDANNOUNCE("CLIENT-SECURITY: [message]<br>Please correct this."))
to_chat_immediate(src, SPAN_BOLDANNOUNCE("CLIENT-SECURITY: [message]<br>Please correct this."))

/client/proc/security_kick(message, tell_user, immediate)
log_access("client security: kicking [key_name(src)] | [message]")
message_admins("client security: kicking [key_name(src)] | [message]")
if(tell_user)
to_chat(src, SPAN_BOLDANNOUNCE("CLIENT-SECURITY: [message]<br>Please correct this.<br>You will now be disconnected."))
to_chat_immediate(src, SPAN_BOLDANNOUNCE("CLIENT-SECURITY: [message]<br>Please correct this.<br>You will now be disconnected."))
disconnection_message(message)
if(!immediate)
queue_security_kick(5 SECONDS)
Expand Down
5 changes: 3 additions & 2 deletions config/entries/general.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ MINIMAPS_ENABLED
## These trigger for any version below (non-inclusive) the given version, so 510 triggers on 509 or lower.
## These messages will be followed by one stating the clients current version and the required version for clarity.
## If CLIENT_WARN_POPUP is uncommented a popup window with the message will be displayed instead
#CLIENT_WARN_VERSION 511
#CLIENT_WARN_VERSION 515
#CLIENT_WARN_BUILD 1635
#CLIENT_WARN_POPUP
#CLIENT_WARN_MESSAGE Byond released 511 as the stable release. You can set the framerate your client runs at, which makes the game feel very different and cool. Shortly after its release we will end up using 511 client features and you will be forced to update.
#CLIENT_WARN_MESSAGE Byond released 515 as the stable release. This comes bundled with a host of niceties, including image generation for UIs and :: operators.
CLIENT_ERROR_VERSION 511
CLIENT_ERROR_MESSAGE Your version of byond is not supported. Please upgrade.
## The minimum build needed for joining the server, if using 512, a good minimum build would be 1421 as that disables the Middle Mouse Button exploit.
Expand Down
Loading