Move Script Database Update code from nse_main.cc (Lua code embedded in C

strings) to nse_main.lua.
This commit is contained in:
batrick 2010-07-07 16:31:17 +00:00
parent 885bc6e034
commit 45a51eff5c
4 changed files with 44 additions and 96 deletions

View file

@ -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

View file

@ -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];

View file

@ -42,8 +42,6 @@ void open_nse (void);
void script_scan (std::vector<Target *> &targets);
void close_nse (void);
int script_updatedb (void);
#define SCRIPT_ENGINE "NSE"
#ifdef WIN32

View file

@ -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);