Adds external auth (#6380)

This commit is contained in:
Karolis
2019-05-10 01:05:58 +03:00
committed by Werner
parent 78dee7b9e5
commit 96c2e1c163
12 changed files with 192 additions and 42 deletions

View File

@@ -1646,6 +1646,7 @@
#include "code\modules\mob\abstract\observer\logout.dm"
#include "code\modules\mob\abstract\observer\observer.dm"
#include "code\modules\mob\abstract\observer\say.dm"
#include "code\modules\mob\abstract\unauthed\login.dm"
#include "code\modules\mob\language\generic.dm"
#include "code\modules\mob\language\language.dm"
#include "code\modules\mob\language\monkey.dm"

View File

@@ -296,6 +296,9 @@ var/list/gamemode_cache = list()
var/ntsl_hostname = "localhost"
var/ntsl_port = "1945"
// Is external Auth enabled
var/external_auth = FALSE
/datum/configuration/New()
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
for (var/T in L)
@@ -903,6 +906,9 @@ var/list/gamemode_cache = list()
if ("ntsl_port")
ntsl_port = value
if ("external_auth")
external_auth = TRUE
else
log_misc("Unknown setting in configuration: '[name]'")

View File

@@ -5,7 +5,7 @@ world/IsBanned(key,address,computer_id)
return ..()
//Guest Checking
if(!config.guests_allowed && IsGuestKey(key))
if(!(config.guests_allowed || config.external_auth) && IsGuestKey(key))
log_access("Failed Login: [key] - Guests not allowed",ckey=key_name(key))
message_admins("<span class='notice'>Failed Login: [key] - Guests not allowed</span>")
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")

View File

@@ -71,3 +71,5 @@
var/obj/screen/plane_master/parallax_master/parallax_master = null
var/obj/screen/plane_master/parallax_dustmaster/parallax_dustmaster = null
var/obj/screen/plane_master/parallax_spacemaster/parallax_spacemaster = null
var/authed = TRUE

View File

@@ -23,6 +23,11 @@
if(!usr || usr != mob) //stops us calling Topic for somebody else's client. Also helps prevent usr=null
return
if(!authed)
if(href_list["authaction"] in list("guest", "forums")) // Protection
..()
return
// asset_cache
if(href_list["asset_cache_confirm_arrival"])
//to_chat(src, "ASSET JOB [href_list["asset_cache_confirm_arrival"]] ARRIVED.")
@@ -324,17 +329,53 @@
if(byond_version < MIN_CLIENT_VERSION) //Out of date client.
return null
if(!config.guests_allowed && IsGuestKey(key))
if(!(config.guests_allowed || config.external_auth) && IsGuestKey(key))
alert(src,"This server doesn't allow guest accounts to play. Please go to http://www.byond.com/ and register for a key.","Guest","OK")
del(src)
return
to_chat(src, "<span class='alert'>If the title screen is black, resources are still downloading. Please be patient until the title screen appears.</span>")
clients += src
directory[ckey] = src
if (LAZYLEN(config.client_blacklist_version))
var/client_version = "[byond_version].[byond_build]"
if (client_version in config.client_blacklist_version)
to_chat(src, "<span class='danger'><b>Your version of BYOND is explicitly blacklisted from joining this server!</b></span>")
to_chat(src, "Your current version: [client_version].")
to_chat(src, "Visit http://www.byond.com/download/ to download a different version. Try looking for a newer one, or go one lower.")
log_access("Failed Login: [key] [computer_id] [address] - Blacklisted BYOND version: [client_version].")
del(src)
return 0
if(IsGuestKey(key) && config.external_auth)
//src.real_mob = ..()
src.authed = FALSE
var/mob/abstract/unauthed/m = new()
m.client = src
return m
//Do auth shit
else
. = ..()
src.InitPerfs()
src.InitClient()
/client/proc/InitPerfs()
//preferences datum - also holds some persistant data for the client (because we may as well keep these datums to a minimum)
prefs = preferences_datums[ckey]
if(!prefs)
prefs = new /datum/preferences(src)
preferences_datums[ckey] = prefs
prefs.gather_notifications(src)
prefs.client = src // Safety reasons here.
prefs.last_ip = address //these are gonna be used for banning
prefs.last_id = computer_id //these are gonna be used for banning
/client/proc/InitClient()
to_chat(src, "<span class='alert'>If the title screen is black, resources are still downloading. Please be patient until the title screen appears.</span>")
//Admin Authorisation
holder = admin_datums[ckey]
if(holder)
@@ -343,6 +384,19 @@
log_client_to_db()
if (byond_version < config.client_error_version)
to_chat(src, "<span class='danger'><b>Your version of BYOND is too old!</b></span>")
to_chat(src, config.client_error_message)
to_chat(src, "Your version: [byond_version].")
to_chat(src, "Required version: [config.client_error_version] or later.")
to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of BYOND.")
if (holder)
to_chat(src, "Admins get a free pass. However, <b>please</b> update your BYOND as soon as possible. Certain things may cause crashes if you play with your present version.")
else
log_access("Failed Login: [key] [computer_id] [address] - Outdated BYOND major version: [byond_version].")
del(src)
return 0
// New player, and we don't want any.
if (!holder)
if (config.access_deny_new_players && player_age == -1)
@@ -360,42 +414,6 @@
del(src)
return 0
if (byond_version < config.client_error_version)
to_chat(src, "<span class='danger'><b>Your version of BYOND is too old!</b></span>")
to_chat(src, config.client_error_message)
to_chat(src, "Your version: [byond_version].")
to_chat(src, "Required version: [config.client_error_version] or later.")
to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of BYOND.")
if (holder)
to_chat(src, "Admins get a free pass. However, <b>please</b> update your BYOND as soon as possible. Certain things may cause crashes if you play with your present version.")
else
log_access("Failed Login: [key] [computer_id] [address] - Outdated BYOND major version: [byond_version].")
del(src)
return 0
if (LAZYLEN(config.client_blacklist_version))
var/client_version = "[byond_version].[byond_build]"
if (client_version in config.client_blacklist_version)
to_chat(src, "<span class='danger'><b>Your version of BYOND is explicitly blacklisted from joining this server!</b></span>")
to_chat(src, "Your current version: [client_version].")
to_chat(src, "Visit http://www.byond.com/download/ to download a different version. Try looking for a newer one, or go one lower.")
log_access("Failed Login: [key] [computer_id] [address] - Blacklisted BYOND version: [client_version].")
del(src)
return 0
//preferences datum - also holds some persistant data for the client (because we may as well keep these datums to a minimum)
prefs = preferences_datums[ckey]
if(!prefs)
prefs = new /datum/preferences(src)
preferences_datums[ckey] = prefs
prefs.gather_notifications(src)
prefs.client = src // Safety reasons here.
prefs.last_ip = address //these are gonna be used for banning
prefs.last_id = computer_id //these are gonna be used for banning
. = ..() //calls mob.Login()
if(holder)
add_admin_verbs()

View File

@@ -25,6 +25,7 @@
var/client/my_client // Need to keep track of this ourselves, since by the time Logout() is called the client has already been nulled
/mob/abstract/new_player/Login()
client.InitPerfs()
update_Login_details() //handles setting lastKnownIP and computer_id for use by the ban systems as well as checking for multikeying
to_chat(src, "<div class='info'>Game ID: <div class='danger'>[game_id]</div></div>")

View File

@@ -0,0 +1,60 @@
/var/list/unauthed = list()
/mob/abstract/unauthed
authed = FALSE
var/token = ""
/mob/abstract/unauthed/New()
verbs -= typesof(/mob/verb)
/mob/abstract/unauthed/Login()
update_Login_details()
to_chat(src, "<span class='danger'><b>You need to authenticate before you can continue.</b></span>")
token = md5("[client.ckey][client.computer_id][world.time][rand()]")
unauthed[token] = src
client.verbs -= typesof(/client/verb)
var/uihtml = "<html><head><style>body * {display: block;text-align:center;margin: 14px 0;font-size:24px;text-decoration:none;font-family:Segoe UI,Frutiger,Frutiger Linotype,Dejavu Sans,Helvetica Neue,Arial,sans-serif;}</style></head><body><p>Please select:</p>"
if(config.guests_allowed)
uihtml += "<a href='?src=\ref[src];authaction=guest'>Login as guest</a>"
if(config.webint_url)
uihtml += "<a href='?src=\ref[src];authaction=forums'>Login via forums</a>"
if(!config.guests_allowed && config.webint_url)
src.OpenForumAuthWindow()
show_browser(src, uihtml, "window=auth;size=300x300;border=0;can_close=0;can_resize=0;can_minimize=0;titlebar=1")
/mob/abstract/unauthed/proc/ClientLogin(var/newkey)
if(!client)
qdel(src)
var/client/c = client
show_browser(src, null, "window=auth;")
client.verbs += typesof(/client/verb) // Let's return regular client verbs
client.authed = TRUE // We declare client as authed now
// Check for bans
var/list/ban_data = world.IsBanned(ckey(newkey), c.address, c.computer_id)
if(ban_data)
to_chat(c, "You are banned for this server.")
to_chat(c, "Reason: [ban_data["reason"]]")
to_chat(c, "Description: [ban_data["desc"]]")
del(c)
return
directory -= client.ckey
if(newkey)
client.key = newkey // Try seeting ckey
directory[c.ckey] = c
// If mob exists for that ckey, then BYOND will transfer client to it.
if(istype(c.mob, /mob/abstract/unauthed))
c.mob = new /mob/abstract/new_player() // Else we just treat them as new player
c.InitPerfs() // We init pers just in case mob transfer didn't
c.InitClient() // And now we shal continue client initilization (permissions and stuff)
unauthed -= token
/mob/abstract/unauthed/Topic(href, href_list)
switch(href_list["authaction"])
if("guest")
src.ClientLogin(null)
if("forums")
src.OpenForumAuthWindow()
/mob/abstract/unauthed/proc/OpenForumAuthWindow()
src << link("[config.webint_url]server/auth?token=[token]")

View File

@@ -24,6 +24,7 @@
log_access("Notice: [key_name(src)] has the same [matches] as [key_name(M)] (no longer logged in).",ckey=key_name(src))
/mob/Login()
client.InitPerfs() // Init perfs in case they wasn't initilized
player_list |= src
update_Login_details()
SSfeedback.update_status()

View File

@@ -236,3 +236,5 @@
var/disconnect_time = null//Time of client loss, set by Logout(), for timekeeping
var/mob_thinks = TRUE
var/authed = TRUE

View File

@@ -12,7 +12,7 @@
var/versionstring = null
//The Version Number follows SemVer http://semver.org/
version["major"] = 2 //Major Version Number --> Increment when implementing breaking changes
version["minor"] = 6 //Minor Version Number --> Increment when adding features
version["minor"] = 7 //Minor Version Number --> Increment when adding features
version["patch"] = 0 //Patchlevel --> Increment when fixing bugs
versionstring = "[version["major"]].[version["minor"]].[version["patch"]]"

View File

@@ -170,3 +170,58 @@
response = "Poll data fetched"
data = poll_data
return TRUE
// Authenticates client from external system
/datum/topic_command/auth_client
name = "auth_client"
description = "Authenticates client from external system."
params = list(
"key" = list("name"="key","desc"="Verified key to be set for client.","type"="str","req"=1),
"clienttoken" = list("name"="clienttoken","desc"="Token for identifying the unique client.","type"="str","req"=1),
)
/datum/topic_command/auth_client/run_command(queryparams)
if(!(queryparams["clienttoken"] in unauthed))
statuscode = 404
response = "Client with such token is not found."
return TRUE
var/mob/abstract/unauthed/una = unauthed[queryparams["clienttoken"]]
if(!istype(una) || !una.client)
statuscode = 500
response = "Somethnig went horribly wrong."
return TRUE
if(!config.external_auth)
statuscode = 500
response = "External auth is disalowed."
del(una.client)
del(una)
return TRUE
var/client/cl = directory[ckey(queryparams["key"])]
if(cl)
to_chat(cl, "Another connection has been made using your login key. This session has been terminated.")
del(cl)
statuscode = 200
response = "Client has been authenticated sucessfully."
una.ClientLogin(queryparams["key"])
// Updates external auth state
/datum/topic_command/set_extenal_auth
name = "set_extenal_auth"
description = "Enables or disables external authentication."
params = list(
"state" = list("name"="state","desc"="State to witch option should be updated. If not provided option is toggled.","type"="int","req"=0)
)
/datum/topic_command/set_extenal_auth/run_command(queryparams)
if(queryparams["state"] == null)
config.external_auth = !config.external_auth
else
config.external_auth = queryparams["state"]
statuscode = 200
response = "External authentication state has been updated sucessfully."
data = config.external_auth

View File

@@ -0,0 +1,4 @@
author: Karolis2011
delete-after: True
changes:
- rscadd: "Adds external auth mechanism to allow to play even when BYOND hub is down."