Banking system with Client-Server Sessions

Started by PaullyBeenis, Mar 05, 2021, 12:13 AM

Previous topic - Next topic

PaullyBeenis

Hey all!

I'm working on a banking system for my server and I'd like some assistance in organization of how the server and client sessions should be ran.

Server side
I have a command computer that will act as the server and be inaccessible by players. Clients will send rednet commands to the server to authenticate and then view their balance or send money.

I'll have an "approved client list" of pocket computers/normal computers (ATMS) I have personally setup and locked down to the client bank app. The server will only accept communication from the ID's of these computers.

There is currently 1 lua file on the server bank.lua (https://pastebin.com/2qZ9qEVd)

Client Side
I'll need to write an OS that locks the clients down to only run the bank app and not allow users out of it. (WIP)

Clients will open a session on the server, authenticate, and then send commands to the server for their account. example: getbalance, send(joe, 500)

Current test code I have: https://pastebin.com/fDP3AZ7a


The Question

So the problem is, how can I have multiple client sessions connected to the server at once? The only solution I can think of is to have 10 bank.lua files running on the server at once and each one only communicates with 1 specific user account. That idea sounds awful however.

Lupus590

You have a security problem, rednet IDs depend on the computer IDs and computer IDs can be faked. You will want to look into secure signing systems of real-life instead, which will include some public-key encryption. You might want to look at real-life SSL and key exchange.

For having multiple client sessions at the same time, the way that real-life web servers do it is to have the server have a very short term memory and every request to be a new thread.

A basic rundown with how real-life web servers do this, they get a request and start up a thread to resolve it. Once the thread has resolved the request it sends a response and then terminates itself, the server now has no memory of the request unless that request interacted with the permanent data store.

For CC, you can ignore the thread part as the event queue will be able to take care of this for you.

PaullyBeenis

Quote from: Lupus590 on Mar 05, 2021, 10:19 AMYou have a security problem, rednet IDs depend on the computer IDs and computer IDs can be faked. You will want to look into secure signing systems of real-life instead, which will include some public-key encryption. You might want to look at real-life SSL and key exchange.

For having multiple client sessions at the same time, the way that real-life web servers do it is to have the server have a very short term memory and every request to be a new thread.

A basic rundown with how real-life web servers do this, they get a request and start up a thread to resolve it. Once the thread has resolved the request it sends a response and then terminates itself, the server now has no memory of the request unless that request interacted with the permanent data store.

For CC, you can ignore the thread part as the event queue will be able to take care of this for you.

Thanks for the tips, I'll focus more on security when I have the functionality working. If I understand the event queue correctly, I would have that running on my server and it would wait for requests from clients?

Here is my current though process:


-- Client side:
-- User confirms identity of server from a rednet 3 way handshake type method to confirm its not being spoofed.
-- User sends rednet msg: authenticate(PaullyBeenis,1234)

-- Server side:
-- 2 files running at once, one that listens for messages and adds requests to the event queue, and another file that will pull the events and then run them???

lua file 1:
while true do
    local id,msg,dist=rednet.receive(port)
    if msg.find(str, "authenticate") then
        os.queueEvent("authenticate", username, password)
  end
end

lua file 2:
while true do
    local event, username, password = os.pullEvent()
    if event == "authenticate" then
        if accounts[username]:authenticate(password) then
            -- Add session to sessions list with UNIX time of when it was started and a number token to refer to it.
            -- provide number token to the client to use during banking commands ex: getBalance(token).
            -- Have a 3rd looping lua file running that checks session list every 60 seconds to see if sessions are expired and removes them if they are.
    else
        print("Event: " .. event)
    end
end


Is any of that making sense or am I being an idiot?

Lupus590

Quote from: PaullyBeenis on Mar 06, 2021, 01:57 AM-- 2 files running at once, one that listens for messages and adds requests to the event queue, and another file that will pull the events and then run them???
You don't need two separate files or even a duplicate event loop (maybe, the handshake stuff might disrupt that) Also, it sounds like you are not aware of the parallel API which will be useful in this situation.

rednet.recive doesn't have a port argument, see: https://tweaked.cc/module/rednet.html#v:receive

sending table data will be better than using string.find (mentioning which, you should double-check how you are using string.find as you have done it wrong in the example that you've given.

PaullyBeenis

Quote from: Lupus590 on Mar 06, 2021, 08:44 AM
Quote from: PaullyBeenis on Mar 06, 2021, 01:57 AM-- 2 files running at once, one that listens for messages and adds requests to the event queue, and another file that will pull the events and then run them???
You don't need two separate files or even a duplicate event loop (maybe, the handshake stuff might disrupt that) Also, it sounds like you are not aware of the parallel API which will be useful in this situation.

rednet.recive doesn't have a port argument, see: https://tweaked.cc/module/rednet.html#v:receive

sending table data will be better than using string.find (mentioning which, you should double-check how you are using string.find as you have done it wrong in the example that you've given.

Thank you again, some very useful tips.

as for the string.find I was just writing all of that code as an example, I haven't even run it until now which I took you advice and changed to sending table data which is much easier.


BlackDragon

If I were you I would check if the modem was present when startup of the script.