From 20cf487b3383b0242ae3dbc8a4518c82099ab416 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 18 Nov 2008 21:11:27 +0000 Subject: [PATCH] Replace the mix of spaces and tabs in the main NSE files with uniform two-space indents, which seems to be the dominant style. --- nse_debug.cc | 92 ++--- nse_fs.cc | 261 +++++++------- nse_init.cc | 22 +- nse_main.cc | 930 ++++++++++++++++++++++++------------------------- nse_main.h | 6 +- nse_nmaplib.cc | 772 ++++++++++++++++++++-------------------- nse_nmaplib.h | 6 +- 7 files changed, 1038 insertions(+), 1051 deletions(-) diff --git a/nse_debug.cc b/nse_debug.cc index 04dc5fb4f7..1874ad0f53 100644 --- a/nse_debug.cc +++ b/nse_debug.cc @@ -2,63 +2,63 @@ #include "output.h" void l_dumpStack(lua_State *L) { - int stack_height = lua_gettop(L); - int i; - - log_write(LOG_PLAIN, "-== Stack Dump Begin ==-\n"); - for(i = -1; i >= 0 - stack_height; i--) { - log_write(LOG_PLAIN, "%d: ", i); - l_dumpValue(L, i); - } + int stack_height = lua_gettop(L); + int i; - log_write(LOG_PLAIN, "-== Stack Dump End ==-\n"); + log_write(LOG_PLAIN, "-== Stack Dump Begin ==-\n"); + for(i = -1; i >= 0 - stack_height; i--) { + log_write(LOG_PLAIN, "%d: ", i); + l_dumpValue(L, i); + } + + log_write(LOG_PLAIN, "-== Stack Dump End ==-\n"); } void l_dumpValue(lua_State *L, int i) { - switch (lua_type(L, i)) - { - case LUA_TTABLE: - l_dumpTable(L, i); - break; - case LUA_TFUNCTION: - l_dumpFunction(L, i); - break; - case LUA_TSTRING: - log_write(LOG_PLAIN, "string '%s'\n", lua_tostring(L, i)); - break; - case LUA_TBOOLEAN: - log_write(LOG_PLAIN, "boolean: %s\n", - lua_toboolean(L, i) ? "true" : "false"); - break; - case LUA_TNUMBER: - log_write(LOG_PLAIN, "number: %g\n", lua_tonumber(L, i)); - break; - default: - log_write(LOG_PLAIN, "%s\n", lua_typename(L, lua_type(L, i))); - } + switch (lua_type(L, i)) + { + case LUA_TTABLE: + l_dumpTable(L, i); + break; + case LUA_TFUNCTION: + l_dumpFunction(L, i); + break; + case LUA_TSTRING: + log_write(LOG_PLAIN, "string '%s'\n", lua_tostring(L, i)); + break; + case LUA_TBOOLEAN: + log_write(LOG_PLAIN, "boolean: %s\n", + lua_toboolean(L, i) ? "true" : "false"); + break; + case LUA_TNUMBER: + log_write(LOG_PLAIN, "number: %g\n", lua_tonumber(L, i)); + break; + default: + log_write(LOG_PLAIN, "%s\n", lua_typename(L, lua_type(L, i))); + } } void l_dumpTable(lua_State *L, int index) { - log_write(LOG_PLAIN, "table\n"); - lua_pushnil(L); + log_write(LOG_PLAIN, "table\n"); + lua_pushnil(L); - if (index<0) --index; - while(lua_next(L, index) != 0) - { - l_dumpValue(L, -2); - l_dumpValue(L, -1); - lua_pop(L, 1); - } + if (index<0) --index; + while(lua_next(L, index) != 0) + { + l_dumpValue(L, -2); + l_dumpValue(L, -1); + lua_pop(L, 1); + } } void l_dumpFunction(lua_State *L, int index) { -// lua_Debug ar; + // lua_Debug ar; - log_write(LOG_PLAIN, "function\n"); + log_write(LOG_PLAIN, "function\n"); -// lua_pushvalue(L, index); -// lua_getinfo(L, ">n", &ar); -// -// log_write(LOG_PLAIN, "\tname: %s %s\n", ar.namewhat, ar.name); - fflush(stdout); + // lua_pushvalue(L, index); + // lua_getinfo(L, ">n", &ar); + // + // log_write(LOG_PLAIN, "\tname: %s %s\n", ar.namewhat, ar.name); + fflush(stdout); } diff --git a/nse_fs.cc b/nse_fs.cc index 2339563821..75a2d824bf 100644 --- a/nse_fs.cc +++ b/nse_fs.cc @@ -1,5 +1,5 @@ #ifndef WIN32 - #include "dirent.h" +#include "dirent.h" #endif #include "errno.h" @@ -12,13 +12,13 @@ extern NmapOps o; static bool filename_is_absolute(const char *file) { - if (file[0] == '/') - return true; + if (file[0] == '/') + return true; #ifdef WIN32 - if ((file[0] != '\0' && file[1] == ':') || file[0] == '\\') - return true; + if ((file[0] != '\0' && file[1] == ':') || file[0] == '\\') + return true; #endif - return false; + return false; } /* This is simply the most portable way to check @@ -37,154 +37,149 @@ int nse_check_extension (const char* ext, const char* path) } int nse_fetchfile(char *path, size_t path_len, const char *file) { - int type = nmap_fetchfile(path, path_len, file); + int type = nmap_fetchfile(path, path_len, file); - // lets look in /scripts too - if(type == 0) { - std::string alt_path = std::string(SCRIPT_ENGINE_LUA_DIR) + std::string(file); - type = nmap_fetchfile(path, path_len, alt_path.c_str()); - } + // lets look in /scripts too + if(type == 0) { + std::string alt_path = std::string(SCRIPT_ENGINE_LUA_DIR) + std::string(file); + type = nmap_fetchfile(path, path_len, alt_path.c_str()); + } - return type; + return type; } /* This is a modification of nse_fetchfile that first looks for an * absolute file name. */ int nse_fetchfile_absolute(char *path, size_t path_len, const char *file) { - if (filename_is_absolute(file)) { - if (o.debugging > 1) - log_write(LOG_STDOUT, "%s: Trying absolute path %s\n", SCRIPT_ENGINE, file); - Strncpy(path, file, path_len); - return nmap_fileexistsandisreadable(file); - } - - return nse_fetchfile(path, path_len, file); + if (filename_is_absolute(file)) { + if (o.debugging > 1) + log_write(LOG_STDOUT, "%s: Trying absolute path %s\n", SCRIPT_ENGINE, file); + Strncpy(path, file, path_len); + return nmap_fileexistsandisreadable(file); + } + + return nse_fetchfile(path, path_len, file); } #ifdef WIN32 int nse_scandir (lua_State *L) { - HANDLE dir; - WIN32_FIND_DATA entry; - std::string path; - BOOL morefiles = FALSE; - const char *dirname = luaL_checkstring(L, 1); - int files_or_dirs = luaL_checkint(L, 2); - - lua_createtable(L, 100, 0); // 100 files average - - dir = FindFirstFile((std::string(dirname) + "\\*").c_str(), &entry); - - if (dir == INVALID_HANDLE_VALUE) - { - error("%s: No files in '%s\\*'", SCRIPT_ENGINE, dirname); - return SCRIPT_ENGINE_ERROR; - } - - while(!(morefiles == FALSE && GetLastError() == ERROR_NO_MORE_FILES)) { - // if we are looking for files and this file doesn't end with .nse or - // is a directory, then we don't look further at it - if(files_or_dirs == FILES) { - if(!( - (nse_check_extension(SCRIPT_ENGINE_EXTENSION, entry.cFileName)) - && !(entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - )) { - morefiles = FindNextFile(dir, &entry); - continue; - } - - // if we are looking for dirs and this dir - // isn't a directory, then we don't look further at it - } else if(files_or_dirs == DIRS) { - if(!( - (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - )) { - morefiles = FindNextFile(dir, &entry); - continue; - } - - // they have passed an invalid value for files_or_dirs - } else { - fatal("%s: In: %s:%i This should never happen.", - SCRIPT_ENGINE, __FILE__, __LINE__); - } - - // otherwise we add it to the results - // we assume that dirname ends with a directory separator of some kind - path = std::string(dirname) + "\\" + std::string(entry.cFileName); - lua_pushstring(L, path.c_str()); - lua_rawseti(L, -2, lua_objlen(L, -2) + 1); - morefiles = FindNextFile(dir, &entry); - } - - - return 1; + HANDLE dir; + WIN32_FIND_DATA entry; + std::string path; + BOOL morefiles = FALSE; + const char *dirname = luaL_checkstring(L, 1); + int files_or_dirs = luaL_checkint(L, 2); + + lua_createtable(L, 100, 0); // 100 files average + + dir = FindFirstFile((std::string(dirname) + "\\*").c_str(), &entry); + + if (dir == INVALID_HANDLE_VALUE) + { + error("%s: No files in '%s\\*'", SCRIPT_ENGINE, dirname); + return SCRIPT_ENGINE_ERROR; + } + + while(!(morefiles == FALSE && GetLastError() == ERROR_NO_MORE_FILES)) { + // if we are looking for files and this file doesn't end with .nse or + // is a directory, then we don't look further at it + if(files_or_dirs == FILES) { + if(!((nse_check_extension(SCRIPT_ENGINE_EXTENSION, entry.cFileName)) + && !(entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + )) { + morefiles = FindNextFile(dir, &entry); + continue; + } + + // if we are looking for dirs and this dir + // isn't a directory, then we don't look further at it + } else if(files_or_dirs == DIRS) { + if(!(entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + morefiles = FindNextFile(dir, &entry); + continue; + } + + // they have passed an invalid value for files_or_dirs + } else { + fatal("%s: In: %s:%i This should never happen.", + SCRIPT_ENGINE, __FILE__, __LINE__); + } + + // otherwise we add it to the results + // we assume that dirname ends with a directory separator of some kind + path = std::string(dirname) + "\\" + std::string(entry.cFileName); + lua_pushstring(L, path.c_str()); + lua_rawseti(L, -2, lua_objlen(L, -2) + 1); + morefiles = FindNextFile(dir, &entry); + } + + + return 1; } #else int nse_scandir (lua_State *L) { - DIR* dir; - struct dirent* entry; - struct stat stat_entry; - const char *dirname = luaL_checkstring(L, 1); - int files_or_dirs = luaL_checkint(L, 2); + DIR* dir; + struct dirent* entry; + struct stat stat_entry; + const char *dirname = luaL_checkstring(L, 1); + int files_or_dirs = luaL_checkint(L, 2); lua_createtable(L, 100, 0); // 100 files average - dir = opendir(dirname); - if(dir == NULL) { - error("%s: Could not open directory '%s'.", SCRIPT_ENGINE, dirname); - return SCRIPT_ENGINE_ERROR; - } - - // note that if there is a symlink in the dir, we have to rely on - // the .nse extension - // if they provide a symlink to a dir which ends with .nse, things - // break :/ - while((entry = readdir(dir)) != NULL) { - std::string path = std::string(dirname) + "/" + std::string(entry->d_name); - - if(stat(path.c_str(), &stat_entry) != 0) - fatal("%s: In: %s:%i This should never happen.", - SCRIPT_ENGINE, __FILE__, __LINE__); - - // if we are looking for files and this file doesn't end with .nse and - // isn't a file or a link, then we don't look further at it - if(files_or_dirs == FILES) { - if(!( - (nse_check_extension(SCRIPT_ENGINE_EXTENSION, entry->d_name)) - && (S_ISREG(stat_entry.st_mode) - || S_ISLNK(stat_entry.st_mode)) - )) { - continue; - } - - // if we are looking for dirs and this dir - // isn't a dir or a link, then we don't look further at it - } else if(files_or_dirs == DIRS) { - if(!( - (S_ISDIR(stat_entry.st_mode) - || S_ISLNK(stat_entry.st_mode)) - )) { - continue; - } - - // they have passed an invalid value for files_or_dirs - } else { - fatal("%s: In: %s:%i This should never happen.", - SCRIPT_ENGINE, __FILE__, __LINE__); - } - - // otherwise we add it to the results - lua_pushstring(L, path.c_str()); - lua_rawseti(L, -2, lua_objlen(L, -2) + 1); - } - - closedir(dir); - - return 1; + dir = opendir(dirname); + if(dir == NULL) { + error("%s: Could not open directory '%s'.", SCRIPT_ENGINE, dirname); + return SCRIPT_ENGINE_ERROR; + } + + // note that if there is a symlink in the dir, we have to rely on + // the .nse extension + // if they provide a symlink to a dir which ends with .nse, things + // break :/ + while((entry = readdir(dir)) != NULL) { + std::string path = std::string(dirname) + "/" + std::string(entry->d_name); + + if(stat(path.c_str(), &stat_entry) != 0) + fatal("%s: In: %s:%i This should never happen.", + SCRIPT_ENGINE, __FILE__, __LINE__); + + // if we are looking for files and this file doesn't end with .nse and + // isn't a file or a link, then we don't look further at it + if(files_or_dirs == FILES) { + if(!(nse_check_extension(SCRIPT_ENGINE_EXTENSION, entry->d_name) + && (S_ISREG(stat_entry.st_mode) + || S_ISLNK(stat_entry.st_mode)) + )) { + continue; + } + + // if we are looking for dirs and this dir + // isn't a dir or a link, then we don't look further at it + } else if(files_or_dirs == DIRS) { + if(!(S_ISDIR(stat_entry.st_mode) + || S_ISLNK(stat_entry.st_mode) + )) { + continue; + } + + // they have passed an invalid value for files_or_dirs + } else { + fatal("%s: In: %s:%i This should never happen.", + SCRIPT_ENGINE, __FILE__, __LINE__); + } + + // otherwise we add it to the results + lua_pushstring(L, path.c_str()); + lua_rawseti(L, -2, lua_objlen(L, -2) + 1); + } + + closedir(dir); + + return 1; } #endif diff --git a/nse_init.cc b/nse_init.cc index e55247efcd..06778d24aa 100644 --- a/nse_init.cc +++ b/nse_init.cc @@ -85,7 +85,7 @@ static int loadfile (lua_State *L) lua_pop(L, 2); lua_createtable(L, 0, 11); // Environment for script (index 2) - + lua_pushvalue(L, 1); // tell the script about its filename lua_setfield(L, -2, FILENAME); @@ -93,7 +93,7 @@ static int loadfile (lua_State *L) lua_setfield(L, -2, RUNLEVEL); lua_createtable(L, 0, 1); // script gets access to global env - lua_pushvalue(L, LUA_GLOBALSINDEX); // We may want to use G(L)->mainthread + lua_pushvalue(L, LUA_GLOBALSINDEX); // We may want to use G(L)->mainthread // later if this function becomes // exposed. See lstate.h lua_setfield(L, -2, "__index"); @@ -193,7 +193,7 @@ static int loaddir (lua_State *L) { int i; luaL_checkstring(L, 1); // directory to load - + lua_pushcclosure(L, nse_scandir, 0); lua_pushvalue(L, 1); lua_pushinteger(L, FILES); @@ -217,7 +217,7 @@ static int loaddir (lua_State *L) static int init_setpath (lua_State *L) { char path[MAX_FILENAME_LEN]; - + /* set the path lua searches for modules*/ if (nmap_fetchfile(path, MAX_FILENAME_LEN, SCRIPT_ENGINE_LIB_DIR) != 2) luaL_error(L, "'%s' not a directory", SCRIPT_ENGINE_LIB_DIR); @@ -285,7 +285,7 @@ int init_lua (lua_State *L) lua_pushcclosure(L, init_setpath, 0); lua_call(L, 0, 0); - + lua_newtable(L); current_hosts = luaL_ref(L, LUA_REGISTRYINDEX); @@ -398,7 +398,7 @@ int init_updatedb (lua_State *L) luaL_error(L, "Could not open file '%s' for writing.", path); SCRIPT_ENGINE_DEBUGGING( - log_write(LOG_STDOUT, "%s: Trying to add %u scripts to the database.\n", + log_write(LOG_STDOUT, "%s: Trying to add %u scripts to the database.\n", SCRIPT_ENGINE, lua_objlen(L, 1)); ) @@ -425,7 +425,7 @@ int init_updatedb (lua_State *L) lua_setfenv(L, -2); // set it if ( lua_pcall(L, 0, 0, 0) != 0 ) { // skip scripts that produce errors - log_write(LOG_STDOUT, "%s: Skipping script '%s' because it produced errors while loading.\n", + log_write(LOG_STDOUT, "%s: Skipping script '%s' because it produced errors while loading.\n", SCRIPT_ENGINE, file ); SCRIPT_ENGINE_VERBOSE( error("%s", lua_tostring(L, -1)); @@ -619,7 +619,7 @@ static int loadcategories (lua_State *L) { int i, top = lua_gettop(L); char c_dbpath[MAX_FILENAME_LEN]; - static const char *dbpath = SCRIPT_ENGINE_LUA_DIR SCRIPT_ENGINE_DATABASE; + static const char *dbpath = SCRIPT_ENGINE_LUA_DIR SCRIPT_ENGINE_DATABASE; /* Build the script database if it doesn't exist. */ if (nmap_fetchfile(c_dbpath, sizeof(c_dbpath), dbpath) == 0) @@ -744,7 +744,7 @@ int init_rules (lua_State *L) lua_replace(L, -2); // remove value type = nse_fetchfile_absolute(path, sizeof(path), lua_tostring(L, -1)); } - + switch (type) { case 0: // no such path @@ -766,13 +766,13 @@ int init_rules (lua_State *L) lua_call(L, 1, 0); break; default: - fatal("%s: In: %s:%i This should never happen.", + fatal("%s: In: %s:%i This should never happen.", SCRIPT_ENGINE, __FILE__, __LINE__); } lua_pop(L, 1); } - // Compute some stats + // Compute some stats SCRIPT_ENGINE_DEBUGGING( size_t rules_count; lua_getfield(L, LUA_REGISTRYINDEX, HOSTTESTS); diff --git a/nse_main.cc b/nse_main.cc index 2cdf3486fb..a56e951f42 100644 --- a/nse_main.cc +++ b/nse_main.cc @@ -19,17 +19,17 @@ extern NmapOps o; struct run_record { - short type; // 0 - hostrule; 1 - portrule - Port* port; - Target* host; + short type; // 0 - hostrule; 1 - portrule + Port* port; + Target* host; }; struct thread_record { - lua_State* thread; - int resume_arguments; - unsigned int registry_idx; // index in the main state registry - double runlevel; - struct run_record rr; + lua_State* thread; + int resume_arguments; + unsigned int registry_idx; // index in the main state registry + double runlevel; + struct run_record rr; }; int current_hosts = 0; @@ -40,9 +40,9 @@ std::list waiting_scripts; class CompareRunlevels { public: - bool operator() (const struct thread_record& lhs, const struct thread_record& rhs) { - return lhs.runlevel < rhs.runlevel; - } + bool operator() (const struct thread_record& lhs, const struct thread_record& rhs) { + return lhs.runlevel < rhs.runlevel; + } }; // prior execution @@ -53,10 +53,10 @@ int process_preparethread(lua_State* L, struct thread_record* tr); // helper functions int process_getScriptId(lua_State* L, ScriptResult * ssr); int process_pickScriptsForPort( - lua_State* L, - Target* target, - Port* port, - std::list& torun_threads); + lua_State* L, + Target* target, + Port* port, + std::list& torun_threads); // execution int process_mainloop(lua_State* L); @@ -137,7 +137,7 @@ int script_updatedb (void) lua_State *L; SCRIPT_ENGINE_VERBOSE( - log_write(LOG_STDOUT, "%s: Updating rule database.\n", + log_write(LOG_STDOUT, "%s: Updating rule database.\n", SCRIPT_ENGINE); ) @@ -148,16 +148,16 @@ int script_updatedb (void) return 0; } lua_atpanic(L, panic); - + status = lua_cpcall(L, init_lua, NULL); if (status != 0) { error("%s: error while initializing Lua State:\n%s\n", - SCRIPT_ENGINE, lua_tostring(L, -1)); + SCRIPT_ENGINE, lua_tostring(L, -1)); ret = SCRIPT_ENGINE_ERROR; goto finishup; } - + lua_settop(L, 0); // safety, is 0 anyway lua_rawgeti(L, LUA_REGISTRYINDEX, errfunc); // index 1 @@ -170,9 +170,9 @@ int script_updatedb (void) ret = SCRIPT_ENGINE_ERROR; goto finishup; } - + log_write(LOG_STDOUT, "NSE script database updated successfully.\n"); - + finishup: lua_close(L); if (ret != SCRIPT_ENGINE_SUCCESS) @@ -186,7 +186,7 @@ int script_updatedb (void) /* 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 + * aborted before script-scanning */ int script_check_args (void) { @@ -215,263 +215,263 @@ int script_check_args (void) ret = SCRIPT_ENGINE_ERROR; finishup: - lua_close(L); - return ret; + lua_close(L); + return ret; } /* open a lua instance * open the lua standard libraries * open all the scripts and prepare them for execution - * (export nmap bindings, add them to host/port rulesets etc.) + * (export nmap bindings, add them to host/port rulesets etc.) * apply all scripts on all hosts * */ int script_scan(std::vector &targets) { - int status; - std::vector::iterator target_iter; - std::list >::iterator runlevel_iter; - std::list::iterator thr_iter; - std::list torun_threads; - std::vector::iterator script_iter; - lua_State* L; - - o.current_scantype = SCRIPT_SCAN; - - SCRIPT_ENGINE_VERBOSE( - log_write(LOG_STDOUT, "%s: Initiating script scanning.\n", SCRIPT_ENGINE); - ) - - SCRIPT_ENGINE_DEBUGGING( - unsigned int tlen = targets.size(); - char targetstr[128]; - if(tlen > 1) - log_write(LOG_STDOUT, "%s: Script scanning %d hosts.\n", - SCRIPT_ENGINE, tlen); - else - log_write(LOG_STDOUT, "%s: Script scanning %s.\n", - SCRIPT_ENGINE, (*targets.begin())->NameIP(targetstr, sizeof(targetstr))); - ) - - L = luaL_newstate(); - if (L == NULL) { - error("%s: Failed luaL_newstate()", SCRIPT_ENGINE); + int status; + std::vector::iterator target_iter; + std::list >::iterator runlevel_iter; + std::list::iterator thr_iter; + std::list torun_threads; + std::vector::iterator script_iter; + lua_State* L; + + o.current_scantype = SCRIPT_SCAN; + + SCRIPT_ENGINE_VERBOSE( + log_write(LOG_STDOUT, "%s: Initiating script scanning.\n", SCRIPT_ENGINE); + ) + + SCRIPT_ENGINE_DEBUGGING( + unsigned int tlen = targets.size(); + char targetstr[128]; + if(tlen > 1) + log_write(LOG_STDOUT, "%s: Script scanning %d hosts.\n", + SCRIPT_ENGINE, tlen); + else + log_write(LOG_STDOUT, "%s: Script scanning %s.\n", + SCRIPT_ENGINE, (*targets.begin())->NameIP(targetstr, sizeof(targetstr))); + ) + + L = luaL_newstate(); + if (L == NULL) { + error("%s: Failed luaL_newstate()", SCRIPT_ENGINE); return SCRIPT_ENGINE_ERROR; - } - lua_atpanic(L, panic); + } + lua_atpanic(L, panic); - status = lua_cpcall(L, init_lua, NULL); - if (status != 0) - { - error("%s: error while initializing Lua State:\n%s\n", + status = lua_cpcall(L, init_lua, NULL); + if (status != 0) + { + error("%s: error while initializing Lua State:\n%s\n", SCRIPT_ENGINE, lua_tostring(L, -1)); - status = SCRIPT_ENGINE_ERROR; - goto finishup; - } + status = SCRIPT_ENGINE_ERROR; + goto finishup; + } - //set the arguments - if provided - status = lua_cpcall(L, init_setargs, NULL); + //set the arguments - if provided + status = lua_cpcall(L, init_setargs, NULL); + if (status != 0) + { + error("%s: error while setting arguments for scripts:\n%s\n", + SCRIPT_ENGINE, lua_tostring(L, -1)); + status = SCRIPT_ENGINE_ERROR; + goto finishup; + } + + lua_settop(L, 0); // safety, is 0 anyway + lua_rawgeti(L, LUA_REGISTRYINDEX, errfunc); // index 1 + + if (!lua_checkstack(L, o.chosenScripts.size() + 1)) + { + error("%s: stack overflow at %s:%d", SCRIPT_ENGINE, __FILE__, __LINE__); + status = SCRIPT_ENGINE_ERROR; + goto finishup; + } + lua_pushcclosure(L, init_rules, 0); + for (script_iter = o.chosenScripts.begin(); + script_iter != o.chosenScripts.end(); + script_iter++) + lua_pushstring(L, script_iter->c_str()); + status = lua_pcall(L, o.chosenScripts.size(), 0, 1); if (status != 0) { - error("%s: error while setting arguments for scripts:\n%s\n", + error("%s: error while initializing script rules:\n%s\n", SCRIPT_ENGINE, lua_tostring(L, -1)); status = SCRIPT_ENGINE_ERROR; goto finishup; } - lua_settop(L, 0); // safety, is 0 anyway - lua_rawgeti(L, LUA_REGISTRYINDEX, errfunc); // index 1 + SCRIPT_ENGINE_DEBUGGING(log_write(LOG_STDOUT, "%s: Matching rules.\n", SCRIPT_ENGINE);) - if (!lua_checkstack(L, o.chosenScripts.size() + 1)) - { - error("%s: stack overflow at %s:%d", SCRIPT_ENGINE, __FILE__, __LINE__); - status = SCRIPT_ENGINE_ERROR; + for(target_iter = targets.begin(); target_iter != targets.end(); target_iter++) { + std::string key = ((Target*) (*target_iter))->targetipstr(); + lua_rawgeti(L, LUA_REGISTRYINDEX, current_hosts); + lua_pushstring(L, key.c_str()); + lua_pushlightuserdata(L, (void *) *target_iter); + lua_settable(L, -3); + lua_pop(L, 1); + + status = process_preparehost(L, *target_iter, torun_threads); + if(status != SCRIPT_ENGINE_SUCCESS){ goto finishup; } - lua_pushcclosure(L, init_rules, 0); - for (script_iter = o.chosenScripts.begin(); - script_iter != o.chosenScripts.end(); - script_iter++) - lua_pushstring(L, script_iter->c_str()); - status = lua_pcall(L, o.chosenScripts.size(), 0, 1); - if (status != 0) - { - error("%s: error while initializing script rules:\n%s\n", - SCRIPT_ENGINE, lua_tostring(L, -1)); - status = SCRIPT_ENGINE_ERROR; + } + + status = process_preparerunlevels(torun_threads); + if(status != SCRIPT_ENGINE_SUCCESS) { + goto finishup; + } + + SCRIPT_ENGINE_DEBUGGING(log_write(LOG_STDOUT, "%s: Running scripts.\n", SCRIPT_ENGINE);) + + for(runlevel_iter = torun_scripts.begin(); runlevel_iter != torun_scripts.end(); runlevel_iter++) { + running_scripts = (*runlevel_iter); + + SCRIPT_ENGINE_DEBUGGING(log_write(LOG_STDOUT, "%s: Runlevel: %f\n", + SCRIPT_ENGINE, + running_scripts.front().runlevel);) + + /* Start the time-out clocks for targets with scripts in this + * runlevel. The clock is stopped in process_finalize(). + */ + for (thr_iter = running_scripts.begin(); + thr_iter != running_scripts.end(); + thr_iter++) + if (!thr_iter->rr.host->timeOutClockRunning()) + thr_iter->rr.host->startTimeOutClock(NULL); + + status = process_mainloop(L); + if(status != SCRIPT_ENGINE_SUCCESS){ goto finishup; } + } - SCRIPT_ENGINE_DEBUGGING(log_write(LOG_STDOUT, "%s: Matching rules.\n", SCRIPT_ENGINE);) - - for(target_iter = targets.begin(); target_iter != targets.end(); target_iter++) { - std::string key = ((Target*) (*target_iter))->targetipstr(); - lua_rawgeti(L, LUA_REGISTRYINDEX, current_hosts); - lua_pushstring(L, key.c_str()); - lua_pushlightuserdata(L, (void *) *target_iter); - lua_settable(L, -3); - lua_pop(L, 1); - - status = process_preparehost(L, *target_iter, torun_threads); - if(status != SCRIPT_ENGINE_SUCCESS){ - goto finishup; - } - } - - status = process_preparerunlevels(torun_threads); - if(status != SCRIPT_ENGINE_SUCCESS) { - goto finishup; - } - - SCRIPT_ENGINE_DEBUGGING(log_write(LOG_STDOUT, "%s: Running scripts.\n", SCRIPT_ENGINE);) - - for(runlevel_iter = torun_scripts.begin(); runlevel_iter != torun_scripts.end(); runlevel_iter++) { - running_scripts = (*runlevel_iter); - - SCRIPT_ENGINE_DEBUGGING(log_write(LOG_STDOUT, "%s: Runlevel: %f\n", - SCRIPT_ENGINE, - running_scripts.front().runlevel);) - - /* Start the time-out clocks for targets with scripts in this - * runlevel. The clock is stopped in process_finalize(). - */ - for (thr_iter = running_scripts.begin(); - thr_iter != running_scripts.end(); - thr_iter++) - if (!thr_iter->rr.host->timeOutClockRunning()) - thr_iter->rr.host->startTimeOutClock(NULL); - - status = process_mainloop(L); - if(status != SCRIPT_ENGINE_SUCCESS){ - goto finishup; - } - } - finishup: - SCRIPT_ENGINE_DEBUGGING( - log_write(LOG_STDOUT, "%s: Script scanning completed.\n", SCRIPT_ENGINE); - ) - lua_close(L); - torun_scripts.clear(); - if(status != SCRIPT_ENGINE_SUCCESS) { - error("%s: Aborting script scan.", SCRIPT_ENGINE); - return SCRIPT_ENGINE_ERROR; - } else { - return SCRIPT_ENGINE_SUCCESS; - } + SCRIPT_ENGINE_DEBUGGING( + log_write(LOG_STDOUT, "%s: Script scanning completed.\n", SCRIPT_ENGINE); + ) + lua_close(L); + torun_scripts.clear(); + if(status != SCRIPT_ENGINE_SUCCESS) { + error("%s: Aborting script scan.", SCRIPT_ENGINE); + return SCRIPT_ENGINE_ERROR; + } else { + return SCRIPT_ENGINE_SUCCESS; + } } int process_mainloop(lua_State *L) { - int state; - int unfinished = running_scripts.size() + waiting_scripts.size(); - struct thread_record current; - ScanProgressMeter progress = ScanProgressMeter(SCRIPT_ENGINE); - - double total = (double) unfinished; - double done = 0; - - std::list::iterator iter; - struct timeval now; - - // while there are scripts in running or waiting state, we loop. - // we rely on nsock_loop to protect us from busy loops when - // all scripts are waiting. - while( unfinished > 0 ) { - - if(l_nsock_loop(50) == NSOCK_LOOP_ERROR) { - error("%s: An error occured in the nsock loop", SCRIPT_ENGINE); - return SCRIPT_ENGINE_ERROR; - } - - unfinished = running_scripts.size() + waiting_scripts.size(); - - if (keyWasPressed()) { - done = 1.0 - (((double) unfinished) / total); - if (o.verbose > 1 || o.debugging) { - log_write(LOG_STDOUT, "Active NSE scripts: %d\n", unfinished); - log_flush(LOG_STDOUT); - } - progress.printStats(done, NULL); - } - - SCRIPT_ENGINE_VERBOSE( - if(progress.mayBePrinted(NULL)) { - done = 1.0 - (((double) unfinished) / total); - if(o.verbose > 1 || o.debugging) - progress.printStats(done, NULL); - else - progress.printStatsIfNeccessary(done, NULL); - }) - - gettimeofday(&now, NULL); - - for(iter = waiting_scripts.begin(); iter != waiting_scripts.end(); iter++) - if (iter->rr.host->timedOut(&now)) { - running_scripts.push_front((*iter)); - waiting_scripts.erase(iter); - iter = waiting_scripts.begin(); - } - - // Run the garbage collecter. FIXME: This can error in a __gc metamethod - lua_gc(L, LUA_GCSTEP, 5); - - while (!running_scripts.empty()) { - current = *(running_scripts.begin()); - - if (current.rr.host->timedOut(&now)) - state = LUA_ERRRUN; - else - state = lua_resume(current.thread, current.resume_arguments); - - if(state == LUA_YIELD) { - // this script has performed a network io operation - // we put it in the waiting - // when the network io operation has completed, - // a callback from the nsock library will put the - // script back into the running state - - waiting_scripts.push_back(current); - running_scripts.pop_front(); - } else if( state == 0) { - // this script has finished - // we first check if it produced output - // then we release the thread and remove it from the - // running_scripts list - - if(lua_isstring (current.thread, 2)) { // FIXME + int state; + int unfinished = running_scripts.size() + waiting_scripts.size(); + struct thread_record current; + ScanProgressMeter progress = ScanProgressMeter(SCRIPT_ENGINE); + + double total = (double) unfinished; + double done = 0; + + std::list::iterator iter; + struct timeval now; + + // while there are scripts in running or waiting state, we loop. + // we rely on nsock_loop to protect us from busy loops when + // all scripts are waiting. + while( unfinished > 0 ) { + + if(l_nsock_loop(50) == NSOCK_LOOP_ERROR) { + error("%s: An error occured in the nsock loop", SCRIPT_ENGINE); + return SCRIPT_ENGINE_ERROR; + } + + unfinished = running_scripts.size() + waiting_scripts.size(); + + if (keyWasPressed()) { + done = 1.0 - (((double) unfinished) / total); + if (o.verbose > 1 || o.debugging) { + log_write(LOG_STDOUT, "Active NSE scripts: %d\n", unfinished); + log_flush(LOG_STDOUT); + } + progress.printStats(done, NULL); + } + + SCRIPT_ENGINE_VERBOSE( + if(progress.mayBePrinted(NULL)) { + done = 1.0 - (((double) unfinished) / total); + if(o.verbose > 1 || o.debugging) + progress.printStats(done, NULL); + else + progress.printStatsIfNeccessary(done, NULL); + }) + + gettimeofday(&now, NULL); + + for(iter = waiting_scripts.begin(); iter != waiting_scripts.end(); iter++) + if (iter->rr.host->timedOut(&now)) { + running_scripts.push_front((*iter)); + waiting_scripts.erase(iter); + iter = waiting_scripts.begin(); + } + + // Run the garbage collecter. FIXME: This can error in a __gc metamethod + lua_gc(L, LUA_GCSTEP, 5); + + while (!running_scripts.empty()) { + current = *(running_scripts.begin()); + + if (current.rr.host->timedOut(&now)) + state = LUA_ERRRUN; + else + state = lua_resume(current.thread, current.resume_arguments); + + if(state == LUA_YIELD) { + // this script has performed a network io operation + // we put it in the waiting + // when the network io operation has completed, + // a callback from the nsock library will put the + // script back into the running state + + waiting_scripts.push_back(current); + running_scripts.pop_front(); + } else if( state == 0) { + // this script has finished + // we first check if it produced output + // then we release the thread and remove it from the + // running_scripts list + + if(lua_isstring (current.thread, 2)) { // FIXME ScriptResult sr; lua_State *thread = current.thread; - SCRIPT_ENGINE_TRY(process_getScriptId(thread, &sr)); + SCRIPT_ENGINE_TRY(process_getScriptId(thread, &sr)); lua_getfield(thread, 2, "gsub"); lua_pushvalue(thread, 2); // output FIXME lua_pushliteral(thread, "[^%w%s%p]"); lua_pushcclosure(thread, escape_char, 0); lua_call(thread, 3, 1); - sr.set_output(lua_tostring(thread, -1)); - if(current.rr.type == 0) { - current.rr.host->scriptResults.push_back(sr); - } else if(current.rr.type == 1) { - current.rr.port->scriptResults.push_back(sr); - current.rr.host->ports.numscriptresults++; - } - lua_pop(thread, 2); - } - - SCRIPT_ENGINE_TRY(process_finalize(L, current.registry_idx)); - } else { - // this script returned because of an error - // print the failing reason if the verbose level is high enough - SCRIPT_ENGINE_DEBUGGING( - const char* errmsg = lua_tostring(current.thread, -1); - log_write(LOG_STDOUT, "%s: %s\n", SCRIPT_ENGINE, errmsg); - ) - SCRIPT_ENGINE_TRY(process_finalize(L, current.registry_idx)); - } - } // while - } - - progress.endTask(NULL, NULL); - - return SCRIPT_ENGINE_SUCCESS; + sr.set_output(lua_tostring(thread, -1)); + if(current.rr.type == 0) { + current.rr.host->scriptResults.push_back(sr); + } else if(current.rr.type == 1) { + current.rr.port->scriptResults.push_back(sr); + current.rr.host->ports.numscriptresults++; + } + lua_pop(thread, 2); + } + + SCRIPT_ENGINE_TRY(process_finalize(L, current.registry_idx)); + } else { + // this script returned because of an error + // print the failing reason if the verbose level is high enough + SCRIPT_ENGINE_DEBUGGING( + const char* errmsg = lua_tostring(current.thread, -1); + log_write(LOG_STDOUT, "%s: %s\n", SCRIPT_ENGINE, errmsg); + ) + SCRIPT_ENGINE_TRY(process_finalize(L, current.registry_idx)); + } + } // while + } + + progress.endTask(NULL, NULL); + + return SCRIPT_ENGINE_SUCCESS; } // If the target still has scripts in either running_scripts @@ -479,199 +479,194 @@ int process_mainloop(lua_State *L) { // pertains to scripts in the current runlevel. int has_target_finished(Target *target) { - std::list::iterator iter; + std::list::iterator iter; - for (iter = waiting_scripts.begin(); iter != waiting_scripts.end(); iter++) - if (target == iter->rr.host) return 0; + for (iter = waiting_scripts.begin(); iter != waiting_scripts.end(); iter++) + if (target == iter->rr.host) return 0; - for (iter = running_scripts.begin(); iter != running_scripts.end(); iter++) - if (target == iter->rr.host) return 0; + for (iter = running_scripts.begin(); iter != running_scripts.end(); iter++) + if (target == iter->rr.host) return 0; - return 1; + return 1; } int process_finalize(lua_State* L, unsigned int registry_idx) { - luaL_unref(L, LUA_REGISTRYINDEX, registry_idx); - struct thread_record thr = running_scripts.front(); + luaL_unref(L, LUA_REGISTRYINDEX, registry_idx); + struct thread_record thr = running_scripts.front(); - running_scripts.pop_front(); + running_scripts.pop_front(); - if (has_target_finished(thr.rr.host)) - thr.rr.host->stopTimeOutClock(NULL); + if (has_target_finished(thr.rr.host)) + thr.rr.host->stopTimeOutClock(NULL); - return SCRIPT_ENGINE_SUCCESS; + return SCRIPT_ENGINE_SUCCESS; } int process_waiting2running(lua_State* L, int resume_arguments) { - std::list::iterator iter; + std::list::iterator iter; - // find the lua state which has received i/o - for( iter = waiting_scripts.begin(); - (*iter).thread != L; - iter++) { + // find the lua state which has received i/o + for(iter = waiting_scripts.begin(); (*iter).thread != L; iter++) { - // It is very unlikely that a thread which - // is not in the waiting queue tries to - // continue - // it does happen when they try to do socket i/o - // inside a pcall + // It is very unlikely that a thread which + // is not in the waiting queue tries to + // continue + // it does happen when they try to do socket i/o + // inside a pcall - // This also happens when we timeout a script - // In this case, the script is still in the waiting - // queue and we will have manually removed it from - // the waiting queue so we just return. + // This also happens when we timeout a script + // In this case, the script is still in the waiting + // queue and we will have manually removed it from + // the waiting queue so we just return. - if(iter == waiting_scripts.end()) - return SCRIPT_ENGINE_SUCCESS; - } + if(iter == waiting_scripts.end()) + return SCRIPT_ENGINE_SUCCESS; + } - (*iter).resume_arguments = resume_arguments; + (*iter).resume_arguments = resume_arguments; - // put the thread back into the running - // queue - //running_scripts.push_front((*iter)); - running_scripts.push_back((*iter)); - waiting_scripts.erase(iter); + // put the thread back into the running + // queue + //running_scripts.push_front((*iter)); + running_scripts.push_back((*iter)); + waiting_scripts.erase(iter); - return SCRIPT_ENGINE_SUCCESS; + return SCRIPT_ENGINE_SUCCESS; } /* Gets the basename of a script filename and removes any ".nse" extension. */ static char *abbreviate_script_filename(const char *filename) { - char *abbrev; + char *abbrev; - abbrev = path_get_basename(filename); - if (abbrev == NULL) - return NULL; - if (nse_check_extension(SCRIPT_ENGINE_EXTENSION, abbrev)) - abbrev[strlen(abbrev) - strlen(SCRIPT_ENGINE_EXTENSION)] = '\0'; + abbrev = path_get_basename(filename); + if (abbrev == NULL) + return NULL; + if (nse_check_extension(SCRIPT_ENGINE_EXTENSION, abbrev)) + abbrev[strlen(abbrev) - strlen(SCRIPT_ENGINE_EXTENSION)] = '\0'; - return abbrev; + return abbrev; } /* Tries to get the script id (based on the filename) and stores it in the * script scan result structure. If someone changed the filename field to a * nonstring we complain. */ int process_getScriptId(lua_State* L, ScriptResult *sr) { - const char *filename; - char *id; - - lua_getfield(L, 1, FILENAME); - filename = lua_tostring(L, -1); - if (filename == NULL) { - error("%s: The script's 'filename' entry was changed to:", - SCRIPT_ENGINE); - l_dumpValue(L, -1); - return SCRIPT_ENGINE_ERROR; - } - lua_pop(L, 1); - - id = abbreviate_script_filename(filename); - if (id == NULL) { - /* On error just use the filename. */ - sr->set_id(filename); - } else { - sr->set_id(id); - free(id); - } - - return SCRIPT_ENGINE_SUCCESS; + const char *filename; + char *id; + + lua_getfield(L, 1, FILENAME); + filename = lua_tostring(L, -1); + if (filename == NULL) { + error("%s: The script's 'filename' entry was changed to:", + SCRIPT_ENGINE); + l_dumpValue(L, -1); + return SCRIPT_ENGINE_ERROR; + } + lua_pop(L, 1); + + id = abbreviate_script_filename(filename); + if (id == NULL) { + /* On error just use the filename. */ + sr->set_id(filename); + } else { + sr->set_id(id); + free(id); + } + + return SCRIPT_ENGINE_SUCCESS; } -/* try all host and all port rules against the +/* try all host and all port rules against the * state of the current target * make a list with run records for the scripts * which want to run * process all scripts in the list * */ int process_preparehost(lua_State* L, Target* target, std::list& torun_threads) { - PortList* plist = &(target->ports); - Port* current = NULL; - - /* find the matching hostrules - * */ - lua_getfield(L, LUA_REGISTRYINDEX, HOSTTESTS); - lua_pushnil(L); - while (lua_next(L, -2) != 0) - { - // Hostrule function & file closure on stack - lua_pushvalue(L, -2); // hostrule function (key) - lua_newtable(L); - set_hostinfo(L, target); // hostrule argument - SCRIPT_ENGINE_LUA_TRY(lua_pcall(L, 1, 1, 0)); - - if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) - { - struct thread_record tr; - tr.rr.type = 0; - tr.rr.port = NULL; - tr.rr.host = target; - - SCRIPT_ENGINE_TRY(process_preparethread(L, &tr)); + PortList* plist = &(target->ports); + Port* current = NULL; - torun_threads.push_back(tr); + /* find the matching hostrules */ + lua_getfield(L, LUA_REGISTRYINDEX, HOSTTESTS); + lua_pushnil(L); + while (lua_next(L, -2) != 0) + { + // Hostrule function & file closure on stack + lua_pushvalue(L, -2); // hostrule function (key) + lua_newtable(L); + set_hostinfo(L, target); // hostrule argument + SCRIPT_ENGINE_LUA_TRY(lua_pcall(L, 1, 1, 0)); - SCRIPT_ENGINE_DEBUGGING( - lua_getfenv(L, -2); // file closure environment - lua_getfield(L, -1, FILENAME); - log_write(LOG_STDOUT, "%s: Will run %s against %s\n", - SCRIPT_ENGINE, - lua_tostring(L, -1), - target->targetipstr()); - lua_pop(L, 2); - ) - } - lua_pop(L, 2); // boolean and file closure + if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) + { + struct thread_record tr; + tr.rr.type = 0; + tr.rr.port = NULL; + tr.rr.host = target; + + SCRIPT_ENGINE_TRY(process_preparethread(L, &tr)); + + torun_threads.push_back(tr); + + SCRIPT_ENGINE_DEBUGGING( + lua_getfenv(L, -2); // file closure environment + lua_getfield(L, -1, FILENAME); + log_write(LOG_STDOUT, "%s: Will run %s against %s\n", + SCRIPT_ENGINE, + lua_tostring(L, -1), + target->targetipstr()); + lua_pop(L, 2); + ) } + lua_pop(L, 2); // boolean and file closure + } - /* find the matching port rules - * */ - lua_getfield(L, LUA_REGISTRYINDEX, PORTTESTS); + /* find the matching port rules */ + lua_getfield(L, LUA_REGISTRYINDEX, PORTTESTS); - /* because of the port iteration API we need to awkwardly iterate - * over the kinds of ports we're interested in explictely. - * */ - current = NULL; - while((current = plist->nextPort(current, TCPANDUDP, PORT_OPEN)) != NULL) { - SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun_threads)); - } + /* because of the port iteration API we need to awkwardly iterate + * over the kinds of ports we're interested in explictely. */ + current = NULL; + while((current = plist->nextPort(current, TCPANDUDP, PORT_OPEN)) != NULL) { + SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun_threads)); + } - while((current = plist->nextPort(current, TCPANDUDP, PORT_OPENFILTERED)) != NULL) { - SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun_threads)); - } + while((current = plist->nextPort(current, TCPANDUDP, PORT_OPENFILTERED)) != NULL) { + SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun_threads)); + } - while((current = plist->nextPort(current, TCPANDUDP, PORT_UNFILTERED)) != NULL) { - SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun_threads)); - } + while((current = plist->nextPort(current, TCPANDUDP, PORT_UNFILTERED)) != NULL) { + SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun_threads)); + } - lua_pop(L, 2); // Hostrules, Portrules + lua_pop(L, 2); // Hostrules, Portrules - return SCRIPT_ENGINE_SUCCESS; + return SCRIPT_ENGINE_SUCCESS; } int process_preparerunlevels(std::list torun_threads) { - std::list current_runlevel; - std::list::iterator runlevel_iter; - double runlevel_idx = 0.0; - - torun_threads.sort(CompareRunlevels()); - - for( runlevel_iter = torun_threads.begin(); - runlevel_iter != torun_threads.end(); - runlevel_iter++) { - - if(runlevel_idx < (*runlevel_iter).runlevel) { - runlevel_idx = (*runlevel_iter).runlevel; - current_runlevel.clear(); - //push_back an empty list in which we store all scripts of the - //current runlevel... - torun_scripts.push_back(current_runlevel); - } - - torun_scripts.back().push_back(*runlevel_iter); - } - - return SCRIPT_ENGINE_SUCCESS; + std::list current_runlevel; + std::list::iterator runlevel_iter; + double runlevel_idx = 0.0; + + torun_threads.sort(CompareRunlevels()); + + for( runlevel_iter = torun_threads.begin(); + runlevel_iter != torun_threads.end(); + runlevel_iter++) { + + if(runlevel_idx < (*runlevel_iter).runlevel) { + runlevel_idx = (*runlevel_iter).runlevel; + current_runlevel.clear(); + //push_back an empty list in which we store all scripts of the + //current runlevel... + torun_scripts.push_back(current_runlevel); + } + + torun_scripts.back().push_back(*runlevel_iter); + } + + return SCRIPT_ENGINE_SUCCESS; } /* Because we can't iterate over all ports of interest in one go @@ -680,41 +675,41 @@ int process_preparerunlevels(std::list torun_threads) { * Note that we assume that at -1 on the stack we can find the portrules * */ int process_pickScriptsForPort(lua_State* L, Target* target, Port* port, std::list& torun_threads) { - lua_pushnil(L); - while (lua_next(L, -2) != 0) + lua_pushnil(L); + while (lua_next(L, -2) != 0) + { + // Portrule function & file closure on stack + lua_pushvalue(L, -2); // portrule function (key) + lua_newtable(L); + set_hostinfo(L, target); // portrule argument 1 + lua_newtable(L); + set_portinfo(L, port); // portrule argument 2 + SCRIPT_ENGINE_LUA_TRY(lua_pcall(L, 2, 1, 0)); + + if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) { - // Portrule function & file closure on stack - lua_pushvalue(L, -2); // portrule function (key) - lua_newtable(L); - set_hostinfo(L, target); // portrule argument 1 - lua_newtable(L); - set_portinfo(L, port); // portrule argument 2 - SCRIPT_ENGINE_LUA_TRY(lua_pcall(L, 2, 1, 0)); - - if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) - { - struct thread_record tr; - tr.rr.type = 1; - tr.rr.port = port; - tr.rr.host = target; - - SCRIPT_ENGINE_TRY(process_preparethread(L, &tr)); - - torun_threads.push_back(tr); - - SCRIPT_ENGINE_DEBUGGING( - lua_getfenv(L, -2); // file closure environment - lua_getfield(L, -1, FILENAME); - log_write(LOG_STDOUT, "%s: Will run %s against %s\n", - SCRIPT_ENGINE, - lua_tostring(L, -1), - target->targetipstr()); - lua_pop(L, 2); - ) - } - lua_pop(L, 2); // boolean and file closure + struct thread_record tr; + tr.rr.type = 1; + tr.rr.port = port; + tr.rr.host = target; + + SCRIPT_ENGINE_TRY(process_preparethread(L, &tr)); + + torun_threads.push_back(tr); + + SCRIPT_ENGINE_DEBUGGING( + lua_getfenv(L, -2); // file closure environment + lua_getfield(L, -1, FILENAME); + log_write(LOG_STDOUT, "%s: Will run %s against %s\n", + SCRIPT_ENGINE, + lua_tostring(L, -1), + target->targetipstr()); + lua_pop(L, 2); + ) } - return SCRIPT_ENGINE_SUCCESS; + lua_pop(L, 2); // boolean and file closure + } + return SCRIPT_ENGINE_SUCCESS; } /* Create a new lua thread and prepare it for execution @@ -724,56 +719,53 @@ int process_pickScriptsForPort(lua_State* L, Target* target, Port* port, std::li * */ int process_preparethread(lua_State* L, struct thread_record *tr){ - lua_State *thread = lua_newthread(L); - tr->registry_idx = luaL_ref(L, LUA_REGISTRYINDEX); // store thread - tr->thread = thread; - - lua_pushvalue(L, -2); // File closure - lua_getfenv(L, -1); // get script file environment - lua_getfield(L, -1, FILENAME); // get its filename - - lua_createtable(L, 0, 11); // new environment - lua_pushvalue(L, -2); // script filename - lua_setfield(L, -2, FILENAME); - lua_pushnumber(L, 1.0); // set a default RUNLEVEL - lua_setfield(L, -2, RUNLEVEL); - lua_createtable(L, 0, 1); // metatable for env - lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_setfield(L, -2, "__index"); // global access - lua_setmetatable(L, -2); - - lua_pushvalue(L, -4); // script file closure - lua_pushvalue(L, -2); // script env - lua_setfenv(L, -2); - SCRIPT_ENGINE_LUA_TRY( - lua_pcall(L, 0, 0, 0) // file closure loads globals (action, id, etc.) - ); - - lua_getfield(L, -1, RUNLEVEL); - tr->runlevel = lua_tonumber(L, -1); - lua_pop(L, 1); - - // move the script action closure into the thread - lua_getfield(L, -1, ACTION); // action closure - lua_xmove(L, thread, 2); - lua_pop(L, 1); // filename - lua_setfenv(L, -2); // reset old env - lua_pop(L, 1); // file closure - - // make the info table - lua_newtable(thread); - set_hostinfo(thread, tr->rr.host); - - /* if this is a host rule we don't have - * a port state - * */ - if(tr->rr.port != NULL) { - lua_newtable(thread); - set_portinfo(thread, tr->rr.port); - tr->resume_arguments = 2; - } - else - tr->resume_arguments = 1; - - return SCRIPT_ENGINE_SUCCESS; + lua_State *thread = lua_newthread(L); + tr->registry_idx = luaL_ref(L, LUA_REGISTRYINDEX); // store thread + tr->thread = thread; + + lua_pushvalue(L, -2); // File closure + lua_getfenv(L, -1); // get script file environment + lua_getfield(L, -1, FILENAME); // get its filename + + lua_createtable(L, 0, 11); // new environment + lua_pushvalue(L, -2); // script filename + lua_setfield(L, -2, FILENAME); + lua_pushnumber(L, 1.0); // set a default RUNLEVEL + lua_setfield(L, -2, RUNLEVEL); + lua_createtable(L, 0, 1); // metatable for env + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); // global access + lua_setmetatable(L, -2); + + lua_pushvalue(L, -4); // script file closure + lua_pushvalue(L, -2); // script env + lua_setfenv(L, -2); + SCRIPT_ENGINE_LUA_TRY( + lua_pcall(L, 0, 0, 0) // file closure loads globals (action, id, etc.) + ); + + lua_getfield(L, -1, RUNLEVEL); + tr->runlevel = lua_tonumber(L, -1); + lua_pop(L, 1); + + // move the script action closure into the thread + lua_getfield(L, -1, ACTION); // action closure + lua_xmove(L, thread, 2); + lua_pop(L, 1); // filename + lua_setfenv(L, -2); // reset old env + lua_pop(L, 1); // file closure + + // make the info table + lua_newtable(thread); + set_hostinfo(thread, tr->rr.host); + + /* if this is a host rule we don't have a port state */ + if(tr->rr.port != NULL) { + lua_newtable(thread); + set_portinfo(thread, tr->rr.port); + tr->resume_arguments = 2; + } else + tr->resume_arguments = 1; + + return SCRIPT_ENGINE_SUCCESS; } diff --git a/nse_main.h b/nse_main.h index 5db6b41432..86e649047f 100644 --- a/nse_main.h +++ b/nse_main.h @@ -2,9 +2,9 @@ #define NMAP_LUA_H extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } #include diff --git a/nse_nmaplib.cc b/nse_nmaplib.cc index 871a769d43..46289128d7 100644 --- a/nse_nmaplib.cc +++ b/nse_nmaplib.cc @@ -17,17 +17,17 @@ #define SCRIPT_ENGINE_GETSTRING(name) \ - char* name; \ - lua_getfield(L, -1, #name); \ - if(lua_isnil(L, -1)) \ - name = NULL; \ - else \ - name = strdup(lua_tostring(L, -1)); \ - lua_pop(L, 1); \ + char* name; \ + lua_getfield(L, -1, #name); \ + if(lua_isnil(L, -1)) \ + name = NULL; \ + else \ + name = strdup(lua_tostring(L, -1)); \ + lua_pop(L, 1); \ #define SCRIPT_ENGINE_PUSHSTRING_NOTNULL(c_str, str) if(c_str != NULL) {\ - lua_pushstring(L, c_str); \ - lua_setfield(L, -2, str); \ + lua_pushstring(L, c_str); \ + lua_setfield(L, -2, str); \ } extern NmapOps o; @@ -137,7 +137,7 @@ int luaopen_nmap (lua_State *L) {"timing_level", l_get_timing_level}, {"mutex", l_mutex}, {"get_dns_servers", l_get_dns_servers}, - {NULL, NULL} + {NULL, NULL} }; lua_settop(L, 0); // clear stack @@ -167,100 +167,100 @@ int luaopen_nmap (lua_State *L) * table which is currently on the stack * */ void set_portinfo(lua_State *L, Port* port) { - struct serviceDeductions sd; + struct serviceDeductions sd; - port->getServiceDeductions(&sd); + port->getServiceDeductions(&sd); - lua_pushnumber(L, (double) port->portno); - lua_setfield(L, -2, "number"); + lua_pushnumber(L, (double) port->portno); + lua_setfield(L, -2, "number"); - lua_pushstring(L, sd.name); - lua_setfield(L, -2, "service"); + lua_pushstring(L, sd.name); + lua_setfield(L, -2, "service"); - lua_pushstring(L, (port->proto == IPPROTO_TCP)? "tcp": "udp"); - lua_setfield(L, -2, "protocol"); + lua_pushstring(L, (port->proto == IPPROTO_TCP)? "tcp": "udp"); + lua_setfield(L, -2, "protocol"); - lua_newtable(L); - set_version(L, sd); - lua_setfield(L, -2, "version"); + lua_newtable(L); + set_version(L, sd); + lua_setfield(L, -2, "version"); - lua_pushstring(L, statenum2str(port->state)); - lua_setfield(L, -2, "state"); + lua_pushstring(L, statenum2str(port->state)); + lua_setfield(L, -2, "state"); - lua_pushstring(L, reason_str(port->reason.reason_id, 1)); - lua_setfield(L, -2, "reason"); + lua_pushstring(L, reason_str(port->reason.reason_id, 1)); + lua_setfield(L, -2, "reason"); } void set_version(lua_State *L, struct serviceDeductions sd) { - SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.name, "name"); - - lua_pushnumber(L, sd.name_confidence); - lua_setfield(L, -2, "name_confidence"); - - SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.product, "product"); - SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.version, "version"); - SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.extrainfo, "extrainfo"); - SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.hostname, "hostname"); - SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.ostype, "ostype"); - SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.devicetype, "devicetype"); - - switch(sd.service_tunnel) { - case(SERVICE_TUNNEL_NONE): - SCRIPT_ENGINE_PUSHSTRING_NOTNULL("none", "service_tunnel"); - break; - case(SERVICE_TUNNEL_SSL): - SCRIPT_ENGINE_PUSHSTRING_NOTNULL("ssl", "service_tunnel"); - break; - default: - fatal("%s: In: %s:%i This should never happen.", - SCRIPT_ENGINE, __FILE__, __LINE__); - break; - } - - SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.service_fp, "service_fp"); - - switch(sd.dtype) { - case(SERVICE_DETECTION_TABLE): - SCRIPT_ENGINE_PUSHSTRING_NOTNULL("table", "service_fp"); - break; - case(SERVICE_DETECTION_PROBED): - SCRIPT_ENGINE_PUSHSTRING_NOTNULL("probed", "service_fp"); - break; - default: - fatal("%s: In: %s:%i This should never happen.", - SCRIPT_ENGINE, __FILE__, __LINE__); - break; - } - - switch(sd.rpc_status) { - case(RPC_STATUS_UNTESTED): - SCRIPT_ENGINE_PUSHSTRING_NOTNULL("untested", "rpc_status"); - break; - case(RPC_STATUS_UNKNOWN): - SCRIPT_ENGINE_PUSHSTRING_NOTNULL("unknown", "rpc_status"); - break; - case(RPC_STATUS_GOOD_PROG): - SCRIPT_ENGINE_PUSHSTRING_NOTNULL("good_prog", "rpc_status"); - break; - case(RPC_STATUS_NOT_RPC): - SCRIPT_ENGINE_PUSHSTRING_NOTNULL("not_rpc", "rpc_status"); - break; - default: - fatal("%s: In: %s:%i This should never happen.", - SCRIPT_ENGINE, __FILE__, __LINE__); - break; - } - - if(sd.rpc_status == RPC_STATUS_GOOD_PROG) { - lua_pushnumber(L, sd.rpc_program); - lua_setfield(L, -2, "rpc_program"); - - lua_pushnumber(L, sd.rpc_lowver); - lua_setfield(L, -2, "rpc_lowver"); - - lua_pushnumber(L, sd.rpc_highver); - lua_setfield(L, -2, "rpc_highver"); - } + SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.name, "name"); + + lua_pushnumber(L, sd.name_confidence); + lua_setfield(L, -2, "name_confidence"); + + SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.product, "product"); + SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.version, "version"); + SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.extrainfo, "extrainfo"); + SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.hostname, "hostname"); + SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.ostype, "ostype"); + SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.devicetype, "devicetype"); + + switch(sd.service_tunnel) { + case(SERVICE_TUNNEL_NONE): + SCRIPT_ENGINE_PUSHSTRING_NOTNULL("none", "service_tunnel"); + break; + case(SERVICE_TUNNEL_SSL): + SCRIPT_ENGINE_PUSHSTRING_NOTNULL("ssl", "service_tunnel"); + break; + default: + fatal("%s: In: %s:%i This should never happen.", + SCRIPT_ENGINE, __FILE__, __LINE__); + break; + } + + SCRIPT_ENGINE_PUSHSTRING_NOTNULL(sd.service_fp, "service_fp"); + + switch(sd.dtype) { + case(SERVICE_DETECTION_TABLE): + SCRIPT_ENGINE_PUSHSTRING_NOTNULL("table", "service_fp"); + break; + case(SERVICE_DETECTION_PROBED): + SCRIPT_ENGINE_PUSHSTRING_NOTNULL("probed", "service_fp"); + break; + default: + fatal("%s: In: %s:%i This should never happen.", + SCRIPT_ENGINE, __FILE__, __LINE__); + break; + } + + switch(sd.rpc_status) { + case(RPC_STATUS_UNTESTED): + SCRIPT_ENGINE_PUSHSTRING_NOTNULL("untested", "rpc_status"); + break; + case(RPC_STATUS_UNKNOWN): + SCRIPT_ENGINE_PUSHSTRING_NOTNULL("unknown", "rpc_status"); + break; + case(RPC_STATUS_GOOD_PROG): + SCRIPT_ENGINE_PUSHSTRING_NOTNULL("good_prog", "rpc_status"); + break; + case(RPC_STATUS_NOT_RPC): + SCRIPT_ENGINE_PUSHSTRING_NOTNULL("not_rpc", "rpc_status"); + break; + default: + fatal("%s: In: %s:%i This should never happen.", + SCRIPT_ENGINE, __FILE__, __LINE__); + break; + } + + if(sd.rpc_status == RPC_STATUS_GOOD_PROG) { + lua_pushnumber(L, sd.rpc_program); + lua_setfield(L, -2, "rpc_program"); + + lua_pushnumber(L, sd.rpc_lowver); + lua_setfield(L, -2, "rpc_lowver"); + + lua_pushnumber(L, sd.rpc_highver); + lua_setfield(L, -2, "rpc_highver"); + } } /* set host ip, host name and target name onto the @@ -273,149 +273,149 @@ void set_version(lua_State *L, struct serviceDeductions sd) { * points to nil! * */ void set_hostinfo(lua_State *L, Target *currenths) { - unsigned int i; - char hostname[1024]; - - lua_pushstring(L, strncpy(hostname, currenths->targetipstr(), 1024)); - lua_setfield(L, -2, "ip"); - - lua_pushstring(L, strncpy(hostname, currenths->HostName(), 1024)); - lua_setfield(L, -2, "name"); - - if ( currenths->TargetName() ) { // else nil - lua_pushstring(L, strncpy(hostname, currenths->TargetName(), 1024)); - lua_setfield(L, -2, "targetname"); - } - - if(currenths->directlyConnectedOrUnset() != -1){ - lua_pushboolean(L, currenths->directlyConnected()); - lua_setfield(L, -2, "directly_connected"); - } - - if(currenths->MACAddress()){ // else nil - lua_pushlstring (L, (const char*)currenths->MACAddress() , 6); - lua_setfield(L, -2, "mac_addr"); - } - if(currenths->SrcMACAddress()){ // else nil - lua_pushlstring(L, (const char*)currenths->SrcMACAddress(), 6); - lua_setfield(L, -2, "mac_addr_src"); - } - if(currenths->deviceName()){ - lua_pushstring(L, strncpy(hostname, currenths->deviceName(), 1024)); - lua_setfield(L, -2, "interface"); - } - if( (u32)(currenths->v4host().s_addr) ){ - struct in_addr adr = currenths->v4host(); - lua_pushlstring(L, (char*)&adr, 4); - lua_setfield(L, -2, "bin_ip"); - } - if( (u32)(currenths->v4source().s_addr) ){ - struct in_addr adr = currenths->v4source(); - lua_pushlstring(L, (char*)&adr, 4); - lua_setfield(L, -2, "bin_ip_src"); - } - - FingerPrintResults *FPR = NULL; - - FPR = currenths->FPR; - - /* if there has been an os scan which returned a pretty certain - * result, we will use it in the scripts - * matches which aren't perfect are not needed in the scripts - */ - if( currenths->osscanPerformed() && - FPR != NULL && - FPR->overall_results == OSSCAN_SUCCESS && - FPR->num_perfect_matches > 0 && - FPR->num_perfect_matches <= 8 ) { - - lua_newtable(L); - - // this will run at least one time and at most 8 times, see if condition - for(i = 0; FPR->accuracy[i] == 1; i++) { - lua_pushstring(L, FPR->prints[i]->OS_name); - lua_rawseti(L, -2, i); - } - lua_setfield(L, -2, "os"); - } + unsigned int i; + char hostname[1024]; + + lua_pushstring(L, strncpy(hostname, currenths->targetipstr(), 1024)); + lua_setfield(L, -2, "ip"); + + lua_pushstring(L, strncpy(hostname, currenths->HostName(), 1024)); + lua_setfield(L, -2, "name"); + + if ( currenths->TargetName() ) { // else nil + lua_pushstring(L, strncpy(hostname, currenths->TargetName(), 1024)); + lua_setfield(L, -2, "targetname"); + } + + if(currenths->directlyConnectedOrUnset() != -1){ + lua_pushboolean(L, currenths->directlyConnected()); + lua_setfield(L, -2, "directly_connected"); + } + + if(currenths->MACAddress()){ // else nil + lua_pushlstring (L, (const char*)currenths->MACAddress() , 6); + lua_setfield(L, -2, "mac_addr"); + } + if(currenths->SrcMACAddress()){ // else nil + lua_pushlstring(L, (const char*)currenths->SrcMACAddress(), 6); + lua_setfield(L, -2, "mac_addr_src"); + } + if(currenths->deviceName()){ + lua_pushstring(L, strncpy(hostname, currenths->deviceName(), 1024)); + lua_setfield(L, -2, "interface"); + } + if( (u32)(currenths->v4host().s_addr) ){ + struct in_addr adr = currenths->v4host(); + lua_pushlstring(L, (char*)&adr, 4); + lua_setfield(L, -2, "bin_ip"); + } + if( (u32)(currenths->v4source().s_addr) ){ + struct in_addr adr = currenths->v4source(); + lua_pushlstring(L, (char*)&adr, 4); + lua_setfield(L, -2, "bin_ip_src"); + } + + FingerPrintResults *FPR = NULL; + + FPR = currenths->FPR; + + /* if there has been an os scan which returned a pretty certain + * result, we will use it in the scripts + * matches which aren't perfect are not needed in the scripts + */ + if(currenths->osscanPerformed() && + FPR != NULL && + FPR->overall_results == OSSCAN_SUCCESS && + FPR->num_perfect_matches > 0 && + FPR->num_perfect_matches <= 8 ) { + + lua_newtable(L); + + // this will run at least one time and at most 8 times, see if condition + for(i = 0; FPR->accuracy[i] == 1; i++) { + lua_pushstring(L, FPR->prints[i]->OS_name); + lua_rawseti(L, -2, i); + } + lua_setfield(L, -2, "os"); + } } static int l_port_accessor(lua_State *L) { - int retvalues = 0; - - char* function_name; - const char *target_ip; - int portno; - int proto; - - Target* target; - PortList* plist; - Port* port; - - lua_Debug ldebug; - lua_getstack(L, 0, &ldebug); - lua_getinfo(L, "n", &ldebug); - function_name = strdup(ldebug.name); - - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checktype(L, 2, LUA_TTABLE); - - lua_getfield(L, 1, "ip"); - luaL_checktype(L, -1, LUA_TSTRING); - target_ip = lua_tostring(L, -1); - lua_pop(L, 1); - - lua_getfield(L, 2, "number"); - luaL_checktype(L, -1, LUA_TNUMBER); - portno = lua_tointeger(L, -1); - lua_pop(L, 1); - - lua_getfield(L, 2, "protocol"); - luaL_checktype(L, -1, LUA_TSTRING); - proto = (strcmp(lua_tostring(L, -1), "tcp") == 0)? IPPROTO_TCP : IPPROTO_UDP; - lua_pop(L, 1); - - lua_rawgeti(L, LUA_REGISTRYINDEX, current_hosts); - lua_pushstring(L, target_ip); - lua_gettable(L, -2); - if (lua_isnil(L, -1)) - return luaL_argerror(L, 1, "Host isn't being processed right now."); - else - { - target = (Target *) lua_touserdata(L, -1); - lua_pop(L, 2); - } + int retvalues = 0; + + char* function_name; + const char *target_ip; + int portno; + int proto; + + Target* target; + PortList* plist; + Port* port; + + lua_Debug ldebug; + lua_getstack(L, 0, &ldebug); + lua_getinfo(L, "n", &ldebug); + function_name = strdup(ldebug.name); + + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checktype(L, 2, LUA_TTABLE); + + lua_getfield(L, 1, "ip"); + luaL_checktype(L, -1, LUA_TSTRING); + target_ip = lua_tostring(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 2, "number"); + luaL_checktype(L, -1, LUA_TNUMBER); + portno = lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 2, "protocol"); + luaL_checktype(L, -1, LUA_TSTRING); + proto = (strcmp(lua_tostring(L, -1), "tcp") == 0)? IPPROTO_TCP : IPPROTO_UDP; + lua_pop(L, 1); + + lua_rawgeti(L, LUA_REGISTRYINDEX, current_hosts); + lua_pushstring(L, target_ip); + lua_gettable(L, -2); + if (lua_isnil(L, -1)) + return luaL_argerror(L, 1, "Host isn't being processed right now."); + else + { + target = (Target *) lua_touserdata(L, -1); + lua_pop(L, 2); + } + + plist = &(target->ports); + port = NULL; + + while((port = plist->nextPort(port, proto, PORT_UNKNOWN)) != NULL) { + if(port->portno == portno) + break; + } + + // if the port wasn't scanned we return nil + if(port == NULL) { + free(function_name); + return 0; + } - plist = &(target->ports); - port = NULL; - - while((port = plist->nextPort(port, proto, PORT_UNKNOWN)) != NULL) { - if(port->portno == portno) - break; - } - - // if the port wasn't scanned we return nil - if(port == NULL) { - free(function_name); - return 0; - } - - if(strcmp(function_name, "set_port_state") == 0) - retvalues = l_set_port_state(L, target, port); - else if(strcmp(function_name, "set_port_version") == 0) - retvalues = l_set_port_version(L, target, port); - else if(strcmp(function_name, "get_port_state") == 0) - retvalues = l_get_port_state(L, target, port); - - // remove host and port argument from the stack - lua_remove(L, 2); - lua_remove(L, 1); - free(function_name); - return retvalues; + if(strcmp(function_name, "set_port_state") == 0) + retvalues = l_set_port_state(L, target, port); + else if(strcmp(function_name, "set_port_version") == 0) + retvalues = l_set_port_version(L, target, port); + else if(strcmp(function_name, "get_port_state") == 0) + retvalues = l_get_port_state(L, target, port); + + // remove host and port argument from the stack + lua_remove(L, 2); + lua_remove(L, 1); + free(function_name); + return retvalues; } /* this function can be called from lua to obtain the port state - * of a port different from the one the script rule is matched + * of a port different from the one the script rule is matched * against * it retrieves the host.ip of the host on which the script is * currently running, looks up the host in the table of currently @@ -425,10 +425,10 @@ static int l_port_accessor(lua_State *L) { * the state of more than one port * */ static int l_get_port_state(lua_State *L, Target* target, Port* port) { - lua_newtable(L); - set_portinfo(L, port); + lua_newtable(L); + set_portinfo(L, port); - return 1; + return 1; } /* unlike set_portinfo() this function sets the port state in nmap. @@ -436,210 +436,210 @@ static int l_get_port_state(lua_State *L, Target* target, Port* port) { * filtered, the script is free to say so. * */ static int l_set_port_state(lua_State *L, Target* target, Port* port) { - char* state; - PortList* plist = &(target->ports); - - luaL_checktype(L, -1, LUA_TSTRING); - state = strdup(lua_tostring(L, -1)); - lua_pop(L, 1); - - switch(state[0]) { - case 'o': - if (strcmp(state, "open")) - luaL_argerror (L, 4, "Invalid port state."); - if (port->state == PORT_OPEN) - goto noset; - plist->addPort(port->portno, port->proto, NULL, PORT_OPEN); - port->state = PORT_OPEN; - break; - case 'c': - if (strcmp(state, "closed")) - luaL_argerror (L, 4, "Invalid port state."); - if (port->state == PORT_CLOSED) - goto noset; - plist->addPort(port->portno, port->proto, NULL, PORT_CLOSED); - port->state = PORT_CLOSED; - break; - default: - luaL_argerror (L, 4, "Invalid port state."); - } - - port->reason.reason_id = ER_SCRIPT; + char* state; + PortList* plist = &(target->ports); + + luaL_checktype(L, -1, LUA_TSTRING); + state = strdup(lua_tostring(L, -1)); + lua_pop(L, 1); + + switch(state[0]) { + case 'o': + if (strcmp(state, "open")) + luaL_argerror (L, 4, "Invalid port state."); + if (port->state == PORT_OPEN) + goto noset; + plist->addPort(port->portno, port->proto, NULL, PORT_OPEN); + port->state = PORT_OPEN; + break; + case 'c': + if (strcmp(state, "closed")) + luaL_argerror (L, 4, "Invalid port state."); + if (port->state == PORT_CLOSED) + goto noset; + plist->addPort(port->portno, port->proto, NULL, PORT_CLOSED); + port->state = PORT_CLOSED; + break; + default: + luaL_argerror (L, 4, "Invalid port state."); + } + + port->reason.reason_id = ER_SCRIPT; noset: - free(state); - return 0; + free(state); + return 0; } static int l_set_port_version(lua_State *L, Target* target, Port* port) { - luaL_checktype(L, 3, LUA_TSTRING); - char* c_probestate = strdup(lua_tostring(L, -1)); - lua_pop(L, 1); - - enum service_tunnel_type tunnel = SERVICE_TUNNEL_NONE; - enum serviceprobestate probestate = PROBESTATE_INITIAL; - - lua_getfield(L, -1, "version"); - SCRIPT_ENGINE_GETSTRING(name); - SCRIPT_ENGINE_GETSTRING(product); - SCRIPT_ENGINE_GETSTRING(version); - SCRIPT_ENGINE_GETSTRING(extrainfo); - SCRIPT_ENGINE_GETSTRING(hostname); - SCRIPT_ENGINE_GETSTRING(ostype); - SCRIPT_ENGINE_GETSTRING(devicetype); - // SCRIPT_ENGINE_GETSTRING(fingerprint); - - SCRIPT_ENGINE_GETSTRING(service_tunnel); - if(service_tunnel == NULL) - tunnel = SERVICE_TUNNEL_NONE; - else if(strcmp(service_tunnel, "none") == 0) - tunnel = SERVICE_TUNNEL_NONE; - else if(strcmp(service_tunnel, "ssl") == 0) - tunnel = SERVICE_TUNNEL_SSL; - else - luaL_argerror(L, 2, "Invalid value for port.version.service_tunnel"); - lua_pop(L, 1); - - if(c_probestate == NULL) - probestate = PROBESTATE_INITIAL; - if(strcmp(c_probestate, "hardmatched") == 0) - probestate = PROBESTATE_FINISHED_HARDMATCHED; - else if(strcmp(c_probestate, "softmatched") == 0) - probestate = PROBESTATE_FINISHED_SOFTMATCHED; - else if(strcmp(c_probestate, "nomatch") == 0) - probestate = PROBESTATE_FINISHED_NOMATCH; - else if(strcmp(c_probestate, "tcpwrapped") == 0) - probestate = PROBESTATE_FINISHED_TCPWRAPPED; - else if(strcmp(c_probestate, "incomplete") == 0) - probestate = PROBESTATE_INCOMPLETE; - else - luaL_argerror(L, 3, "Invalid value for probestate."); - -// port->setServiceProbeResults(probestate, name, -// tunnel, product, version, -// extrainfo, hostname, ostype, -// devicetype, fingerprint); - -//should prevent a assertion-failure during output if the OutputTable does -//not contain columns for the fields other than the name - if(o.servicescan){ - port->setServiceProbeResults(probestate, name, - tunnel, product, version, - extrainfo, hostname, ostype, - devicetype, NULL); - }else{ - port->setServiceProbeResults(probestate, name, - tunnel, NULL, NULL, - NULL, NULL, NULL, - NULL, NULL); - } - - - free(service_tunnel); - free(name); - free(product); - free(version); - free(extrainfo); - free(hostname); - free(ostype); - free(devicetype); -// free(fingerprint); - return 0; + luaL_checktype(L, 3, LUA_TSTRING); + char* c_probestate = strdup(lua_tostring(L, -1)); + lua_pop(L, 1); + + enum service_tunnel_type tunnel = SERVICE_TUNNEL_NONE; + enum serviceprobestate probestate = PROBESTATE_INITIAL; + + lua_getfield(L, -1, "version"); + SCRIPT_ENGINE_GETSTRING(name); + SCRIPT_ENGINE_GETSTRING(product); + SCRIPT_ENGINE_GETSTRING(version); + SCRIPT_ENGINE_GETSTRING(extrainfo); + SCRIPT_ENGINE_GETSTRING(hostname); + SCRIPT_ENGINE_GETSTRING(ostype); + SCRIPT_ENGINE_GETSTRING(devicetype); + // SCRIPT_ENGINE_GETSTRING(fingerprint); + + SCRIPT_ENGINE_GETSTRING(service_tunnel); + if(service_tunnel == NULL) + tunnel = SERVICE_TUNNEL_NONE; + else if(strcmp(service_tunnel, "none") == 0) + tunnel = SERVICE_TUNNEL_NONE; + else if(strcmp(service_tunnel, "ssl") == 0) + tunnel = SERVICE_TUNNEL_SSL; + else + luaL_argerror(L, 2, "Invalid value for port.version.service_tunnel"); + lua_pop(L, 1); + + if(c_probestate == NULL) + probestate = PROBESTATE_INITIAL; + if(strcmp(c_probestate, "hardmatched") == 0) + probestate = PROBESTATE_FINISHED_HARDMATCHED; + else if(strcmp(c_probestate, "softmatched") == 0) + probestate = PROBESTATE_FINISHED_SOFTMATCHED; + else if(strcmp(c_probestate, "nomatch") == 0) + probestate = PROBESTATE_FINISHED_NOMATCH; + else if(strcmp(c_probestate, "tcpwrapped") == 0) + probestate = PROBESTATE_FINISHED_TCPWRAPPED; + else if(strcmp(c_probestate, "incomplete") == 0) + probestate = PROBESTATE_INCOMPLETE; + else + luaL_argerror(L, 3, "Invalid value for probestate."); + + // port->setServiceProbeResults(probestate, name, + // tunnel, product, version, + // extrainfo, hostname, ostype, + // devicetype, fingerprint); + + //should prevent a assertion-failure during output if the OutputTable does + //not contain columns for the fields other than the name + if(o.servicescan){ + port->setServiceProbeResults(probestate, name, + tunnel, product, version, + extrainfo, hostname, ostype, + devicetype, NULL); + }else{ + port->setServiceProbeResults(probestate, name, + tunnel, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL); + } + + + free(service_tunnel); + free(name); + free(product); + free(version); + free(extrainfo); + free(hostname); + free(ostype); + free(devicetype); + // free(fingerprint); + return 0; } static int l_print_debug_unformatted(lua_State *L) { int verbosity=1; const char *out; - + if (lua_gettop(L) != 2) return luaL_error(L, "Incorrect number of arguments\n"); - + verbosity = luaL_checkinteger(L, 1); if (verbosity > o.verbose) return 0; out = luaL_checkstring(L, 2); - + log_write(LOG_STDOUT, "%s DEBUG: %s\n", SCRIPT_ENGINE, out); - + return 0; } static int l_exc_finalize(lua_State *L) { - if (!lua_toboolean(L, 1)) { - /* false or nil. */ - lua_pushvalue(L, lua_upvalueindex(1)); - lua_call(L, 0, 0); - lua_settop(L, 2); - lua_error(L); - return 0; - } else if(lua_isboolean(L, 1) && lua_toboolean(L, 1)) { - /* true. */ - lua_remove(L, 1); - return lua_gettop(L); - } else { - fatal("%s: In: %s:%i Trying to finalize a non conforming function. Are you sure you return true on success followed by the remaining return values and nil on failure followed by an error string?", - SCRIPT_ENGINE, __FILE__, __LINE__); - - return 0; - } + if (!lua_toboolean(L, 1)) { + /* false or nil. */ + lua_pushvalue(L, lua_upvalueindex(1)); + lua_call(L, 0, 0); + lua_settop(L, 2); + lua_error(L); + return 0; + } else if(lua_isboolean(L, 1) && lua_toboolean(L, 1)) { + /* true. */ + lua_remove(L, 1); + return lua_gettop(L); + } else { + fatal("%s: In: %s:%i Trying to finalize a non conforming function. Are you sure you return true on success followed by the remaining return values and nil on failure followed by an error string?", + SCRIPT_ENGINE, __FILE__, __LINE__); + + return 0; + } } static int l_exc_do_nothing(lua_State *L) { - (void) L; - return 0; + (void) L; + return 0; } static int l_exc_newtry(lua_State *L) { - lua_settop(L, 1); - if (lua_isnil(L, 1)) - lua_pushcfunction(L, l_exc_do_nothing); - lua_pushcclosure(L, l_exc_finalize, 1); - return 1; + lua_settop(L, 1); + if (lua_isnil(L, 1)) + lua_pushcfunction(L, l_exc_do_nothing); + lua_pushcclosure(L, l_exc_finalize, 1); + return 1; } static int l_get_verbosity(lua_State *L) { - lua_pushnumber(L, o.verbose); - return 1; + lua_pushnumber(L, o.verbose); + return 1; } static int l_get_debugging(lua_State *L) { - lua_pushnumber(L, o.debugging); - return 1; + lua_pushnumber(L, o.debugging); + return 1; } static int l_get_have_ssl(lua_State *L) { #if HAVE_OPENSSL - lua_pushboolean(L, true); + lua_pushboolean(L, true); #else - lua_pushboolean(L, false); + lua_pushboolean(L, false); #endif - return 1; + return 1; } static int l_fetchfile(lua_State *L) { - char buf[FILENAME_MAX]; - const char *req = lua_tostring(L, -1); + char buf[FILENAME_MAX]; + const char *req = lua_tostring(L, -1); - if (!req) - goto err; + if (!req) + goto err; - if (nmap_fetchfile(buf, sizeof buf, (char *) req) != 1) - goto err; + if (nmap_fetchfile(buf, sizeof buf, (char *) req) != 1) + goto err; - lua_pop(L, 1); - lua_pushstring(L, buf); - return 1; + lua_pop(L, 1); + lua_pushstring(L, buf); + return 1; err: - lua_pop(L, 1); - lua_pushnil(L); - return 0; + lua_pop(L, 1); + lua_pushnil(L); + return 0; } static int l_get_timing_level(lua_State *L) { - lua_pushnumber(L, o.timing_level); - return 1; + lua_pushnumber(L, o.timing_level); + return 1; } diff --git a/nse_nmaplib.h b/nse_nmaplib.h index bfa014460d..661993d251 100644 --- a/nse_nmaplib.h +++ b/nse_nmaplib.h @@ -2,9 +2,9 @@ #define NSE_NMAPLIB extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } class Target;