From 45a51eff5cf69de188f8d4b20aa872a350a7d03d Mon Sep 17 00:00:00 2001 From: batrick Date: Wed, 7 Jul 2010 16:31:17 +0000 Subject: [PATCH] Move Script Database Update code from nse_main.cc (Lua code embedded in C strings) to nse_main.lua. --- nmap.cc | 6 ++-- nse_main.cc | 84 ++-------------------------------------------------- nse_main.h | 2 -- nse_main.lua | 48 +++++++++++++++++++++++++----- 4 files changed, 44 insertions(+), 96 deletions(-) diff --git a/nmap.cc b/nmap.cc index d1dd4cc85..18fb09452 100644 --- a/nmap.cc +++ b/nmap.cc @@ -1597,13 +1597,11 @@ int nmap_main(int argc, char *argv[]) { #ifndef NOLUA if (o.scriptupdatedb) { - script_updatedb(); - // disable warnings - o.max_ips_to_scan = o.numhosts_scanned; + o.max_ips_to_scan = o.numhosts_scanned; // disable warnings? } if (o.servicescan) o.scriptversion = 1; - if (o.scriptversion || o.script) + if (o.scriptversion || o.script || o.scriptupdatedb) open_nse(); #endif diff --git a/nse_main.cc b/nse_main.cc index 7175abf83..06a48384a 100644 --- a/nse_main.cc +++ b/nse_main.cc @@ -144,12 +144,6 @@ static int key_was_pressed (lua_State *L) return 1; } -static int updatedb (lua_State *L) -{ - lua_pushboolean(L, script_updatedb()); - return 1; -} - static int scp (lua_State *L) { static const char * const ops[] = {"printStats", "printStatsIfNecessary", @@ -189,7 +183,6 @@ static void open_cnse (lua_State *L) {"dir", nse_readdir}, {"nsock_loop", nsock_loop}, {"key_was_pressed", key_was_pressed}, - {"updatedb", updatedb}, {"scan_progress_meter", scan_progress_meter}, {"timedOut", timedOut}, {"startTimeOutClock", startTimeOutClock}, @@ -210,6 +203,8 @@ static void open_cnse (lua_State *L) lua_setfield(L, -2, "default"); lua_pushboolean(L, o.scriptversion == 1); lua_setfield(L, -2, "scriptversion"); + lua_pushboolean(L, o.scriptupdatedb == 1); + lua_setfield(L, -2, "scriptupdatedb"); lua_pushliteral(L, SCRIPT_ENGINE_LUA_DIR SCRIPT_ENGINE_DATABASE); lua_setfield(L, -2, "script_dbpath"); lua_pushstring(L, o.scriptargs); @@ -278,81 +273,6 @@ static void set_nmap_libraries (lua_State *L) lua_pop(L, 3); /* require, package, package.preload */ } -int script_updatedb (void) -{ - static const char load_db[] = - "local nse = ...\n" - "local _G, assert, ipairs, loadfile, setfenv, setmetatable, rawget, type =" - " _G, assert, ipairs, loadfile, setfenv, setmetatable, rawget, type\n" - "local lower, match, create, resume, open = \n" - " string.lower, string.match, coroutine.create, coroutine.resume," - " io.open\n" - /* set the package.path */ - "local t, path = assert(nse.fetchfile_absolute('nselib/'))\n" - "assert(t == 'directory', 'could not locate nselib directory!')\n" - "package.path = package.path..';'..path..'?.lua'\n" - /* fetch the scripts directory */ - "local t, path = nse.fetchfile_absolute('scripts/')\n" - "assert(t == 'directory', 'could not locate scripts directory')\n" - "local db = assert(open(path..'script.db', 'w'),\n" - " 'could not open database for writing')\n" - /* dump the scripts/categories */ - "local scripts = {}\n" - "for f in nse.dir(path) do\n" - " if match(f, '%.nse$') then\n" - " local file = path ..\"/\".. f\n" - " table.insert(scripts, file)\n" - " end\n" - "end\n" - "table.sort(scripts)\n" - "for i, script in ipairs(scripts) do\n" - " local env = setmetatable({}, {__index = _G})\n" - " local thread = create(setfenv(assert(loadfile(script)), env))\n" - " assert(resume(thread))\n" - " local categories = rawget(env, 'categories')\n" - " assert(type(categories) == 'table', script.." - " ' categories field is not a table')\n" - " local basename = assert(match(script, '[/\\\\]?([^/\\\\]-%.nse)$'))\n" - " table.sort(categories)\n" - " db:write('Entry { filename = \"', basename, '\", categories = {')\n" - " for j, category in ipairs(categories) do\n" - " db:write(' \"', lower(category), '\",')\n" - " end\n" - " db:write(' } }\\n')\n" - "end\n" - "db:close()\n"; - int status = 1; - lua_State *L; - - log_write(LOG_STDOUT, "%s: Updating rule database.\n", SCRIPT_ENGINE); - - L = luaL_newstate(); - if (L == NULL) - fatal("%s: error opening lua for database update\n", SCRIPT_ENGINE); - lua_atpanic(L, panic); /* we let Lua panic if memory error */ - luaL_openlibs(L); - set_nmap_libraries(L); - - lua_settop(L, 0); // safety, is 0 anyway - lua_getglobal(L, "debug"); - lua_getfield(L, -1, "traceback"); - lua_replace(L, -2); - - if (luaL_loadstring(L, load_db) != 0) - fatal("%s: loading load_db failed %s", SCRIPT_ENGINE, lua_tostring(L, -1)); - open_cnse(L); - if (lua_pcall(L, 1, 0, 1) != 0) - { - error("%s: error while updating Script Database:\n%s\n", - SCRIPT_ENGINE, lua_tostring(L, -1)); - status = 0; - } - else - log_write(LOG_STDOUT, "NSE script database updated successfully.\n"); - lua_close(L); - return status; -} - static int init_main (lua_State *L) { char path[MAXPATHLEN]; diff --git a/nse_main.h b/nse_main.h index f2a1c61bf..9cfc38ba0 100644 --- a/nse_main.h +++ b/nse_main.h @@ -42,8 +42,6 @@ void open_nse (void); void script_scan (std::vector &targets); void close_nse (void); -int script_updatedb (void); - #define SCRIPT_ENGINE "NSE" #ifdef WIN32 diff --git a/nse_main.lua b/nse_main.lua index ab14db172..b61e9a367 100644 --- a/nse_main.lua +++ b/nse_main.lua @@ -67,6 +67,8 @@ local yield = coroutine.yield; local traceback = debug.traceback; +local open = io.open; + local max = math.max; local byte = string.byte; @@ -92,6 +94,10 @@ do -- Append the nselib directory to the Lua search path package.path = path.."?.lua;"..package.path; end +local script_database_type, script_database_path = + cnse.fetchfile_absolute(cnse.script_dbpath); +local script_database_update = cnse.scriptupdatedb; + local stdnse = require "stdnse"; (require "strict")() -- strict global checking @@ -340,14 +346,7 @@ end local function get_chosen_scripts (rules) check_rules(rules); - local script_dbpath = cnse.script_dbpath; - local t, path = cnse.fetchfile_absolute(script_dbpath); - if not t then - print_verbose(1, "Creating non-existent script database."); - assert(cnse.updatedb(), "could not update script database!"); - t, path = assert(cnse.fetchfile_absolute(script_dbpath)); - end - local db_closure = assert(loadfile(path), + local db_closure = assert(loadfile(script_database_path), "database appears to be corrupt or out of date;\n".. "\tplease update using: nmap --script-updatedb"); @@ -763,6 +762,39 @@ do -- Load script arguments (--script-args) nmap.registry.args = parse_table("{"..args.."}", 1); end +-- Update Missing Script Database? +if script_database_type ~= "file" then + print_verbose(1, "Script Database missing, will create new one."); + script_database_update = true; -- force update +end + +if script_database_update then + log_write("stdout", "Updating rule database."); + local t, path = cnse.fetchfile_absolute('scripts/'); -- fetch script directory + assert(t == 'directory', 'could not locate scripts directory'); + script_database_path = path.."script.db"; + local db = assert(open(script_database_path, 'w')); + local scripts = {}; + for f in cnse.dir(path) do + if match(f, '%.nse$') then + scripts[#scripts+1] = path.."/"..f; + end + end + sort(scripts); + for i, script in ipairs(scripts) do + script = Script.new(script); + sort(script.categories); + db:write('Entry { filename = "', script.basename, '", '); + db:write('categories = {'); + for j, category in ipairs(script.categories) do + db:write(' "', lower(category), '",'); + end + db:write(' } }\n'); + end + db:close(); + log_write("stdout", "Script Database updated successfully."); +end + -- Load all user chosen scripts local chosen_scripts = get_chosen_scripts(rules); print_verbose(1, "Loaded %d scripts for scanning.", #chosen_scripts);