This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
KingofGamesYami's profile picture

[Fixed]isAdmin not working correctly

Started by KingofGamesYami, 11 April 2014 - 11:46 AM
KingofGamesYami #1
Posted 11 April 2014 - 01:46 PM
OS

local function loadFile(file)
local file = io.open(file, "r")
local data = file:read()
file:close()
return textutils.unserialize(data)
end
local UserPass = loadFile("KingOS_Files/UserPass")
local Admin = loadFile("KingOS_Files/Admin")
local Viewer = loadFile("KingOS_Files/Viewer")
--
--  Adaptation of the Secure Hashing Algorithm (SHA-244/256)
--  Found Here: http://lua-users.org/wiki/SecureHashAlgorithm
--
--  Using an adapted version of the bit library
--  Found Here: https://bitbucket.org/Boolsheet/bslf/src/1ee664885805/bit.lua
--
local MOD = 2^32
local MODM = MOD-1
local function memoize(f)
local mt = {}
local t = setmetatable({}, mt)
function mt:__index(k)
  local v = f(k)
  t[k] = v
  return v
end
return t
end
local function make_bitop_uncached(t, m)
local function bitop(a, B)/>/>/>
  local res,p = 0,1
  while a ~= 0 and b ~= 0 do
   local am, bm = a % m, b % m
   res = res + t[am][bm] * p
   a = (a - am) / m
   b = (b - bm) / m
   p = p*m
  end
  res = res + (a + B)/>/>/> * p
  return res
end
return bitop
end
local function make_bitop(t)
local op1 = make_bitop_uncached(t,2^1)
local op2 = memoize(function(a) return memoize(function(B)/>/>/> return op1(a, B)/>/>/> end) end)
return make_bitop_uncached(op2, 2 ^ (t.n or 1))
end
local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})
local function bxor(a, b, c, ...)
local z = nil
if b then
  a = a % MOD
  b = b % MOD
  z = bxor1(a, B)/>/>/>
  if c then z = bxor(z, c, ...) end
  return z
elseif a then return a % MOD
else return 0 end
end
local function band(a, b, c, ...)
local z
if b then
  a = a % MOD
  b = b % MOD
  z = ((a + B)/>/>/> - bxor1(a,B)/>/>/>) / 2
  if c then z = bit32_band(z, c, ...) end
  return z
elseif a then return a % MOD
else return MODM end
end
local function bnot(x) return (-1 - x) % MOD end
local function rshift1(a, disp)
if disp < 0 then return lshift(a,-disp) end
return math.floor(a % 2 ^ 32 / 2 ^ disp)
end
local function rshift(x, disp)
if disp > 31 or disp < -31 then return 0 end
return rshift1(x % MOD, disp)
end
local function lshift(a, disp)
if disp < 0 then return rshift(a,-disp) end
return (a * 2 ^ disp) % 2 ^ 32
end
local function rrotate(x, disp)
	x = x % MOD
	disp = disp % 32
	local low = band(x, 2 ^ disp - 1)
	return rshift(x, disp) + lshift(low, 32 - disp)
end
local k = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
}
local function str2hexa(s)
return (string.gsub(s, ".", function(c) return string.format("%02x", string.byte(c)) end))
end
local function num2s(l, n)
local s = ""
for i = 1, n do
  local rem = l % 256
  s = string.char(rem) .. s
  l = (l - rem) / 256
end
return s
end
local function s232num(s, i)
local n = 0
for i = i, i + 3 do n = n*256 + string.byte(s, i) end
return n
end
local function preproc(msg, len)
local extra = 64 - ((len + 9) % 64)
len = num2s(8 * len, 8)
msg = msg .. "\128" .. string.rep("\0", extra) .. len
assert(#msg % 64 == 0)
return msg
end
local function initH256(H)
H[1] = 0x6a09e667
H[2] = 0xbb67ae85
H[3] = 0x3c6ef372
H[4] = 0xa54ff53a
H[5] = 0x510e527f
H[6] = 0x9b05688c
H[7] = 0x1f83d9ab
H[8] = 0x5be0cd19
return H
end
local function digestblock(msg, i, H)
local w = {}
for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end
for j = 17, 64 do
  local v = w[j - 15]
  local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
  v = w[j - 2]
  w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
end
local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
for i = 1, 64 do
  local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
  local maj = bxor(band(a, B)/>/>/>, band(a, c), band(b, c))
  local t2 = s0 + maj
  local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
  local ch = bxor (band(e, f), band(bnot(e), g))
  local t1 = h + s1 + ch + k[i] + w[i]
  h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
end
H[1] = band(H[1] + a)
H[2] = band(H[2] + B)/>/>/>
H[3] = band(H[3] + c)
H[4] = band(H[4] + d)
H[5] = band(H[5] + e)
H[6] = band(H[6] + f)
H[7] = band(H[7] + g)
H[8] = band(H[8] + h)
end
local function sha256(msg)
msg = preproc(msg, #msg)
local H = initH256({})
for i = 1, #msg, 64 do digestblock(msg, i, H) end
return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..
  num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))
end

local function setUserPass()
local file = io.open("/KingOS_Files/UserPass", "w")
file:write(textutils.serialize(UserPass))
file:close()
end
function promptFor(text, ...) --it will print 'text: ', and only except answers specified aftet text. eg promptFor("hello", "right", "left") would accept 'right' or 'left'
local tArgs = {...}
local tValid = {}
for i = 1, #tArgs do
  tValid[tArgs[i]] = true
end
term.write(text..": ")
local input = read()
if tValid[input] or #tArgs == 0 then
  return input
else
  print("Valid Options:") --gives the user a list of specified options
  for i = 1, #tArgs do
   print(tArgs[i])
   if i < #tArgs then
	term.write("or ")
   end
  end
  return promptFor(text, ...)
end
end
function promptForUser(...)
local Args = {...}
print("Please Enter Username &amp; Password")
term.write("Username: ")
local Username = read()
term.write("Password: ")
local uPass = (read("*"))
local User = {}
local cPass = {}
for i = 1, #Args, 2 do
  User[i] = Args[i]
  cPass[i] = Args[i+1]
end
local x
for k,v in pairs(User) do
  if v == Username then
   x = k
  end
end
if Username == User[x] and uPass == cPass[x] then
  print("Welcome "..Username.."!")
  return Username
elseif Username == User[x] and uPass ~= cPass[x] then
  print("Incorrect Password")
  return promptForUser(tries, ...)
else
  print("This program isn't working!")
  sleep(1)
end
end
function promptForSecure(text, char, tries, ...)
local Args = {...}
local Valid = {}
for i = 1, #Args do
  Valid[Args[i]] = true
end
term.write(text..": ")
input = read(char)
if Valid[input] or #Args == 0 then
  return input
elseif tries == 0 then
  return false
else
  tries = tries-1
  print("Please try again.")
  return promptForSecure(text, char, tries, ...)
