From 17416feb5efee528ca5e8a74d63c04f0d5e31bf4 Mon Sep 17 00:00:00 2001 From: dmiller Date: Thu, 16 Jan 2020 19:12:58 +0000 Subject: [PATCH] New outlib library for output-related functions --- CHANGELOG | 3 +++ nselib/outlib.lua | 49 ++++++++++++++++++++++++++++++++++++ nselib/unittest.lua | 1 + scripts/clock-skew.nse | 23 ++--------------- scripts/ssl-enum-ciphers.nse | 23 ++--------------- 5 files changed, 57 insertions(+), 42 deletions(-) create mode 100644 nselib/outlib.lua diff --git a/CHANGELOG b/CHANGELOG index 84ac822f9..d8cb59f06 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ #Nmap Changelog ($Id$); -*-text-*- +o [NSE] New outlib library will consolidate functions related to NSE output, + both string formatting conventions and structured output. [Daniel Miller] + o New XML output "hosthint" tag emitted during host discovery when a target is found to be up. This gives earlier notification than waiting for the hostgroup to finish all scan phases. [Paul Miseiko] diff --git a/nselib/outlib.lua b/nselib/outlib.lua new file mode 100644 index 000000000..c04eff8bc --- /dev/null +++ b/nselib/outlib.lua @@ -0,0 +1,49 @@ +--- Helper functions for NSE script output +-- +-- These functions are useful for ensuring output is consistently ordered +-- between scans and following conventions for output formatting. +-- +-- @author Daniel Miller +-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html +-- @class module +-- @name outlib + +local tableaux = require "tableaux" +local keys = tableaux.keys + +local coroutine = require "coroutine" +local wrap = coroutine.wrap +local yield = coroutine.yield + +local table = require "table" +local sort = table.sort + +local setmetatable = setmetatable +local ipairs = ipairs + +local _ENV = {} + +--- Create a table that yields elements sorted by key when iterated over with pairs() +-- +-- The returned table is like a sorted view of the original table; it should be +-- treated as read-only, and any new data should be added to the original table +-- instead. +--@param t The table whose data should be used +--@return out A table that can be passed to pairs() to get sorted results +function sorted_by_key(t) + local out = {} + setmetatable(out, { + __pairs = function(_) + local order = keys(t) + sort(order) + return wrap(function() + for i,k in ipairs(order) do + yield(k, t[k]) + end + end) + end + }) + return out +end + +return _ENV diff --git a/nselib/unittest.lua b/nselib/unittest.lua index ef50f5c8f..ac90c3182 100644 --- a/nselib/unittest.lua +++ b/nselib/unittest.lua @@ -105,6 +105,7 @@ local libs = { "omp2", "openssl", "ospf", +"outlib", "packet", "pcre", "pgsql", diff --git a/scripts/clock-skew.nse b/scripts/clock-skew.nse index 33701cb7d..0b123fdea 100644 --- a/scripts/clock-skew.nse +++ b/scripts/clock-skew.nse @@ -3,6 +3,7 @@ local datetime = require "datetime" local formulas = require "formulas" local math = require "math" local nmap = require "nmap" +local outlib = require "outlib" local stdnse = require "stdnse" local table = require "table" @@ -126,26 +127,6 @@ local function sorted_keys(t) return ret end ---- Return a table that yields elements sorted by key when iterated over with pairs() --- Should probably put this in a formatting library later. --- Depends on keys() function defined above. ---@param t The table whose data should be used ---@return out A table that can be passed to pairs() to get sorted results -function sorted_by_key(t) - local out = {} - setmetatable(out, { - __pairs = function(_) - local order = sorted_keys(t) - return coroutine.wrap(function() - for i,k in ipairs(order) do - coroutine.yield(k, t[k]) - end - end) - end - }) - return out -end - postaction = function() local skews = nmap.registry.clock_skews @@ -184,7 +165,7 @@ postaction = function() end if next(out) then - return sorted_by_key(out) + return outlib.sorted_by_key(out) end end diff --git a/scripts/ssl-enum-ciphers.nse b/scripts/ssl-enum-ciphers.nse index 690f04891..591a576a3 100644 --- a/scripts/ssl-enum-ciphers.nse +++ b/scripts/ssl-enum-ciphers.nse @@ -1,6 +1,7 @@ local coroutine = require "coroutine" local math = require "math" local nmap = require "nmap" +local outlib = require "outlib" local shortport = require "shortport" local sslcert = require "sslcert" local stdnse = require "stdnse" @@ -1070,26 +1071,6 @@ portrule = function (host, port) return shortport.ssl(host, port) or sslcert.getPrepareTLSWithoutReconnect(port) end ---- Return a table that yields elements sorted by key when iterated over with pairs() --- Should probably put this in a formatting library later. --- Depends on keys() function defined above. ---@param t The table whose data should be used ---@return out A table that can be passed to pairs() to get sorted results -function sorted_by_key(t) - local out = {} - setmetatable(out, { - __pairs = function(_) - local order = sorted_keys(t) - return coroutine.wrap(function() - for i,k in ipairs(order) do - coroutine.yield(k, t[k]) - end - end) - end - }) - return out -end - action = function(host, port) if not have_ssl then @@ -1129,5 +1110,5 @@ action = function(host, port) end results["least strength"] = least - return sorted_by_key(results) + return outlib.sorted_by_key(results) end