mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Merge r18689:r19511 from /nmap-exp/djalal/nse-rules.
o Add two new Script scan phases: Script Pre-scanning phase: before any Nmap scan operation, activated by the new "prerule". Script Post-scanning phase: after all Nmap scan operations, activated by the new "postrule". o New environment variables: SCRIPT_PATH SCRIPT_NAME SCRIPT_TYPE: the type of the rule that activated the script.
This commit is contained in:
@@ -73,8 +73,9 @@
|
||||
It represents to the topmost element of the output document.
|
||||
-->
|
||||
<!ELEMENT nmaprun (scaninfo*, verbose, debugging,
|
||||
((taskbegin, taskprogress*, taskend) | host | output)*,
|
||||
runstats) >
|
||||
((taskbegin, taskprogress*, taskend) |
|
||||
prescripts | postscripts | host | output)*,
|
||||
runstats) >
|
||||
<!ATTLIST nmaprun
|
||||
scanner (nmap) #REQUIRED
|
||||
args CDATA #IMPLIED
|
||||
@@ -332,3 +333,5 @@
|
||||
>
|
||||
|
||||
<!ELEMENT hostscript ( script+ )>
|
||||
<!ELEMENT prescript ( script+ )>
|
||||
<!ELEMENT postscript ( script+ )>
|
||||
|
||||
@@ -244,6 +244,6 @@ struct scan_lists {
|
||||
int prot_count;
|
||||
};
|
||||
|
||||
typedef enum { STYPE_UNKNOWN, HOST_DISCOVERY, ACK_SCAN, SYN_SCAN, FIN_SCAN, XMAS_SCAN, UDP_SCAN, CONNECT_SCAN, NULL_SCAN, WINDOW_SCAN, SCTP_INIT_SCAN, SCTP_COOKIE_ECHO_SCAN, RPC_SCAN, MAIMON_SCAN, IPPROT_SCAN, PING_SCAN, PING_SCAN_ARP, IDLE_SCAN, BOUNCE_SCAN, SERVICE_SCAN, OS_SCAN, SCRIPT_SCAN, TRACEROUTE}stype;
|
||||
typedef enum { STYPE_UNKNOWN, HOST_DISCOVERY, ACK_SCAN, SYN_SCAN, FIN_SCAN, XMAS_SCAN, UDP_SCAN, CONNECT_SCAN, NULL_SCAN, WINDOW_SCAN, SCTP_INIT_SCAN, SCTP_COOKIE_ECHO_SCAN, RPC_SCAN, MAIMON_SCAN, IPPROT_SCAN, PING_SCAN, PING_SCAN_ARP, IDLE_SCAN, BOUNCE_SCAN, SERVICE_SCAN, OS_SCAN, SCRIPT_PRE_SCAN, SCRIPT_SCAN, SCRIPT_POST_SCAN, TRACEROUTE}stype;
|
||||
|
||||
#endif /*GLOBAL_STRUCTURES_H */
|
||||
|
||||
25
nmap.cc
25
nmap.cc
@@ -442,6 +442,10 @@ int nmap_main(int argc, char *argv[]) {
|
||||
HostGroupState *hstate = NULL;
|
||||
char *endptr = NULL;
|
||||
struct scan_lists ports = { 0 };
|
||||
#ifndef NOLUA
|
||||
/* Pre-Scan and Post-Scan script results datastructure */
|
||||
ScriptResults *script_scan_results = NULL;
|
||||
#endif
|
||||
TargetGroup *exclude_group = NULL;
|
||||
char myname[MAXHOSTNAMELEN + 1];
|
||||
#if (defined(IN_ADDR_DEEPSTRUCT) || defined( SOLARIS))
|
||||
@@ -1602,6 +1606,13 @@ int nmap_main(int argc, char *argv[]) {
|
||||
o.scriptversion = 1;
|
||||
if (o.scriptversion || o.script || o.scriptupdatedb)
|
||||
open_nse();
|
||||
|
||||
if (o.script) {
|
||||
script_scan_results = get_script_scan_results_obj();
|
||||
script_scan(Targets, SCRIPT_PRE_SCAN);
|
||||
printscriptresults(script_scan_results, SCRIPT_PRE_SCAN);
|
||||
script_scan_results->clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Time to create a hostgroup state object filled with all the requested
|
||||
@@ -1815,7 +1826,7 @@ int nmap_main(int argc, char *argv[]) {
|
||||
|
||||
#ifndef NOLUA
|
||||
if(o.script || o.scriptversion) {
|
||||
script_scan(Targets);
|
||||
script_scan(Targets, SCRIPT_SCAN);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1866,6 +1877,14 @@ int nmap_main(int argc, char *argv[]) {
|
||||
o.numhosts_scanning = 0;
|
||||
} while(!o.max_ips_to_scan || o.max_ips_to_scan > o.numhosts_scanned);
|
||||
|
||||
#ifndef NOLUA
|
||||
if (o.script) {
|
||||
script_scan(Targets, SCRIPT_POST_SCAN);
|
||||
printscriptresults(script_scan_results, SCRIPT_POST_SCAN);
|
||||
script_scan_results->clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
delete hstate;
|
||||
if (exclude_group)
|
||||
delete[] exclude_group;
|
||||
@@ -2573,7 +2592,9 @@ const char *scantype2str(stype scantype) {
|
||||
case BOUNCE_SCAN: return "Bounce Scan"; break;
|
||||
case SERVICE_SCAN: return "Service Scan"; break;
|
||||
case OS_SCAN: return "OS Scan"; break;
|
||||
case SCRIPT_PRE_SCAN: return "Script Pre-Scan"; break;
|
||||
case SCRIPT_SCAN: return "Script Scan"; break;
|
||||
case SCRIPT_POST_SCAN: return "Script Post-Scan"; break;
|
||||
case TRACEROUTE: return "Traceroute" ; break;
|
||||
default: assert(0); break;
|
||||
}
|
||||
@@ -2795,5 +2816,3 @@ int nmap_fetchfile(char *filename_returned, int bufferlen, const char *file) {
|
||||
return foundsomething;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
47
nse_main.cc
47
nse_main.cc
@@ -22,6 +22,11 @@
|
||||
#define NSE_MAIN "NSE_MAIN" /* the main function */
|
||||
#define NSE_TRACEBACK "NSE_TRACEBACK"
|
||||
|
||||
/* Script Scan phases */
|
||||
#define NSE_PRE_SCAN "NSE_PRE_SCAN"
|
||||
#define NSE_SCAN "NSE_SCAN"
|
||||
#define NSE_POST_SCAN "NSE_POST_SCAN"
|
||||
|
||||
/* These are indices into the registry, for data shared with nse_main.lua. The
|
||||
definitions here must match those in nse_main.lua. */
|
||||
#define NSE_YIELD "NSE_YIELD"
|
||||
@@ -37,6 +42,9 @@
|
||||
|
||||
extern NmapOps o;
|
||||
|
||||
/* global object to store Pre-Scan and Post-Scan script results */
|
||||
static ScriptResults script_scan_results;
|
||||
|
||||
static int timedOut (lua_State *L)
|
||||
{
|
||||
Target *target = get_target(L, 1);
|
||||
@@ -101,6 +109,15 @@ static int ports (lua_State *L)
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int script_set_output (lua_State *L)
|
||||
{
|
||||
ScriptResult sr;
|
||||
sr.set_id(luaL_checkstring(L, 1));
|
||||
sr.set_output(luaL_checkstring(L, 2));
|
||||
script_scan_results.push_back(sr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int host_set_output (lua_State *L)
|
||||
{
|
||||
ScriptResult sr;
|
||||
@@ -188,6 +205,7 @@ static void open_cnse (lua_State *L)
|
||||
{"startTimeOutClock", startTimeOutClock},
|
||||
{"stopTimeOutClock", stopTimeOutClock},
|
||||
{"ports", ports},
|
||||
{"script_set_output", script_set_output},
|
||||
{"host_set_output", host_set_output},
|
||||
{"port_set_output", port_set_output},
|
||||
{NULL, NULL}
|
||||
@@ -231,6 +249,11 @@ std::string ScriptResult::get_id (void) const
|
||||
return id;
|
||||
}
|
||||
|
||||
ScriptResults *get_script_scan_results_obj (void)
|
||||
{
|
||||
return &script_scan_results;
|
||||
}
|
||||
|
||||
/* int panic (lua_State *L)
|
||||
*
|
||||
* Panic function set via lua_atpanic().
|
||||
@@ -333,6 +356,7 @@ static int run_main (lua_State *L)
|
||||
|
||||
/* New host group */
|
||||
lua_newtable(L);
|
||||
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, NSE_CURRENT_HOSTS);
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, NSE_TRACEBACK); /* index 1 */
|
||||
@@ -363,8 +387,23 @@ static int run_main (lua_State *L)
|
||||
}
|
||||
lua_pop(L, 1); /* pop NSE_CURRENT_HOSTS */
|
||||
|
||||
if (lua_pcall(L, 1, 0, 1) != 0) lua_error(L); /* we wanted a traceback */
|
||||
/* push script scan type phase */
|
||||
switch (o.current_scantype)
|
||||
{
|
||||
case SCRIPT_PRE_SCAN:
|
||||
lua_pushstring(L, NSE_PRE_SCAN);
|
||||
break;
|
||||
case SCRIPT_SCAN:
|
||||
lua_pushstring(L, NSE_SCAN);
|
||||
break;
|
||||
case SCRIPT_POST_SCAN:
|
||||
lua_pushstring(L, NSE_POST_SCAN);
|
||||
break;
|
||||
default:
|
||||
fatal("%s: failed to set the script scan phase.\n", SCRIPT_ENGINE);
|
||||
}
|
||||
|
||||
if (lua_pcall(L, 2, 0, 1) != 0) lua_error(L); /* we wanted a traceback */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -495,18 +534,16 @@ void open_nse (void)
|
||||
}
|
||||
}
|
||||
|
||||
void script_scan (std::vector<Target *> &targets)
|
||||
void script_scan (std::vector<Target *> &targets, stype scantype)
|
||||
{
|
||||
o.current_scantype = SCRIPT_SCAN;
|
||||
o.current_scantype = scantype;
|
||||
|
||||
assert(L_NSE != NULL);
|
||||
lua_settop(L_NSE, 0); /* clear the stack */
|
||||
|
||||
if (lua_cpcall(L_NSE, run_main, (void *) &targets) != 0)
|
||||
{
|
||||
error("%s: Script Engine Scan Aborted.\nAn error was thrown by the "
|
||||
"engine: %s", SCRIPT_ENGINE, lua_tostring(L_NSE, -1));
|
||||
}
|
||||
}
|
||||
|
||||
void close_nse (void)
|
||||
|
||||
@@ -13,6 +13,9 @@ extern "C" {
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
#include "nmap.h"
|
||||
#include "global_structures.h"
|
||||
|
||||
class ScriptResult
|
||||
{
|
||||
private:
|
||||
@@ -27,6 +30,10 @@ class ScriptResult
|
||||
|
||||
typedef std::list<ScriptResult> ScriptResults;
|
||||
|
||||
/* Call this to get a ScriptResults object which can be
|
||||
* used to store Pre-Scan and Post-Scan script Results */
|
||||
ScriptResults *get_script_scan_results_obj (void);
|
||||
|
||||
class Target;
|
||||
|
||||
|
||||
@@ -39,7 +46,7 @@ void nse_selectedbyname (lua_State *);
|
||||
void nse_gettarget (lua_State *, int);
|
||||
|
||||
void open_nse (void);
|
||||
void script_scan (std::vector<Target *> &targets);
|
||||
void script_scan (std::vector<Target *> &targets, stype scantype);
|
||||
void close_nse (void);
|
||||
|
||||
#define SCRIPT_ENGINE "NSE"
|
||||
|
||||
274
nse_main.lua
274
nse_main.lua
@@ -32,6 +32,11 @@
|
||||
|
||||
local NAME = "NSE";
|
||||
|
||||
-- Script Scan phases.
|
||||
local NSE_PRE_SCAN = "NSE_PRE_SCAN";
|
||||
local NSE_SCAN = "NSE_SCAN";
|
||||
local NSE_POST_SCAN = "NSE_POST_SCAN";
|
||||
|
||||
-- String keys into the registry (_R), for data shared with nse_main.cc.
|
||||
local YIELD = "NSE_YIELD";
|
||||
local BASE = "NSE_BASE";
|
||||
@@ -107,6 +112,14 @@ local stdnse = require "stdnse";
|
||||
-- differentiate between yields initiated by NSE or regular coroutine yields.
|
||||
local NSE_YIELD_VALUE = {};
|
||||
|
||||
-- Table of different supported rules.
|
||||
local NSE_SCRIPT_RULES = {
|
||||
prerule = "prerule",
|
||||
hostrule = "hostrule",
|
||||
portrule = "portrule",
|
||||
postrule = "postrule",
|
||||
};
|
||||
|
||||
do
|
||||
-- This is the method by which we allow a script to have nested
|
||||
-- coroutines. If a sub-thread yields in an NSE function such as
|
||||
@@ -187,14 +200,79 @@ do
|
||||
-- Outputs debug information at level 1 or higher.
|
||||
-- Changes "%THREAD" with an appropriate identifier for the debug level
|
||||
function Thread:d (fmt, ...)
|
||||
if debugging() > 1 then
|
||||
print_debug(1, gsub(fmt, "%%THREAD", self.info), ...);
|
||||
local against;
|
||||
if self.host and self.port then
|
||||
against = " against "..self.host.ip..":"..self.port.number;
|
||||
elseif self.host then
|
||||
against = " against "..self.host.ip;
|
||||
else
|
||||
print_debug(1, gsub(fmt, "%%THREAD", self.short_basename), ...);
|
||||
against = "";
|
||||
end
|
||||
if debugging() > 1 then
|
||||
fmt = gsub(fmt, "%%THREAD_AGAINST", self.info..against);
|
||||
fmt = gsub(fmt, "%%THREAD", self.info);
|
||||
else
|
||||
fmt = gsub(fmt, "%%THREAD_AGAINST", self.short_basename..against);
|
||||
fmt = gsub(fmt, "%%THREAD", self.short_basename);
|
||||
end
|
||||
print_debug(1, fmt, ...);
|
||||
end
|
||||
|
||||
-- Sets scripts output. Variable result is a string.
|
||||
function Thread:set_output(result)
|
||||
if self.type == "prerule" or self.type == "postrule" then
|
||||
cnse.script_set_output(self.id, result);
|
||||
elseif self.type == "hostrule" then
|
||||
cnse.host_set_output(self.host, self.id, result);
|
||||
elseif self.type == "portrule" then
|
||||
cnse.port_set_output(self.host, self.port, self.id, result);
|
||||
end
|
||||
end
|
||||
|
||||
function Thread:close ()
|
||||
-- prerule/postrule scripts may be timed out in the future
|
||||
-- based on start time and script lifetime?
|
||||
function Thread:timed_out ()
|
||||
if self.type == "hostrule" or self.type == "portrule" then
|
||||
return cnse.timedOut(self.host);
|
||||
end
|
||||
return nil;
|
||||
end
|
||||
|
||||
function Thread:start_time_out_clock ()
|
||||
if self.type == "hostrule" or self.type == "portrule" then
|
||||
return cnse.startTimeOutClock(self.host);
|
||||
end
|
||||
return nil;
|
||||
end
|
||||
|
||||
function Thread:stop_time_out_clock ()
|
||||
if self.type == "hostrule" or self.type == "portrule" then
|
||||
return cnse.stopTimeOutClock(self.host);
|
||||
end
|
||||
return nil;
|
||||
end
|
||||
|
||||
-- Register scripts in the timeouts list to track their timeouts.
|
||||
function Thread:start (timeouts)
|
||||
self:d("Starting %THREAD_AGAINST.");
|
||||
if self.host then
|
||||
timeouts[self.host] = timeouts[self.host] or {};
|
||||
timeouts[self.host][self.co] = true;
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove scripts from the timeouts list and call their
|
||||
-- destructor handles.
|
||||
function Thread:close (timeouts, result)
|
||||
self.error = result;
|
||||
if self.host then
|
||||
timeouts[self.host][self.co] = nil;
|
||||
-- Any more threads running for this script/host?
|
||||
if not next(timeouts[self.host]) then
|
||||
self:stop_time_out_clock();
|
||||
timeouts[self.host] = nil;
|
||||
end
|
||||
end
|
||||
local ch = self.close_handlers;
|
||||
for key, destructor_t in pairs(ch) do
|
||||
destructor_t.destructor(destructor_t.thread, key);
|
||||
@@ -210,11 +288,13 @@ do
|
||||
-- Returns:
|
||||
-- thread The thread (class) is returned, or nil.
|
||||
function Script:new_thread (rule, ...)
|
||||
assert(rule == "hostrule" or rule == "portrule");
|
||||
local script_type = assert(NSE_SCRIPT_RULES[rule]);
|
||||
if not self[rule] then return nil end -- No rule for this script?
|
||||
local file_closure = self.file_closure;
|
||||
local env = setmetatable({
|
||||
filename = self.filename,
|
||||
SCRIPT_PATH = self.filename,
|
||||
SCRIPT_NAME = self.short_basename,
|
||||
SCRIPT_TYPE = script_type,
|
||||
}, {__index = _G});
|
||||
setfenv(file_closure, env);
|
||||
local unique_value = {}; -- to test valid yield
|
||||
@@ -238,7 +318,7 @@ do
|
||||
env = env,
|
||||
identifier = tostring(co),
|
||||
info = format("'%s' (%s)", self.short_basename, tostring(co));
|
||||
type = rule == "hostrule" and "host" or "port",
|
||||
type = script_type,
|
||||
close_handlers = {},
|
||||
}, {
|
||||
__metatable = Thread,
|
||||
@@ -291,10 +371,19 @@ do
|
||||
type(field).."', expected type '"..t.."'");
|
||||
end
|
||||
end
|
||||
-- Check one of two required rule functions exists
|
||||
local hostrule, portrule = rawget(env, "hostrule"), rawget(env, "portrule");
|
||||
assert(type(hostrule) == "function" or type(portrule) == "function",
|
||||
filename.." is missing a required function: 'hostrule' or 'portrule'");
|
||||
-- Check the required rule functions
|
||||
local rules = {}
|
||||
for rule in pairs(NSE_SCRIPT_RULES) do
|
||||
local rulef = rawget(env, rule);
|
||||
assert(type(rulef) == "function" or rulef == nil,
|
||||
rule.." must be a function!");
|
||||
rules[rule] = rulef;
|
||||
end
|
||||
assert(next(rules), filename.." is missing required function: 'rule'");
|
||||
local prerule = rules.prerule;
|
||||
local hostrule = rules.hostrule;
|
||||
local portrule = rules.portrule;
|
||||
local postrule = rules.postrule;
|
||||
-- Assert that categories is an array of strings
|
||||
for i, category in ipairs(rawget(env, "categories")) do
|
||||
assert(type(category) == "string",
|
||||
@@ -314,8 +403,10 @@ do
|
||||
filename,
|
||||
id = match(filename, "^.-[/\\]([^\\/]-)%.nse$") or filename,
|
||||
file_closure = file_closure,
|
||||
hostrule = type(hostrule) == "function" and hostrule or nil,
|
||||
portrule = type(portrule) == "function" and portrule or nil,
|
||||
prerule = prerule,
|
||||
hostrule = hostrule,
|
||||
portrule = portrule,
|
||||
postrule = postrule,
|
||||
args = {n = 0};
|
||||
categories = rawget(env, "categories"),
|
||||
author = rawget(env, "author"),
|
||||
@@ -518,26 +609,24 @@ end
|
||||
-- The main loop function for NSE. It handles running all the script threads.
|
||||
-- Arguments:
|
||||
-- threads An array of threads (a runlevel) to run.
|
||||
local function run (threads)
|
||||
-- scantype A string that indicates the current script scan phase.
|
||||
local function run (threads, scantype)
|
||||
-- running scripts may be resumed at any time. waiting scripts are
|
||||
-- yielded until Nsock wakes them. After being awakened with
|
||||
-- nse_restore, waiting threads become pending and later are moved all
|
||||
-- at once back to running.
|
||||
local running, waiting, pending = {}, {}, {};
|
||||
local all = setmetatable({}, {__mode = "kv"}); -- base coroutine to Thread
|
||||
-- hosts maps a host to a list of threads for that host.
|
||||
local hosts, total = {}, 0;
|
||||
local current;
|
||||
local current; -- The currently running Thread.
|
||||
local total = 0; -- Number of threads, for record keeping.
|
||||
local timeouts = {}; -- A list to save and to track scripts timeout.
|
||||
local progress = cnse.scan_progress_meter(NAME);
|
||||
|
||||
print_debug(1, "NSE Script Threads (%d) running:", #threads);
|
||||
while #threads > 0 do
|
||||
local thread = remove(threads);
|
||||
thread:d("Starting %THREAD against %s%s.", thread.host.ip,
|
||||
thread.port and ":"..thread.port.number or "");
|
||||
all[thread.co], running[thread.co], total = thread, thread, total+1;
|
||||
hosts[thread.host] = hosts[thread.host] or {};
|
||||
hosts[thread.host][thread.co] = true;
|
||||
thread:start(timeouts);
|
||||
end
|
||||
|
||||
-- Map of yielded threads to the base Thread
|
||||
@@ -586,9 +675,11 @@ local function run (threads)
|
||||
current.parent.info, tostring(co));
|
||||
local thread = {
|
||||
co = co,
|
||||
id = current.id,
|
||||
args = {n = select("#", ...), ...},
|
||||
host = current.host,
|
||||
port = current.port,
|
||||
type = current.type,
|
||||
parent = current.parent,
|
||||
info = format("'%s' worker (%s)", current.short_basename, tostring(co));
|
||||
-- d = function(...) end, -- output no debug information
|
||||
@@ -633,28 +724,28 @@ local function run (threads)
|
||||
end
|
||||
end
|
||||
|
||||
-- Checked for timed-out hosts.
|
||||
-- Checked for timed-out scripts and hosts.
|
||||
for co, thread in pairs(waiting) do
|
||||
if cnse.timedOut(thread.host) then
|
||||
if thread:timed_out() then
|
||||
waiting[co], all[co] = nil, nil;
|
||||
thread:d("%THREAD %s%s timed out", thread.host.ip,
|
||||
thread.port and ":"..thread.port.number or "");
|
||||
thread:close();
|
||||
thread:d("%THREAD %stimed out", thread.host
|
||||
and format("%s%s ", thread.host.ip,
|
||||
thread.port and ":"..thread.port.number or "")
|
||||
or "");
|
||||
thread:close(timeouts, "timed out");
|
||||
end
|
||||
end
|
||||
|
||||
for co, thread in pairs(running) do
|
||||
current, running[co] = thread, nil;
|
||||
cnse.startTimeOutClock(thread.host);
|
||||
thread:start_time_out_clock();
|
||||
|
||||
local s, result = resume(co, unpack(thread.args, 1, thread.args.n));
|
||||
if not s then -- script error...
|
||||
hosts[thread.host][co], all[co] = nil, nil;
|
||||
thread:d("%THREAD against %s%s threw an error!\n%s\n",
|
||||
thread.host.ip, thread.port and ":"..thread.port.number or "",
|
||||
all[co] = nil;
|
||||
thread:d("%THREAD_AGAINST threw an error!\n%s\n",
|
||||
traceback(co, tostring(result)));
|
||||
thread.error = result;
|
||||
thread:close();
|
||||
thread:close(timeouts, result);
|
||||
elseif status(co) == "suspended" then
|
||||
if result == NSE_YIELD_VALUE then
|
||||
waiting[co] = thread;
|
||||
@@ -663,7 +754,7 @@ local function run (threads)
|
||||
thread:close();
|
||||
end
|
||||
elseif status(co) == "dead" then
|
||||
hosts[thread.host][co], all[co] = nil, nil;
|
||||
all[co] = nil;
|
||||
if type(result) == "string" then
|
||||
-- Escape any character outside the range 32-126 except for tab,
|
||||
-- carriage return, and line feed. This makes the string safe for
|
||||
@@ -671,20 +762,10 @@ local function run (threads)
|
||||
result = gsub(result, "[^\t\r\n\032-\126]", function(a)
|
||||
return format("\\x%02X", byte(a));
|
||||
end);
|
||||
if thread.type == "host" then
|
||||
cnse.host_set_output(thread.host, thread.id, result);
|
||||
else
|
||||
cnse.port_set_output(thread.host, thread.port, thread.id, result);
|
||||
end
|
||||
thread:set_output(result);
|
||||
end
|
||||
thread:d("Finished %THREAD against %s%s.", thread.host.ip,
|
||||
thread.port and ":"..thread.port.number or "");
|
||||
thread:close();
|
||||
end
|
||||
|
||||
-- Any more threads running for this host?
|
||||
if not next(hosts[thread.host]) then
|
||||
cnse.stopTimeOutClock(thread.host);
|
||||
thread:d("Finished %THREAD_AGAINST.");
|
||||
thread:close(timeouts);
|
||||
end
|
||||
end
|
||||
|
||||
@@ -804,45 +885,104 @@ for i, script in ipairs(chosen_scripts) do
|
||||
end
|
||||
|
||||
-- main(hosts)
|
||||
-- This is the main function we return to NSE (on the C side) which actually
|
||||
-- runs a scan against an array of hosts. nse_main.cc gets this function
|
||||
-- by loading and executing nse_main.lua.
|
||||
-- This is the main function we return to NSE (on the C side), nse_main.cc
|
||||
-- gets this function by loading and executing nse_main.lua. This
|
||||
-- function runs a script scan phase according to its arguments.
|
||||
-- Arguments:
|
||||
-- hosts An array of hosts to scan.
|
||||
return function (hosts)
|
||||
if #hosts > 1 then
|
||||
print_verbose(1, "Script scanning %d hosts.", #hosts);
|
||||
elseif #hosts == 1 then
|
||||
print_verbose(1, "Script scanning %s.", hosts[1].ip);
|
||||
end
|
||||
|
||||
-- Set up the runlevels.
|
||||
-- scantype A string that indicates the current script scan phase.
|
||||
-- Possible string values are:
|
||||
-- "SCRIPT_PRE_SCAN"
|
||||
-- "SCRIPT_SCAN"
|
||||
-- "SCRIPT_POST_SCAN"
|
||||
return function (hosts, scantype)
|
||||
-- Used to set up the runlevels.
|
||||
local threads, runlevels = {}, {};
|
||||
for j, host in ipairs(hosts) do
|
||||
-- Check hostrules for this host.
|
||||
|
||||
-- Every script thread has a table that is used in the run function
|
||||
-- (the main loop of NSE).
|
||||
-- This is the list of the thread table key/value pairs:
|
||||
-- Key Value
|
||||
-- type A string that indicates the rule type of the script.
|
||||
-- co A thread object to identify the coroutine.
|
||||
-- parent A table that contains the parent thread table (it self).
|
||||
-- close_handlers
|
||||
-- A table that contains the thread destructor handlers.
|
||||
-- info A string that contains the script name and the thread
|
||||
-- debug information.
|
||||
-- args A table that contains the arguments passed to scripts,
|
||||
-- arguments can be host and port tables.
|
||||
-- env A table that contains the global script environment:
|
||||
-- categories, description, author, license, nmap table,
|
||||
-- action function, rule functions, SCRIPT_PATH,
|
||||
-- SCRIPT_NAME, SCRIPT_TYPE (pre|host|port|post rule).
|
||||
-- identifier
|
||||
-- A string to identify the thread address.
|
||||
-- host A table that contains the target host information. This
|
||||
-- will be nil for Pre-scanning and Post-scanning scripts.
|
||||
-- port A table that contains the target port information. This
|
||||
-- will be nil for Pre-scanning and Post-scanning scripts.
|
||||
|
||||
-- activate prerule scripts
|
||||
if (scantype == NSE_PRE_SCAN) then
|
||||
print_verbose(1, "Script Pre-scanning.");
|
||||
for i, script in ipairs(chosen_scripts) do
|
||||
local thread = script:new_thread("hostrule", tcopy(host));
|
||||
local thread = script:new_thread("prerule");
|
||||
if thread then
|
||||
local runlevel = thread.runlevel;
|
||||
if threads[runlevel] == nil then insert(runlevels, runlevel); end
|
||||
threads[runlevel] = threads[runlevel] or {};
|
||||
insert(threads[runlevel], thread);
|
||||
thread.args, thread.host = {n = 1, tcopy(host)}, host;
|
||||
thread.args = {n = 0};
|
||||
end
|
||||
end
|
||||
-- Check portrules for this host.
|
||||
for port in cnse.ports(host) do
|
||||
-- activate hostrule and portrule scripts
|
||||
elseif (scantype == NSE_SCAN) then
|
||||
if #hosts > 1 then
|
||||
print_verbose(1, "Script scanning %d hosts.", #hosts);
|
||||
elseif #hosts == 1 then
|
||||
print_verbose(1, "Script scanning %s.", hosts[1].ip);
|
||||
end
|
||||
|
||||
-- Check hostrules for this host.
|
||||
for j, host in ipairs(hosts) do
|
||||
for i, script in ipairs(chosen_scripts) do
|
||||
local thread = script:new_thread("portrule", tcopy(host), tcopy(port));
|
||||
local thread = script:new_thread("hostrule", tcopy(host));
|
||||
if thread then
|
||||
local runlevel = thread.runlevel;
|
||||
if threads[runlevel] == nil then insert(runlevels, runlevel); end
|
||||
threads[runlevel] = threads[runlevel] or {};
|
||||
insert(threads[runlevel], thread);
|
||||
thread.args, thread.host, thread.port =
|
||||
{n = 2, tcopy(host), tcopy(port)}, host, port;
|
||||
thread.args, thread.host = {n = 1, tcopy(host)}, host;
|
||||
end
|
||||
end
|
||||
-- Check portrules for this host.
|
||||
for port in cnse.ports(host) do
|
||||
for i, script in ipairs(chosen_scripts) do
|
||||
local thread = script:new_thread("portrule", tcopy(host), tcopy(port));
|
||||
if thread then
|
||||
local runlevel = thread.runlevel;
|
||||
if threads[runlevel] == nil then insert(runlevels, runlevel); end
|
||||
threads[runlevel] = threads[runlevel] or {};
|
||||
insert(threads[runlevel], thread);
|
||||
thread.args, thread.host, thread.port =
|
||||
{n = 2, tcopy(host), tcopy(port)}, host, port;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- activate postrule scripts
|
||||
elseif (scantype == NSE_POST_SCAN) then
|
||||
print_verbose(1, "Script Post-scanning.");
|
||||
for i, script in ipairs(chosen_scripts) do
|
||||
local thread = script:new_thread("postrule");
|
||||
if thread then
|
||||
local runlevel = thread.runlevel;
|
||||
if threads[runlevel] == nil then insert(runlevels, runlevel); end
|
||||
threads[runlevel] = threads[runlevel] or {};
|
||||
insert(threads[runlevel], thread);
|
||||
thread.args = {n = 0};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -850,7 +990,7 @@ return function (hosts)
|
||||
for i, runlevel in ipairs(runlevels) do
|
||||
print_verbose(1, "Starting runlevel %u (of %u) scan.", runlevel,
|
||||
#runlevels);
|
||||
run(threads[runlevel]);
|
||||
run(threads[runlevel], scantype);
|
||||
end
|
||||
|
||||
collectgarbage "collect";
|
||||
|
||||
29
output.cc
29
output.cc
@@ -1918,6 +1918,35 @@ void printserviceinfooutput(Target * currenths) {
|
||||
}
|
||||
|
||||
#ifndef NOLUA
|
||||
void printscriptresults(ScriptResults * scriptResults, stype scantype) {
|
||||
ScriptResults::iterator iter;
|
||||
char *script_output;
|
||||
|
||||
if (scriptResults->size() > 0) {
|
||||
if (scantype == SCRIPT_PRE_SCAN) {
|
||||
xml_start_tag("prescript");
|
||||
log_write(LOG_PLAIN, "Pre-scan script results:\n");
|
||||
}
|
||||
else {
|
||||
xml_start_tag("postscript");
|
||||
log_write(LOG_PLAIN, "Post-scan script results:\n");
|
||||
}
|
||||
|
||||
for (iter = scriptResults->begin();
|
||||
iter != scriptResults->end();
|
||||
iter++) {
|
||||
xml_open_start_tag("script");
|
||||
xml_attribute("id", "%s", iter->get_id().c_str());
|
||||
xml_attribute("output", "%s", iter->get_output().c_str());
|
||||
xml_close_empty_tag();
|
||||
script_output = formatScriptOutput((*iter));
|
||||
log_write(LOG_PLAIN, "%s\n", script_output);
|
||||
free(script_output);
|
||||
}
|
||||
xml_end_tag();
|
||||
}
|
||||
}
|
||||
|
||||
void printhostscriptresults(Target * currenths) {
|
||||
ScriptResults::iterator iter;
|
||||
char *script_output;
|
||||
|
||||
3
output.h
3
output.h
@@ -213,6 +213,9 @@ void printosscanoutput(Target *currenths);
|
||||
service scan (if it was performed) */
|
||||
void printserviceinfooutput(Target *currenths);
|
||||
|
||||
/* Use this function to report NSE_PRE_SCAN and NSE_POST_SCAN results */
|
||||
void printscriptresults(ScriptResults *scriptResults, stype scantype);
|
||||
|
||||
void printhostscriptresults(Target *currenths);
|
||||
|
||||
/* Print a table with traceroute hops. */
|
||||
|
||||
@@ -209,7 +209,7 @@ function ip_to_asn( query )
|
||||
local status, decoded_response = dns.query( query, options)
|
||||
|
||||
if not status then
|
||||
stdnse.print_debug( "%s Error from dns.query(): %s", filename, decoded_response )
|
||||
stdnse.print_debug( "%s Error from dns.query(): %s", SCRIPT_NAME, decoded_response )
|
||||
end
|
||||
|
||||
return status, decoded_response
|
||||
|
||||
@@ -56,7 +56,7 @@ function grab_banner(host, port)
|
||||
if not status then
|
||||
local errlvl = { ["EOF"]=3,["TIMEOUT"]=3,["ERROR"]=2 }
|
||||
stdnse.print_debug(errlvl[response] or 1, "%s failed for %s on %s port %s. Message: %s",
|
||||
filename, host.ip, port.protocol, port.number, response or "No Message." )
|
||||
SCRIPT_NAME, host.ip, port.protocol, port.number, response or "No Message." )
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -87,8 +87,7 @@ function output( out )
|
||||
|
||||
if type(out) ~= "string" or out == "" then return nil end
|
||||
|
||||
-- convert filename from full filepath to filename -extn
|
||||
local filename = filename:match( "[\\/]([^\\/]+)\.nse$" )
|
||||
local filename = SCRIPT_NAME
|
||||
local line_len = 75 -- The character width of command/shell prompt window.
|
||||
local fline_offset = 5 -- number of chars excluding script id not available to the script on the first line
|
||||
|
||||
|
||||
@@ -57,7 +57,8 @@ action = function(host, port)
|
||||
end
|
||||
|
||||
if not pcall(require,'openssl') then
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.", filename )
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.",
|
||||
SCRIPT_NAME)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@@ -150,13 +150,12 @@ end
|
||||
-- @return nil
|
||||
|
||||
function init()
|
||||
local filename = filename and filename:match( "[\\/]([^\\/]+)\.nse$" ) or ""
|
||||
local customlist = nmap.registry.args.users or
|
||||
(nmap.registry.args.userdir and nmap.registry.args.userdir.users) or
|
||||
nmap.registry.args['userdir.users']
|
||||
local read, usernames = datafiles.parse_file(customlist or "nselib/data/usernames.lst", {})
|
||||
if not read then
|
||||
stdnse.print_debug(1, "%s %s", filename,
|
||||
stdnse.print_debug(1, "%s %s", SCRIPT_NAME,
|
||||
usernames or "Unknown Error reading usernames list.")
|
||||
nmap.registry.userdir = {}
|
||||
return nil
|
||||
@@ -164,7 +163,7 @@ function init()
|
||||
-- random dummy username to catch false positives (not necessary)
|
||||
-- if #usernames > 0 then table.insert(usernames, 1, randomstring()) end
|
||||
nmap.registry.userdir = usernames
|
||||
stdnse.print_debug(1, "%s Testing %d usernames.", filename, #usernames)
|
||||
stdnse.print_debug(1, "%s Testing %d usernames.", SCRIPT_NAME, #usernames)
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ action = function(host, port)
|
||||
end
|
||||
return stdnse.strjoin(" ", capstrings)
|
||||
elseif type(err) == "string" then
|
||||
stdnse.print_debug(1, "%s: '%s' for %s", filename, err, host.ip)
|
||||
stdnse.print_debug(1, "%s: '%s' for %s", SCRIPT_NAME, err, host.ip)
|
||||
return
|
||||
else
|
||||
return "server doesn't support CAPABILITIES"
|
||||
|
||||
@@ -28,7 +28,8 @@ require 'unpwdb'
|
||||
if not pcall(require,"openssl") then
|
||||
portrule = function() return false end
|
||||
action = function() end
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.", filename )
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.",
|
||||
SCRIPT_NAME)
|
||||
return;
|
||||
end
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ dependencies = {"mysql-brute", "mysql-empty-password"}
|
||||
if not pcall(require,"openssl") then
|
||||
portrule = function() return false end
|
||||
action = function() end
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.", filename )
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.",
|
||||
SCRIPT_NAME)
|
||||
return;
|
||||
end
|
||||
|
||||
|
||||
@@ -41,7 +41,8 @@ dependencies = {"mysql-brute", "mysql-empty-password"}
|
||||
if not pcall(require,"openssl") then
|
||||
portrule = function() return false end
|
||||
action = function() end
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.", filename )
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.",
|
||||
SCRIPT_NAME)
|
||||
return;
|
||||
end
|
||||
|
||||
|
||||
@@ -49,7 +49,8 @@ dependencies = {"mysql-brute", "mysql-empty-password"}
|
||||
if not pcall(require,"openssl") then
|
||||
portrule = function() return false end
|
||||
action = function() end
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.", filename )
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.",
|
||||
SCRIPT_NAME)
|
||||
return;
|
||||
end
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ if pcall(require,"openssl") then
|
||||
else
|
||||
portrule = function() return false end
|
||||
action = function() end
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.", filename )
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.",
|
||||
SCRIPT_NAME)
|
||||
return;
|
||||
end
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ action = function(host, port)
|
||||
end
|
||||
return stdnse.strjoin(" ", capstrings)
|
||||
elseif type(err) == "string" then
|
||||
stdnse.print_debug(1, "%s: '%s' for %s", filename, err, host.ip)
|
||||
stdnse.print_debug(1, "%s: '%s' for %s", SCRIPT_NAME, err, host.ip)
|
||||
return
|
||||
else
|
||||
return "server doesn't support CAPA"
|
||||
|
||||
@@ -233,7 +233,7 @@ action = function(host, port)
|
||||
end
|
||||
|
||||
if #injectable > 0 then
|
||||
stdnse.print_debug(1, "%s: Testing %d suspicious URLs", filename, #injectable )
|
||||
stdnse.print_debug(1, "%s: Testing %d suspicious URLs", SCRIPT_NAME, #injectable )
|
||||
-- test all potentially vulnerable queries
|
||||
injectableQs = build_injection_vector(injectable)
|
||||
local responses = inject(host, port, injectableQs)
|
||||
|
||||
@@ -50,7 +50,8 @@ if pcall(require,"openssl") then
|
||||
else
|
||||
portrule = function() return false end
|
||||
action = function() end
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.", filename )
|
||||
stdnse.print_debug( 3, "Skipping %s script because OpenSSL is missing.",
|
||||
SCRIPT_NAME)
|
||||
return;
|
||||
end
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ hostrule = function( host )
|
||||
|
||||
local is_private, err = ipOps.isPrivate( host.ip )
|
||||
if is_private == nil then
|
||||
stdnse.print_debug( "%s Error in Hostrule: %s.", filename, err )
|
||||
stdnse.print_debug( "%s Error in Hostrule: %s.", SCRIPT_NAME, err )
|
||||
return false
|
||||
end
|
||||
|
||||
@@ -190,7 +190,7 @@ action = function( host )
|
||||
|
||||
status, retval = pcall( get_next_action, tracking, host.ip )
|
||||
if not status then
|
||||
stdnse.print_debug( "%s %s pcall caught an exception in get_next_action: %s.", filename, host.ip, retval )
|
||||
stdnse.print_debug( "%s %s pcall caught an exception in get_next_action: %s.", SCRIPT_NAME, host.ip, retval )
|
||||
else tracking = retval end
|
||||
|
||||
if tracking.this_db then
|
||||
@@ -201,13 +201,13 @@ action = function( host )
|
||||
-- analyse data
|
||||
status, retval = pcall( analyse_response, tracking, host.ip, response, data )
|
||||
if not status then
|
||||
stdnse.print_debug( "%s %s pcall caught an exception in analyse_response: %s.", filename, host.ip, retval )
|
||||
stdnse.print_debug( "%s %s pcall caught an exception in analyse_response: %s.", SCRIPT_NAME, host.ip, retval )
|
||||
else data = retval end
|
||||
|
||||
-- get next action
|
||||
status, retval = pcall( get_next_action, tracking, host.ip )
|
||||
if not status then
|
||||
stdnse.print_debug( "%s %s pcall caught an exception in get_next_action: %s.", filename, host.ip, retval )
|
||||
stdnse.print_debug( "%s %s pcall caught an exception in get_next_action: %s.", SCRIPT_NAME, host.ip, retval )
|
||||
if not tracking.last_db then tracking.last_db, tracking.this_db = tracking.this_db or tracking.next_db, nil end
|
||||
else tracking = retval end
|
||||
end
|
||||
@@ -340,7 +340,7 @@ function check_response_cache( ip )
|
||||
-- record found in cache
|
||||
return true, nil
|
||||
else
|
||||
stdnse.print_debug( 1, "%s %s Error in check_response_cache: Empty Cache Entry was found.", filename, ip )
|
||||
stdnse.print_debug( 1, "%s %s Error in check_response_cache: Empty Cache Entry was found.", SCRIPT_NAME, ip )
|
||||
end
|
||||
|
||||
return false, nil
|
||||
@@ -461,7 +461,7 @@ function get_db_from_assignments( ip )
|
||||
end
|
||||
|
||||
if not nmap.registry.whois.local_assignments_data or not nmap.registry.whois.local_assignments_data[af] then
|
||||
stdnse.print_debug( 1, "%s Error in get_db_from_assignments: Missing assignments data in registry.", filename )
|
||||
stdnse.print_debug( 1, "%s Error in get_db_from_assignments: Missing assignments data in registry.", SCRIPT_NAME )
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -488,14 +488,14 @@ end
|
||||
function do_query(db, ip)
|
||||
|
||||
if type( db ) ~= "string" or not nmap.registry.whois.whoisdb[db] then
|
||||
stdnse.print_debug("%s %s Error in do_query: %s is not a defined Whois service.", filename, ip, db)
|
||||
stdnse.print_debug("%s %s Error in do_query: %s is not a defined Whois service.", SCRIPT_NAME, ip, db)
|
||||
return nil
|
||||
end
|
||||
|
||||
local service = nmap.registry.whois.whoisdb[db]
|
||||
|
||||
if type( service.hostname ) ~= "string" or service.hostname == "" then
|
||||
stdnse.print_debug("%s %s Error in do_query: Invalid hostname for %s.", filename, ip, db)
|
||||
stdnse.print_debug("%s %s Error in do_query: Invalid hostname for %s.", SCRIPT_NAME, ip, db)
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -511,7 +511,7 @@ function do_query(db, ip)
|
||||
|
||||
local socket = nmap.new_socket()
|
||||
local catch = function()
|
||||
stdnse.print_debug( "%s %s Connection to %s failed or was aborted! No Output for this Target.", filename, ip, db )
|
||||
stdnse.print_debug( "%s %s Connection to %s failed or was aborted! No Output for this Target.", SCRIPT_NAME, ip, db )
|
||||
nmap.registry.whois.mutex[db] "done"
|
||||
socket:close()
|
||||
end
|
||||
@@ -534,7 +534,7 @@ function do_query(db, ip)
|
||||
|
||||
socket:close()
|
||||
|
||||
stdnse.print_debug(3, "%s %s Ended Query at %s.", filename, ip, db)
|
||||
stdnse.print_debug(3, "%s %s Ended Query at %s.", SCRIPT_NAME, ip, db)
|
||||
|
||||
if #result == 0 then
|
||||
return nil
|
||||
@@ -587,13 +587,13 @@ function analyse_response( tracking, ip, response, data )
|
||||
if type( meta ) == "table" and type( meta.fieldreq ) == "table" and type( meta.fieldreq.ob_exist ) == "string" then
|
||||
have_objects = response:match( meta.fieldreq.ob_exist )
|
||||
else
|
||||
stdnse.print_debug( 2, "%s %s Could not check for objects, problem with meta data.", filename, ip )
|
||||
stdnse.print_debug( 2, "%s %s Could not check for objects, problem with meta data.", SCRIPT_NAME, ip )
|
||||
have_objects = false
|
||||
end
|
||||
|
||||
-- if we do not recognize objects check for an known error/non-object message
|
||||
if not have_objects then
|
||||
stdnse.print_debug( 4, "%s %s %s has not responded with the expected objects.", filename, ip, this_db )
|
||||
stdnse.print_debug( 4, "%s %s %s has not responded with the expected objects.", SCRIPT_NAME, ip, this_db )
|
||||
local tmp, msg
|
||||
-- may have found our record saying something similar to "No Record Found"
|
||||
for _, pattern in ipairs( nmap.registry.whois.m_none ) do
|
||||
@@ -601,7 +601,7 @@ function analyse_response( tracking, ip, response, data )
|
||||
local pattern_u = pattern:gsub( "$addr", ip:upper() )
|
||||
msg = response:match( pattern_l ) or response:match( pattern_u )
|
||||
if msg then
|
||||
stdnse.print_debug( 4, "%s %s %s responded with a message which is assumed to be authoritative (but may not be).", filename, ip, this_db )
|
||||
stdnse.print_debug( 4, "%s %s %s responded with a message which is assumed to be authoritative (but may not be).", SCRIPT_NAME, ip, this_db )
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -610,7 +610,7 @@ function analyse_response( tracking, ip, response, data )
|
||||
for _, pattern in ipairs( nmap.registry.whois.m_err ) do
|
||||
msg = response:match( pattern )
|
||||
if msg then
|
||||
stdnse.print_debug( 4, "%s %s %s responded with an ERROR message.", filename, ip, this_db )
|
||||
stdnse.print_debug( 4, "%s %s %s responded with an ERROR message.", SCRIPT_NAME, ip, this_db )
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -629,7 +629,7 @@ function analyse_response( tracking, ip, response, data )
|
||||
for setname, set in pairs( nmap.registry.whois.fields_meta ) do
|
||||
if set ~= nmap.registry.whois.whoisdb[this_db].fieldreq and response:match(set.ob_exist) then
|
||||
foreign_obj = setname
|
||||
stdnse.print_debug( 4, "%s %s %s seems to have responded using the set of objects named: %s.", filename, ip, this_db, foreign_obj )
|
||||
stdnse.print_debug( 4, "%s %s %s seems to have responded using the set of objects named: %s.", SCRIPT_NAME, ip, this_db, foreign_obj )
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -638,7 +638,7 @@ function analyse_response( tracking, ip, response, data )
|
||||
meta = nmap.registry.whois.whoisdb.ripe
|
||||
meta.redirects = nil
|
||||
have_objects = true
|
||||
stdnse.print_debug( 4, "%s %s %s will use the display properties of ripe.", filename, ip, this_db )
|
||||
stdnse.print_debug( 4, "%s %s %s will use the display properties of ripe.", SCRIPT_NAME, ip, this_db )
|
||||
elseif foreign_obj then
|
||||
-- find a display to match the objects.
|
||||
for some_db, db_props in pairs( nmap.registry.whois.whoisdb ) do
|
||||
@@ -647,7 +647,7 @@ function analyse_response( tracking, ip, response, data )
|
||||
meta = nmap.registry.whois.whoisdb[some_db]
|
||||
meta.redirects = nil
|
||||
have_objects = true
|
||||
stdnse.print_debug( 4, "%s %s %s will use the display properties of %s.", filename, ip, this_db, some_db )
|
||||
stdnse.print_debug( 4, "%s %s %s will use the display properties of %s.", SCRIPT_NAME, ip, this_db, some_db )
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -656,7 +656,7 @@ function analyse_response( tracking, ip, response, data )
|
||||
|
||||
-- extract fields from the entire response for record/redirect discovery
|
||||
if have_objects then
|
||||
stdnse.print_debug( 4, "%s %s Parsing Query response from %s.", filename, ip, this_db )
|
||||
stdnse.print_debug( 4, "%s %s Parsing Query response from %s.", SCRIPT_NAME, ip, this_db )
|
||||
data[this_db] = extract_objects_from_response( response, this_db, ip, meta )
|
||||
end
|
||||
|
||||
@@ -664,7 +664,7 @@ function analyse_response( tracking, ip, response, data )
|
||||
|
||||
-- do record/redirect discovery, cache found redirect
|
||||
if not nmap.registry.whois.nofollow and have_objects and meta.redirects then
|
||||
stdnse.print_debug( 4, "%s %s Testing response for redirection.", filename, ip )
|
||||
stdnse.print_debug( 4, "%s %s Testing response for redirection.", SCRIPT_NAME, ip )
|
||||
found, nextdb, data.iana = redirection_rules( this_db, ip, data, meta )
|
||||
end
|
||||
|
||||
@@ -672,7 +672,7 @@ function analyse_response( tracking, ip, response, data )
|
||||
-- modify the data table depending on whether we're redirecting or quitting
|
||||
if have_objects then
|
||||
|
||||
stdnse.print_debug( 5, "%s %s Extracting Fields from response.", filename, ip )
|
||||
stdnse.print_debug( 5, "%s %s Extracting Fields from response.", SCRIPT_NAME, ip )
|
||||
|
||||
-- optionally constrain response to a more focused area
|
||||
-- discarding previous extraction
|
||||
@@ -684,7 +684,7 @@ function analyse_response( tracking, ip, response, data )
|
||||
end
|
||||
if offset > 1 and meta.unordered then
|
||||
-- fetch an object immediately in front of inetnum
|
||||
stdnse.print_debug( 5, "%s %s %s Searching for an object group immediately before this range.", filename, ip, this_db )
|
||||
stdnse.print_debug( 5, "%s %s %s Searching for an object group immediately before this range.", SCRIPT_NAME, ip, this_db )
|
||||
-- split objects from the record, up to offset. Last object should be the one we want.
|
||||
local obj_sel = stdnse.strsplit( "\r?\n\r?\n", response:sub( 1, offset ) )
|
||||
response_chunk = "\n" .. obj_sel[#obj_sel] .. "\n"
|
||||
@@ -716,10 +716,10 @@ function analyse_response( tracking, ip, response, data )
|
||||
end
|
||||
|
||||
-- DEBUG
|
||||
stdnse.print_debug( 6, "%s %s %s Fields captured :", filename, ip, this_db )
|
||||
stdnse.print_debug( 6, "%s %s %s Fields captured :", SCRIPT_NAME, ip, this_db )
|
||||
for ob, t in pairs( data[this_db] ) do
|
||||
for fieldname, fieldvalue in pairs( t ) do
|
||||
stdnse.print_debug( 6, "%s %s %s %s.%s %s.", filename, ip, this_db, ob, fieldname, fieldvalue )
|
||||
stdnse.print_debug( 6, "%s %s %s %s.%s %s.", SCRIPT_NAME, ip, this_db, ob, fieldname, fieldvalue )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -807,15 +807,15 @@ function extract_objects_from_response( response_string, db, ip, meta, specific_
|
||||
-- we either receive a table for one object or for all objects
|
||||
if type( specific_object ) == "string" and meta.fieldreq[specific_object] then
|
||||
objects_to_extract[specific_object] = meta.fieldreq[specific_object]
|
||||
stdnse.print_debug( 5, "%s %s Extracting a single object: %s.", filename, ip, specific_object )
|
||||
stdnse.print_debug( 5, "%s %s Extracting a single object: %s.", SCRIPT_NAME, ip, specific_object )
|
||||
else
|
||||
stdnse.print_debug( 5, "%s %s Extracting all objects.", filename, ip )
|
||||
stdnse.print_debug( 5, "%s %s Extracting all objects.", SCRIPT_NAME, ip )
|
||||
objects_to_extract = meta.fieldreq
|
||||
end
|
||||
|
||||
for object_name, object in pairs( objects_to_extract ) do
|
||||
if object_name and object_name ~= "ob_exist" then
|
||||
stdnse.print_debug(5, "%s %s Seeking object group: %s.", filename, ip, object_name)
|
||||
stdnse.print_debug(5, "%s %s Seeking object group: %s.", SCRIPT_NAME, ip, object_name)
|
||||
extracted_objects[object_name] = {}
|
||||
extracted_objects[object_name].for_compare = {} -- this will allow us to compare two tables
|
||||
-- get a substr of response_string that corresponds to a single object
|
||||
@@ -824,7 +824,7 @@ function extract_objects_from_response( response_string, db, ip, meta, specific_
|
||||
-- if we could not find the end, make the end EOF
|
||||
ob_end = ob_end or -1
|
||||
if ob_start and ob_end then
|
||||
stdnse.print_debug(5, "%s %s Capturing: %s with indices %s and %s.", filename, ip, object_name, ob_start, ob_end )
|
||||
stdnse.print_debug(5, "%s %s Capturing: %s with indices %s and %s.", SCRIPT_NAME, ip, object_name, ob_start, ob_end )
|
||||
local obj_string = response_string:sub( ob_start, ob_end )
|
||||
for fieldname, pattern in pairs( object ) do
|
||||
if fieldname ~= "ob_start" and fieldname ~= "ob_end" then
|
||||
@@ -897,19 +897,19 @@ function redirection_rules( db, ip, data, meta )
|
||||
|
||||
-- arin record points to iana so we won't follow and we assume we have our record
|
||||
if directed_to == iana and directed_from == arin then
|
||||
stdnse.print_debug( 4, "%s %s %s Accept arin record (matched IANA).", filename, ip, directed_from )
|
||||
stdnse.print_debug( 4, "%s %s %s Accept arin record (matched IANA).", SCRIPT_NAME, ip, directed_from )
|
||||
return true, nil, ( icnt+1 )
|
||||
end
|
||||
|
||||
-- non-arin record points to iana so we query arin next
|
||||
if directed_to == iana then
|
||||
stdnse.print_debug( 4, "%s %s Redirecting to arin (matched IANA).", filename, ip )
|
||||
stdnse.print_debug( 4, "%s %s Redirecting to arin (matched IANA).", SCRIPT_NAME, ip )
|
||||
return false, arin, ( icnt+1 )
|
||||
end
|
||||
|
||||
-- a redirect, but not to iana or to self, so we follow it.
|
||||
if directed_to ~= nmap.registry.whois.whoisdb[directed_from].id then
|
||||
stdnse.print_debug( 4, "%s %s %s redirects us to %s.", filename, ip, directed_from, directed_to )
|
||||
stdnse.print_debug( 4, "%s %s %s redirects us to %s.", SCRIPT_NAME, ip, directed_from, directed_to )
|
||||
return false, directed_to, icnt
|
||||
end
|
||||
|
||||
@@ -925,14 +925,14 @@ function redirection_rules( db, ip, data, meta )
|
||||
-- if a field has been captured for the given redirect info
|
||||
if data[db][obj] and data[db][obj][fld] then
|
||||
|
||||
stdnse.print_debug( 5, "%s %s Seek redirect in object: %s.%s for %s.", filename, ip, obj, fld, pattern )
|
||||
stdnse.print_debug( 5, "%s %s Seek redirect in object: %s.%s for %s.", SCRIPT_NAME, ip, obj, fld, pattern )
|
||||
-- iterate over nmap.registry.whois.whoisdb to find pattern (from each service) in the designated field
|
||||
for member, mem_properties in pairs( nmap.registry.whois.whoisdb ) do
|
||||
|
||||
-- if pattern if found in the field, we have a redirect to member
|
||||
if type( mem_properties[pattern] ) == "string" and string.lower( data[db][obj][fld] ):match( mem_properties[pattern] ) then
|
||||
|
||||
stdnse.print_debug( 5, "%s %s Matched %s in %s.%s.", filename, ip, pattern, obj, fld )
|
||||
stdnse.print_debug( 5, "%s %s Matched %s in %s.%s.", SCRIPT_NAME, ip, pattern, obj, fld )
|
||||
return redirection_validation( nmap.registry.whois.whoisdb[member].id, db, iana_count )
|
||||
|
||||
elseif type( mem_properties[pattern] ) == "table" then
|
||||
@@ -940,7 +940,7 @@ function redirection_rules( db, ip, data, meta )
|
||||
-- pattern is an array of patterns
|
||||
for _, pattn in ipairs( mem_properties[pattern] ) do
|
||||
if type( pattn ) == "string" and string.lower( data[db][obj][fld] ):match( pattn ) then
|
||||
stdnse.print_debug( 5, "%s %s Matched %s in %s.%s.", filename, ip, pattern, obj, fld )
|
||||
stdnse.print_debug( 5, "%s %s Matched %s in %s.%s.", SCRIPT_NAME, ip, pattern, obj, fld )
|
||||
return redirection_validation( nmap.registry.whois.whoisdb[member].id, db, iana_count )
|
||||
end
|
||||
end
|
||||
@@ -994,7 +994,7 @@ function constrain_response( response, db, ip, meta )
|
||||
|
||||
if # mptr > 1 then
|
||||
-- find the closest one to host.ip and constrain the response to it
|
||||
stdnse.print_debug( 5, "%s %s %s Focusing on the smallest of %s address ranges.", filename, ip, db, #mptr )
|
||||
stdnse.print_debug( 5, "%s %s %s Focusing on the smallest of %s address ranges.", SCRIPT_NAME, ip, db, #mptr )
|
||||
-- sort the table mptr into nets ascending
|
||||
table.sort( mptr, smallest_range )
|
||||
-- select the first net that includes host.ip
|
||||
@@ -1012,15 +1012,15 @@ function constrain_response( response, db, ip, meta )
|
||||
if mptr[index+1] and ( mptr[index+1].pointer > mptr[index].pointer ) then
|
||||
bound = mptr[index+1].pointer
|
||||
end
|
||||
stdnse.print_debug(5, "%s %s %s Smallest range containing target IP addr. is %s.", filename, ip, db, trim( str_net ) )
|
||||
stdnse.print_debug(5, "%s %s %s Smallest range containing target IP addr. is %s.", SCRIPT_NAME, ip, db, trim( str_net ) )
|
||||
local dbg = "%s %s %s smallest range is offset from %s to %s."
|
||||
-- isolate inetnum and associated objects
|
||||
if bound then
|
||||
stdnse.print_debug(5, dbg, filename, ip, db, ptr, bound)
|
||||
stdnse.print_debug(5, dbg, SCRIPT_NAME, ip, db, ptr, bound)
|
||||
-- get from pointer to bound
|
||||
return response:sub(ptr,bound), ptr
|
||||
else
|
||||
stdnse.print_debug(5, dbg, filename, ip, db, ptr, "the end")
|
||||
stdnse.print_debug(5, dbg, SCRIPT_NAME, ip, db, ptr, "the end")
|
||||
-- or get the whole thing from the pointer onwards
|
||||
return response:sub(ptr), ptr
|
||||
end
|
||||
@@ -1062,7 +1062,7 @@ function not_short_prefix( ip, range, redirect )
|
||||
first, last, err[#err+1] = ipOps.get_ips_from_range( range )
|
||||
|
||||
if #err > 0 then
|
||||
stdnse.print_debug( 1, "%s Error in not_short_prefix: s%.", filename, table.concat( err, " " ) )
|
||||
stdnse.print_debug( 1, "%s Error in not_short_prefix: s%.", SCRIPT_NAME, table.concat( err, " " ) )
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -1106,7 +1106,7 @@ function add_to_cache( ip, range, redirect, data )
|
||||
-- we need to cache some range so we'll cache the small assignment that includes ip.
|
||||
if type( range ) ~= "string" or type( get_prefix_length( range ) ) ~= "number" then
|
||||
range = get_assignment( ip, longest_prefix )
|
||||
stdnse.print_debug(5, "%s %s Caching an assumed Range: %s", filename, ip, range)
|
||||
stdnse.print_debug(5, "%s %s Caching an assumed Range: %s", SCRIPT_NAME, ip, range)
|
||||
end
|
||||
|
||||
nmap.registry.whois.cache[ip] = {} -- destroy any previous cache entry for this target.
|
||||
@@ -1196,13 +1196,13 @@ function output( ip, services_queried )
|
||||
end
|
||||
|
||||
if type( services_queried ) ~= "table" then
|
||||
stdnse.print_debug( "%s %s Error in output(): No data found.", filename, ip )
|
||||
stdnse.print_debug( "%s %s Error in output(): No data found.", SCRIPT_NAME, ip )
|
||||
return nil
|
||||
elseif #services_queried == 0 then
|
||||
stdnse.print_debug( "%s %s Error in output(): No data found, no queries were completed.", filename, ip )
|
||||
stdnse.print_debug( "%s %s Error in output(): No data found, no queries were completed.", SCRIPT_NAME, ip )
|
||||
return nil
|
||||
elseif #services_queried > 0 then
|
||||
stdnse.print_debug( "%s %s Error in output(): No data found - could not understand query responses.", filename, ip )
|
||||
stdnse.print_debug( "%s %s Error in output(): No data found - could not understand query responses.", SCRIPT_NAME, ip )
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -1223,7 +1223,7 @@ function get_output_from_cache( ip )
|
||||
|
||||
local ip_key = get_cache_key( ip )
|
||||
if not ip_key then
|
||||
stdnse.print_debug( 1, "%s %s Error in get_output_from_cache().", filename, ip )
|
||||
stdnse.print_debug( 1, "%s %s Error in get_output_from_cache().", SCRIPT_NAME, ip )
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -1672,7 +1672,7 @@ function get_args()
|
||||
nmap.registry.whois.using_cache = false
|
||||
elseif ( db == "nofile" ) then
|
||||
nmap.registry.whois.using_local_assignments_file = false
|
||||
stdnse.print_debug( 2, "%s: Not using local assignments data.", filename )
|
||||
stdnse.print_debug( 2, "%s: Not using local assignments data.", SCRIPT_NAME )
|
||||
end
|
||||
elseif not ( string.match( table.concat( t, " " ), db ) ) then
|
||||
-- we have a unique valid whois db
|
||||
@@ -1683,18 +1683,18 @@ function get_args()
|
||||
if ( #t > 0 ) and nmap.registry.whois.using_local_assignments_file then
|
||||
-- "nofile" was not explicitly supplied, but it is implied by supplying custom whoisdb_default_order
|
||||
nmap.registry.whois.using_local_assignments_file = false
|
||||
stdnse.print_debug(3, "%s: Not using local assignments data because custom whoisdb_default_order was supplied.", filename)
|
||||
stdnse.print_debug(3, "%s: Not using local assignments data because custom whoisdb_default_order was supplied.", SCRIPT_NAME)
|
||||
end
|
||||
|
||||
if ( #t > 1 ) and nmap.registry.whois.nofollow then
|
||||
-- using nofollow, we do not follow redirects and can only accept what we find as a record therefore we only accept the first db supplied
|
||||
t = {t[1]}
|
||||
stdnse.print_debug( 1, "%s: Too many args supplied with 'nofollow', only using %s.", filename, t[1] )
|
||||
stdnse.print_debug( 1, "%s: Too many args supplied with 'nofollow', only using %s.", SCRIPT_NAME, t[1] )
|
||||
end
|
||||
|
||||
if ( #t > 0 ) then
|
||||
nmap.registry.whois.whoisdb_default_order = t
|
||||
stdnse.print_debug( 2, "%s: whoisdb_default_order: %s.", filename, table.concat( t, " " ) )
|
||||
stdnse.print_debug( 2, "%s: whoisdb_default_order: %s.", SCRIPT_NAME, table.concat( t, " " ) )
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1723,7 +1723,7 @@ function get_local_assignments_data()
|
||||
local fetchfile = "nmap-services"
|
||||
local directory_path, err = get_parentpath( fetchfile )
|
||||
if err then
|
||||
stdnse.print_debug( 1, "%s: Nmap.fetchfile() failed to get a path to %s: %s.", filename, fetchfile, err )
|
||||
stdnse.print_debug( 1, "%s: Nmap.fetchfile() failed to get a path to %s: %s.", SCRIPT_NAME, fetchfile, err )
|
||||
return nil, err
|
||||
end
|
||||
|
||||
@@ -1739,10 +1739,10 @@ function get_local_assignments_data()
|
||||
local file, exists = directory_path .. assignment_data_spec.local_resource
|
||||
exists, err = file_exists( file )
|
||||
if not exists and err then
|
||||
stdnse.print_debug( 1, "%s: Error accessing %s: %s.", filename, file, err )
|
||||
stdnse.print_debug( 1, "%s: Error accessing %s: %s.", SCRIPT_NAME, file, err )
|
||||
elseif not exists then
|
||||
update_required = true
|
||||
stdnse.print_debug( 2, "%s: %s does not exist or is empty. Fetching it now...", filename, file )
|
||||
stdnse.print_debug( 2, "%s: %s does not exist or is empty. Fetching it now...", SCRIPT_NAME, file )
|
||||
elseif exists then
|
||||
update_required, modified_date, entity_tag = requires_updating( file )
|
||||
end
|
||||
@@ -1751,7 +1751,7 @@ function get_local_assignments_data()
|
||||
|
||||
-- read an existing and up-to-date file into file_content.
|
||||
if exists and not update_required then
|
||||
stdnse.print_debug( 2, "%s: %s was cached less than %s ago. Reading...", filename, file, nmap.registry.whois.local_assignments_file_expiry )
|
||||
stdnse.print_debug( 2, "%s: %s was cached less than %s ago. Reading...", SCRIPT_NAME, file, nmap.registry.whois.local_assignments_file_expiry )
|
||||
file_content = read_from_file( file )
|
||||
end
|
||||
|
||||
@@ -1760,10 +1760,10 @@ function get_local_assignments_data()
|
||||
if update_required then
|
||||
http_response = ( conditional_download( assignment_data_spec.remote_resource, modified_date, entity_tag ) )
|
||||
if not http_response or type( http_response.status ) ~= "number" then
|
||||
stdnse.print_debug( 1, "%s: Failed whilst requesting %s.", filename, assignment_data_spec.remote_resource )
|
||||
stdnse.print_debug( 1, "%s: Failed whilst requesting %s.", SCRIPT_NAME, assignment_data_spec.remote_resource )
|
||||
elseif http_response.status == 200 then
|
||||
-- prepend our file header
|
||||
stdnse.print_debug( 2, "%s: Retrieved %s.", filename, assignment_data_spec.remote_resource )
|
||||
stdnse.print_debug( 2, "%s: Retrieved %s.", SCRIPT_NAME, assignment_data_spec.remote_resource )
|
||||
file_content = stdnse.strsplit( "\r?\n", http_response.body )
|
||||
table.insert( file_content, 1, "** Do Not Alter This Line or The Following Line **" )
|
||||
local hline = {}
|
||||
@@ -1773,19 +1773,19 @@ function get_local_assignments_data()
|
||||
table.insert( file_content, 2, table.concat( hline ) )
|
||||
write_success, err = write_to_file( file, file_content )
|
||||
if err then
|
||||
stdnse.print_debug( 1, "%s: Error writing %s to %s: %s.", filename, assignment_data_spec.remote_resource, file, err )
|
||||
stdnse.print_debug( 1, "%s: Error writing %s to %s: %s.", SCRIPT_NAME, assignment_data_spec.remote_resource, file, err )
|
||||
end
|
||||
elseif http_response.status == 304 then
|
||||
-- update our file header with a new timestamp
|
||||
stdnse.print_debug( 1, "%s: %s is up-to-date.", filename, file )
|
||||
stdnse.print_debug( 1, "%s: %s is up-to-date.", SCRIPT_NAME, file )
|
||||
file_content = read_from_file( file )
|
||||
file_content[2] = file_content[2]:gsub("^<[\-\+]?%d+>(.*)$", "<" .. os.time() .. ">%1")
|
||||
write_success, err = write_to_file( file, file_content )
|
||||
if err then
|
||||
stdnse.print_debug( 1, "%s: Error writing to %s: %s.", filename, file, err )
|
||||
stdnse.print_debug( 1, "%s: Error writing to %s: %s.", SCRIPT_NAME, file, err )
|
||||
end
|
||||
else
|
||||
stdnse.print_debug( 1, "%s: HTTP %s whilst requesting %s.", filename, http_response.status, assignment_data_spec.remote_resource )
|
||||
stdnse.print_debug( 1, "%s: HTTP %s whilst requesting %s.", SCRIPT_NAME, http_response.status, assignment_data_spec.remote_resource )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1799,7 +1799,7 @@ function get_local_assignments_data()
|
||||
if #t == 0 or err then
|
||||
-- good header, but bad file? Kill the file!
|
||||
write_to_file( file, "" )
|
||||
stdnse.print_debug( 1, "%s: Problem with the data in %s.", filename, file )
|
||||
stdnse.print_debug( 1, "%s: Problem with the data in %s.", SCRIPT_NAME, file )
|
||||
else
|
||||
for i, v in pairs( t ) do
|
||||
ret[address_family][#ret[address_family]+1] = v
|
||||
@@ -1818,7 +1818,7 @@ function get_local_assignments_data()
|
||||
for af, t in pairs( ret ) do
|
||||
if #t == 0 then
|
||||
ret[af] = nil
|
||||
stdnse.print_debug( 1, "%s: Cannot use local assignments file for address family %s.", filename, af )
|
||||
stdnse.print_debug( 1, "%s: Cannot use local assignments file for address family %s.", SCRIPT_NAME, af )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1829,9 +1829,9 @@ end
|
||||
|
||||
|
||||
---
|
||||
-- Uses <code>nmap.fetchfile</code> to get the path of the parent directory of the supplied Nmap datafile filename.
|
||||
-- Uses <code>nmap.fetchfile</code> to get the path of the parent directory of the supplied Nmap datafile SCRIPT_NAME.
|
||||
-- @param fname String - Filename of an Nmap datafile.
|
||||
-- @return String - The filepath of the directory containing the supplied filename including the trailing slash (or nil in case of an error).
|
||||
-- @return String - The filepath of the directory containing the supplied SCRIPT_NAME including the trailing slash (or nil in case of an error).
|
||||
-- @return Nil or error message in case of an error.
|
||||
|
||||
function get_parentpath( fname )
|
||||
@@ -1940,7 +1940,7 @@ function read_from_file( file )
|
||||
|
||||
local f, err, _ = io.open( file, "r" )
|
||||
if not f then
|
||||
stdnse.print_debug( 1, "%s: Error opening %s for reading: %s", filename, file, err )
|
||||
stdnse.print_debug( 1, "%s: Error opening %s for reading: %s", SCRIPT_NAME, file, err )
|
||||
return nil, err
|
||||
end
|
||||
|
||||
@@ -1998,7 +1998,7 @@ function conditional_download( url, mod_date, e_tag )
|
||||
-- follow one redirection
|
||||
if request_response.status ~= 304 and ( tostring( request_response.status ):match( "30%d" ) and
|
||||
type( request_response.header.location ) == "string" and request_response.header.location ~= "" ) then
|
||||
stdnse.print_debug( 2, "%s: HTTP Status:%d New Location: %s.", filename, request_response.status, request_response.header.location )
|
||||
stdnse.print_debug( 2, "%s: HTTP Status:%d New Location: %s.", SCRIPT_NAME, request_response.status, request_response.header.location )
|
||||
request_response = http.get_url( request_response.header.location, request_options )
|
||||
end
|
||||
|
||||
@@ -2027,7 +2027,7 @@ function write_to_file( file, content )
|
||||
|
||||
local f, err, _ = io.open( file, "w" )
|
||||
if not f then
|
||||
stdnse.print_debug( 1, "%s: Error opening %s for writing: %s.", filename, file, err )
|
||||
stdnse.print_debug( 1, "%s: Error opening %s for writing: %s.", SCRIPT_NAME, file, err )
|
||||
return nil, err
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user