end
end
local function newUser(Name, Password, aLevel)
UserPass[#UserPass+1] = Name
UserPass[#UserPass+1] = sha256(Password)
if aLevel == "Admin" then
  Admin[#Admin+1] = Name
elseif aLevel == "Viewer" then
  Viewer[#Viewer+1] = Name
end
setUserPass()
end
local function isAdmin(User)
for k,v in pairs(Admin) do
  if v == User then
   return true
  elseif v == nil then
   return false
  end
end
end
local function isViewer(User)
for k,v in pairs(Viewer) do
  if v == UserLogin then
   return true
  elseif v == nil then
   return false
  end
end
end
--os.pullEvent = os.pullEventRaw
local UserLogin = promptForUser(UserPass)
if UserLogin == false then
os.reboot()
end
while true do
local action = promptFor("Action")
if string.lower(action) == "logout" then
  print("Logging out...")
  sleep(2)
  print("Shutting down...")
  sleep(2)
  os.reboot()
elseif isAdmin(UserLogin) then
  if string.sub(action, 0, 5) == "set up" then
   newUser(p.promptFor("Name"), promptForSecure("Password", nil, "*"), api.promptFor("Access Level", "Admin", "Viewer"))
  else
   shell.run(action)
  end
elseif isViewer(UserLogin) then
  if string.sub(action, 0, 3) == "edit" then
   print("You don't have access to do that!")
  else
   shell.run(action)
  end
end
end
Installer

local MOD = 2^32
local MODM = MOD-1
local function memoize(f)
local mt = {}
local t = setmetatable({}, mt)
function mt:__index(k)
  local v = f(k)
  t[k] = v
  return v
end
return t
end
local function make_bitop_uncached(t, m)
local function bitop(a, B)/>/>
  local res,p = 0,1
  while a ~= 0 and b ~= 0 do
   local am, bm = a % m, b % m
   res = res + t[am][bm] * p
   a = (a - am) / m
   b = (b - bm) / m
   p = p*m
  end
  res = res + (a + B)/>/> * p
  return res
end
return bitop
end
local function make_bitop(t)
local op1 = make_bitop_uncached(t,2^1)
local op2 = memoize(function(a) return memoize(function( B)/>/> return op1(a, B)/>/> end) end)
return make_bitop_uncached(op2, 2 ^ (t.n or 1))
end
local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})
local function bxor(a, b, c, ...)
local z = nil
if b then
  a = a % MOD
  b = b % MOD
  z = bxor1(a, B)/>/>
  if c then z = bxor(z, c, ...) end
  return z
elseif a then return a % MOD
else return 0 end
end
local function band(a, b, c, ...)
local z
if b then
  a = a % MOD
  b = b % MOD
  z = ((a + B)/>/> - bxor1(a, B)/>/>) / 2
  if c then z = bit32_band(z, c, ...) end
  return z
elseif a then return a % MOD
else return MODM end
end
local function bnot(x) return (-1 - x) % MOD end
local function rshift1(a, disp)
if disp < 0 then return lshift(a,-disp) end
return math.floor(a % 2 ^ 32 / 2 ^ disp)
end
local function rshift(x, disp)
if disp > 31 or disp < -31 then return 0 end
return rshift1(x % MOD, disp)
end
local function lshift(a, disp)
if disp < 0 then return rshift(a,-disp) end
return (a * 2 ^ disp) % 2 ^ 32
end
local function rrotate(x, disp)
	x = x % MOD
	disp = disp % 32
	local low = band(x, 2 ^ disp - 1)
	return rshift(x, disp) + lshift(low, 32 - disp)
end
local k = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
}
local function str2hexa(s)
return (string.gsub(s, ".", function© return string.format("%02x", string.byte©) end))
end
local function num2s(l, n)
local s = ""
for i = 1, n do
  local rem = l % 256
  s = string.char(rem) .. s
  l = (l - rem) / 256
end
return s
end
local function s232num(s, i)
local n = 0
for i = i, i + 3 do n = n*256 + string.byte(s, i) end
return n
end
local function preproc(msg, len)
local extra = 64 - ((len + 9) % 64)
len = num2s(8 * len, 8)
msg = msg .. "\128" .. string.rep("\0", extra) .. len
assert(#msg % 64 == 0)
return msg
end
local function initH256(H)
H[1] = 0x6a09e667
H[2] = 0xbb67ae85
H[3] = 0x3c6ef372
H[4] = 0xa54ff53a
H[5] = 0x510e527f
H[6] = 0x9b05688c
H[7] = 0x1f83d9ab
H[8] = 0x5be0cd19
return H
end
local function digestblock(msg, i, H)
local w = {}
for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end
for j = 17, 64 do
  local v = w[j - 15]
  local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
  v = w[j - 2]
  w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
end
local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
for i = 1, 64 do
  local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
  local maj = bxor(band(a, B)/>/>, band(a, c), band(b, c))
  local t2 = s0 + maj
  local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
  local ch = bxor (band(e, f), band(bnot(e), g))
  local t1 = h + s1 + ch + k[i] + w[i]
  h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
end
H[1] = band(H[1] + a)
H[2] = band(H[2] + B)/>/>
H[3] = band(H[3] + c)
H[4] = band(H[4] + d)
H[5] = band(H[5] + e)
H[6] = band(H[6] + f)
H[7] = band(H[7] + g)
H[8] = band(H[8] + h)
end
local function sha256(msg)
msg = preproc(msg, #msg)
local H = initH256({})
for i = 1, #msg, 64 do digestblock(msg, i, H) end
return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..
  num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))
end
local function promptFor(text, ...) --it will print 'text: ', and only except answers specified after text. eg promptFor("hello", "right", "left") would accept 'right' or 'left'
local tArgs = {...}
local tValid = {}
for i = 1, #tArgs do
  tValid[tArgs[i]] = true
end
term.write(text..": ")
local input = read()
if tValid[input] or #tArgs == 0 then
  return input
else
  print("Valid Options:") --gives the user a list of specified options
  for i = 1, #tArgs do
   print(tArgs[i])
   if i < #tArgs then
	term.write("or ")
   end
  end
  return promptFor(text, ...)
end
end
function promptForSecure(text, char, tries, ...)
local Args = {...}
local Valid = {}
for i = 1, #Args do
  Valid[Args[i]] = true
end
term.write(text..": ")
input = read(char)
if Valid[input] or #Args == 0 then
  return input
elseif tries == 0 then
  return false
else
  tries = tries-1
  print("Please try again.")
  return promptForSecure(text, char, tries, ...)
end
end
print("Setting Up User Accounts")
sleep(1)
local aName = promptFor("Admin Username")
local aPass = sha256(promptForSecure("Admin Password", "*"))
local UserPass = {aName, aPass}
print("Creating required files")
fs.makeDir("KingOS_Files")
local file = io.open("KingOS_Files/UserPass", "w")
file:write(textutils.serialize(UserPass))
file:close()
print("UserPass created!")
local Admin = textutils.serialize({aName})
local file = io.open("KingOS_Files/Admin", "w")
file:write(Admin)
file:close()
print("Admin created!")
local file = io.open("KingOS_Files/Viewer", "w")
file:write(textutils.serialize({}))
file:close()
print("Viewer created!")
sleep(1)
print("Success!")
sleep(0.1)
print("Installing KingOS")
sleep(1)
--shell.run("pastebin get [code] startup")
print("Success!")
sleep(1)
os.reboot()
I am trying to get the login function to work properly, but it is *apparently* returning an incorrect value. The problem may be in my loadFile function, or the fact that … is already an array when it is called, thus turining it into this: {{…}} if that's possible. I don't know how to correct this, as I don't know how many users I will have.
edit: I think the problem lies in the OS itself, but the installer could be to blame. The lines marked as comments are marked as such on purpose, because they would either not work until I finalize it, or would mess with testing.
edit 2: a better description of the problem:
I log in just fine, but it then refuses to use anything other than the logout, because the username returned wasn't in Viewer or Admin (I checked manually and my username was in the Admin file)
Edited on 12 April 2014 - 10:16 PM
OReezy #2
Posted 11 April 2014 - 04:11 PM
Without indentation its hard to follow your code but I did look at your loadFile() and two things stand out to me:
local data = file:read()
Looking at the wiki, the read() function is only usable in binary read mode ("rb"). For the normal read mode ("r"), you have readLine() and readAll() Although I'm pretty sure it would give you an attempt to call nil error if this was the case. Have you tried printing the variable to verify its getting the value you think its getting?

Also, textutils.unserialize() is used for tables. If your file doesn't contain a table that could be an issue too.

Edit: Looked again at the isAdmin() and the second thing shouldn't be an issue.
Edited on 11 April 2014 - 02:30 PM
CometWolf #3
Posted 11 April 2014 - 05:20 PM
I did look at your loadFile() and two things stand out to me:
local data = file:read()
Looking at the wiki, the read() function is only usable in binary read mode ("rb"). For the normal read mode ("r"), you have readLine() and readAll() Although I'm pretty sure it would give you an attempt to call nil error if this was the case. Have you tried printing the variable to verify its getting the value you think its getting?
Note that he uses the io API, not fs. io.read is pretty much equivalent to fs.readLine.
http://www.lua.org/manual/5.1/manual.html#5.7
Though confirming that it's loading correctly is probably not a bad idea either way.
KingofGamesYami #4
Posted 11 April 2014 - 11:10 PM
Sorry for not replying earlier, I was in school all day…
Anyway, I know the textutils.unserialize isn't the problem, as I store all my data (that needs saving) in tables.
PS: Sorry about the indents, the forum does this to me ever time I post code >,<
Bomb Bloke #5
Posted 12 April 2014 - 01:59 AM
local function isViewer(User)
.
.
.
if v == UserLogin then

PS: Sorry about the indents, the forum does this to me ever time I post code >,<

Disable the rich-text editor before pasting (use the little light switch toggle at the upper-left of the posting window).
Edited on 12 April 2014 - 12:01 AM