From b868e7f3ce750a8d6d1f036eb23001c8cfea6b76 Mon Sep 17 00:00:00 2001 From: dmiller Date: Fri, 27 Jul 2012 20:07:38 +0000 Subject: [PATCH] Move caching code to datafiles lib Scripts no longer need to implement caching of datafiles tables in the registry, since the datafiles.lua library keeps its own cache in the registry. A side-effect is that scripts should not change the tables returned by datafiles.parse_{protocols,rpc,services,mac_prefixes}(), as doing so will affect all other scripts that use those functions. --- nselib/datafiles.lua | 57 +++++++++++++++++++++++-------------- scripts/address-info.nse | 13 +++------ scripts/lltd-discovery.nse | 9 ++---- scripts/nbstat.nse | 9 ++---- scripts/snmp-interfaces.nse | 9 ++---- scripts/unusual-port.nse | 38 ++++++++++--------------- 6 files changed, 61 insertions(+), 74 deletions(-) diff --git a/nselib/datafiles.lua b/nselib/datafiles.lua index d88149df7..e1815e265 100644 --- a/nselib/datafiles.lua +++ b/nselib/datafiles.lua @@ -32,6 +32,20 @@ local common_files = { } +-- Helper for parse_* functions +local parse_and_cache = function(filename) + nmap.registry.datafiles = nmap.registry.datafiles or {} + if not nmap.registry.datafiles[filename] then + local status + status, nmap.registry.datafiles[filename] = parse_file(filename) + if not status then + return false, string.format("Error parsing %s", filename) + end + end + + return true, nmap.registry.datafiles[filename] +end + --- -- Read and parse nmap-protocols. @@ -42,12 +56,7 @@ local common_files = { -- @return Table (if status is true) or error string (if status is false). -- @see parse_file parse_protocols = function() - local status, protocols_table = parse_file("nmap-protocols") - if not status then - return false, "Error parsing nmap-protocols" - end - - return true, protocols_table + return parse_and_cache("nmap-protocols") end @@ -59,12 +68,7 @@ end -- @return Table (if status is true) or error string (if status is false). -- @see parse_file parse_rpc = function() - local status, rpc_table = parse_file("nmap-rpc") - if not status then - return false, "Error parsing nmap-rpc" - end - - return true, rpc_table + return parse_and_cache("nmap-rpc") end @@ -86,9 +90,25 @@ parse_services = function(protocol) return false, "Bad protocol for nmap-services: use tcp or udp" end - local status, services_table = parse_file("nmap-services", protocol) - if not status then - return false, "Error parsing nmap-services" + local services_table + nmap.registry.datafiles = nmap.registry.datafiles or {} + nmap.registry.datafiles.services = nmap.registry.datafiles.services or {} + if protocol then + if not nmap.registry.datafiles.services[protocol] then + local status + status, nmap.registry.datafiles.services[protocol] = parse_file("nmap-services", protocol) + if not status then + return false, "Error parsing nmap-services" + end + end + services_table = nmap.registry.datafiles.services[protocol] + else + local status + status, nmap.registry.datafiles.services = parse_file("nmap-services") + if not status then + return false, "Error parsing nmap-services" + end + services_table = nmap.registry.datafiles.services end return true, services_table @@ -103,12 +123,7 @@ end -- @return Table (if status is true) or error string (if status is false). -- @see parse_file parse_mac_prefixes = function() - local status, mac_prefixes_table = parse_file("nmap-mac-prefixes") - if not status then - return false, "Error parsing nmap-mac-prefixes" - end - - return true, mac_prefixes_table + return parse_and_cache("nmap-mac-prefixes") end diff --git a/scripts/address-info.nse b/scripts/address-info.nse index b7a26f55c..d3d77c81f 100644 --- a/scripts/address-info.nse +++ b/scripts/address-info.nse @@ -99,16 +99,11 @@ local function matches(addr, pattern) end local function get_manuf(mac) - if not nmap.registry.mac then - local catch = function() return end - local try = nmap.new_try(catch) - -- Create the table in the registry so we can share between scripts - nmap.registry.mac = {} - nmap.registry.mac.prefixes = try(datafiles.parse_mac_prefixes()) - end + local catch = function() return "Unknown" end + local try = nmap.new_try(catch) + local mac_prefixes = try(datafiles.parse_mac_prefixes()) local prefix = string.upper(string.format("%02x%02x%02x", mac[1], mac[2], mac[3])) - local manuf = nmap.registry.mac.prefixes[prefix] or "Unknown" - return manuf + return mac_prefixes[prefix] or "Unknown" end local function format_mac(mac) diff --git a/scripts/lltd-discovery.nse b/scripts/lltd-discovery.nse index 2c5054ce1..ad91e6d22 100644 --- a/scripts/lltd-discovery.nse +++ b/scripts/lltd-discovery.nse @@ -67,18 +67,13 @@ end local function get_mac_addr( mac ) local catch = function() return end local try = nmap.new_try(catch) - -- Build the MAC prefix lookup table - if not nmap.registry.lltd_discovery then - -- Create the table in the registry so we can share between script instances - nmap.registry.lltd_discovery = {} - nmap.registry.lltd_discovery.mac_prefixes = try(datafiles.parse_mac_prefixes()) - end + local mac_prefixes = try(datafiles.parse_mac_prefixes()) if mac:len() ~= 6 then return "Unknown" else local prefix = string.upper(string.format("%02x%02x%02x", mac:byte(1), mac:byte(2), mac:byte(3))) - local manuf = nmap.registry.lltd_discovery.mac_prefixes[prefix] or "Unknown" + local manuf = mac_prefixes[prefix] or "Unknown" return string.format("%02x:%02x:%02x:%02x:%02x:%02x (%s)", mac:byte(1), mac:byte(2), mac:byte(3), mac:byte(4), mac:byte(5), mac:byte(6), manuf ) end end diff --git a/scripts/nbstat.nse b/scripts/nbstat.nse index 10fc82c87..b9b7a2cee 100644 --- a/scripts/nbstat.nse +++ b/scripts/nbstat.nse @@ -100,18 +100,13 @@ action = function(host) return stdnse.format_output(false, user_name) end - -- Build the MAC prefix lookup table - if not nmap.registry.nbstat then - -- Create the table in the registry so we can share between script instances - nmap.registry.nbstat = {} - nmap.registry.nbstat.mac_prefixes = try(datafiles.parse_mac_prefixes()) - end + local mac_prefixes = try(datafiles.parse_mac_prefixes()) -- Format the Mac address in the standard way if(#statistics >= 6) then -- MAC prefixes are matched on the first three bytes, all uppercase prefix = string.upper(string.format("%02x%02x%02x", statistics:byte(1), statistics:byte(2), statistics:byte(3))) - manuf = nmap.registry.nbstat.mac_prefixes[prefix] + manuf = mac_prefixes[prefix] if manuf == nil then manuf = "unknown" end diff --git a/scripts/snmp-interfaces.nse b/scripts/snmp-interfaces.nse index 3604fb929..83e197622 100644 --- a/scripts/snmp-interfaces.nse +++ b/scripts/snmp-interfaces.nse @@ -184,18 +184,13 @@ end function get_mac_addr( mac ) local catch = function() return end local try = nmap.new_try(catch) - -- Build the MAC prefix lookup table - if not nmap.registry.snmp_interfaces then - -- Create the table in the registry so we can share between script instances - nmap.registry.snmp_interfaces = {} - nmap.registry.snmp_interfaces.mac_prefixes = try(datafiles.parse_mac_prefixes()) - end + local mac_prefixes = try(datafiles.parse_mac_prefixes()) if mac:len() ~= 6 then return "Unknown" else local prefix = string.upper(string.format("%02x%02x%02x", mac:byte(1), mac:byte(2), mac:byte(3))) - local manuf = nmap.registry.snmp_interfaces.mac_prefixes[prefix] or "Unknown" + local manuf = mac_prefixes[prefix] or "Unknown" return string.format("%02x:%02x:%02x:%02x:%02x:%02x (%s)", mac:byte(1), mac:byte(2), mac:byte(3), mac:byte(4), mac:byte(5), mac:byte(6), manuf ) end end diff --git a/scripts/unusual-port.nse b/scripts/unusual-port.nse index 44e20e269..53d943043 100644 --- a/scripts/unusual-port.nse +++ b/scripts/unusual-port.nse @@ -22,7 +22,17 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = { "safe" } -portrule = function() return true end +local svc_table + +portrule = function() + local status + status, svc_table = datafiles.parse_services() + if not status then + return false --Can't check if we don't have a table! + end + return true +end + hostrule = function() return true end -- the hostrule is only needed to warn @@ -85,7 +95,7 @@ servicechecks = { ['ncacn_http'] = function(host, port) return true end, } -local function checkService(host, port) +portaction = function(host, port) local ok = false if ( port.version.name_confidence <= 3 ) then @@ -98,9 +108,9 @@ local function checkService(host, port) ok = servicechecks[port.service](host, port) end if ( not(ok) and port.service and - ( port.service == nmap.registry[SCRIPT_NAME]['services'][port.protocol][port.number] or - "unknown" == nmap.registry[SCRIPT_NAME]['services'][port.protocol][port.number] or - not(nmap.registry[SCRIPT_NAME]['services'][port.protocol][port.number]) ) ) then + ( port.service == svc_table[port.protocol][port.number] or + "unknown" == svc_table[port.protocol][port.number] or + not(svc_table[port.protocol][port.number]) ) ) then ok = true end if ( not(ok) ) then @@ -108,24 +118,6 @@ local function checkService(host, port) end end -local function loadTables() - for _, proto in ipairs({"tcp","udp"}) do - if ( not(nmap.registry[SCRIPT_NAME]['services'][proto]) ) then - local status, svc_table = datafiles.parse_services(proto) - if ( status ) then - nmap.registry[SCRIPT_NAME]['services'][proto] = svc_table - end - end - end -end - -portaction = function(host, port) - nmap.registry[SCRIPT_NAME] = nmap.registry[SCRIPT_NAME] or {} - nmap.registry[SCRIPT_NAME]['services'] = nmap.registry[SCRIPT_NAME]['services'] or {} - loadTables() - return checkService(host, port) -end - local Actions = { hostrule = hostaction, portrule = portaction