Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- GitHub File Downloader for Self-Suppling
- local function GITget(branch, file)
- local response = http.get(
- "https://raw.githubusercontent.com/Chickenbreadlp/ReboOSt/"..branch.."/"..textutils.urlEncode( file )
- )
- if response then
- local sResponse = response.readAll()
- response.close()
- return sResponse
- else
- end
- end
- local function GITdownload(branch, filename, sFile)
- if fs.exists( sFile ) then
- return
- end
- local res = GITget(branch, filename)
- if res then
- local file = fs.open( sFile, "w" )
- file.write( res )
- file.close()
- end
- end
- -- Pastebin Downloader for Self-Suppling
- local function PASget(paste)
- local response = http.get(
- "http://pastebin.com/raw/"..textutils.urlEncode( paste )
- )
- if response then
- local sResponse = response.readAll()
- response.close()
- return sResponse
- else
- end
- end
- local function PASdownload(paste, sFile)
- if fs.exists( sFile ) then
- return
- end
- local res = PASget(paste)
- if res then
- local file = fs.open( sFile, "w" )
- file.write( res )
- file.close()
- end
- end
- -- Way to create a keypair for AES from single case-sensitive key for Server functions
- local function unfoldkeyS(keyhash)
- math.randomseed(tonumber(keyhash, 36))
- local key = {}
- local iv = {}
- for i=1, 16 do
- key[i] = math.random(0, 0xFF)
- iv[i] = math.random(0, 0xFF)
- end
- math.randomseed(math.random())
- return key, iv
- end
- -- Way to create a keypair for AES from single case-sensitive key for Clint functions
- local function unfoldkeyC(Key)
- local keyhash = hash.sha256(Key)
- math.randomseed(tonumber(keyhash, 36))
- local key = {}
- local iv = {}
- for i=1, 16 do
- key[i] = math.random(0, 0xFF)
- iv[i] = math.random(0, 0xFF)
- end
- math.randomseed(math.random())
- return key, iv
- end
- -- checks if needed APIs are available and (if not) do exist
- local function checkAPI()
- if ccaes == nil then
- if fs.exists("/.ccftp/ccaes") then
- os.loadAPI("/.ccftp/ccaes")
- else
- PASdownload("rCYDnCxn", "/.ccftp/ccaes")
- os.loadAPI("/.ccftp/ccaes")
- end
- end
- if hash == nil then
- if fs.exists("/.ccftp/hash") then
- os.loadAPI("/.ccftp/hash")
- else
- GITdownload("release", "ReboOSt/APIs/encryption", "/.ccftp/hash")
- os.loadAPI("/.ccftp/hash")
- end
- end
- end
- -- checks for a Modem
- local function checkModem()
- if peripheral.isPresent("top") and peripheral.getType("top") == "modem" then
- if not rednet.isOpen("top") then
- rednet.open("top")
- end
- return true
- elseif peripheral.isPresent("bottom") and peripheral.getType("bottom") == "modem" then
- if not rednet.isOpen("bottom") then
- rednet.open("bottom")
- end
- return true
- elseif peripheral.isPresent("left") and peripheral.getType("left") == "modem" then
- if not rednet.isOpen("left") then
- rednet.open("left")
- end
- return true
- elseif peripheral.isPresent("right") and peripheral.getType("right") == "modem" then
- if not rednet.isOpen("right") then
- rednet.open("right")
- end
- return true
- elseif peripheral.isPresent("back") and peripheral.getType("back") == "modem" then
- if not rednet.isOpen("back") then
- rednet.open("back")
- end
- return true
- elseif peripheral.isPresent("front") and peripheral.getType("front") == "modem" then
- if not rednet.isOpen("front") then
- rednet.open("front")
- end
- return true
- else
- return false
- end
- end
- -- waits for receiving a message and unserialize it
- local function waitForMessage()
- local senderID = nil
- local message = nil
- senderID, message = rednet.receive("ccFTP")
- -- message = textutils.unserialize(message)
- return message, senderID
- end
- -- sendMessage function for Client tools
- local function sendMessageC(Hostname, UsrName, PassIV, command)
- local message = { UsrName, PassIV, command }
- -- textutils.serialize(message)
- local ID = rednet.lookup("ccFTP", Hostname)
- if ID == nil then
- return false
- else
- rednet.send(ID, message, "ccFTP")
- return true, ID
- end
- end
- -- sendMessage function for Server tools
- local function sendMessageS(message, ID)
- message = textutils.serialize(message)
- rednet.send(ID, message, "ccFTP")
- end
- -- just a placeholder
- local runningHost = nil
- -- runs a FTP Server (Hostname sets the FTP-Server Name ; FtpDir sets the Directory which should be shared through ccFTP ; UsrDir sets the directory, where the Accounts will be saved)
- -- It is not recommended to use Root Directory as FTP Share
- function runServer(Hostname, FtpDir, UsrDir)
- if Hostname == nil then
- error("Hostname missing!")
- end
- local UsrDir = UsrDir or "/.ccftp/Users"
- local FtpDir = FtpDir or "/FTP_Share"
- if not fs.exists(FtpDir) then fs.makeDir(FtpDir) end
- checkAPI()
- if checkModem() then
- runningHost = Hostname
- while(true) do
- rednet.host("ccFTP", Hostname)
- print("1")
- local message = nil
- local senderID = nil
- message, senderID = waitForMessage()
- print("2")
- if #message >= 3 then
- if fs.exists(UsrDir.."/"..message[1]) then
- local file = fs.open(UsrDir.."/"..message[1])
- local pass = file.readLine()
- file.close()
- local key, iv = unfoldkeyS(pass)
- if iv == message[2] then
- if message[3][1] == "DirCont" then
- if message[3] >= 2 then
- if fs.exists(FtpDir.."/"..message[3][2]) then
- local DirCont = fs.list(FtpDir.."/"..message[3][2])
- local DirIdx = {}
- for _, content in ipairs(DirCont) do
- if fs.isDir(UsrDir.."/"..content) then
- table.insert(DirIdx, content)
- end
- end
- sendMessageS( { DirCont, DirIdx } , senderID)
- else
- sendMessageS("ddne", senderID)
- end
- else
- sendMessageS("nea", senderID)
- end
- elseif message[3][1] == "getFile" then
- if message[3] >= 2 then
- if fs.exists(FtpDir.."/"..message[3][2]) then
- local file = fs.open(FtpDir.."/"..message[3][2], "rb")
- local fileData = {}
- local filebyte = file.read()
- repeat
- table.insert(fileData, filebit)
- filebyte = file.read()
- until filebyte == nil
- file.close()
- fileData = ccaes.encrypt_bytestream(fileData, key, iv)
- local response = { iv, fileData }
- sendMessageS(response, senderID)
- else
- sendMessageS("fdne", senderID)
- end
- else
- sendMessageS("nea", senderID)
- end
- elseif message[3][1] == "pushFile" then
- if #message[3] >= 3 then
- local decdat = ccaes.decrypt_bytestream(message[3][3], key, iv)
- local file = fs.open(DtpDir.."/"..message[2], "wb")
- for i = 1, #decdat do
- file.write(decdat[i])
- end
- file.close()
- sendMessageS("OK", senderID)
- else
- sendMessageS("nea", senderID)
- end
- else
- sendMessageS("nsc", senderID)
- end
- else
- sendMessageS("pww", senderID)
- end
- else
- sendMessageS("nsu", senderID)
- end
- else
- sendMessageS("nea", senderID)
- end
- end
- else
- error("No Modem attached!")
- end
- end
- -- runs the Server Shell (should only be used in parralel with runServer)
- function runServerShell()
- while(true) do
- local opull = os.pullEvent
- os.pullEvent = os.pullEventRaw
- local input = string.lower(read())
- os.pullEvent = opull
- if input == "reboot" then
- os.reboot()
- elseif input == "shutdown" then
- os.shutdown()
- elseif input == "change hostname" then
- if runningHost ~= nil then
- os.pullEvent = os.pullEventRaw
- print("Current Hostname: "..runningHost)
- write("New Hostname: ")
- local input = read()
- if input ~= nil then
- rednet.unhost("ccFTP", runningHost)
- rednet.host("ccFTP", input)
- else
- print("Please enter a Hostname!")
- end
- else
- print("There is no ccFTP Server running on this computer!")
- end
- end
- end
- end
- -- gets the Directory Tree for the specified Subdirectory (optional)
- function getDirCont(Hostname, UsrName, UsrPass, Subdir)
- if Hostname == nil then
- error("Hostname required!")
- elseif UsrName == nil then
- error("Username required!")
- elseif UsrPass == nil then
- error("Password required!")
- end
- Subdir = Subdir or ""
- checkAPI()
- if checkModem() then
- print("1")
- local key, iv = unfoldkeyC(UsrPass)
- print("2")
- local worked, hosterID = sendMessageC(Hostname, UsrName, iv, {"DirCont", Subdir})
- print("3")
- if worked then
- print("4")
- local message, senderID = waitForMessage()
- print("5")
- if senderID == hosterID then
- print("6")
- if message[2] ~= nil then
- -- return message[1], message[2]
- print(message[1].." "..message[2])
- else
- -- return message[1]
- print(message)
- end
- end
- end
- else
- error("No Modem attached!")
- end
- end
- -- gets a single File from FTP-Server (FileHost is the full path to the file on the hoster ; FileClient sets the path where the file should be saved)
- function getFile(Hostname, UsrName, UsrPass, FileHost, FileClient)
- if Hostname == nil then
- error("Hostname required!")
- elseif UsrName == nil then
- error("Username required!")
- elseif UsrPass == nil then
- error("Password required!")
- elseif FileHost == nil then
- error("File must be specified!")
- elseif FileClient == nil then
- error("File must be specified!")
- end
- checkAPI()
- if checkModem() then
- local key, iv = unfoldkeyC(UsrPass)
- local worked, hosterID = sendMessageC(Hostname, UsrName, iv, {"getFile", FileHost})
- if worked then
- while(true) do
- local message, senderID = waitForMessage()
- if senderID == hosterID then
- if message[1] == iv then
- local content = ccaes.decrypt_bytestream(message[2], key, iv)
- local file = fs.open(FileClient, "wb")
- for i = 1, #content do
- file.write(content[i])
- end
- file.close()
- return true
- else
- return message
- end
- end
- end
- end
- else
- error("No Modem attached!")
- end
- end
- -- puts a single file onto the FTP-Server (FileClient is the path of the file which should be uploaded ; FileHost sets the full path, where the file should be saved)
- function pushFile(Hostname, UsrName, UsrPass, FileClient, FileHost)
- if Hostname == nil then
- error("Hostname required!")
- elseif UsrName == nil then
- error("Username required!")
- elseif UsrPass == nil then
- error("Password required!")
- elseif FileHost == nil then
- error("File must be specified!")
- elseif FileClient == nil then
- error("File must be specified!")
- elseif not fs.exists(FileClient) then
- error("File must exists!")
- end
- checkAPI()
- if checkModem() then
- local key, iv = unfoldkeyC(UsrPass)
- local file = fs.open(FileClient, "rb")
- local fileData = {}
- local fileByte = file.read()
- repeat
- table.insert(fileData, fileByte)
- fileByte = file.read()
- until fileByte == nil
- file.close()
- fileData = ccaes.encrypt_bytestream(fileData, key, iv)
- local worked, hosterID = sendMessageC(Hostname, UsrName, iv, {"pushFile", FileHost, fileData})
- if worked then
- while(true) do
- local message, senderID = waitForMessage()
- if senderID == hosterID then
- if message == "OK" then
- return true
- else
- return message
- end
- end
- end
- end
- else
- error("No Modem attached!")
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment