• gmsv_gatekeeper - Lua controlled server authentication
    453 replies, posted
  • Avatar of YYZ
  • [QUOTE=jA_cOp;14400802]There should be a way to check if a player object is valid, no?[/QUOTE] Fairly sure the player object doesn't even exist at the time Gatekeeper is doing its work.
  • Avatar of ComWalk
  • [QUOTE=jA_cOp;14400802]There should be a way to check if a player object is valid, no?[/QUOTE] There is no player object at all, so there is no need to verify that a player object is valid.
  • Avatar of jA_cOp
  • [QUOTE=ComWalk;14406906]There is no player object at all, so there is no need to verify that a player object is valid.[/QUOTE] Then what is returned by player.GetAll()? edit: Nevermind, I misread, I thought you had said they [B]did[/B] get returned by player.GetAll
  • Avatar of kevkev
  • Is there any way to remove the password popup at the client (I doubt it but still i want to be sure).
  • Avatar of ComWalk
  • [QUOTE=kevkev;14518831]Is there any way to remove the password popup at the client (I doubt it but still i want to be sure).[/QUOTE] Are you referring to the 'Bad Password' popup or the request for a password to be entered? If you wish to remove the request for the password to be entered, simply set sv_password to "" to make the server appear unpassworded in the server browser. You can then create your own password cvar if you desire, however connecting clients will have to join your server via the console.
  • Avatar of ComWalk
  • [QUOTE=Janorkie;14523603]Could you make a way to suppress the Bad Password message?[/QUOTE] You can override it with a custom message (which was added with the most recent version), however masking it entirely would result in the client treating the server as if it had crashed causing 3 additional connection attempts followed by the client-side "Could not connect" error. I see very little practical use for such a feature and have no plans of implementing it; it results in nothing but a headache for people who try to join. Overriding it should be sufficient for most any use.
  • Avatar of kevkev
  • Yea i was referring to the part when the server was passworded and a client joined that would be allowed to connect.
  • Avatar of ComWalk
  • [QUOTE=kevkev;14526444]Yea i was referring to the part when the server was passworded and a client joined that would be allowed to connect.[/QUOTE] In that case, a trade-off exists: It can either be not there for everybody (and those who would need to join with a password must join from the console), or there for everbody (and those who have no password required have to either enter gibberish or join from the console). Ultimately it doesn't matter which.
  • Avatar of kevkev
  • Is it possible to check with this module when it it installed clientside to check if the server allows the player to join without entering a password and remove the password dialogue?
  • Avatar of Armandur
  • I don't run a server but I can see how greatly this would benefit those that do.
  • Avatar of ComWalk
  • [QUOTE=kevkev;14531130]Is it possible to check with this module when it it installed clientside to check if the server allows the player to join without entering a password and remove the password dialogue?[/QUOTE] Not only is that fundamentally impossible without reversing and modifying unholy amounts of engine code, this module has absolutely no client-side functionality.
  • Avatar of kevkev
  • [QUOTE=ComWalk;14535499]Not only is that fundamentally impossible without reversing and modifying unholy amounts of engine code, this module has absolutely no client-side functionality.[/QUOTE] To bad.
  • Avatar of AzuiSleet
  • Except it's an engine hook, and garry already stated he didn't want to compile his own engine binaries.
  • Avatar of thomasfn
  • Yeah so I'm trying to get this to work, and it won't load at all. The gatekeeper table doesn't exist, so it can't be reading the dll (yes, I did do it serverside). I put the dll in every location possible, but it still won't load. Help anyone? (This is singleplayer, but it should still load the binaries - it does for MySQL, lua socket, and guardian)
  • Avatar of thomasfn
  • How the hell did I miss that, I must have been [b]really[/b] tired last night. Thanks.
  • Avatar of ComWalk
  • Upgraded gatekeeper to version 2.5, this includes the addition of the function gatekeeper.GetNumClients which returns a table detailing total clients in server, total clients active, and total clients currently in the connection process. This was sort of a rush job due to necessity but in the rushed test it held up alright. I plan on really cleaning this module up sometime soon to move away from signature scanning and detours and towards VMT hooking. [QUOTE=Catdaemon;14361390]Is your example code supposed to work when the server is full? I'm playing with this, I'm running password admin then retry but it still says it's full and doesn't kick anyone. Doesn't seem to work with sv_password set either.[/QUOTE] This was caused by players being in the connection process and not quite spawned, making them invisible to gmod lua. This can now be fixed by using gatekeeper.GetNumClients().
  • Avatar of DarkSpider
  • Is there a way you could add the connecting player's userid as one of the args for the PlayerPasswordAuth hook?
  • Avatar of ComWalk
  • [QUOTE=DarkSpider;16417546]Is there a way you could add the connecting player's userid as one of the args for the PlayerPasswordAuth hook?[/QUOTE] I'm not quite sure what you're asking for; do you mean the userid reported by the status concommand (which isn't assigned until after a connection attempt is successful), the entity index of the player (which isn't assigned until way after a connection attempt is successful), or the steamid which is already available in the hook? The first two can't be done because the player [b]isn't in the server yet[/b] (which is pretty much the point of the module), and the third one is already in. [editline]03:49PM[/editline] I've release version 3 with a fix for a potentially exploitable bug as well as cleaned up code. It no longer uses detours, and instead uses VMT hooking (it's much prettier). It now includes an appropriate class definition for CBaseServer and no longer uses signatures or manual vtable lookups to access members or functions. Internal code has been changed significantly, but the only changes affecting how gatekeeper is used are the ability to now return a string in PlayerPasswordAuth and the bug fix.
  • Avatar of yngndrw
  • ComWalk: First off, I love your work. Your approach to getting the Steam ID from the stack is very inventive. I'd just like to ask a few questions and point out what I think may be a small bug. First off, is this PlayerPasswordAuth hook still called when no password has been set and hence even when the player has not entered a password ? (As they haven't been asked for one.) This is for ban-checking before a user has even connected. Secondly, when you normally check Player:SteamID() before a player has spawned in Lua, you usually end up with STEAM_ID_PENDING for a while. How does this module combat this and how "guaranteed" is it that the Steam ID supplied in your hook would be valid ? Thirdly, I noticed that you do some additional checks on the Steam ID - Are these normally done with Player:SteamID() or should these be done by hand for Lua stuff ? Finally the bug (I think.), regarding the line: [code]gLua->Push(gLua->GetGlobal("hook")->GetMember("Call"));[/code] Does the two ILuaObject pointers not need to be unreferenced ? Same goes for the object created here: [code]ILuaObject* gatekeeper = gLua->GetNewTable();[/code] Thanks.
  • Avatar of AzuiSleet
  • This is an engine level hook where it checks if there is a password and whether or not it's valid. This is called for any player connecting, regardless of if there is a password. This is NOT called when the server changes level, the players in the server are already authed and the PlayerPasswordAuth hook will not be called for them. There is no guarantee for the steam id. It can be completely invalid or pending. Garry hasn't specified what members increase refcounts, so it's difficult to say that it's necessary to UnReference after GetGlobal or GetMember.
  • Avatar of ComWalk
  • [QUOTE=yngndrw;16444047]Ah I see, thank you for your help AzuiSleet. :)[/QUOTE] To build on what was said, the steamid I use is pulled from the steam ticket/certificate sent to the server by the client. It is possible for this to be maliciously modified by the client to report any steamid, [b]however[/b] this steam ticket is validated by the server with steam servers and such a modification would result in the client getting kicked further into the connection process. The gatekeeper table is unreferenced (scroll down a tad more), and I'm fairly certain that things from GetGlobal don't need to be unreferenced. (But, as AzuiSleet said, there's really no way to tell. Take that one up with garry.)
  • Avatar of yngndrw
  • So in short - I can use this as an early check for bans, however I should also double check it when they have connected / spawned ? Sounds like it would still be a good advantage to do the earlier check. Would it be reasonable to kick for a Steam ID of "STEAM_ID_UNKNOWN" at this stage, in light of the extra validation that you are doing ? I'm assuming that if a user has not yet sent the Steam ID for whatever reason then it would come up as "STEAM_ID_PENDING" at this stage and that the only IDs which should come up as unknown are people who are trying to get around various checks and a small handful of very unlucky users. (Who should be able to reconnect later with no problem.) Sorry about the gatekeeper object, I missed that unreference. Thank you also ComWalk. :)
  • Avatar of ComWalk
  • [QUOTE=yngndrw;16444368]So in short - I can use this as an early check for bans, however I should also double check it when they have connected / spawned ? Sounds like it would still be a good advantage to do the earlier check. Would it be reasonable to kick for a Steam ID of "STEAM_ID_UNKNOWN" at this stage, in light of the extra validation that you are doing ? I'm assuming that if a user has not yet sent the Steam ID for whatever reason then it would come up as "STEAM_ID_PENDING" at this stage and that the only IDs which should come up as unknown are people who are trying to get around various checks and a small handful of very unlucky users. (Who should be able to reconnect later with no problem.) [/QUOTE] You are correct on all counts. Checking both in PlayerPasswordAuth and on spawn is what I would suggest that you do, and from what I have seen, every instance in which STEAM_ID_UNKNOWN is reported would result in a kick later in the connection process for an invalid steam ticket anyways. In my testing I have actually never seen STEAM_ID_PENDING. I suspect that STEAM_ID_PENDING is used instead of the steamid in the steam certificate until the certificate has been verified by the server. If I am right, since I rip the steamid straight out of the certificate the lack of STEAM_ID_PENDING makes sense, but I am no expert on how steam works and could very well be wrong. [QUOTE=yngndrw;16444368] Sorry about the gatekeeper object, I missed that unreference. Thank you also ComWalk. :) [/QUOTE] Don't worry about it, and no problem.