1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Speed improvement for script afp-ls. Closes #2098

This commit is contained in:
nnposter
2020-08-31 00:25:09 +00:00
parent fd16f90242
commit 05ad57df21
3 changed files with 50 additions and 44 deletions

View File

@@ -10,6 +10,9 @@ o [GH#2104] Fixed parsing of TCP options which would hang (infinite loop) if an
o [NSE][GH#2105] Fetching of SSH2 keys might fail because of key exchange o [NSE][GH#2105] Fetching of SSH2 keys might fail because of key exchange
confusion [nnposter] confusion [nnposter]
o [NSE][GH#2098] Performance of script afp-ls has been dramatically improved
[nnposter]
o [NSE][GH#2091] Parsing of AFP FPGetFileDirParms and o [NSE][GH#2091] Parsing of AFP FPGetFileDirParms and
FPEnumerateExt2FPEnumerateExt2 responses was not working correctly [nnposter] FPEnumerateExt2FPEnumerateExt2 responses was not working correctly [nnposter]

View File

@@ -1567,15 +1567,22 @@ Helper = {
-- @param depth number containing the current depth (used when called recursively) -- @param depth number containing the current depth (used when called recursively)
-- @param parent table containing information about the parent object (used when called recursively) -- @param parent table containing information about the parent object (used when called recursively)
-- @return status boolean true on success, false on failure -- @return status boolean true on success, false on failure
-- @return dir table containing a table for each directory item with the following <code>type</code>, -- @return dir table containing a table for each directory item with the following:
-- <code>name</code> and <code>id</code> -- <code>type</code>, <code>name</code>, <code>id</code>,
-- <code>fsize</code>, <code>uid</code>, <code>gid</code>,
-- <code>privs</code>, <code>create</code>, <code>modify</code>
Dir = function( self, str_path, options, depth, parent ) Dir = function( self, str_path, options, depth, parent )
local status, result local status, result
local depth = depth or 1 local depth = depth or 1
local options = options or { max_depth = 1 } local options = options or { max_depth = 1 }
local response, records local response, records
local f_bm = FILE_BITMAP.NodeId + FILE_BITMAP.ParentDirId + FILE_BITMAP.LongName local f_bm = FILE_BITMAP.NodeId | FILE_BITMAP.ParentDirId
local d_bm = DIR_BITMAP.NodeId + DIR_BITMAP.ParentDirId + DIR_BITMAP.LongName | FILE_BITMAP.LongName | FILE_BITMAP.UnixPrivileges
| FILE_BITMAP.CreationDate | FILE_BITMAP.ModificationDate
| FILE_BITMAP.ExtendedDataForkSize
local d_bm = DIR_BITMAP.NodeId | DIR_BITMAP.ParentDirId
| DIR_BITMAP.LongName | DIR_BITMAP.UnixPrivileges
| DIR_BITMAP.CreationDate | DIR_BITMAP.ModificationDate
local TYPE_DIR = 0x80 local TYPE_DIR = 0x80
@@ -1597,29 +1604,39 @@ Helper = {
end end
local path = { type=PATH_TYPE.LongName, name="" } local path = { type=PATH_TYPE.LongName, name="" }
response = self.proto:fp_enumerate_ext2( parent.vol_id, parent.did, f_bm, d_bm, 1000, 1, 52800, path) response = self.proto:fp_enumerate_ext2( parent.vol_id, parent.did, f_bm, d_bm, 1000, 1, 1000 * 300, path)
if response:getErrorCode() ~= ERROR.FPNoErr then if response:getErrorCode() ~= ERROR.FPNoErr then
return false, response:getErrorMessage() return false, response:getErrorMessage()
end end
records = response.result or {} records = response.result or {}
local dir_item = {} local dir_items = {}
for _, record in ipairs( records ) do for _, record in ipairs( records ) do
if ( options and options.dironly ) then local isdir = record.type == TYPE_DIR
if ( record.type == TYPE_DIR ) then -- Skip non-directories if option "dironly" is set
table.insert( dir_item, { ['type'] = record.type, ['name'] = record.LongName, ['id'] = record.NodeId } ) if isdir or not options.dironly then
local item = {type = record.type,
name = record.LongName,
id = record.NodeId,
fsize = record.ExtendedDataForkSize or 0}
local privs = (record.UnixPrivileges or {}).ua_permissions
if privs then
item.uid = record.UnixPrivileges.uid
item.gid = record.UnixPrivileges.gid
item.privs = (isdir and "d" or "-") .. Util.decode_unix_privs(privs)
end end
else item.create = Util.time_to_string(record.CreationDate)
table.insert( dir_item, { ['type'] = record.type, ['name'] = record.LongName, ['id'] = record.NodeId } ) item.modify = Util.time_to_string(record.ModificationDate)
table.insert( dir_items, item )
end end
if ( record.type == TYPE_DIR ) then if isdir then
self:Dir("", options, depth + 1, { vol_id = parent.vol_id, did=record.NodeId, dir_name=record.LongName, out_tbl=dir_item} ) self:Dir("", options, depth + 1, { vol_id = parent.vol_id, did=record.NodeId, dir_name=record.LongName, out_tbl=dir_items} )
end end
end end
table.insert( parent.out_tbl, dir_item ) table.insert( parent.out_tbl, dir_items )
return true, parent.out_tbl return true, parent.out_tbl
end, end,

View File

@@ -94,8 +94,11 @@ The output is intended to resemble the output of <code>ls</code>.
-- <elem key="bytes">0</elem> -- <elem key="bytes">0</elem>
-- </table> -- </table>
-- Version 0.1 -- Version 0.2
-- Created 04/03/2011 - v0.1 - created by Patrik Karlsson -- Created 04/03/2011 - v0.1 - created by Patrik Karlsson
-- Modified 08/02/2020 - v0.2 - replaced individual date/size/ownership calls
-- with direct sourcing from the output of
-- afp.Helper.Dir
author = "Patrik Karlsson" author = "Patrik Karlsson"
@@ -147,42 +150,25 @@ action = function(host, port)
for _, vol in ipairs( vols ) do for _, vol in ipairs( vols ) do
local status, tbl = afpHelper:Dir( vol ) local status, tbl = afpHelper:Dir( vol )
if ( not(status) ) then if ( not(status) ) then
ls.report_error( ls.report_error(output, ("ERROR: Failed to list the contents of %s"):format(vol))
output,
("ERROR: Failed to list the contents of %s"):format(vol))
else else
ls.new_vol(output, vol, true) ls.new_vol(output, vol, true)
local continue = true
for _, item in ipairs(tbl[1]) do for _, item in ipairs(tbl[1]) do
if ( item and item.name ) then if item and item.name then
local status, result = afpHelper:GetFileUnixPermissions( if not (item.privs and item.create) then
vol, item.name) ls.report_error(output, ("ERROR: Failed to retrieve file details for %/%s"):format(vol, item.name))
if ( status ) then
local status, fsize = afpHelper:GetFileSize( vol, item.name)
if ( not(status) ) then
ls.report_error(
output,
("ERROR: Failed to retrieve file size for %/%s"):format(vol, item.name))
else else
local status, date = afpHelper:GetFileDates( vol, item.name) local continue = ls.add_file(output, {
if ( not(status) ) then item.privs, item.uid, item.gid,
ls.report_error( item.fsize, item.create, item.name
output,
("\n\nERROR: Failed to retrieve file dates for %/%s"):format(vol, item.name))
else
continue = ls.add_file(output, {
result.privs, result.uid, result.gid,
fsize, date.create, item.name
}) })
end
end
end
end
if not continue then if not continue then
ls.report_info(output, ("maxfiles limit reached (%d)"):format(maxfiles)) ls.report_info(output, ("maxfiles limit reached (%d)"):format(maxfiles))
break break
end end
end end
end
end
ls.end_vol(output) ls.end_vol(output)
end end
end end