Page 1 of 2

Safe Login to Server

Posted: Thu Dec 24, 2020 1:54 pm
by Bubble1820DE
Hey guys :ultraglee:

I would like to create an online game and therefore I am using sock.lua (https://camchenry.com/sock.lua/) to do client-server communication. I am struggling to implement a safe login system.

My idea: Every client needs to send a username and a password to the server. After that, the server checks if the received username and password combination exists and accepts the client to login into the game.

So... I think sending the username+password to the server is not secure. Do you guys have any solution for me?

The best thing would be to implement a steam login (https://partner.steamgames.com/doc/features/auth)...

I have also found this https://github.com/britzl/steamworks-defold. Can this be implemented into Love2D as well?

Thanks in advance

Re: Safe Login to Server

Posted: Thu Dec 24, 2020 9:51 pm
by eliddell
You're stepping into a minefield, I'm afraid. Getting network code that's going to be exposed to the open Internet properly secured is a hard problem. Before you go any further, think carefully about what you're trying to do and why.

Do you actually need accounts? What are they meant to do in the context of your game? Are you intending to charge money for use of the server? What data is being stored by the server that has to persist from session to session?

You should never, ever, ever transmit *or store* passwords as plain text, because there *will* be some idiot somewhere who reuses the password from his online banking credentials for your game. Store only hashes of passwords. Transmit passwords only over encrypted connections. sock.lua does not appear to implement encryption of any sort, so you'd have to layer something overtop of it. Simplest method would likely be using an asymmetric algorithm and including the server's public key with your program, although that might cause problems if the server's private key is ever compromised. (If you don't understand what I just said, you probably shouldn't try to implement any of this yourself without reading up on cryptography first.)

You can, in theory, include any Lua library in a Löve program (with possibly some loss of portability if it uses native code), but keep in mind that if you use Steam's auth, people who don't have Steam accounts won't be able to play your game. You may be okay with this. (The same problem arises if you use Google's or Facebook's auth.) It's certainly safer than roll-your-own in terms of passwords possibly escaping.

Re: Safe Login to Server

Posted: Fri Dec 25, 2020 7:08 am
by ivan
Writing a secure login and authentication system is a hard problem. LuaSocket does not support SSL.

Or you can use my Steamworks binding:
https://love2d.org/forums/viewtopic.php?t=87917
My library supports generic HTTPS requests, although you are better off using the existing Steamworks authentication.

Re: Safe Login to Server

Posted: Fri Dec 25, 2020 1:10 pm
by Bubble1820DE
eliddell wrote: Thu Dec 24, 2020 9:51 pm You're stepping into a minefield, I'm afraid. Getting network code that's going to be exposed to the open Internet properly secured is a hard problem. Before you go any further, think carefully about what you're trying to do and why.

Do you actually need accounts? What are they meant to do in the context of your game? Are you intending to charge money for use of the server? What data is being stored by the server that has to persist from session to session?

You should never, ever, ever transmit *or store* passwords as plain text, because there *will* be some idiot somewhere who reuses the password from his online banking credentials for your game. Store only hashes of passwords. Transmit passwords only over encrypted connections. sock.lua does not appear to implement encryption of any sort, so you'd have to layer something overtop of it. Simplest method would likely be using an asymmetric algorithm and including the server's public key with your program, although that might cause problems if the server's private key is ever compromised. (If you don't understand what I just said, you probably shouldn't try to implement any of this yourself without reading up on cryptography first.)

You can, in theory, include any Lua library in a Löve program (with possibly some loss of portability if it uses native code), but keep in mind that if you use Steam's auth, people who don't have Steam accounts won't be able to play your game. You may be okay with this. (The same problem arises if you use Google's or Facebook's auth.) It's certainly safer than roll-your-own in terms of passwords possibly escaping.
Players one my server can kill enemies and earn exp, coins... I want to store these things. Also, they can buy stuff for real money (for example premium currency). This entire cryptography seems to be complex enough :3 Therefore using Steam auth would be a safer option for me
ivan wrote: Fri Dec 25, 2020 7:08 am Writing a secure login and authentication system is a hard problem. LuaSocket does not support SSL.

Or you can use my Steamworks binding:
https://love2d.org/forums/viewtopic.php?t=87917
My library supports generic HTTPS requests, although you are better off using the existing Steamworks authentication.
I would really like to use these steamworks bindings, but I can't access your file:

Image

Re: Safe Login to Server

Posted: Fri Dec 25, 2020 9:37 pm
by ivan
Sorry about that. The repository should be visible now.

Re: Safe Login to Server

Posted: Sat Dec 26, 2020 1:58 am
by Bubble1820DE
ivan wrote: Fri Dec 25, 2020 9:37 pm Sorry about that. The repository should be visible now.
Thanks I installed it :)

I am using your code for testing but also receiving an error.

Code: Select all

local ffi = require('ffi')
local lib = require('sworks.flat')
lib.SteamAPI_Init()

local uhandle = lib.SteamAPI_GetHSteamUser()
local user = lib.SteamInternal_FindOrCreateUserInterface(uhandle, 'SteamUser020')
local id = lib.SteamAPI_ISteamUser_GetSteamID(user)
local cid = ffi.new('CSteamID')
cid.m_steamid.m_comp.m_unAccountID = id
local req = lib.SteamAPI_ISteamUserStats_RequestUserStats(user, cid)

local utils = lib.SteamInternal_FindOrCreateUserInterface(uhandle, 'SteamUtils009')
local failed = ffi.new('bool[1]')
while true do
  if lib.SteamAPI_ISteamUtils_IsAPICallCompleted(utils, req, failed) then
    break
  end
end
if failed[1] then
  print('request failed')
else
  print('stats received!')
end
Image

Re: Safe Login to Server

Posted: Sat Dec 26, 2020 7:18 am
by ivan
Thanks for pointing this out. The library works although I haven't had time to update the examples or produce decent documentation.

The flat API is considerably harder and requires good understanding of Lua FFI:

Code: Select all

local cid = ffi.new('uint64_t', id)
local req = lib.SteamAPI_ISteamUserStats_RequestUserStats(user, cid)
I recommend using the higher layer of abstraction:

Code: Select all

steam = require("sworks.main")
assert(steam.init() and steam.isRunning(), 'Steam client must be running')
assert(steam.isConnected(), 'Steam is in Offline mode')
user = steam.getUser()
print('hello '..user:getName())
user:requestStats(function(ok, msg)
  if ok then
    print('stats received!')
  else
    print('request failed:'..msg)
  end
end)
while true do
  steam.update()
end

Re: Safe Login to Server

Posted: Sat Dec 26, 2020 10:11 am
by Bubble1820DE
ivan wrote: Sat Dec 26, 2020 7:18 am Thanks for pointing this out. The library works although I haven't had time to update the examples or produce decent documentation.

The flat API is considerably harder and requires good understanding of Lua FFI:
...
I want to use GetAuthSessionTicket so I think I need to use the flat API. Is it possible to do that with the higher layer of abstraction? :o:

Could you please provide me an example of how to use GetAuthSessionTicket with your library? :awesome:

Thanks in advance

Re: Safe Login to Server

Posted: Sat Dec 26, 2020 2:45 pm
by ivan
You can call:

Code: Select all

user = steam.getUser()
ticket = user:getAuthTicket()
Having said that, there is rarely a need for the ticket so
make sure you read and understand the Steamworks documentation.
The following two functions should be enough for most games:

Code: Select all

steam.isRunning()
steam.isConnected()

Re: Safe Login to Server

Posted: Sun Dec 27, 2020 10:53 am
by Bubble1820DE
ivan wrote: Sat Dec 26, 2020 2:45 pm You can call:

Code: Select all

user = steam.getUser()
ticket = user:getAuthTicket()
Thank you so much! :awesome:

I just have one more question. The client gets the ticket with user:getAuthTicket(). After that, the client sends the ticket to the server. Afterwards, the server needs to verify the ticket with this web-request AuthenticateUserTicket.

Could u please give me an example of how to do it? Do I need to do it with steam.request(...)?
I have found an example here: https://stackoverflow.com/questions/461 ... uest-error

I also need to convert the ticket from binary to hex into an appropriately sized byte character array :S

Image