Advertisement
Guest User

server.lua

a guest
Dec 10th, 2018
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.68 KB | None | 0 0
  1. local channels = {
  2.   atm = 1,
  3.   db = 2,
  4. }
  5.  
  6. os.loadAPI("/database/common.lua")
  7. os.loadAPI("/database/sha256.lua")
  8.  
  9. local database = {}
  10. local dbpath = "/bank.db"
  11. local logpath = "/bank.log"
  12. local maintenance_pass = "test"
  13. local modem = peripheral.find("modem")
  14.  
  15. local function loadDB(path)
  16.   local ret = {}
  17.   if fs.exists(path) then
  18.     local f = fs.open(path, "r")
  19.     local c = f.readAll()
  20.     ret = textutils.unserialise(c)
  21.     if not ret then return false end
  22.   end
  23.   return ret
  24. end
  25. local function saveDB(path, db)
  26.   local f = fs.open(path, "w")
  27.   local s = textutils.serialise(db)
  28.   f.write(s)
  29.   f.close()
  30.   return true
  31. end
  32. local function printHeader(str, ny)
  33.   local w, h = term.getSize()
  34.   local x, y = term.getCursorPos()
  35.   term.setCursorPos(math.ceil(w/2) - math.floor(#str/2), ny or 1)
  36.   term.clearLine()
  37.   term.write(str)
  38.   term.setCursorPos(x, y)
  39. end
  40. local logfile = fs.open(logpath, "a")
  41. local function log(top, str, nosave)
  42.   local form = (top and ("["..top.."] ") or "")..(str)
  43.   print(form)
  44.   printHeader("Database running with "..dbpath)
  45.   if not nosave then
  46.     logfile.writeLine(form)
  47.     logfile.flush()
  48.   end
  49. end
  50.  
  51. database = loadDB(dbpath)
  52. saveDB(dbpath, database)
  53.  
  54. -- modem.open(channels.db)
  55. term.clear()
  56. term.setCursorPos(1,2)
  57. logfile.writeLine()
  58. log("Init", "Database started")
  59.  
  60. while true do
  61.   local event, side, chan, reply, msg = os.pullEvent()
  62.   if event == "modem_message" and chan == channels.db and reply == channels.atm and type(msg) == "table" then
  63.  
  64.     if msg[1] == "auth" then
  65.       local user = msg[2]:lower()
  66.       local userdata = database[user]
  67.       if userdata then
  68.         modem.transmit(reply, channels.db, {true, userdata.salt})
  69.         local resp = common.waitForMsg(reply, 2)
  70.         if resp and resp[1] then
  71.           local ok = resp[2] == userdata.passwd
  72.           modem.transmit(reply, channels.db, {ok, not ok and "Wrong password" or nil})
  73.           log("Auth", (ok and "Valid" or "Invalid").." auth: "..user)
  74.         else log("Auth", user.." timed out")
  75.         end
  76.       else
  77.         log("Auth", "User not found: "..user)
  78.         modem.transmit(reply, channels.db, {false, "User not found"})
  79.       end
  80.  
  81.     elseif msg[1] == "register" then
  82.       local user = msg[2]:lower()
  83.       local ok = true
  84.       if user:find("%s") then ok = false log("Register", "Tried registering with a space: "..user) modem.transmit(reply, channels.db, {false, "Username cannot contain spaces"}) end
  85.       if database[user] then ok = false log("Register", "User already exists: "..user) modem.transmit(reply, channels.db, {false, "User already exists"}) end
  86.       if ok then
  87.         local salt = common.genSalt(16)
  88.         modem.transmit(reply, channels.db, {true, salt})
  89.         local r = common.waitForMsg(reply, 2)
  90.         if r and r[1] and type(r[2]) == "string" and #r[2] == 64 then
  91.           database[user] = {}
  92.           database[user].balance = 0
  93.           database[user].passwd = r[2]
  94.           database[user].salt = salt
  95.           saveDB(dbpath, database)
  96.           log("Register", user.." created")
  97.           modem.transmit(reply, channels.db, {true})
  98.         else
  99.           log("Register", user.." timed out")
  100.         end
  101.       end
  102.  
  103.     elseif msg[1] == "balance" then
  104.       local user = msg[2]:lower()
  105.       local userdata = database[user]
  106.       if msg[3] == userdata.passwd then
  107.         modem.transmit(reply, channels.db, {true, userdata.balance})
  108.         log("Balance", "Sent balance: "..user)
  109.       else
  110.         modem.transmit(reply, channels.db, {false, "Invalid hash"})
  111.         log("Balance", "Invalid hash from: "..user)
  112.       end
  113.  
  114.     elseif msg[1] == "transfer" then
  115.       local user = msg[2]:lower()
  116.       local recip = msg[4]:lower()
  117.       local hash = msg[3]
  118.       local amt = tonumber(msg[5]) or math.huge
  119.       amt = math.abs(amt)
  120.       local userdat = database[user]
  121.       local recipdat = database[recip]
  122.       local ok = true
  123.  
  124.       if not recipdat then ok = false log("Transfer", user.." tried to send to invalid: "..recip) modem.transmit(reply, channels.db, {false, "Recipient doesn't exist"}) end
  125.       if userdat.passwd ~= hash then ok = false log("Transfer", "Invalid hash from: "..user) modem.transmit(reply, channels.db, {false, "Invalid hash"}) end
  126.       if userdat.balance < amt then ok = false log("Transfer", user.." tried to send "..amt.." but has "..userdat.balance.." to "..recip) modem.transmit(reply, channels.db, {false, "Insufficent funds"}) end
  127.       if ok then
  128.         database[user].balance = userdat.balance - amt
  129.         database[recip].balance = recipdat.balance + amt
  130.         saveDB(dbpath, database)
  131.         modem.transmit(reply, channels.db, {true, userdat.balance})
  132.         log("Transfer", user.." transfered "..amt.." to "..recip)
  133.       end
  134.     end
  135.  
  136.   elseif event == "key" and side == keys.enter then
  137.     log("Admin", "Enter password")
  138.     write("> ")
  139.     local pswd = read("*")
  140.     if pswd == maintenance_pass then
  141.       log("Admin", "Entering maintenance mode")
  142.       while true do
  143.         write("> ")
  144.         local cmd = read()
  145.         cmd = common.split(cmd, "%s")
  146.         if cmd[1] == "set" then
  147.           local user = cmd[2]:lower()
  148.           local amt = tonumber(cmd[3]) or 0
  149.           if database[user] then
  150.             database[user].balance = amt
  151.             saveDB(dbpath, database)
  152.             log("Admin", "Set "..user.." balance to "..amt)
  153.           else
  154.             log("Admin", "Cannot set balance of "..user)
  155.           end
  156.  
  157.         elseif cmd[1] == "add" then
  158.           local user = cmd[2]:lower()
  159.           local amt = tonumber(cmd[3]) or 0
  160.           if database[user] then
  161.             database[user].balance = database[user].balance + amt
  162.             saveDB(dbpath, database)
  163.             log("Admin", (amt >= 0 and "Added " or "Removed ")..amt.." to "..user.."'s balance")
  164.           else
  165.             log("Admin", "Cannot add to balance of "..user)
  166.           end
  167.  
  168.         elseif cmd[1] == "create" then
  169.           local user = cmd[2]:lower()
  170.           local ok = true
  171.           if user:find("%s") then ok = false log("Admin", "Tried registering with a space: "..user) end
  172.           if database[user] then ok = false log("Admin", "User already exists: "..user) end
  173.           if ok then
  174.             write("Password: ")
  175.             local pass = read()
  176.             local salt = common.genSalt(16)
  177.             local hash = sha256.pbkdf2(pass, salt, 64):toHex()
  178.             database[user] = {}
  179.             database[user].balance = 0
  180.             database[user].passwd = hash
  181.             database[user].salt = salt
  182.             saveDB(dbpath, database)
  183.             log("Admin", user.." created")
  184.           end
  185.  
  186.         elseif cmd[1] == "delete" then
  187.           local user = cmd[2]:lower()
  188.           if database[user] then
  189.             database[user] = nil
  190.             saveDB(dbpath, database)
  191.             log("Admin", user.." deleted from database")
  192.           else
  193.             log("Admin", "Tried to delete invalid user: "..user)
  194.           end
  195.  
  196.         elseif cmd[1] == "recover" then
  197.           local user = cmd[2]:lower()
  198.           if database[user] then
  199.             write("New Password: ")
  200.             local pass = read()
  201.             local salt = common.genSalt(16)
  202.             local hash = sha256.pbkdf2(pass, salt, 64):toHex()
  203.             database[user].passwd = hash
  204.             database[user].salt = salt
  205.             saveDB(dbpath, database)
  206.             log("Admin", user.." password changed")
  207.           else
  208.             log("Admin", user.." does not exists")
  209.           end
  210.  
  211.         elseif cmd[1] == "list" then
  212.           local users = {}
  213.           for user, userdat in pairs(database) do
  214.             log(nil, user..": "..userdat.balance, true)
  215.           end
  216.         elseif cmd[1] == "help" then
  217.           log(nil, "set <user> <balance> -- Sets a users balance", true)
  218.           log(nil, "add <user> <+/- amount> -- Add or remove from user balance", true)
  219.           log(nil, "create <user> -- Add an account to the database", true)
  220.           log(nil, "delete <user> -- Removes an account from the database", true)
  221.           log(nil, "recover <user> -- Changes an account's password", true)
  222.           log(nil, "list -- Lists accounts", true)
  223.           log(nil, "quit -- Quits maintenance mode", true)
  224.           log(nil, "stop -- Stops the database", true)
  225.  
  226.         elseif cmd[1] == "quit" then break
  227.         elseif cmd[1] == "stop" then return
  228.  
  229.         else log("Command", "Invalid command: "..(cmd[1] or ""), true)
  230.         end
  231.         repeat event, side = os.pullEvent("key") until side == keys.enter
  232.       end
  233.       log("Admin", "Exiting maintenance")
  234.     else
  235.       log("Admin", "Wrong password")
  236.     end
  237.   end
  238. end
  239. log("Admin", "Database shutting down")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement