diff --git a/nmap.cc b/nmap.cc index 222306d67..65d39cc9c 100644 --- a/nmap.cc +++ b/nmap.cc @@ -659,6 +659,8 @@ int nmap_main(int argc, char *argv[]) { o.chooseScripts(optarg); } else if(strcmp(long_options[option_index].name,"script-args")==0){ o.scriptargs=strdup(optarg); + if(script_check_args()!=0) + fatal("Error parsing --script-args\n"); }else if (optcmp(long_options[option_index].name, "script-trace") == 0) { o.scripttrace = 1; } else if (optcmp(long_options[option_index].name, "script-updatedb") == 0){ diff --git a/nse_init.cc b/nse_init.cc index 4e4f5d29b..f84de2f3a 100644 --- a/nse_init.cc +++ b/nse_init.cc @@ -19,6 +19,7 @@ #include int init_setlualibpath(lua_State* l); +int init_setargs(lua_State *l); int init_parseargs(lua_State* l); int init_loadfile(lua_State* l, char* filename); int init_loaddir(lua_State* l, char* dirname); @@ -60,8 +61,6 @@ int init_lua(lua_State* l) { SCRIPT_ENGINE_TRY(set_nmaplib(l)); lua_setglobal(l, "nmap"); SCRIPT_ENGINE_TRY(init_setlualibpath(l)); - /* add the provided commandline args to the registry */ - SCRIPT_ENGINE_TRY(init_parseargs(l)); return SCRIPT_ENGINE_SUCCESS; } @@ -115,12 +114,14 @@ int init_setlualibpath(lua_State* l){ lua_pop(l,3); return SCRIPT_ENGINE_SUCCESS; } - +/* parses the argument provided to --script-args and leaves the processed + * string on the stack, after this it only has to be prepended with + * "={" and appended by "}", before it can be called by + * luaL_loadbuffer() + */ int init_parseargs(lua_State* l){ //FIXME - free o.script-args after we're finished!!! - const char* tmp; - std::string processed_args = std::string("nmap.registry.args={"); - //try the easy way: + if(o.scriptargs==NULL){ //if no arguments are provided we're done return SCRIPT_ENGINE_SUCCESS; } @@ -131,44 +132,58 @@ int init_parseargs(lua_State* l){ lua_pushstring(l,o.scriptargs); lua_pushstring(l,"=([^{},$]+)"); lua_pushstring(l,"=\"%1\""); - if(lua_pcall(l,3,1,0)!=0){ - error("error parsing --script-args"); - return SCRIPT_ENGINE_ERROR; - } - processed_args.append(lua_tostring(l,-1)); + SCRIPT_ENGINE_TRY(lua_pcall(l,3,1,0)); + + /* copy the result on the bottom of the stack, since this is the part + * we want to return + */ + lua_pushvalue(l,-1); + lua_insert(l,1); lua_pushstring(l,"%b{}"); lua_pushstring(l,""); - if(lua_pcall(l,3,1,0)!=0){ - error("error parsing --script-args"); - return SCRIPT_ENGINE_ERROR; - } - tmp=lua_tostring(l,-1); + SCRIPT_ENGINE_TRY(lua_pcall(l,3,1,0)); lua_getfield(l,-2,"find"); lua_pushvalue(l,-2); lua_pushstring(l,"[{}]"); - if(lua_pcall(l,2,1,0)!=0){ - error("error parsing --script-args"); - return SCRIPT_ENGINE_ERROR; - } + SCRIPT_ENGINE_TRY(lua_pcall(l,2,1,0)); if(!lua_isnil(l,-1)){ error("unbalanced brackets inside script-options!!\n"); return SCRIPT_ENGINE_ERROR; } - processed_args.push_back('}'); - lua_settop(l,0); //clear stack + lua_settop(l,1); //clear stack - tmp = processed_args.c_str(); - luaL_loadbuffer(l,tmp,strlen(tmp),"Script-Arguments"); + //luaL_loadbuffer(l,tmp,strlen(tmp),"Script-Arguments"); + //if(lua_pcall(l,0,0,0)!=0){ +// error("error loading --script-args: %s",lua_tostring(l,-1)); +// return SCRIPT_ENGINE_ERROR; +// } + + return SCRIPT_ENGINE_SUCCESS; +} +/* set the arguments inside the nmap.registry, for use by scripts + */ +int init_setargs(lua_State *l){ + const char *argbuf; + size_t argbuflen; + if(o.scriptargs==NULL){ + return SCRIPT_ENGINE_SUCCESS; + } + /* we'll concatenate the stuff we need to prepend and append to the + * processed using lua's functionality + */ + SCRIPT_ENGINE_TRY(init_parseargs(l)); + lua_pushstring(l,"nmap.registry.args={"); + lua_insert(l,-2); + lua_pushstring(l,"}"); + lua_concat(l,3); + argbuf=lua_tolstring(l,-1,&argbuflen); + luaL_loadbuffer(l,argbuf,argbuflen,"Script-Arguments-prerun"); if(lua_pcall(l,0,0,0)!=0){ error("error loading --script-args: %s",lua_tostring(l,-1)); return SCRIPT_ENGINE_ERROR; } - //lua_getglobal(l,"nmap"); - //l_dumpStack(l); - return SCRIPT_ENGINE_SUCCESS; } - /* if there were no command line arguments specifying * which scripts should be run, a default script set is * chosen diff --git a/nse_init.h b/nse_init.h index 480bf5089..83d1d4f3f 100644 --- a/nse_init.h +++ b/nse_init.h @@ -15,6 +15,12 @@ extern "C" { // opens the standard libraries and the nmap lua library int init_lua(lua_State* l); +//takes the script arguments provided to nmap through --script-args and +//processes and checks them - leaves the processed string on the stack +int init_parseargs(lua_State* l); +//sets the previously parsed args inside nmap.registry +int init_setargs(lua_State* l); + // you give it a description of scripts to run and it // populates the tables 'hosttests' and 'porttests' in l with // activation records for tests diff --git a/nse_main.cc b/nse_main.cc index cd3f69997..f70a009ea 100644 --- a/nse_main.cc +++ b/nse_main.cc @@ -105,6 +105,35 @@ finishup: } } +//int check_scripts(){ +//} +/* check the script-arguments provided to nmap (--script-args) before + * scanning starts - otherwise the whole scan will run through and be + * aborted before script-scanning + */ +int script_check_args(){ + lua_State* l; + const char *argbuf; + size_t argbuflen; + + l= lua_open(); + if(l==NULL){ + fatal("Error opening lua, for checking arguments\n"); + } + /* set all global libraries (we'll need the string-lib) */ + SCRIPT_ENGINE_TRY(init_lua(l)); + SCRIPT_ENGINE_TRY(init_parseargs(l)); + lua_pushstring(l,"t={"); + lua_insert(l,-2); + lua_pushstring(l,"}"); + lua_concat(l,3); + argbuf=lua_tolstring(l,-1,&argbuflen); + luaL_loadbuffer(l,argbuf,argbuflen,"Script-Arguments-prerun"); + SCRIPT_ENGINE_TRY(lua_pcall(l,0,0,0)); + + lua_close(l); + return SCRIPT_ENGINE_SUCCESS; +} /* open a lua instance * open the lua standard libraries * open all the scripts and prepare them for execution @@ -144,6 +173,11 @@ int script_scan(std::vector &targets) { if(status != SCRIPT_ENGINE_SUCCESS) { goto finishup; } + //set the arguments - if provided + status = init_setargs(l); + if(status != SCRIPT_ENGINE_SUCCESS) { + goto finishup; + } status = init_rules(l, o.chosenScripts); if(status != SCRIPT_ENGINE_SUCCESS) { diff --git a/nse_main.h b/nse_main.h index be454547c..00390525a 100644 --- a/nse_main.h +++ b/nse_main.h @@ -18,5 +18,7 @@ class Target; int script_scan(std::vector &targets); int script_updatedb(); +//parses the arguments provided to scripts via nmap's --script-args option +int script_check_args(); #endif