Chickenbreadlp

ccFTP [Ask A Pro Example] [Broken]

Jun 3rd, 2016
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.09 KB | None | 0 0
  1.  -- GitHub File Downloader for Self-Suppling
  2. local function GITget(branch, file)
  3.     local response = http.get(
  4.         "https://raw.githubusercontent.com/Chickenbreadlp/ReboOSt/"..branch.."/"..textutils.urlEncode( file )
  5.     )
  6.  
  7.     if response then
  8.         local sResponse = response.readAll()
  9.         response.close()
  10.         return sResponse
  11.     else
  12.     end
  13. end
  14. local function GITdownload(branch, filename, sFile)
  15.     if fs.exists( sFile ) then
  16.         return
  17.     end
  18.  
  19.     local res = GITget(branch, filename)
  20.     if res then
  21.         local file = fs.open( sFile, "w" )
  22.         file.write( res )
  23.         file.close()
  24.     end
  25. end
  26.  
  27.  -- Pastebin Downloader for Self-Suppling
  28. local function PASget(paste)
  29.     local response = http.get(
  30.         "http://pastebin.com/raw/"..textutils.urlEncode( paste )
  31.     )
  32.  
  33.     if response then
  34.         local sResponse = response.readAll()
  35.         response.close()
  36.         return sResponse
  37.     else
  38.     end
  39. end
  40. local function PASdownload(paste, sFile)
  41.     if fs.exists( sFile ) then
  42.         return
  43.     end
  44.  
  45.     local res = PASget(paste)
  46.     if res then
  47.         local file = fs.open( sFile, "w" )
  48.         file.write( res )
  49.         file.close()
  50.     end
  51. end
  52.  
  53.  
  54.  -- Way to create a keypair for AES from single case-sensitive key for Server functions
  55. local function unfoldkeyS(keyhash)
  56.  math.randomseed(tonumber(keyhash, 36))
  57.  local key = {}
  58.  local iv = {}
  59.  for i=1, 16 do
  60.   key[i] = math.random(0, 0xFF)
  61.   iv[i] = math.random(0, 0xFF)
  62.  end
  63.  math.randomseed(math.random())
  64.  return key, iv
  65. end
  66.  
  67.  -- Way to create a keypair for AES from single case-sensitive key for Clint functions
  68. local function unfoldkeyC(Key)
  69.  local keyhash = hash.sha256(Key)
  70.  math.randomseed(tonumber(keyhash, 36))
  71.  local key = {}
  72.  local iv = {}
  73.  for i=1, 16 do
  74.   key[i] = math.random(0, 0xFF)
  75.   iv[i] = math.random(0, 0xFF)
  76.  end
  77.  math.randomseed(math.random())
  78.  return key, iv
  79. end
  80.  
  81.  -- checks if needed APIs are available and (if not) do exist
  82. local function checkAPI()
  83.  if ccaes == nil then
  84.   if fs.exists("/.ccftp/ccaes") then
  85.    os.loadAPI("/.ccftp/ccaes")
  86.   else
  87.    PASdownload("rCYDnCxn", "/.ccftp/ccaes")
  88.    os.loadAPI("/.ccftp/ccaes")
  89.   end
  90.  end
  91.  if hash == nil then
  92.   if fs.exists("/.ccftp/hash") then
  93.    os.loadAPI("/.ccftp/hash")
  94.   else
  95.    GITdownload("release", "ReboOSt/APIs/encryption", "/.ccftp/hash")
  96.    os.loadAPI("/.ccftp/hash")
  97.   end
  98.  end
  99. end
  100.  
  101.  -- checks for a Modem
  102. local function checkModem()
  103.  if peripheral.isPresent("top") and peripheral.getType("top") == "modem" then
  104.   if not rednet.isOpen("top") then
  105.    rednet.open("top")
  106.   end
  107.   return true
  108.  elseif peripheral.isPresent("bottom") and peripheral.getType("bottom") == "modem" then
  109.   if not rednet.isOpen("bottom") then
  110.    rednet.open("bottom")
  111.   end
  112.   return true
  113.  elseif peripheral.isPresent("left") and peripheral.getType("left") == "modem" then
  114.   if not rednet.isOpen("left") then
  115.    rednet.open("left")
  116.   end
  117.   return true
  118.  elseif peripheral.isPresent("right") and peripheral.getType("right") == "modem" then
  119.   if not rednet.isOpen("right") then
  120.    rednet.open("right")
  121.   end
  122.   return true
  123.  elseif peripheral.isPresent("back") and peripheral.getType("back") == "modem" then
  124.   if not rednet.isOpen("back") then
  125.    rednet.open("back")
  126.   end
  127.   return true
  128.  elseif peripheral.isPresent("front") and peripheral.getType("front") == "modem" then
  129.   if not rednet.isOpen("front") then
  130.    rednet.open("front")
  131.   end
  132.   return true
  133.  else
  134.   return false
  135.  end
  136. end
  137.  
  138.  -- waits for receiving a message and unserialize it
  139. local function waitForMessage()
  140.  local senderID = nil
  141.  local message = nil
  142.  senderID, message = rednet.receive("ccFTP")
  143. -- message = textutils.unserialize(message)
  144.  return message, senderID
  145. end
  146.  
  147.  -- sendMessage function for Client tools
  148. local function sendMessageC(Hostname, UsrName, PassIV, command)
  149.  local message = { UsrName, PassIV, command }
  150. -- textutils.serialize(message)
  151.  local ID = rednet.lookup("ccFTP", Hostname)
  152.  if ID == nil then
  153.   return false
  154.  else
  155.   rednet.send(ID, message, "ccFTP")
  156.   return true, ID
  157.  end
  158. end
  159.  
  160.  -- sendMessage function for Server tools
  161. local function sendMessageS(message, ID)
  162.  message = textutils.serialize(message)
  163.  rednet.send(ID, message, "ccFTP")
  164. end
  165.  
  166.  -- just a placeholder
  167. local runningHost = nil
  168.  
  169.  -- 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)
  170.  -- It is not recommended to use Root Directory as FTP Share
  171. function runServer(Hostname, FtpDir, UsrDir)
  172.  
  173.  if Hostname == nil then
  174.   error("Hostname missing!")
  175.  end
  176.  
  177.  local UsrDir = UsrDir or "/.ccftp/Users"
  178.  local FtpDir = FtpDir or "/FTP_Share"
  179.  if not fs.exists(FtpDir) then fs.makeDir(FtpDir) end
  180.  
  181.  checkAPI()
  182.  
  183.  if checkModem() then
  184.   runningHost = Hostname
  185.   while(true) do
  186.    
  187.    rednet.host("ccFTP", Hostname)
  188.    
  189.    print("1")
  190.    local message = nil
  191.    local senderID = nil
  192.    message, senderID = waitForMessage()
  193.    print("2")
  194.    
  195.    if #message >= 3 then
  196.     if fs.exists(UsrDir.."/"..message[1]) then
  197.    
  198.      local file = fs.open(UsrDir.."/"..message[1])
  199.      local pass = file.readLine()
  200.      file.close()
  201.      
  202.      local key, iv = unfoldkeyS(pass)
  203.      
  204.      if iv == message[2] then
  205.      
  206.       if message[3][1] == "DirCont" then
  207.        if message[3] >= 2 then
  208.         if fs.exists(FtpDir.."/"..message[3][2]) then
  209.          local DirCont = fs.list(FtpDir.."/"..message[3][2])
  210.          local DirIdx = {}
  211.          for _, content in ipairs(DirCont) do
  212.           if fs.isDir(UsrDir.."/"..content) then
  213.            table.insert(DirIdx, content)
  214.           end
  215.          end
  216.          sendMessageS( { DirCont, DirIdx } , senderID)
  217.         else
  218.          sendMessageS("ddne", senderID)
  219.         end
  220.        else
  221.         sendMessageS("nea", senderID)
  222.        end
  223.      
  224.       elseif message[3][1] == "getFile" then
  225.        if message[3] >= 2 then
  226.         if fs.exists(FtpDir.."/"..message[3][2]) then
  227.          local file = fs.open(FtpDir.."/"..message[3][2], "rb")
  228.          local fileData = {}
  229.          local filebyte = file.read()
  230.          repeat
  231.           table.insert(fileData, filebit)
  232.           filebyte = file.read()
  233.          until filebyte == nil
  234.          file.close()
  235.          fileData = ccaes.encrypt_bytestream(fileData, key, iv)
  236.          local response = { iv, fileData }
  237.          sendMessageS(response, senderID)
  238.         else
  239.          sendMessageS("fdne", senderID)
  240.         end
  241.        else
  242.         sendMessageS("nea", senderID)
  243.        end
  244.      
  245.       elseif message[3][1] == "pushFile" then
  246.        if #message[3] >= 3 then
  247.         local decdat = ccaes.decrypt_bytestream(message[3][3], key, iv)
  248.         local file = fs.open(DtpDir.."/"..message[2], "wb")
  249.         for i = 1, #decdat do
  250.          file.write(decdat[i])
  251.         end
  252.         file.close()
  253.         sendMessageS("OK", senderID)
  254.        
  255.        else
  256.         sendMessageS("nea", senderID)
  257.        end
  258.      
  259.       else
  260.        sendMessageS("nsc", senderID)
  261.       end
  262.      
  263.      else
  264.       sendMessageS("pww", senderID)
  265.      end
  266.    
  267.     else
  268.      sendMessageS("nsu", senderID)
  269.     end
  270.    
  271.    else
  272.     sendMessageS("nea", senderID)
  273.    end
  274.  
  275.   end
  276.  
  277.  else
  278.   error("No Modem attached!")
  279.  end
  280.  
  281. end
  282.  
  283.  -- runs the Server Shell (should only be used in parralel with runServer)
  284. function runServerShell()
  285.  while(true) do
  286.   local opull = os.pullEvent
  287.   os.pullEvent = os.pullEventRaw
  288.   local input = string.lower(read())
  289.   os.pullEvent = opull
  290.   if input == "reboot" then
  291.    os.reboot()
  292.   elseif input == "shutdown" then
  293.    os.shutdown()
  294.   elseif input == "change hostname" then
  295.    if runningHost ~= nil then
  296.     os.pullEvent = os.pullEventRaw
  297.     print("Current Hostname: "..runningHost)
  298.     write("New Hostname: ")
  299.     local input = read()
  300.     if input ~= nil then
  301.      rednet.unhost("ccFTP", runningHost)
  302.      rednet.host("ccFTP", input)
  303.     else
  304.      print("Please enter a Hostname!")
  305.     end
  306.    else
  307.     print("There is no ccFTP Server running on this computer!")
  308.    end
  309.   end
  310.  end
  311. end
  312.  
  313.  -- gets the Directory Tree for the specified Subdirectory (optional)
  314. function getDirCont(Hostname, UsrName, UsrPass, Subdir)
  315.  if Hostname == nil then
  316.   error("Hostname required!")
  317.  elseif UsrName == nil then
  318.   error("Username required!")
  319.  elseif UsrPass == nil then
  320.   error("Password required!")
  321.  end
  322.  Subdir = Subdir or ""
  323.  checkAPI()
  324.  if checkModem() then
  325.   print("1")
  326.   local key, iv = unfoldkeyC(UsrPass)
  327.   print("2")
  328.   local worked, hosterID = sendMessageC(Hostname, UsrName, iv, {"DirCont", Subdir})
  329.   print("3")
  330.   if worked then
  331.    print("4")
  332.    local message, senderID = waitForMessage()
  333.    print("5")
  334.    if senderID == hosterID then
  335.     print("6")
  336.     if message[2] ~= nil then
  337. --   return message[1], message[2]
  338.      print(message[1].." "..message[2])
  339.     else
  340. --   return message[1]
  341.      print(message)
  342.     end
  343.    end
  344.   end
  345.  else
  346.   error("No Modem attached!")
  347.  end
  348. end
  349.  
  350.  -- 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)
  351. function getFile(Hostname, UsrName, UsrPass, FileHost, FileClient)
  352.  if Hostname == nil then
  353.   error("Hostname required!")
  354.  elseif UsrName == nil then
  355.   error("Username required!")
  356.  elseif UsrPass == nil then
  357.   error("Password required!")
  358.  elseif FileHost == nil then
  359.   error("File must be specified!")
  360.  elseif FileClient == nil then
  361.   error("File must be specified!")
  362.  end
  363.  checkAPI()
  364.  if checkModem() then
  365.   local key, iv = unfoldkeyC(UsrPass)
  366.   local worked, hosterID = sendMessageC(Hostname, UsrName, iv, {"getFile", FileHost})
  367.   if worked then
  368.    while(true) do
  369.     local message, senderID = waitForMessage()
  370.     if senderID == hosterID then
  371.      if message[1] == iv then
  372.       local content = ccaes.decrypt_bytestream(message[2], key, iv)
  373.       local file = fs.open(FileClient, "wb")
  374.       for i = 1, #content do
  375.        file.write(content[i])
  376.       end
  377.       file.close()
  378.       return true
  379.      else
  380.       return message
  381.      end
  382.     end
  383.    end
  384.   end
  385.  else
  386.   error("No Modem attached!")
  387.  end
  388. end
  389.  
  390.  -- 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)
  391. function pushFile(Hostname, UsrName, UsrPass, FileClient, FileHost)
  392.  if Hostname == nil then
  393.   error("Hostname required!")
  394.  elseif UsrName == nil then
  395.   error("Username required!")
  396.  elseif UsrPass == nil then
  397.   error("Password required!")
  398.  elseif FileHost == nil then
  399.   error("File must be specified!")
  400.  elseif FileClient == nil then
  401.   error("File must be specified!")
  402.  elseif not fs.exists(FileClient) then
  403.   error("File must exists!")
  404.  end
  405.  checkAPI()
  406.  if checkModem() then
  407.   local key, iv = unfoldkeyC(UsrPass)
  408.   local file = fs.open(FileClient, "rb")
  409.   local fileData = {}
  410.   local fileByte = file.read()
  411.   repeat
  412.   table.insert(fileData, fileByte)
  413.   fileByte = file.read()
  414.   until fileByte == nil
  415.   file.close()
  416.   fileData = ccaes.encrypt_bytestream(fileData, key, iv)
  417.   local worked, hosterID = sendMessageC(Hostname, UsrName, iv, {"pushFile", FileHost, fileData})
  418.   if worked then
  419.    while(true) do
  420.     local message, senderID = waitForMessage()
  421.     if senderID == hosterID then
  422.      if message == "OK" then
  423.       return true
  424.      else
  425.       return message
  426.      end
  427.     end
  428.    end
  429.   end
  430.  else
  431.   error("No Modem attached!")
  432.  end
  433. end
Advertisement
Add Comment
Please, Sign In to add comment