Advertisement
Chickenbreadlp

ccFTP (Rev3) [API]

Jun 21st, 2016
457
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 20.41 KB | None | 0 0
  1. --[[
  2.     MIT License
  3.  
  4.     Copyright © 2016 Chickenbreadlp
  5.  
  6.     Permission is hereby granted, free of charge, to any person obtaining a copy
  7.     of this software and associated documentation files (the "Software"), to deal
  8.     in the Software without restriction, including without limitation the rights
  9.     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10.     copies of the Software, and to permit persons to whom the Software is
  11.     furnished to do so, subject to the following conditions:
  12.  
  13.     The above copyright notice and this permission notice shall be included in all
  14.     copies or substantial portions of the Software.
  15.  
  16.     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19.     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21.     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.     SOFTWARE.
  23. ]]
  24.  
  25. local ccFTPRev = "Rev3"
  26. local runningFTPHost = nil
  27.  
  28.  -- GitHub File Downloader for Self-Suppling
  29. local function GITget(branch, file)
  30.     local response = http.get(
  31.         "https://raw.githubusercontent.com/Chickenbreadlp/ReboOSt/"..branch.."/"..textutils.urlEncode( file )
  32.     )
  33.  
  34.     if response then
  35.         local sResponse = response.readAll()
  36.         response.close()
  37.         return sResponse
  38.     else
  39.     end
  40. end
  41. local function GITdownload(branch, filename, sFile)
  42.     if fs.exists( sFile ) then
  43.         return
  44.     end
  45.  
  46.     local res = GITget(branch, filename)
  47.     if res then
  48.         local file = fs.open( sFile, "w" )
  49.         file.write( res )
  50.         file.close()
  51.     end
  52. end
  53.  
  54.  -- Pastebin Downloader for Self-Suppling
  55. local function PASget(paste)
  56.     local response = http.get(
  57.         "http://pastebin.com/raw/"..textutils.urlEncode( paste )
  58.     )
  59.  
  60.     if response then
  61.         local sResponse = response.readAll()
  62.         response.close()
  63.         return sResponse
  64.     else
  65.     end
  66. end
  67. local function PASdownload(paste, sFile)
  68.     if fs.exists( sFile ) then
  69.         return
  70.     end
  71.  
  72.     local res = PASget(paste)
  73.     if res then
  74.         local file = fs.open( sFile, "w" )
  75.         file.write( res )
  76.         file.close()
  77.     end
  78. end
  79.  
  80.  
  81.  -- Way to create a keypair for AES256 from SHA256 keyhash
  82. local function unfoldkeyS(keyhash)
  83.  math.randomseed(tonumber(keyhash, 36))
  84.  local key = {}
  85.  local iv = {}
  86.  for i=1, 32 do
  87.   key[i] = math.random(0, 0xFF)
  88.   iv[i] = math.random(0, 0xFF)
  89.  end
  90.  math.randomseed(os.clock())
  91.  return key, iv
  92. end
  93.  
  94.  -- Way to create a keypair for AES256 from single case-sensitive key
  95. local function unfoldkeyC(Key)
  96.  local keyhash = hash.sha256(Key)
  97.  math.randomseed(tonumber(keyhash, 36))
  98.  local key = {}
  99.  local iv = {}
  100.  for i=1, 32 do
  101.   key[i] = math.random(0, 0xFF)
  102.   iv[i] = math.random(0, 0xFF)
  103.  end
  104.  math.randomseed(os.clock())
  105.  return key, iv
  106. end
  107.  
  108.  
  109.  -- checks if needed APIs are available and (if not) do exist
  110. local function checkAPI()
  111.  if ccaes == nil then
  112.   if fs.exists("/.ccftp/ccaes") then
  113.    os.loadAPI("/.ccftp/ccaes")
  114.   else
  115.    PASdownload("rCYDnCxn", "/.ccftp/ccaes")
  116.    os.loadAPI("/.ccftp/ccaes")
  117.   end
  118.  end
  119.  if hash == nil then
  120.   if fs.exists("/.ccftp/hash") then
  121.    os.loadAPI("/.ccftp/hash")
  122.   else
  123.    GITdownload("release", "ReboOSt/APIs/encryption", "/.ccftp/hash")
  124.    os.loadAPI("/.ccftp/hash")
  125.   end
  126.  end
  127. end
  128.  
  129.  -- checks for a Modem
  130. local function checkModem()
  131.  if rednet.isOpen() then
  132.   return true
  133.  end
  134.  for _, side in ipairs( rs.getSides() ) do
  135.   if peripheral.isPresent( side ) and peripheral.getType( side ) == "modem" then
  136.    rednet.open( side )
  137.    return true
  138.   end
  139.  end
  140.  return false
  141. end
  142.  
  143.  
  144.  -- waits for receiving a message and unserialize it
  145. local function waitForMessage(typ)
  146.  local senderID = nil
  147.  local command = nil
  148.  if typ == "C" then
  149.   senderID, command = rednet.receive("ccFTP", 5)
  150.  elseif typ == "S" then
  151.   senderID, command = rednet.receive("ccFTP")
  152.  end
  153. -- command = textutils.unserialize(command)
  154.  return command, senderID
  155. end
  156.  
  157.  -- sendMessage function for Client tools
  158. local function sendMessageC(Hostname, UsrName, PassIV, ClientVer, command)
  159.  local command = { UsrName, PassIV, command, ClientVer }
  160. -- textutils.serialize(command)
  161.  local hostID = rednet.lookup("ccFTP", Hostname)
  162.  if hostID == nil then
  163.   return nil
  164.  else
  165.   rednet.send(hostID, command, "ccFTP")
  166.   return hostID
  167.  end
  168. end
  169.  
  170.  -- sendMessage function for Server tools
  171. local function sendMessageS(response, ID)
  172. -- command = textutils.serialize(command)
  173.  rednet.send(ID, response, "ccFTP")
  174. end
  175.  
  176.  
  177.  -- returns the local API Rev
  178. function getClientVer()
  179.  return ccFTPRev
  180. end
  181.  
  182.  -- returns the API Rev of Hostname or "nsh" if Hostname was not found
  183. function getServerVer(Hostname)
  184.  checkAPI()
  185.  if checkModem() then
  186.   local hosterID = sendMessageC(Hostname, hash.sha256("VerCheck"), hash.sha256("VerCheck"), ccFTPRev, "VerCheck")
  187.   if hosterID then
  188.    local response, senderID = waitForMessage("C")
  189.    if senderID == hosterID and response ~= "nsu" then
  190.     return response
  191.    elseif response == "nsu" then
  192.     return "Rev2"
  193.    elseif senderID == nil then
  194.     return "nsh"
  195.    end
  196.   elseif hosterID == nil then
  197.    return "nsh"
  198.   end
  199.  end
  200. end
  201.  
  202.  
  203.   ---- Server Functions ----
  204.  
  205.  -- returns true and current hostname if hostname is still active else it returns false
  206. function getRunningHost()
  207.  if runningFTPHost ~= nil then
  208.   return true, runningFTPHost
  209.  else
  210.   return false
  211.  end
  212. end
  213.  
  214.  -- returns true if hostname was still active and is now shutdown, false if no hostname was running
  215. function closeServer()
  216.  if runningFTPHost ~= nil then
  217.   rednet.unhost("ccFTP", runningFTPHost)
  218.   runningFTPHost = nil
  219.   return true
  220.  else
  221.   return false
  222.  end
  223. end
  224.  
  225.  -- 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)
  226.  -- It is not recommended to use Root Directory as FTP Share
  227. function runServer(Hostname, loopoff, FtpDir, UsrDir)
  228.  
  229.  if Hostname == nil then
  230.   return "nHn"
  231.  end
  232.  
  233.  local UsrDir = UsrDir
  234.  local FtpDir = FtpDir
  235.  local loopoff = loopoff
  236.  
  237.  if type(loopoff) ~= "boolean" then
  238.   loopoff = false
  239.  end
  240.  
  241.  if type(UsrDir) ~= "string" then UsrDir = "/.ccftp/Users" end
  242.  if type(FtpDir) ~= "string" then FtpDir = "/FTP_Share" end
  243.  if not fs.exists(FtpDir) then fs.makeDir(FtpDir) end
  244.  
  245.  checkAPI()
  246.  
  247.  if checkModem() then
  248.   if runningFTPHost ~= Hostname and runningFTPHost ~= nil then
  249.    closeServer()
  250.   end
  251.   rednet.host("ccFTP", Hostname)
  252.   runningFTPHost = Hostname
  253.   while true do
  254.    
  255.    local commandtab = nil
  256.    local sender = nil
  257.    commandtab, sender = waitForMessage("S")
  258.    if type(commandtab) == "table" then
  259.    if #commandtab >= 3 then
  260.     if (commandtab[1] == hash.sha256("VerCheck") or commandtab[1] == "VerCheck") and commandtab[2] == hash.sha256("VerCheck") and commandtab[3] == "VerCheck" then
  261.      sendMessageS(ccFTPRev, sender)
  262.      if loopoff == true and commandtab[1] == "VerCheck" then
  263.       return true, sender, "VerCheck", "", ""
  264.      end
  265.     elseif fs.exists(UsrDir.."/"..commandtab[1]) and type(commandtab[3]) == "string" and commandtab[4] == ccFTPRev then
  266.    
  267.      local file = fs.open(UsrDir.."/"..commandtab[1], "r")
  268.      local pass = file.readLine()
  269.      file.close()
  270.      
  271.      local key, iv = unfoldkeyS(pass)
  272.      
  273.      if hash.sha256("iv"..iv[15]) == commandtab[2] then
  274.      
  275.       local decrypttab = textutils.unserialize(ccaes.decrypt_str(commandtab[3], key, iv))
  276.       if type(decrypttab) == "table" then
  277.      
  278.       if decrypttab[1] == "DirCont" then
  279.        if #decrypttab >= 2 then
  280.         if fs.exists(FtpDir.."/"..decrypttab[2]) and fs.isDir(FtpDir.."/"..decrypttab[2]) then
  281.          local DirConto = fs.list(FtpDir.."/"..decrypttab[2])
  282.          local DirCont = {}
  283.          local DirIdx = {}
  284.          for _, content in ipairs(DirConto) do
  285.           if fs.isDir(FtpDir.."/"..content) then
  286.            table.insert(DirIdx, content)
  287.           else
  288.            table.insert(DirCont, content)
  289.           end
  290.          end
  291.          local resa = ccaes.encrypt_str(textutils.serialize(DirCont), key, iv)
  292.          local resb = ccaes.encrypt_str(textutils.serialize(DirIdx), key, iv)
  293.          sendMessageS({true, resa, resb}, sender)
  294.          if loopoff == true then
  295.           return true, sender, commandtab[1], "DirCont", decrypttab[2]
  296.          end
  297.         else
  298.          sendMessageS({true, ccaes.encrypt_str("ddne", key, iv)}, sender)
  299.          if loopoff == true then
  300.           return false, sender, commandtab[1], "DirCont", "ddne"
  301.          end
  302.         end
  303.        else
  304.         sendMessageS({true, ccaes.encrypt_str("nea", key, iv)}, sender)
  305.         if loopoff == true then
  306.          return false, sender, commandtab[1], "DirCont", "nea"
  307.         end
  308.        end
  309.      
  310.       elseif decrypttab[1] == "getFile" then
  311.        if #decrypttab >= 2 then
  312.         if fs.exists(FtpDir.."/"..decrypttab[2]) and not fs.isDir(FtpDir.."/"..decrypttab[2]) then
  313.          local file = fs.open(FtpDir.."/"..decrypttab[2], "rb")
  314.          local fileData = {}
  315.          local filebyte = file.read()
  316.          repeat
  317.           table.insert(fileData, filebyte)
  318.           filebyte = file.read()
  319.          until filebyte == nil
  320.          file.close()
  321.          local response = ccaes.encrypt_bytestream(fileData, key, iv)
  322.          response = { hash.sha256("iv"..iv[16]), response }
  323.          sendMessageS(response, sender)
  324.          if loopoff == true then
  325.           return true, sender, commandtab[1], "getFile", decrypttab[2]
  326.          end
  327.         else
  328.          sendMessageS({true, ccaes.encrypt_str("fdne", key, iv)}, sender)
  329.          if loopoff == true then
  330.           return false, sender, commandtab[1], "getFile", "fdne"
  331.          end
  332.         end
  333.        else
  334.         sendMessageS({true, ccaes.encrypt_str("nea", key, iv)}, sender)
  335.         if loopoff == true then
  336.          return false, sender, commandtab[1], "getFile", "nea"
  337.         end
  338.        end
  339.      
  340.       elseif decrypttab[1] == "pushFile" then
  341.        if #decrypttab >= 3 then
  342.         local decdat = ccaes.decrypt_bytestream(decrypttab[3], key, iv)
  343.         local file = fs.open(FtpDir.."/"..decrypttab[2], "wb")
  344.         for i = 1, #decdat do
  345.          file.write(decdat[i])
  346.         end
  347.         file.close()
  348.         sendMessageS({true, ccaes.encrypt_str("OK", key, iv)}, sender)
  349.         if loopoff == true then
  350.          return true, sender, commandtab[1], "pushFile", decrypttab[2]
  351.         end
  352.        
  353.        else
  354.         sendMessageS({true, ccaes.encrypt_str("nea", key, iv)}, sender)
  355.         if loopoff == true then
  356.          return false, sender, commandtab[1], "pushFile", "nea"
  357.         end
  358.        end
  359.      
  360.       elseif decrypttab[1] == "delFile" then
  361.        if #decrypttab >= 2 then
  362.         if fs.exists(FtpDir.."/"..decrypttab[2]) then
  363.          fs.delete(FtpDir.."/"..decrypttab[2])
  364.          sendMessageS({true, ccaes.encrypt_str("OK", key, iv)}, sender)
  365.          if loopoff == true then
  366.           return true, sender, commandtab[1], "delFile", decrypttab[2]
  367.          end
  368.         else
  369.          sendMessageS({true, ccaes.encrypt_str("fdne", key, iv)}, sender)
  370.          if loopoff == true then
  371.           return false, sender, commandtab[1], "delFile", "fdne"
  372.          end
  373.         end
  374.        
  375.        else
  376.         sendMessageS({true, ccaes.encrypt_str("nea", key, iv)}, sender)
  377.         if loopoff == true then
  378.          return false, sender, commandtab[1], "delFile", "nea"
  379.         end
  380.        end
  381.      
  382.       else
  383.        sendMessageS({true, ccaes.encrypt_str("nsc", key, iv)}, sender)
  384.        if loopoff == true then
  385.         return false, sender, commandtab[1], decrypttab[1], "nsc"
  386.        end
  387.       end
  388.      end
  389.      else
  390.       sendMessageS({false, "pww"}, sender)
  391.       if loopoff == true then
  392.        return false, sender, commandtab[1], "", "pww"
  393.       end
  394.      end
  395.    
  396.     elseif commandtab[4] ~= ccFTPRev then
  397.      sendMessageS({false, "wCV"}, sender)
  398.      if loopoff == true then
  399.       return false, sender, commandtab[1], "", "wCV"
  400.      end
  401.    
  402.     else
  403.      sendMessageS({false, "nsu"}, sender)
  404.      if loopoff == true then
  405.       return false, sender, commandtab[1], "", "nsu"
  406.      end
  407.     end
  408.    
  409.    else
  410.     sendMessageS({false, "nea"}, sender)
  411.     if loopoff == true then
  412.      return false, commandtab[1], sender, "nea"
  413.     end
  414.    end
  415.    end
  416.  
  417.   end
  418.  
  419.  else
  420.   return "nMa"
  421.  end
  422.  
  423. end
  424.  
  425.  -- creates a new user (should only be run on ftp server) returns true when finishing succesfull; returns nUsrN when no user is specified; returns nUsrP when no Password is specified; returns UsrE when user already exists
  426. function createUser(UsrName, UsrPass, UsrDir)
  427.  checkAPI()
  428.  if UsrName == nil then return "nUsrN" end
  429.  if UsrPass == nil then return "nUsrP" end
  430.  if type(UsrDir) ~= "string" then UsrDir = "/.ccftp/Users" end
  431.  if fs.exists(UsrDir.."/"..UsrName) or UsrName == hash.sha256("VerCheck") then return "UsrE" end
  432.  local file = fs.open(UsrDir.."/"..UsrName, "w")
  433.  file.writeLine(hash.sha256(UsrPass))
  434.  file.close()
  435.  return true
  436. end
  437.  
  438.  -- renames an already existing User (should only be run on ftp server) returns true when successfull; returns noUsrN when oUsrName not specified; returns nnUsrN when nUsrName not specified; returns nUsrP when UsrPass not specified; returns nsUsr when User does not exists; returns nUsrE when target name exists;returns pww when password wrong
  439. function renameUser(oUsrName, nUsrName, UsrPass, UsrDir)
  440.  checkAPI()
  441.  if oUsrName == nil then return "noUsrN" end
  442.  if nUsrName == nil then return "nnUsrN" end
  443.  if UsrPass == nil then return "nUsrP" end
  444.  if type(UsrDir) ~= "string" then UsrDir = "/.ccftp/Users" end
  445.  if not fs.exists(UsrDir.."/"..oUsrName) then return "nsUsr" end
  446.  if fs.exists(UsrDir.."/"..nUsrName) or nUsrName == hash.sha256("VerCheck") then return "nUsrE" end
  447.  local file = fs.open(UserDir.."/"..oUsrName, "r")
  448.  local opass = file.readLine()
  449.  file.close()
  450.  if opass == hash.sha256(UsrPass) then
  451.   fs.move(UsrDir.."/"..oUsrName, UsrDir.."/"..nUsrName)
  452.   return true
  453.  else
  454.   return "pww"
  455.  end
  456. end
  457.  
  458.  -- changes the password from any existing User (should only be run on ftp server) returns true when successfull; returns nUsrN when UsrName not specified; returns noUsrP when oUsrPass not specified; returns nnUsrP when nUsrPass not specified; returns nsUsr when User does not exists; returns pww when password wrong
  459. function changeUserPass(UsrName, oUsrPass, nUsrPass, UsrDir)
  460.  checkAPI()
  461.  if UsrName == nil then return "nUsrN" end
  462.  if oUsrPass == nil then return "noUsrP" end
  463.  if nUsrPass == nil then return "nnUsrP" end
  464.  if type(UsrDir) ~= "string" then UsrDir = "/.ccftp/Users" end
  465.  if not fs.exists(UsrDir.."/"..UsrName) then return "nsUsr" end
  466.  local file = fs.open(UsrDir.."/"..UsrName, "r")
  467.  local opass = file.readLine()
  468.  file.close()
  469.  if opass == hash.sha256(oUsrPass) then
  470.   local file = fs.open(UsrDir.."/"..UsrName, "w")
  471.   file.writeLine(hash.sha256(nUsrPass))
  472.   file.close()
  473.   return true
  474.  else
  475.   return "pww"
  476.  end
  477. end
  478.  
  479.  -- removes any given user (should only be run on ftp server) returns true when successfull; returns nUsrN when UsrName not specified; returns nUsrP when UsrPass not specified; returns nsUsr when User does not exists; returns pww when password wrong
  480. function removeUser(UsrName, UsrPass, UsrDir)
  481.  checkAPI()
  482.  if UsrName == nil then return "nUsrN" end
  483.  if UsrPass == nil then return "nUsrP" end
  484.  if type(UsrDir) ~= "string" then UsrDir = "/.ccftp/Users" end
  485.  if not fs.exists(UsrDir.."/"..UsrName) then return "nsUsr" end
  486.  local file = fs.open(UsrDir.."/"..UsrName)
  487.  local opass = file.readLine()
  488.  file.close()
  489.  if opass == hash.sha256(UsrPass) then
  490.   fs.delete(UsrDir.."/"..UsrName)
  491.   return true
  492.  else
  493.   return "pww"
  494.  end
  495. end
  496.  
  497.  
  498.   ---- Client Functions ----
  499.  
  500.  -- gets the Directory Tree for the specified Subdirectory (optional)
  501. function getDirCont(Hostname, UsrName, UsrPass, Subdir)
  502.  local servver = getServerVer(Hostname)
  503.  if Hostname == nil then
  504.   return "nHn"
  505.  elseif UsrName == nil then
  506.   return "nUsrN"
  507.  elseif UsrPass == nil then
  508.   return "nUsrP"
  509.  elseif servver ~= ccFTPRev then
  510.   if servver:find("Rev") then
  511.    return "wSV"
  512.   else
  513.    return servver
  514.   end
  515.  end
  516.  Subdir = Subdir or ""
  517.  checkAPI()
  518.  if checkModem() then
  519.   local key, iv = unfoldkeyC(UsrPass)
  520.   local hosterID = sendMessageC(Hostname, UsrName, hash.sha256("iv"..iv[15]), ccFTPRev, ccaes.encrypt_str(textutils.serialize({"DirCont", Subdir}), key, iv))
  521.   if hosterID then
  522.    local response, senderID = waitForMessage("C")
  523.    if senderID == hosterID then
  524.     if response[1] == true then
  525.      local resd = ccaes.decrypt_str(response[2], key, iv)
  526.      if response[3] ~= nil then
  527.       return textutils.unserialize(resd), textutils.unserialize(ccaes.decrypt_str(response[3], key, iv))
  528.      else
  529.       return resd
  530.      end
  531.     else
  532.      return response[2]
  533.     end
  534.    elseif senderID == nil then
  535.     return "nsh"
  536.    end
  537.   elseif hosterID == nil then
  538.    return "nsh"
  539.   end
  540.  else
  541.   return "nMa"
  542.  end
  543. end
  544.  
  545.  -- gets a single File from FTP-Server (FileHost is the full path to the file in the Share ; FileClient sets the path where the file should be saved)
  546. function getFile(Hostname, UsrName, UsrPass, FileHost, FileClient)
  547.  if Hostname == nil then
  548.   return "nHn"
  549.  elseif UsrName == nil then
  550.   return "nUsrN"
  551.  elseif UsrPass == nil then
  552.   return "nUsrP"
  553.  elseif FileHost == nil then
  554.   return "nFPH"
  555.  elseif FileClient == nil then
  556.   return "nFPC"
  557.  elseif getServerVer(Hostname) ~= ccFTPRev then
  558.   return "wSV"
  559.  end
  560.  checkAPI()
  561.  if checkModem() then
  562.   local key, iv = unfoldkeyC(UsrPass)
  563.   local hosterID = sendMessageC(Hostname, UsrName, hash.sha256("iv"..iv[15]),ccFTPRev, ccaes.encrypt_str(textutils.serialize({"getFile", FileHost}), key, iv))
  564.   if hosterID then
  565.    local response, senderID = waitForMessage("C")
  566.    if senderID == hosterID then
  567.     if response[1] == hash.sha256("iv"..iv[16]) then
  568.      local content = ccaes.decrypt_bytestream(response[2], key, iv)
  569.      local file = fs.open(FileClient, "wb")
  570.      for i = 1, #content do
  571.       file.write(content[i])
  572.      end
  573.      file.close()
  574.      return true
  575.     elseif response[1] == true then
  576.      return ccaes.decrypt_str(response[2], key, iv)
  577.     else
  578.      return response[2]
  579.     end
  580.    elseif senderID == nil then
  581.     return "nsh"
  582.    end
  583.   else
  584.    return "nsh"
  585.   end
  586.  else
  587.   return "nMa"
  588.  end
  589. end
  590.  
  591.  -- 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)
  592. function pushFile(Hostname, UsrName, UsrPass, FileClient, FileHost)
  593.  if Hostname == nil then
  594.   return "nHn"
  595.  elseif UsrName == nil then
  596.   return "nUsrN"
  597.  elseif UsrPass == nil then
  598.   return "nUsrP"
  599.  elseif FileHost == nil then
  600.   return "nFPH"
  601.  elseif FileClient == nil then
  602.   return "nFPC"
  603.  elseif not fs.exists(FileClient) then
  604.   return "FPCnE"
  605.  elseif getServerVer(Hostname) ~= ccFTPRev then
  606.   return "wSV"
  607.  end
  608.  checkAPI()
  609.  if checkModem() then
  610.   local key, iv = unfoldkeyC(UsrPass)
  611.   local file = fs.open(FileClient, "rb")
  612.   local fileData = {}
  613.   local fileByte = file.read()
  614.   repeat
  615.   table.insert(fileData, fileByte)
  616.   fileByte = file.read()
  617.   until fileByte == nil
  618.   file.close()
  619.   fileData = ccaes.encrypt_bytestream(fileData, key, iv)
  620.   local hosterID = sendMessageC(Hostname, UsrName, hash.sha256("iv"..iv[15]), ccFTPRev, ccaes.encrypt_str(textutils.serialize({"pushFile", FileHost, fileData}), key, iv))
  621.   if hosterID then
  622.    local response, senderID = waitForMessage("C")
  623.    if senderID == hosterID then
  624.     if response[1] == true then
  625.      local resd = ccaes.decrypt_str(response[2], key, iv)
  626.      if resd == "OK" then
  627.       return true
  628.      else
  629.       return resd
  630.      end
  631.     else
  632.      return response[2]
  633.     end
  634.    elseif senderID == nil then
  635.     return "nsh"
  636.    end
  637.   else
  638.    return "nsh"
  639.   end
  640.  else
  641.   return "nMa"
  642.  end
  643. end
  644.  
  645.  -- removes a single File from the FTP-Server
  646. function removeFile(Hostname, UsrName, UsrPass, FileHost)
  647.  if Hostname == nil then
  648.   return "nHn"
  649.  elseif UsrName == nil then
  650.   return "nUsrN"
  651.  elseif UsrPass == nil then
  652.   return "nUsrP"
  653.  elseif FileHost == nil then
  654.   return "nFPH"
  655.  elseif getServerVer(Hostname) ~= ccFTPRev then
  656.   return "wSV"
  657.  end
  658.  checkAPI()
  659.  if checkModem() then
  660.   local key, iv = unfoldkeyC(UsrPass)
  661.   local hosterID = sendMessageC(Hostname, UsrName, hash.sha256("iv"..iv[15]), ccFTPRev, ccaes.encrypt_str(textutils.serialize({"delFile", FileHost}), key, iv))
  662.   if hosterID then
  663.    local response, senderID = waitForMessage("C")
  664.    if senderID == hosterID then
  665.     if response[1] == true then
  666.      local resd = ccaes.decrypt_str(response[2], key, iv)
  667.      if resd == "OK" then
  668.       return true
  669.      else
  670.       return resd
  671.      end
  672.     else
  673.      return response[2]
  674.     end
  675.    elseif senderID == nil then
  676.     return "nsh"
  677.    end
  678.   elseif hosterID == nil then
  679.    return "nsh"
  680.   end
  681.  else
  682.   return "nMa"
  683.  end
  684. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement