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 & 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()
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