diff --git a/Makefile.in b/Makefile.in
index b7097dadab..1fa6530c14 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -60,9 +60,9 @@ INSTALLZENMAP=@INSTALLZENMAP@
UNINSTALLZENMAP=@UNINSTALLZENMAP@
ifneq (@LIBLUA_LIBS@,)
-NSE_SRC=nse_main.cc nse_nsock.cc nse_init.cc nse_nmaplib.cc nse_debug.cc nse_pcrelib.cc nse_string.cc
-NSE_HDRS=nse_main.h nse_nsock.h nse_init.h nse_nmaplib.h nse_debug.h nse_macros.h nse_pcrelib.h nse_string.h
-NSE_OBJS=nse_main.o nse_nsock.o nse_init.o nse_nmaplib.o nse_debug.o nse_pcrelib.o nse_string.o
+NSE_SRC=nse_main.cc nse_nsock.cc nse_init.cc nse_fs.cc nse_nmaplib.cc nse_debug.cc nse_pcrelib.cc nse_string.cc
+NSE_HDRS=nse_main.h nse_nsock.h nse_init.h nse_fs.h nse_nmaplib.h nse_debug.h nse_macros.h nse_pcrelib.h nse_string.h
+NSE_OBJS=nse_main.o nse_nsock.o nse_init.o nse_fs.o nse_nmaplib.o nse_debug.o nse_pcrelib.o nse_string.o
NSESTDLIB=nsestdlib
endif
diff --git a/mswin32/nmap.vcproj b/mswin32/nmap.vcproj
index 234bb250be..21193bb29d 100644
--- a/mswin32/nmap.vcproj
+++ b/mswin32/nmap.vcproj
@@ -259,6 +259,10 @@
RelativePath="..\nse_init.cc"
>
+
+
@@ -433,15 +437,15 @@
>
= 0 - stack_height; i--) {
log_write(LOG_PLAIN, "%d: ", i);
- l_dumpValue(l, 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))
+void l_dumpValue(lua_State *L, int i) {
+ switch (lua_type(L, i))
{
case LUA_TTABLE:
- l_dumpTable(l, i);
+ l_dumpTable(L, i);
break;
case LUA_TFUNCTION:
- l_dumpFunction(l, i);
+ l_dumpFunction(L, i);
break;
case LUA_TSTRING:
- log_write(LOG_PLAIN, "string '%s'\n", lua_tostring(l, i));
+ 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");
+ lua_toboolean(L, i) ? "true" : "false");
break;
case LUA_TNUMBER:
- log_write(LOG_PLAIN, "number: %g\n", lua_tonumber(l, i));
+ 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)));
+ log_write(LOG_PLAIN, "%s\n", lua_typename(L, lua_type(L, i)));
}
}
-void l_dumpTable(lua_State *l, int index) {
+void l_dumpTable(lua_State *L, int index) {
log_write(LOG_PLAIN, "table\n");
- lua_pushnil(l);
+ lua_pushnil(L);
if (index<0) --index;
- while(lua_next(l, index) != 0)
+ while(lua_next(L, index) != 0)
{
- l_dumpValue(l, -2);
- l_dumpValue(l, -1);
- lua_pop(l, 1);
+ l_dumpValue(L, -2);
+ l_dumpValue(L, -1);
+ lua_pop(L, 1);
}
}
-void l_dumpFunction(lua_State* l, int index) {
+void l_dumpFunction(lua_State *L, int index) {
// lua_Debug ar;
log_write(LOG_PLAIN, "function\n");
-// lua_pushvalue(l, index);
-// lua_getinfo(l, ">n", &ar);
+// 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
new file mode 100644
index 0000000000..03d30aa965
--- /dev/null
+++ b/nse_fs.cc
@@ -0,0 +1,190 @@
+#ifndef WIN32
+ #include "dirent.h"
+#endif
+
+#include "errno.h"
+#include "nse_macros.h"
+#include "nse_fs.h"
+#include "nmap.h"
+#include "nmap_error.h"
+#include "NmapOps.h"
+
+extern NmapOps o;
+
+static bool filename_is_absolute(const char *file) {
+ if (file[0] == '/')
+ return true;
+#ifdef WIN32
+ if ((file[0] != '\0' && file[1] == ':') || file[0] == '\\')
+ return true;
+#endif
+ return false;
+}
+
+/* This is simply the most portable way to check
+ * if a file has a given extension.
+ * The portability comes at the price of reduced
+ * flexibility.
+ */
+int nse_check_extension (const char* ext, const char* path)
+{
+ int pathlen = strlen(path);
+ int extlen = strlen(ext);
+ if (extlen > pathlen || pathlen > MAX_FILENAME_LEN)
+ return 0;
+ else
+ return strcmp(path + pathlen - extlen, ext) == 0;
+}
+
+int nse_fetchfile(char *path, size_t path_len, const char *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());
+ }
+
+ 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);
+}
+
+#ifdef WIN32
+
+int nse_scandir (lua_State *L)
+ HANDLE dir;
+ WIN32_FIND_DATA entry;
+ std::string path;
+ BOOL morefiles = FALSE;
+ 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(!(
+ (check_extension(SCRIPT_ENGINE_EXTENSION, entry.cFileName) == MATCH)
+ && !(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);
+
+ 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;
+}
+
+#endif
diff --git a/nse_fs.h b/nse_fs.h
new file mode 100644
index 0000000000..204c04d45a
--- /dev/null
+++ b/nse_fs.h
@@ -0,0 +1,22 @@
+#ifndef NSE_FS
+#define NSE_FS
+
+extern "C" {
+ #include "lua.h"
+ #include "lualib.h"
+ #include "lauxlib.h"
+}
+
+#include
+#include
+#include
+
+int nse_check_extension (const char* ext, const char* path);
+
+int nse_fetchfile(char *path, size_t path_len, const char *file);
+
+int nse_fetchfile_absolute(char *path, size_t path_len, const char *file);
+
+int nse_scandir (lua_State *L);
+
+#endif
diff --git a/nse_init.cc b/nse_init.cc
index 5d97113c23..e437f54953 100644
--- a/nse_init.cc
+++ b/nse_init.cc
@@ -2,6 +2,7 @@
#include "nse_nmaplib.h"
#include "nse_macros.h"
#include "nse_debug.h"
+#include "nse_fs.h"
// 3rd Party libs
#include "nse_pcrelib.h"
@@ -12,801 +13,669 @@
#include "nmap_error.h"
#include "NmapOps.h"
-#ifndef WIN32
- #include "dirent.h"
-#endif
-
#include "errno.h"
#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);
-int init_loadcategories(lua_State* l, std::vector categories, std::vector &unusedTags);
-int init_scandir(char* dirname, std::vector& result, int files_or_dirs);
-int init_fetchfile(char *result, size_t result_max_len, char* file);
-int init_fetchfile_absolute(char *path, size_t path_len, char *file);
-int init_updatedb(lua_State* l);
-int init_pick_default_categories(std::vector& chosenScripts);
-
-int check_extension(const char* ext, const char* path);
extern NmapOps o;
-/* open the standard libs */
-int init_lua(lua_State* l) { // FIXME: Use cpcall, let Lua error normally.
- static const luaL_Reg lualibs[] = {
- {"", luaopen_base},
- {LUA_LOADLIBNAME, luaopen_package},
- {LUA_TABLIBNAME, luaopen_table},
- {LUA_IOLIBNAME, luaopen_io},
- {LUA_OSLIBNAME, luaopen_os},
- {LUA_STRLIBNAME, luaopen_string},
- {LUA_MATHLIBNAME, luaopen_math},
- {LUA_DBLIBNAME, luaopen_debug},
- {NSE_PCRELIBNAME, luaopen_pcrelib},
- {NULL, NULL}
- };
-
- const luaL_Reg* lib;
- for (lib = lualibs; lib->func; lib++) {
- lua_pushcfunction(l, lib->func);
- lua_pushstring(l, lib->name);
- SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 1, 0, 0));
- }
-
-
- /* publish the nmap bindings to the script */
- lua_newtable(l);
- SCRIPT_ENGINE_TRY(set_nmaplib(l));
- lua_setglobal(l, "nmap");
- SCRIPT_ENGINE_TRY(init_setlualibpath(l));
- return SCRIPT_ENGINE_SUCCESS;
+extern int current_hosts;
+extern int errfunc;
+
+/* TODO: keep?
+// Error function if a user script attempts to create a new global
+static int global_error(lua_State *L)
+{
+ lua_pushvalue(L, lua_upvalueindex(1));
+ lua_pushvalue(L, 2);
+ if (!lua_tostring(L, -1))
+ {
+ lua_pushliteral(L, "? (of type ");
+ lua_pushstring(L, lua_typename(L, lua_type(L, -2)));
+ lua_pushliteral(L, ")");
+ lua_concat(L, 3);
+ lua_replace(L, -2);
+ }
+ lua_pushvalue(L, lua_upvalueindex(2));
+ lua_concat(L, 3);
+ fprintf(stderr, "%s\n", lua_tostring(L, -1));
+ return lua_error(L);
+} */
+
+/* int error_function (lua_State *L)
+ *
+ * Arguments:
+ * -- error_message (passed by Lua)
+ *
+ * This function is for use with lua_pcall as the error handler.
+ * Because the stack is not unwound when this is called,
+ * we are able to obtain a traceback of the current stack frame.
+ * We use debug.traceback (an upvalue set in init_lua) for the real work.
+ */
+static int error_function (lua_State *L) // for use with lua_pcall
+{
+ luaL_where(L, 1);
+ lua_insert(L, 1);
+ lua_pushvalue(L, lua_upvalueindex(1)); // debug.traceback
+ lua_pushthread(L);
+ lua_pushliteral(L, "");
+ lua_pushinteger(L, 2);
+ lua_call(L, 3, 1);
+ lua_concat(L, 3);
+ return 1;
}
-/*sets two variables, which control where lua looks for modules (implemented in C or lua */
-int init_setlualibpath(lua_State* l){
- char path[MAX_FILENAME_LEN];
- char cpath[MAX_FILENAME_LEN];
-
- const char*oldpath, *oldcpath;
- std::string luapath, luacpath;
- /* set the path lua searches for modules*/
- if(nmap_fetchfile(path, MAX_FILENAME_LEN, SCRIPT_ENGINE_LIB_DIR)!=2){
- /*SCRIPT_ENGINE_LIB_DIR is not a directory - error */
- error("%s: %s not a directory", SCRIPT_ENGINE, SCRIPT_ENGINE_LIB_DIR);
- return SCRIPT_ENGINE_ERROR;
- }
-
- if(nmap_fetchfile(cpath, MAX_FILENAME_LEN, SCRIPT_ENGINE_LIBEXEC_DIR)!=2){
- error("%s: %s not a directory", SCRIPT_ENGINE, SCRIPT_ENGINE_LIBEXEC_DIR);
- return SCRIPT_ENGINE_ERROR;
- }
-
- /* the path lua uses to search for modules is setted to the
- * SCRIPT_ENGINE_LIBDIR/ *.lua with the default path
- * (which is read from the package-module) appended -
- * the path for C-modules is as above but it searches for shared libs (*.so) */
- luapath= std::string(path) + "?.lua;";
+/* load an nmap-lua script
+ * create a new closure to store the script
+ * tell the closure where to find the standard
+ * lua libs and the nmap bindings
+ * we do some error checking to make sure that
+ * the script is well formed
+ * the script is then added to either the hostrules
+ * or the portrules
+ * */
+
+/* int loadfile (lua_State *L)
+ *
+ * Arguments
+ * -- filename File to load
+ *
+ * This function loads a file as a new script.
+ * The file is loaded with it's own environment that has access to the Global
+ * Environment. The function is tested to be sure it set a global with a valid
+ * required_fields[?] ("action", "description", ...), port or host rule.
+ * If it did, the script's environment (table) is saved in the global PORTTESTS
+ * or HOSTTESTS table.
+ */
+static int loadfile (lua_State *L)
+{
+ int i;
+ const char *filename = luaL_checkstring(L, 1);
+ static const char *required_fields[] = {ACTION, DESCRIPTION};
+ lua_settop(L, 1); // removes other arguments
+
+ lua_createtable(L, 0, 11); // Environment for script
+
+ lua_pushvalue(L, 1); // tell the script about its 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); // script gets access to global env
+ 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");
+ lua_setmetatable(L, -2);
+
+ // TODO: Allow scripts to modify globals?
+ /* finally we make sure nobody tampers with the global name space any more
+ * and prepare for runlevel sorting
+ */
+ /* lua_getmetatable(L, -1);
+
+ lua_pushliteral(L, "Attempted to change the global '");
+ lua_pushliteral(L, "' in ");
+ lua_pushstring(L, filename);
+ lua_pushliteral(L, " - use nmap.registry if you really want to share "
+ "data between scripts.");
+ lua_concat(L, 3);
+ lua_pushcclosure(L, global_error, 2);
+ lua_setfield(L, -2, "__newindex");
+ lua_pop(L, 1); */
+
+ if (luaL_loadfile(L, filename) != 0) // load the file
+ luaL_error(L, "'%s' could not be loaded!", filename);
+ lua_pushvalue(L, -2); // push environment table
+ lua_setfenv(L, -2); // set it
+ lua_call(L, 0, 0); // Call the function (loads globals)
+
+ /* Check some required fields */
+ for (i = 0; i < ARRAY_LEN(required_fields); i++)
+ {
+ lua_pushstring(L, required_fields[i]);
+ lua_gettable(L, -2);
+ if (lua_isnil(L, -1))
+ luaL_error(L, "No '%s' field in script '%s'.", required_fields[i],
+ filename);
+ lua_pop(L, 1);
+ }
+ /* store the initialized test in either
+ * the hosttests or the porttests
+ */
+ lua_getfield(L, -1, PORTRULE); // script's portrule
+ lua_getfield(L, -2, HOSTRULE); // script's hostrule
+
+ /* if we are looking at a portrule then store it in the porttestsets table,
+ * else if it is a hostrule, then it goes into the hosttestsets table,
+ * otherwise we fail if there.
+ */
+ if (!lua_isnil(L, -2))
+ {
+ lua_pop(L, 2); // pop port/host rules
+ lua_getglobal(L, PORTTESTS); // Get global PORTTESTS table
+ lua_pushvalue(L, -2); // script's environment
+ lua_rawseti(L, -2, lua_objlen(L, -2) + 1); // add it
+ lua_pop(L, 1); // pop the porttests table
+ }
+ else if (!lua_isnil(L, -1))
+ {
+ lua_pop(L, 2);
+ lua_getglobal(L, HOSTTESTS);
+ lua_pushvalue(L, -2);
+ lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
+ lua_pop(L, 1); // pop the hosttests table
+ }
+ else
+ luaL_error(L, "No rules in script '%s'.", filename);
+ return 0;
+}
+
+/* int loaddir (lua_State *L)
+ *
+ * Arguments
+ * -- directory Directory (string) to load.
+ *
+ * Loads all the scripts (files with a .nse extension), using loadfile.
+ */
+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);
+ lua_call(L, 2, 1);
+
+ lua_pushcclosure(L, loadfile, 0);
+ for (i = 1; i <= (int) lua_objlen(L, -2); i++)
+ {
+ lua_pushvalue(L, -1); // loadfile closure
+ lua_rawgeti(L, -3, i); // filename
+ lua_call(L, 1, 0); // load it
+ }
+ return 0;
+}
+
+/* int init_setpath (lua_State *L)
+ *
+ * Sets the search path of require function to include:
+ * ./nselib/ For Lua Path (.lua files)
+ * ./nselib-bin/ For C Path (.so files)
+ */
+static int init_setpath (lua_State *L)
+{
+ char path[MAX_FILENAME_LEN], cpath[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);
+ if (nmap_fetchfile(cpath, MAX_FILENAME_LEN, SCRIPT_ENGINE_LIBEXEC_DIR) != 2)
+ luaL_error(L, "'%s' not a directory", SCRIPT_ENGINE_LIBEXEC_DIR);
+
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ lua_getfield(L, -1, LUA_LOADLIBNAME); /* "package" */
+ lua_pushstring(L, cpath);
#ifdef WIN32
- luacpath= std::string(cpath) + "?.dll;";
+ lua_pushliteral(L, "?.dll;");
#else
- luacpath= std::string(cpath) + "?.so;";
+ lua_pushliteral(L, "?.so;");
#endif
-
- lua_getglobal(l,"package");
- if(!lua_istable(l,-1)){
- error("%s: the lua global-variable package is not a table?!", SCRIPT_ENGINE);
- return SCRIPT_ENGINE_ERROR;
- }
- lua_getfield(l,-1, "path");
- lua_getfield(l,-2, "cpath");
- if(!lua_isstring(l,-1)||!lua_isstring(l,-2)){
- error("%s: no default paths setted in package table (needed in %s at line %d) -- probably a problem of the lua-configuration?!", SCRIPT_ENGINE, __FILE__, __LINE__);
- return SCRIPT_ENGINE_ERROR;
- }
- oldcpath= lua_tostring(l,-1);
- oldpath = lua_tostring(l,-2);
- luacpath= luacpath + oldcpath;
- luapath= luapath + oldpath;
- lua_pop(l,2);
- lua_pushstring(l, luapath.c_str());
- lua_setfield(l, -2, "path");
- lua_pushstring(l, luacpath.c_str());
- lua_setfield(l, -2, "cpath");
- lua_getfield(l,-1, "path");
- lua_getfield(l,-2, "cpath");
- SCRIPT_ENGINE_DEBUGGING(log_write(LOG_STDOUT, "%s: Using %s to search for C-modules and %s for Lua-modules\n", SCRIPT_ENGINE, lua_tostring(l,-1), lua_tostring(l,-2));)
- /*pop the two strings (luapath and luacpath) and the package table off
- * the stack */
- lua_pop(l,3);
- return SCRIPT_ENGINE_SUCCESS;
+ lua_getfield(L, -3, "cpath"); /* package.cpath */
+ lua_concat(L, 3);
+ lua_setfield(L, -2, "cpath");
+
+ lua_pushstring(L, path);
+ lua_pushliteral(L, "?.lua;");
+ lua_getfield(L, -3, "path"); /* package.path */
+ lua_concat(L, 3);
+ lua_setfield(L, -2, "path");
+
+ return 0;
}
-/* 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_lua (lua_State *L)
+ *
+ * Initializes the Lua State.
+ * Opens standard libraries as well as nmap and pcre.
+ * Sets an error function for use by pcall.
+ * Sets the path for require.
*/
-int init_parseargs(lua_State* l){
- //FIXME - free o.script-args after we're finished!!!
-
- if (o.scriptargs==NULL)
- return SCRIPT_ENGINE_SUCCESS; //if no arguments are provided we're done
-
- lua_pushstring(l, o.scriptargs);
- luaL_getmetafield(l, -1, "__index");
- lua_getfield(l, -1, "gsub");
- lua_pushvalue(l, -3);
- lua_pushliteral(l, "=([^{},]+)");
- lua_pushliteral(l, "=\"%1\"");
- SCRIPT_ENGINE_TRY(lua_pcall(l,3,1,0));
- lua_replace(l, 1);
- lua_settop(l,1); //clear stack
-
- return SCRIPT_ENGINE_SUCCESS;
+int init_lua (lua_State *L)
+{
+ int i;
+ static const luaL_Reg libs[] = {
+ {NSE_PCRELIBNAME, luaopen_pcrelib}, // pcre library
+ {"nmap", luaopen_nmap} // nmap bindings
+ };
+
+ luaL_openlibs(L); // opens all standard libraries
+
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); /* Loaded libraries */
+ for (i = 0; i < ARRAY_LEN(libs); i++) // for each in libs
+ {
+ lua_pushstring(L, libs[i].name);
+ lua_pushcclosure(L, libs[i].func, 0);
+ lua_pushvalue(L, -2);
+ lua_call(L, 1, 1);
+ if (lua_isnil(L, -1))
+ {
+ lua_pushboolean(L, 1);
+ lua_replace(L, -2);
+ }
+ lua_settable(L, -3);
+ }
+ lua_getfield(L, -1, "debug"); // _LOADED.debug
+ lua_getfield(L, -1, "traceback");
+ lua_pushcclosure(L, error_function, 1);
+ errfunc = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ lua_pushcclosure(L, init_setpath, 0);
+ lua_call(L, 0, 0);
+
+ lua_newtable(L);
+ current_hosts = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ return 0;
}
-/* set the arguments inside the nmap.registry, for use by scripts
+
+/* int init_parseargs (lua_State *L)
+ *
+ * Arguments
+ * args Arguments passed through --script-args
+ * Returns
+ * function Function that returns a table with the arguments, or an error
+ * message describing why the arguments could not be parsed.
*/
-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_pushliteral(l,"nmap.registry.args={");
- lua_insert(l,-2);
- lua_pushliteral(l,"}");
- lua_concat(l,3);
- argbuf=lua_tolstring(l,-1,&argbuflen);
- luaL_loadbuffer(l,argbuf,argbuflen, "Script-Arguments");
- lua_replace(l, -2); // remove argbuf string
- 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;
-}
-/* if there were no command line arguments specifying
- * which scripts should be run, a default script set is
- * chosen
- * otherwise the script locators given at the command line
- * (either directories with lua files or lua files) are
- * loaded
- * */
-int init_rules(lua_State* l, std::vector chosenScripts) {
- char path[MAX_FILENAME_LEN];
- int type;
- char* c_iter;
- std::vector unusedTags;
-
- lua_newtable(l);
- lua_setglobal(l, PORTTESTS);
-
- lua_newtable(l);
- lua_setglobal(l, HOSTTESTS);
-
- SCRIPT_ENGINE_TRY(init_pick_default_categories(chosenScripts));
-
- // we try to interpret the choices as categories
- SCRIPT_ENGINE_TRY(init_loadcategories(l, chosenScripts, unusedTags));
-
- // if there's more, we try to interpret as directory or file
- std::vector::iterator iter;
- bool extension_not_matched = false;
- for(iter = unusedTags.begin(); iter != unusedTags.end(); iter++) {
-
- c_iter = strdup((*iter).c_str());
- type = init_fetchfile_absolute(path, sizeof(path), c_iter);
- free(c_iter);
-
- if (type == 0) {
- c_iter = strdup((*iter + std::string(SCRIPT_ENGINE_EXTENSION)).c_str());
- type = init_fetchfile_absolute(path, sizeof(path), c_iter);
- free(c_iter);
- }
-
- switch(type) {
- case 0: // no such path
- error("%s: No such category, file or directory: '%s'", SCRIPT_ENGINE, (*iter).c_str());
- return SCRIPT_ENGINE_ERROR;
- break;
- case 1: // nmap_fetchfile returned a file
- if(check_extension(SCRIPT_ENGINE_EXTENSION, path) != MATCH
- && extension_not_matched == false) {
- error("%s: Warning: Loading '%s' - the recommended file extension is '.nse'.",
- SCRIPT_ENGINE, path);
- extension_not_matched = true;
- }
- SCRIPT_ENGINE_TRY(init_loadfile(l, path));
- break;
- case 2: // nmap_fetchfile returned a dir
- SCRIPT_ENGINE_TRY(init_loaddir(l, path));
- break;
- default:
- fatal("%s: In: %s:%i This should never happen.",
- SCRIPT_ENGINE, __FILE__, __LINE__);
- }
- }
-
- // Compute some stats
- SCRIPT_ENGINE_DEBUGGING(
- int rules_count;
-
- lua_getglobal(l, HOSTTESTS);
- rules_count = lua_objlen(l, -1);
-
- lua_getglobal(l, PORTTESTS);
- rules_count += lua_objlen(l, -1);
- lua_pop(l, 2);
- log_write(LOG_STDOUT, "%s: Initialized %d rules\n", SCRIPT_ENGINE, rules_count);
- )
-
- return SCRIPT_ENGINE_SUCCESS;
-}
+int init_parseargs (lua_State *L)
+{
+ const char *arg;
+ size_t len;
+
+ luaL_checkstring(L, 1);
+ luaL_getmetafield(L, 1, "__index"); // string library
+ lua_getfield(L, -1, "gsub"); // string.gsub
+ lua_pushvalue(L, 1);
+ lua_pushliteral(L, "=([^{},]+)"); // make strings quoted
+ lua_pushliteral(L, "=\"%1\"");
+ lua_call(L, 3, 1);
+
+ lua_pushliteral(L, "return {");
+ lua_insert(L, -2);
+ lua_pushliteral(L, "}");
+ lua_concat(L, 3);
+ arg = lua_tolstring(L, -1, &len);
+ luaL_loadbuffer(L, arg, len, "Script-Args");
-class ExtensionalCategory {
-public:
- std::string category;
- int option;
-
- ExtensionalCategory(std::string _category, int _option) {
- category = _category;
- option = _option;
- }
-};
-
-int init_pick_default_categories(std::vector& chosenScripts) {
- std::vector reserved_categories;
- std::vector::iterator rcat_iter;
-
- reserved_categories.push_back(ExtensionalCategory(std::string("version"), o.scriptversion));
-
- // if they tried to explicitely select an implicit category, we complain
- if(o.script) {
- for( rcat_iter = reserved_categories.begin();
- rcat_iter != reserved_categories.end();
- rcat_iter++) {
- if( (*rcat_iter).option == 0
- && std::find(
- chosenScripts.begin(),
- chosenScripts.end(),
- (*rcat_iter).category) != chosenScripts.end())
- fatal("%s: specifying the \"%s\" category explicitly is not allowed.",
- SCRIPT_ENGINE, (*rcat_iter).category.c_str());
- }
- }
-
- // if no scripts were chosen, we use a default set
- if( (o.script == 1
- && chosenScripts.size() == 0) )
- {
- chosenScripts.push_back(std::string("default"));
- }
-
- // we append the implicitely selected categories
- for( rcat_iter = reserved_categories.begin();
- rcat_iter != reserved_categories.end();
- rcat_iter++) {
- if((*rcat_iter).option == 1)
- chosenScripts.push_back((*rcat_iter).category);
- }
-
- return SCRIPT_ENGINE_SUCCESS;
+ return 1; // return function from luaL_loadbuffer or error message returned
}
-int init_updatedb(lua_State* l) {
- char path[MAX_FILENAME_LEN];
- FILE* scriptdb;
- std::vector files;
- std::vector::iterator iter;
- char* c_iter;
-
- if(nmap_fetchfile(path, sizeof(path)-sizeof(SCRIPT_ENGINE_DATABASE)-1, SCRIPT_ENGINE_LUA_DIR) == 0) {
- error("%s: Couldn't find '%s'", SCRIPT_ENGINE, SCRIPT_ENGINE_LUA_DIR);
- return SCRIPT_ENGINE_ERROR;
- }
-
- SCRIPT_ENGINE_TRY(init_scandir(path, files, FILES));
-
- // we rely on the fact that nmap_fetchfile returned a string which leaves enough room
- // to append the db filename (see call to nmap_fetchfile above)
- strncat(path, SCRIPT_ENGINE_DATABASE, MAX_FILENAME_LEN-1);
-
- scriptdb = fopen(path, "w");
- if(scriptdb == NULL) {
- error("%s: Could not open '%s' for writing: %s",
- SCRIPT_ENGINE, path, strerror(errno));
- return SCRIPT_ENGINE_ERROR;
- }
-
- SCRIPT_ENGINE_DEBUGGING(
- log_write(LOG_STDOUT, "%s: Trying to add %d scripts to the database.\n",
- SCRIPT_ENGINE, (int) files.size());
- )
-
- lua_newtable(l);
- /*give the script global namespace access*/
- lua_newtable(l);
- lua_pushvalue(l, LUA_GLOBALSINDEX);
- lua_setfield(l, -2, "__index");
- lua_setmetatable(l, -2);
-
- std::sort(files.begin(), files.end());
-
- for(iter = files.begin(); iter != files.end(); iter++) {
- c_iter = strdup((*iter).c_str());
- if(check_extension(SCRIPT_ENGINE_EXTENSION, c_iter) == MATCH
- && strstr(c_iter, SCRIPT_ENGINE_DATABASE) == NULL) {
-
- SCRIPT_ENGINE_LUA_TRY(luaL_loadfile(l, c_iter));
- lua_pushvalue(l, -2);
- lua_setfenv(l, -2);
- SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0));
-
- lua_getfield(l, -1, "categories");
- if(lua_isnil(l, -1)) {
- error("%s: Script '%s' does not contain any category categories.", SCRIPT_ENGINE, c_iter);
- return SCRIPT_ENGINE_ERROR;
- }
-
- lua_pushnil(l);
- while(lua_next(l, -2) != 0) {
- char *filename = path_get_basename(c_iter);
- if (filename == NULL) {
- error("%s: Could not allocate temporary memory.", SCRIPT_ENGINE);
- return SCRIPT_ENGINE_ERROR;
- }
- fprintf(scriptdb,
- "Entry{ category = \"%s\", filename = \"%s\" }\n",
- lua_tostring(l, -1), filename);
- free(filename);
- lua_pop(l, 1);
- }
- lua_pop(l, 1); // pop the categories table
- }
-
- free(c_iter);
- }
- lua_pop(l, 1); // pop the closure
-
- if(fclose(scriptdb) != 0) {
- error("%s: Could not close %s: %s", SCRIPT_ENGINE, path, strerror(errno));
- return SCRIPT_ENGINE_ERROR;
- }
-
- return SCRIPT_ENGINE_SUCCESS;
-}
+/* int init_setargs (lua_State *L)
+ *
+ * Takes the function returned by init_parseargs(), calls it, and puts
+ * the returned table in nmap.registry.args
+ */
+int init_setargs (lua_State *L)
+{
+ if (o.scriptargs == NULL)
+ return 0;
-int init_loadcategories(lua_State* l, std::vector categories, std::vector &unusedTags) {
- std::vector::iterator iter;
- std::vector files;
- std::string dbpath = std::string(SCRIPT_ENGINE_LUA_DIR) + std::string(SCRIPT_ENGINE_DATABASE);
- char* c_dbpath_buf;
- char c_dbpath[MAX_FILENAME_LEN];
- const char* stub = "\
-files = {}\n\
-Entry = function(e)\n\
- if (categories[e.category] ~= nil) then\n\
- categories[e.category] = categories[e.category] + 1\n\
- files[e.filename] = true\n\
- end\n\
- if (categories[\"all\"] ~= nil and e.category ~= \"version\") then\n\
- categories[\"all\"] = categories[\"all\"] + 1\n\
- files[e.filename] = true\n\
- end\n\
-end\n";
- int categories_usage;
- char* c_iter;
- char script_path[MAX_FILENAME_LEN];
- int type;
-
- // closure
- lua_newtable(l);
-
- // categories table
- lua_newtable(l);
- for(iter = categories.begin(); iter != categories.end(); iter++) {
- lua_pushinteger(l, 0);
- lua_setfield(l, -2, (*iter).c_str());
- }
- lua_setfield(l, -2, "categories");
-
- // we load the stub
- // the strlen is safe in this case because the stub is a constant string
- SCRIPT_ENGINE_LUA_TRY(luaL_loadbuffer(l, stub, strlen(stub), "Database Stub"));
- lua_pushvalue(l, -2);
- lua_setfenv(l, -2);
- SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0));
-
- // if we can't find the database we try to create it
- c_dbpath_buf = strdup(dbpath.c_str());
- if(nmap_fetchfile(c_dbpath, sizeof(c_dbpath), c_dbpath_buf) == 0) {
- SCRIPT_ENGINE_TRY(init_updatedb(l));
- }
- free(c_dbpath_buf);
-
- SCRIPT_ENGINE_LUA_TRY(luaL_loadfile(l, c_dbpath));
- lua_pushvalue(l, -2);
- lua_setfenv(l, -2);
- SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0));
-
- // retrieve the filenames produced by the stub
- lua_getfield(l, -1, "files");
- lua_pushnil(l);
- while(lua_next(l, -2) != 0) {
- if(lua_isstring(l, -2))
- files.push_back(std::string(lua_tostring(l, -2)));
- else {
- error("%s: One of the filenames in '%s' is not a string?!",
- SCRIPT_ENGINE,
- SCRIPT_ENGINE_DATABASE);
- return SCRIPT_ENGINE_ERROR;
- }
- lua_pop(l, 1);
- }
- lua_pop(l, 1);
-
- // find out which categories didn't produce any filenames
- lua_getfield(l, -1, "categories");
- lua_pushnil(l);
- while(lua_next(l, -2) != 0) {
- categories_usage = lua_tointeger(l, -1);
- if(categories_usage == 0) {
- unusedTags.push_back(std::string(lua_tostring(l, -2)));
- }
- lua_pop(l, 1);
- }
- lua_pop(l, 2);
-
- // load all the files we have found for the given categories
- for(iter = files.begin(); iter != files.end(); iter++) {
- c_iter = strdup((*iter).c_str());
- type = init_fetchfile(script_path, sizeof(script_path), c_iter);
-
- if(type != 1) {
- error("%s: %s is not a file.", SCRIPT_ENGINE, c_iter);
- return SCRIPT_ENGINE_ERROR;
- }
-
- free(c_iter);
-
- SCRIPT_ENGINE_TRY(init_loadfile(l, script_path));
- }
-
- return SCRIPT_ENGINE_SUCCESS;
-}
+ lua_getglobal(L, "nmap");
+ lua_getfield(L, -1, "registry");
-int init_fetchfile(char *path, size_t path_len, char* file) {
- int type;
+ lua_pushcclosure(L, init_parseargs, 0);
+ lua_pushstring(L, o.scriptargs);
+ lua_call(L, 1, 1);
- type = nmap_fetchfile(path, path_len, file);
+ if (!lua_isfunction(L, -1))
+ luaL_error(L, "Bad script arguments!\n\t%s", lua_tostring(L, -1));
- // lets look in /scripts too
- if(type == 0) {
- char* alt_path = strdup((std::string(SCRIPT_ENGINE_LUA_DIR) + std::string(file)).c_str());
- type = nmap_fetchfile(path, path_len, alt_path);
- free(alt_path);
-
- }
+ lua_call(L, 0, 1); /* get returned table */
- return type;
+ lua_setfield(L, -2, "args");
+
+ return 0;
}
-static bool filename_is_absolute(const char *file) {
- if (file[0] == '/')
- return true;
-#ifdef WIN32
- if ((file[0] != '\0' && file[1] == ':') || file[0] == '\\')
- return true;
-#endif
- return false;
+/* int init_updatedb (lua_State *L)
+ *
+ * Loads all the files in ./scripts and puts them in the database.
+ * Each file is loaded and for each of its categories, an entry in the
+ * database is made in the following format:
+ * Entry{ category = "category1", filename = "somefile" }\n"
+ * Entry{ category = "category2", filename = "somefile" }\n"
+ * Each file will have an entry per category.
+ */
+int init_updatedb (lua_State *L)
+{
+ int i;
+ char path[MAX_FILENAME_LEN];
+ FILE *scriptdb;
+ lua_settop(L, 0); // clear all args
+
+ if (nmap_fetchfile(path, sizeof(path) - sizeof(SCRIPT_ENGINE_DATABASE),
+ SCRIPT_ENGINE_LUA_DIR) == 0)
+ luaL_error(L, "Couldn't find '%s'", SCRIPT_ENGINE_LUA_DIR);
+
+ lua_pushcclosure(L, nse_scandir, 0);
+ lua_pushstring(L, path);
+ lua_pushinteger(L, FILES);
+ lua_call(L, 2, 1); // get all the .nse files in ./scripts
+
+ // we rely on the fact that nmap_fetchfile returned a string which leaves enough room
+ // to append the db filename (see call to nmap_fetchfile above)
+ strncat(path, SCRIPT_ENGINE_DATABASE, MAX_FILENAME_LEN-1);
+
+ scriptdb = fopen(path, "w");
+ if (scriptdb == NULL)
+ 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",
+ SCRIPT_ENGINE, lua_objlen(L, 1));
+ )
+
+ // give the script global namespace access
+ lua_createtable(L, 0, 1); // metatable
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ lua_setfield(L, -2, "__index");
+
+ for (i = 1; i <= (int) lua_objlen(L, 1); i++)
+ {
+ const char *file;
+ lua_rawgeti(L, 1, i); // integer key from scan_dir() table
+ file = lua_tostring(L, -1);
+ if (nse_check_extension(SCRIPT_ENGINE_EXTENSION, file) &&
+ strstr(file, SCRIPT_ENGINE_DATABASE) == NULL)
+ {
+ char *filebase = path_get_basename(file);
+ lua_newtable(L); // script environment
+ lua_pushvalue(L, -3); // script metatable
+ lua_setmetatable(L, -2); // set it
+ luaL_loadfile(L, file); // load file
+ lua_pushvalue(L, -2); // push environment
+ lua_setfenv(L, -2); // set it
+ lua_call(L, 0, 0);
+
+ lua_getfield(L, -1, "categories");
+ if (lua_isnil(L, -1))
+ luaL_error(L, "Script, '%s', being added to the database "
+ "has no categories.", file);
+
+ if (filebase == NULL)
+ luaL_error(L, "filename basename could not be generated");
+
+ lua_pushnil(L);
+ while (lua_next(L, -2) != 0)
+ {
+ fprintf(scriptdb, "Entry{ category = \"%s\", filename = \"%s\" }\n",
+ lua_tostring(L, -1), filebase);
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 2); // script environment and categories
+ free(filebase);
+ }
+ lua_pop(L, 1); // filename
+ }
+
+ if (fclose(scriptdb) != 0)
+ luaL_error(L, "Could not close script.db: %s.", strerror(errno));
+
+ return 0;
}
-/* This is a modification of init_fetchfile that first looks for an
- * absolute file name.
+typedef struct extensional_category {
+ char *category;
+ int option;
+} extensional_category;
+
+/* int pick_default_categories (lua_State *L)
+ *
+ * The function is passed all the scripts/directories/categories passed
+ * through --scripts argument. For each of these, we check if a reserved
+ * category (currently "version") has been chosen, and raise a fatal error
+ * if so. Finally the reserved categories are added. Basically, explicitly
+ * adding the reserved categories is illegal.
*/
-int init_fetchfile_absolute(char *path, size_t path_len, 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 init_fetchfile(path, path_len, file);
+static int pick_default_categories (lua_State *L)
+{
+ int i, top = lua_gettop(L);
+ extensional_category reserved_categories[] = {
+ {"version", o.scriptversion},
+ };
+
+ if (top > 0)
+ {
+ // if they tried to explicitely select an implicit category, we complain
+ // ... for each in reserved_categories
+ for (i = 0; i < ARRAY_LEN(reserved_categories); i++)
+ {
+ int j;
+ lua_pushstring(L, reserved_categories[i].category);
+ for (j = 1; j <= top; j++)
+ if (lua_equal(L, j, -1))
+ {
+ fatal("%s: specifying the \"%s\" category explicitly is not allowed.",
+ SCRIPT_ENGINE, lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ }
+ }
+ else if (o.script == 1)
+ {
+ // default set of categories
+ lua_pushliteral(L, "default");
+ }
+
+ // for each in reserved_categories
+ for (i = 0; i < ARRAY_LEN(reserved_categories); i++)
+ if (reserved_categories[i].option == 1)
+ lua_pushstring(L, reserved_categories[i].category);
+
+ return lua_gettop(L);
}
-/* This is simply the most portable way to check
- * if a file has a given extension.
- * The portability comes at the price of reduced
- * flexibility.
+/* int entry (lua_State *L)
+ *
+ * This function is called from the script.db file. It has two upvalues:
+ * [1] Categories The categories/files/directories passed via --script.
+ * [2] Files The Files currently loaded (initially an empty table).
+ * A table is passed from the script database with a category and filename.
+ * The function tests if either the script's (filename's) category was chosen
+ * by checking [1]. Or, it loads the file if [1] has the 'category' "all" and
+ * the script's category is not "version".
*/
-int check_extension(const char* ext, const char* path) {
- int pathlen = strlen(path);
- int extlen = strlen(ext);
- const char* offset;
-
- if( extlen > pathlen
- || pathlen > MAX_FILENAME_LEN)
- return -1;
-
- offset = path + pathlen - extlen;
-
- if(strcmp(offset, ext) != MATCH)
- return 1;
- else
- return MATCH;
+static int entry (lua_State *L)
+{
+ char script_path[MAX_FILENAME_LEN];
+ int not_all;
+
+ luaL_checktype(L, 1, LUA_TTABLE); // Sole argument is a table
+ lua_settop(L, 1);
+ lua_getfield(L, 1, "category"); // index 2
+ lua_getfield(L, 1, "filename"); // index 3
+ if (!(lua_isstring(L, 2) && lua_isstring(L, 3)))
+ luaL_error(L, "bad entry in script database");
+ lua_pushvalue(L, 3); // filename
+ lua_gettable(L, lua_upvalueindex(2)); // already loaded?
+ if (!lua_isnil(L, -1))
+ return 0;
+ lua_pushvalue(L, 2); // category
+ lua_gettable(L, lua_upvalueindex(1)); // check 1
+ lua_pushliteral(L, "version"); // check 2
+ lua_getfield(L, lua_upvalueindex(1), "all"); // check 3
+
+ // if category chosen OR category != "version" and [1].all exists
+ if ((not_all = (!lua_isnil(L, -3))) ||
+ (!(lua_isnil(L, -1) || lua_equal(L, 2, -2))))
+ {
+ if (not_all)
+ lua_pushvalue(L, 2);
+ else
+ lua_pushliteral(L, "all");
+ lua_pushboolean(L, 1); // set category to true
+ lua_settable(L, lua_upvalueindex(1));
+
+ if (nse_fetchfile(script_path, sizeof(script_path),
+ lua_tostring(L, 3)) != 1)
+ luaL_error(L, "%s: %s is not a file!", lua_tostring(L, 3));
+
+ lua_pushvalue(L, 3); // filename
+ lua_pushboolean(L, 1);
+ lua_settable(L, lua_upvalueindex(2)); // loaded
+ lua_pushcclosure(L, loadfile, 0);
+ lua_pushstring(L, script_path);
+ lua_call(L, 1, 0);
+ }
+ return 0;
}
-int init_loaddir(lua_State* l, char* dirname) {
- std::vector files;
- char* c_iter;
+/* int loadcategories (lua_State *L)
+ *
+ * This function takes all the categories/scripts/directories
+ * passed to it and puts them in a table.
+ * This table along with an empty one are used as upvalues to the
+ * Entry closure (see entry above). Finally, the ./scripts/script.db
+ * file is loaded and it's environment set to only include the Entry
+ * closure. The entry function will do the work to load all script files with
+ * chosen categories. After the script database is executed. Any remainining
+ * fields (files/directories and possibly unused categories) are left in the
+ * table to be handled later.
+ */
+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;
- SCRIPT_ENGINE_TRY(init_scandir(dirname, files, FILES));
-
- std::vector::iterator iter;
- for(iter = files.begin(); iter != files.end(); iter++) {
- c_iter = strdup((*iter).c_str());
- SCRIPT_ENGINE_TRY(init_loadfile(l, c_iter));
- free(c_iter);
- }
+ if (nmap_fetchfile(c_dbpath, sizeof(c_dbpath), dbpath) == 0)
+ {
+ lua_pushcclosure(L, init_updatedb, 0);
+ lua_call(L, 0, 0);
+ }
- return SCRIPT_ENGINE_SUCCESS;
-}
+ lua_createtable(L, 0, top); // categories table
+ for (i = 1; i <= top; i++)
+ {
+ lua_pushvalue(L, i); // category/files/directory
+ lua_pushboolean(L, 0); // false (not used)
+ lua_settable(L, -3);
+ }
-#ifdef WIN32
+ luaL_loadfile(L, c_dbpath);
+ lua_createtable(L, 0, 1);
+ lua_pushliteral(L, "Entry");
+ lua_pushvalue(L, -4); // categories table
+ lua_newtable(L); // files loaded
+ lua_pushcclosure(L, entry, 2);
+ lua_settable(L, -3);
+ lua_setfenv(L, -2);
+ lua_call(L, 0, 0); // Let errors go through
+
+ lua_pushnil(L);
+ while (lua_next(L, -2) != 0)
+ {
+ if (lua_toboolean(L, -1)) // category was used?
+ {
+ lua_pushvalue(L, -2);
+ lua_pushnil(L);
+ lua_settable(L, -5); // remove the category
+ }
+ lua_pop(L, 1);
+ }
-int init_scandir(char* dirname, std::vector& result, int files_or_dirs) {
- HANDLE dir;
- WIN32_FIND_DATA entry;
- std::string path;
- BOOL morefiles = FALSE;
-
- 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(!(
- (check_extension(SCRIPT_ENGINE_EXTENSION, entry.cFileName) == MATCH)
- && !(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);
- result.push_back(path);
- morefiles = FindNextFile(dir, &entry);
- }
-
-
- return SCRIPT_ENGINE_SUCCESS;
+ return 1; // unused tags (what's left in categories table)
}
-#else
+/* int init_rules (lua_State *L)
+ *
+ * Arguments
+ * ... All the categories/scripts/directories passed via --script
+ *
+ * This function adds the PORTTESTS and HOSTTESTS globals to the main state.
+ * Then it calls pick_default_categories to check for illegally passed implicit
+ * categories (which it will add otherwise). Next, loadcategories is called
+ * to load all the viable files for which a category was chosen. The unused
+ * tags (files/directories, and possibly unused or invalid categories) are
+ * then each loaded (attempted). If any do not load then an error is raised.
+ */
+int init_rules (lua_State *L)
+{
+ int top = lua_gettop(L); // number of categories/scripts
-int init_scandir(char* dirname, std::vector& result, int files_or_dirs) {
- DIR* dir;
- struct dirent* entry;
- std::string path;
- struct stat stat_entry;
-
- 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) {
- 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(!(
- (check_extension(SCRIPT_ENGINE_EXTENSION, entry->d_name) == MATCH)
- && (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
- result.push_back(path);
- }
-
- closedir(dir);
-
- return SCRIPT_ENGINE_SUCCESS;
-}
+ lua_newtable(L);
+ lua_setglobal(L, PORTTESTS);
-#endif
+ lua_newtable(L);
+ lua_setglobal(L, HOSTTESTS);
-/* Error function if a user script attempts to create a new global */
-/* TODO: Why wasn't _changing_ globals handled? */
-static int global_error(lua_State *L)
-{
- lua_pushvalue(L, lua_upvalueindex(1));
- lua_pushvalue(L, 2);
- if (!lua_tostring(L, -1))
+ lua_pushcclosure(L, pick_default_categories, 0);
+ lua_insert(L, 1);
+ lua_call(L, top, LUA_MULTRET);
+ top = lua_gettop(L); // new number of categories & scripts
+
+ lua_pushcclosure(L, loadcategories, 0);
+ lua_insert(L, 1);
+ lua_call(L, top, 1); // returns unused tags table
+
+ lua_pushcclosure(L, loadfile, 0);
+ lua_pushnil(L);
+ while (lua_next(L, -3) != 0)
{
- lua_pushliteral(L, "? (of type ");
- lua_pushstring(L, lua_typename(L, lua_type(L, -2)));
- lua_pushliteral(L, ")");
- lua_concat(L, 3);
- lua_replace(L, -2);
+ char path[MAX_FILENAME_LEN];
+ int type = nse_fetchfile_absolute(path, sizeof(path),
+ lua_tostring(L, -2));
+
+ if (type == 0)
+ {
+ lua_pushvalue(L, -2); // copy of key
+ lua_pushliteral(L, SCRIPT_ENGINE_EXTENSION);
+ lua_concat(L, 2);
+ lua_replace(L, -2); // remove value
+ type = nse_fetchfile_absolute(path, sizeof(path), lua_tostring(L, -1));
+ }
+
+ switch (type)
+ {
+ case 0: // no such path
+ luaL_error(L, "No such category, file or directory: '%s'",
+ lua_tostring(L, -2));
+ case 1: // nmap_fetchfile returned a file
+ if (!nse_check_extension(SCRIPT_ENGINE_EXTENSION, path))
+ {
+ error("%s: Warning: Loading '%s' - the recommended file extension is '.nse'.",
+ SCRIPT_ENGINE, path);
+ }
+ lua_pushvalue(L, -3); // loadfile closure
+ lua_pushstring(L, path);
+ lua_call(L, 1, 0);
+ break;
+ case 2: // nmap_fetchfile returned a dir
+ lua_pushcclosure(L, loaddir, 0);
+ lua_pushstring(L, path);
+ lua_call(L, 1, 0);
+ break;
+ default:
+ fatal("%s: In: %s:%i This should never happen.",
+ SCRIPT_ENGINE, __FILE__, __LINE__);
+ }
+ lua_pop(L, 1);
}
- lua_pushvalue(L, lua_upvalueindex(2));
- lua_concat(L, 3);
- fprintf(stderr, "%s\n", lua_tostring(L, -1));
- return lua_error(L);
-}
-/* load an nmap-lua script
- * create a new closure to store the script
- * tell the closure where to find the standard
- * lua libs and the nmap bindings
- * we do some error checking to make sure that
- * the script is well formed
- * the script is then added to either the hostrules
- * or the portrules
- * */
-int init_loadfile(lua_State* l, char* filename) {
- int rule_count;
-
- /* create a closure for encapsuled execution
- * give the closure access to the global enviroment
- */
- lua_newtable(l);
-
- /* tell the script about its filename */
- lua_pushstring(l, filename);
- lua_setfield(l, -2, "filename");
-
- /* we give the script access to the global name space
- * */
- lua_newtable(l);
- lua_pushvalue(l, LUA_GLOBALSINDEX);
- lua_setfield(l, -2, "__index");
- lua_setmetatable(l, -2);
-
- /* load the *.nse file, set the closure and execute (init) the test
- * */
- SCRIPT_ENGINE_LUA_TRY(luaL_loadfile(l, filename));
- lua_pushvalue(l, -2);
- lua_setfenv(l, -2);
- SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 0, 0, 0));
-
- /* look at the runlevel, if it is not set, we set it to 1.0
- * */
- lua_getfield(l, -1, RUNLEVEL);
- if(lua_isnil(l, -1)) {
- lua_pushnumber(l, 1.0);
- lua_setfield(l, -3, RUNLEVEL);
- }
- lua_pop(l, 1);
-
- /* finally we make sure nobody tampers with the global name space any more
- * and prepare for runlevel sorting
- * */
- lua_getmetatable(l, -1);
-
- lua_pushliteral(l, "Attempted to change the global '");
- lua_pushliteral(l, "' in ");
- lua_pushstring(l, filename);
- lua_pushliteral(l, " - use nmap.registry if you really want to share "
- "data between scripts.");
- lua_concat(l, 3);
- lua_pushcclosure(l, global_error, 2);
- lua_setfield(l, -2, "__newindex");
-
- lua_setmetatable(l, -2);
-
- /* store the initialized test in either
- * the hosttests or the porttests
- * */
- lua_getfield(l, -1, PORTRULE);
- lua_getfield(l, -2, HOSTRULE);
-
- /* if we are looking at a portrule then store it in the porttestsets table
- * if it is a hostrule, then it goes into the hosttestsets table
- * otherwise we fail
- * if there is no action in the script we also fail
- * */
- if(lua_isnil(l, -2) == 0) {
- lua_pop(l, 2);
- lua_getglobal(l, PORTTESTS);
- rule_count = lua_objlen(l, -1);
- lua_pushvalue(l, -2);
- lua_rawseti(l, -2, (rule_count + 1));
- lua_pop(l, 1); // pop the porttests table
- } else if(lua_isnil(l, -1) == 0) {
- lua_pop(l, 2);
- lua_getglobal(l, HOSTTESTS);
- rule_count = lua_objlen(l, -1);
- lua_pushvalue(l, -2);
- lua_rawseti(l, -2, (rule_count + 1));
- lua_pop(l, 1); // pop the hosttests table
- } else {
- error("%s: No rules in script '%s'.", SCRIPT_ENGINE, filename);
- return SCRIPT_ENGINE_ERROR;
- }
-
- std::vector required_fields;
- required_fields.push_back(std::string(ACTION));
- required_fields.push_back(std::string(DESCRIPTION));
-
- std::vector::iterator iter;
- for(iter = required_fields.begin(); iter != required_fields.end(); iter++) {
- lua_getfield(l, -1, (*iter).c_str());
- if(lua_isnil(l, -1) == 1) {
- error("%s: No '%s' field in script '%s'.", SCRIPT_ENGINE, (*iter).c_str(), filename);
- return SCRIPT_ENGINE_ERROR;
- }
- lua_pop(l, 1); // pop the action
- }
-
-
- lua_pop(l, 1); // pop the closure
-
- return SCRIPT_ENGINE_SUCCESS;
+ // Compute some stats
+ SCRIPT_ENGINE_DEBUGGING(
+ int rules_count;
+
+ lua_getglobal(L, HOSTTESTS);
+ rules_count = lua_objlen(L, -1);
+
+ lua_getglobal(L, PORTTESTS);
+ rules_count += lua_objlen(L, -1);
+ lua_pop(L, 2);
+ log_write(LOG_STDOUT, "%s: Initialized %d rules\n", SCRIPT_ENGINE, rules_count);
+ )
+ return 0;
}
-
diff --git a/nse_init.h b/nse_init.h
index 83d1d4f3fc..ac9f52dcf6 100644
--- a/nse_init.h
+++ b/nse_init.h
@@ -13,19 +13,18 @@ extern "C" {
// initialize the lua state
// opens the standard libraries and the nmap lua library
-int init_lua(lua_State* l);
+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);
+int init_parseargs(lua_State* L);
//sets the previously parsed args inside nmap.registry
-int init_setargs(lua_State* l);
+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
-int init_rules(lua_State* l, std::vector chosenScripts);
-int init_updatedb(lua_State* l);
+int init_rules(lua_State *L);
+int init_updatedb(lua_State* L);
#endif
-
diff --git a/nse_macros.h b/nse_macros.h
index 07e89d132a..e099a24793 100644
--- a/nse_macros.h
+++ b/nse_macros.h
@@ -32,7 +32,7 @@
#define SCRIPT_ENGINE_EXTENSION ".nse"
#define SCRIPT_ENGINE_LUA_TRY(func) if (func != 0) {\
- error("LUA INTERPRETER in %s:%d: %s", __FILE__, __LINE__, (char *)lua_tostring(l, -1));\
+ error("LUA INTERPRETER in %s:%d: %s", __FILE__, __LINE__, (char *)lua_tostring(L, -1));\
return SCRIPT_ENGINE_LUA_ERROR;\
}
@@ -40,10 +40,11 @@
return SCRIPT_ENGINE_ERROR;\
}
+#define ARRAY_LEN(a) ((int)(sizeof(a) / sizeof(a[0])))
+
#define SCRIPT_ENGINE_VERBOSE(msg) if (o.debugging || o.verbose > 0) {msg};
#define SCRIPT_ENGINE_DEBUGGING(msg) if (o.debugging) {msg};
-#define MATCH 0
#define MAX_FILENAME_LEN 4096
#define NOT_PRINTABLE '.'
diff --git a/nse_main.cc b/nse_main.cc
index 1c04fa6d32..c6b4435cc9 100644
--- a/nse_main.cc
+++ b/nse_main.cc
@@ -39,7 +39,8 @@ struct thread_record {
run_record* rr;
};
-std::map current_hosts;
+int current_hosts = 0;
+int errfunc = 0;
std::list > torun_scripts;
std::list running_scripts;
std::list waiting_scripts;
@@ -53,88 +54,118 @@ class CompareRunlevels {
// prior execution
int process_preparerunlevels(std::list torun_threads);
-int process_preparehost(lua_State* l, Target* target, std::list& torun_threads);
-int process_preparethread(lua_State* l, struct run_record rr, struct thread_record* tr);
+int process_preparehost(lua_State* L, Target* target, std::list& torun_threads);
+int process_preparethread(lua_State* L, struct run_record rr, struct thread_record* tr);
// helper functions
-int process_getScriptId(lua_State* l, struct script_scan_result* ssr);
+int process_getScriptId(lua_State* L, struct script_scan_result* ssr);
int process_pickScriptsForPort(
- lua_State* l,
+ lua_State* L,
Target* target,
Port* port,
std::vector& torun);
// execution
-int process_mainloop(lua_State* l);
-int process_waiting2running(lua_State* l, int resume_arguments);
-int process_finalize(lua_State* l, unsigned int registry_idx);
-
-int script_updatedb() {
- int status;
- lua_State* l;
-
- SCRIPT_ENGINE_VERBOSE(
- log_write(LOG_STDOUT, "%s: Updating rule database.\n",
- SCRIPT_ENGINE);
- )
-
- l = luaL_newstate();
- if(l == NULL) {
- error("%s: Failed luaL_newstate()", SCRIPT_ENGINE);
- return 0;
- }
-
- status = init_lua(l);
- if(status != SCRIPT_ENGINE_SUCCESS) {
- goto finishup;
- }
-
- status = init_updatedb(l);
- if(status != SCRIPT_ENGINE_SUCCESS) {
- goto finishup;
- }
-
- log_write(LOG_STDOUT, "NSE script database updated successfully.\n");
+int process_mainloop(lua_State* L);
+int process_waiting2running(lua_State* L, int resume_arguments);
+int process_finalize(lua_State* L, unsigned int registry_idx);
+
+static int panic (lua_State *L)
+{
+ const char *err = lua_tostring(L, 1);
+ fatal("Unprotected error in Lua:\n%s\n", err);
+ return 0;
+}
-finishup:
- lua_close(l);
- if(status != SCRIPT_ENGINE_SUCCESS) {
- error("%s: Aborting database update.\n", SCRIPT_ENGINE);
- return SCRIPT_ENGINE_ERROR;
- } else {
- return SCRIPT_ENGINE_SUCCESS;
- }
+int script_updatedb (void)
+{
+ int status;
+ int ret;
+ lua_State *L;
+
+ SCRIPT_ENGINE_VERBOSE(
+ log_write(LOG_STDOUT, "%s: Updating rule database.\n",
+ SCRIPT_ENGINE);
+ )
+
+ L = luaL_newstate();
+ if (L == NULL)
+ {
+ error("%s: Failed luaL_newstate()", SCRIPT_ENGINE);
+ 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));
+ ret = SCRIPT_ENGINE_ERROR;
+ goto finishup;
+ }
+
+ lua_settop(L, 0); // safety, is 0 anyway
+ lua_rawgeti(L, LUA_REGISTRYINDEX, errfunc); // index 1
+
+ lua_pushcclosure(L, init_updatedb, 0);
+ status = lua_pcall(L, 0, 0, 1);
+ if(status != 0)
+ {
+ error("%s: error while updating Script Database:\n%s\n",
+ SCRIPT_ENGINE, lua_tostring(L, -1));
+ 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)
+ {
+ error("%s: Aborting database update.\n", SCRIPT_ENGINE);
+ return SCRIPT_ENGINE_ERROR;
+ }
+ else
+ return SCRIPT_ENGINE_SUCCESS;
}
-//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= luaL_newstate();
- 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;
+int script_check_args (void)
+{
+ int ret = SCRIPT_ENGINE_SUCCESS, status;
+ lua_State* L = luaL_newstate();
+
+ if (L == NULL)
+ fatal("Error opening lua, for checking arguments\n");
+ lua_atpanic(L, panic);
+
+ /* set all global libraries (we'll need the string-lib) */
+ 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));
+ ret = SCRIPT_ENGINE_ERROR;
+ goto finishup;
+ }
+
+ lua_pushcclosure(L, init_parseargs, 0);
+ lua_pushstring(L, o.scriptargs);
+ lua_pcall(L, 1, 1, 0);
+
+ if (!lua_isfunction(L, -1))
+ ret = SCRIPT_ENGINE_ERROR;
+
+ finishup:
+ lua_close(L);
+ return ret;
}
+
/* open a lua instance
* open the lua standard libraries
* open all the scripts and prepare them for execution
@@ -147,7 +178,8 @@ int script_scan(std::vector &targets) {
std::list >::iterator runlevel_iter;
std::list::iterator thr_iter;
std::list torun_threads;
- lua_State* l;
+ std::vector::iterator script_iter;
+ lua_State* L;
o.current_scantype = SCRIPT_SCAN;
@@ -166,34 +198,66 @@ int script_scan(std::vector &targets) {
SCRIPT_ENGINE, (*targets.begin())->NameIP(targetstr, sizeof(targetstr)));
)
- l = luaL_newstate();
- if(l == NULL) {
+ L = luaL_newstate();
+ if(L == NULL) {
error("%s: Failed luaL_newstate()", SCRIPT_ENGINE);
- return 0;
+ return SCRIPT_ENGINE_ERROR;
}
+ lua_atpanic(L, panic);
- status = init_lua(l);
- if(status != SCRIPT_ENGINE_SUCCESS) {
- goto finishup;
- }
- //set the arguments - if provided
- status = init_setargs(l);
- if(status != SCRIPT_ENGINE_SUCCESS) {
- goto finishup;
- }
+ 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 = init_rules(l, o.chosenScripts);
- if(status != SCRIPT_ENGINE_SUCCESS) {
- goto finishup;
- }
+ //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 initializing script rules:\n%s\n",
+ SCRIPT_ENGINE, lua_tostring(L, -1));
+ status = SCRIPT_ENGINE_ERROR;
+ 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();
- current_hosts[key] = (Target*) *target_iter;
+ 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);
+ status = process_preparehost(L, *target_iter, torun_threads);
if(status != SCRIPT_ENGINE_SUCCESS){
goto finishup;
}
@@ -222,7 +286,7 @@ int script_scan(std::vector &targets) {
if (!thr_iter->rr->host->timeOutClockRunning())
thr_iter->rr->host->startTimeOutClock(NULL);
- status = process_mainloop(l);
+ status = process_mainloop(L);
if(status != SCRIPT_ENGINE_SUCCESS){
goto finishup;
}
@@ -233,8 +297,7 @@ int script_scan(std::vector &targets) {
SCRIPT_ENGINE_DEBUGGING(
log_write(LOG_STDOUT, "%s: Script scanning completed.\n", SCRIPT_ENGINE);
)
- lua_close(l);
- current_hosts.clear();
+ lua_close(L);
torun_scripts.clear();
if(status != SCRIPT_ENGINE_SUCCESS) {
error("%s: Aborting script scan.", SCRIPT_ENGINE);
@@ -244,7 +307,7 @@ int script_scan(std::vector &targets) {
}
}
-int process_mainloop(lua_State* l) {
+int process_mainloop(lua_State *L) {
int state;
int unfinished = running_scripts.size() + waiting_scripts.size();
struct script_scan_result ssr;
@@ -333,8 +396,8 @@ int process_mainloop(lua_State* l) {
lua_pop(current.thread, 2);
}
- SCRIPT_ENGINE_TRY(process_finalize(l, current.registry_idx));
- SCRIPT_ENGINE_TRY(lua_gc(l, LUA_GCCOLLECT, 0));
+ SCRIPT_ENGINE_TRY(process_finalize(L, current.registry_idx));
+ SCRIPT_ENGINE_TRY(lua_gc(L, LUA_GCCOLLECT, 0));
} else {
// this script returned because of an error
// print the failing reason if the verbose level is high enough
@@ -342,7 +405,7 @@ int process_mainloop(lua_State* l) {
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));
+ SCRIPT_ENGINE_TRY(process_finalize(L, current.registry_idx));
}
} // while
}
@@ -368,8 +431,8 @@ int has_target_finished(Target *target) {
return 1;
}
-int process_finalize(lua_State* l, unsigned int registry_idx) {
- luaL_unref(l, LUA_REGISTRYINDEX, registry_idx);
+int process_finalize(lua_State* L, unsigned int registry_idx) {
+ luaL_unref(L, LUA_REGISTRYINDEX, registry_idx);
struct thread_record thr = running_scripts.front();
running_scripts.pop_front();
@@ -380,12 +443,12 @@ int process_finalize(lua_State* l, unsigned int registry_idx) {
return SCRIPT_ENGINE_SUCCESS;
}
-int process_waiting2running(lua_State* l, int resume_arguments) {
+int process_waiting2running(lua_State* L, int resume_arguments) {
std::list::iterator iter;
// find the lua state which has received i/o
for( iter = waiting_scripts.begin();
- (*iter).thread != l;
+ (*iter).thread != L;
iter++) {
// It is very unlikely that a thread which
@@ -417,23 +480,23 @@ int process_waiting2running(lua_State* l, int resume_arguments) {
* if no 'id' field is found, the filename field is used which we set in the
* setup phase. If someone changed the filename field to a nonstring we complain
* */
-int process_getScriptId(lua_State* l, struct script_scan_result *ssr) {
+int process_getScriptId(lua_State* L, struct script_scan_result *ssr) {
- lua_getfield(l, -2, "id");
- lua_getfield(l, -3, "filename");
+ lua_getfield(L, -2, "id");
+ lua_getfield(L, -3, "filename");
- if(lua_isstring(l, -2)) {
- ssr->id = strdup(lua_tostring (l, -2));
- } else if(lua_isstring(l, -1)) {
- ssr->id = strdup(lua_tostring (l, -1));
+ if(lua_isstring(L, -2)) {
+ ssr->id = strdup(lua_tostring (L, -2));
+ } else if(lua_isstring(L, -1)) {
+ ssr->id = strdup(lua_tostring (L, -1));
} else {
error("%s: The script has no 'id' entry, the 'filename' entry was changed to:",
SCRIPT_ENGINE);
- l_dumpValue(l, -1);
+ l_dumpValue(L, -1);
return SCRIPT_ENGINE_ERROR;
}
- lua_pop(l, 2);
+ lua_pop(L, 2);
return SCRIPT_ENGINE_SUCCESS;
}
@@ -444,7 +507,7 @@ int process_getScriptId(lua_State* l, struct script_scan_result *ssr) {
* which want to run
* process all scripts in the list
* */
-int process_preparehost(lua_State* l, Target* target, std::list& torun_threads) {
+int process_preparehost(lua_State* L, Target* target, std::list& torun_threads) {
PortList* plist = &(target->ports);
Port* current = NULL;
size_t rules_count;
@@ -455,20 +518,20 @@ int process_preparehost(lua_State* l, Target* target, std::listtargetipstr());
- lua_pop(l, 1);
+ lua_pop(L, 1);
)
}
- lua_pop(l, 2);
+ lua_pop(L, 2);
}
/* find the matching port rules
* */
- lua_getglobal(l, PORTTESTS);
+ lua_getglobal(L, PORTTESTS);
/* we only publish hostinfo once per portrule */
- lua_newtable(l);
- set_hostinfo(l, target);
+ lua_newtable(L);
+ set_hostinfo(L, target);
/* 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));
+ SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun));
}
while((current = plist->nextPort(current, TCPANDUDP, PORT_OPENFILTERED)) != NULL) {
- SCRIPT_ENGINE_TRY(process_pickScriptsForPort(l, target, current, torun));
+ SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun));
}
while((current = plist->nextPort(current, TCPANDUDP, PORT_UNFILTERED)) != NULL) {
- SCRIPT_ENGINE_TRY(process_pickScriptsForPort(l, target, current, torun));
+ SCRIPT_ENGINE_TRY(process_pickScriptsForPort(L, target, current, torun));
}
// pop the hostinfo, we don't need it anymore
- lua_pop(l, 1);
+ lua_pop(L, 1);
/* ok, let's setup threads for the scripts which said they'd like
* to run
@@ -531,14 +594,14 @@ int process_preparehost(lua_State* l, Target* target, std::list torun_threads) {
}
/* Because we can't iterate over all ports of interest in one go
- * we need to du port matching in a separate function (unlike host
+ * we need to do port matching in a separate function (unlike host
* rule matching)
* Note that we assume that at -2 on the stack we can find the portrules
* and at -1 the hostinfo table
* */
int process_pickScriptsForPort(
- lua_State* l,
+ lua_State* L,
Target* target,
Port* port,
std::vector& torun) {
- size_t rules_count = lua_objlen(l, -2);
+ size_t rules_count = lua_objlen(L, -2);
struct run_record rr;
unsigned int i;
for(i = 1; i <= rules_count; i++) {
- lua_rawgeti(l, -2, i);
+ lua_rawgeti(L, -2, i);
- lua_getfield(l, -1, PORTRULE);
+ lua_getfield(L, -1, PORTRULE);
- lua_pushvalue(l, -3);
+ lua_pushvalue(L, -3);
- lua_newtable(l);
- set_portinfo(l, port);
+ lua_newtable(L);
+ set_portinfo(L, port);
- SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 2, 1, 0));
+ SCRIPT_ENGINE_LUA_TRY(lua_pcall(L, 2, 1, 0));
- if(lua_isboolean (l, -1) && lua_toboolean(l, -1)) {
+ if(lua_isboolean (L, -1) && lua_toboolean(L, -1)) {
rr.type = 1;
rr.index = i;
rr.port = port;
@@ -613,23 +676,23 @@ int process_pickScriptsForPort(
torun.push_back(rr);
SCRIPT_ENGINE_DEBUGGING(
- lua_getfield(l, -2, "filename");
+ lua_getfield(L, -2, "filename");
log_write(LOG_STDOUT, "%s: Will run %s against %s:%d\n",
SCRIPT_ENGINE,
- lua_tostring(l, -1),
+ lua_tostring(L, -1),
target->targetipstr(),
port->portno);
- lua_pop(l, 1);
+ lua_pop(L, 1);
)
- } else if(!lua_isboolean (l, -1)) {
- lua_getfield(l, -2, "filename");
+ } else if(!lua_isboolean (L, -1)) {
+ lua_getfield(L, -2, "filename");
error("%s: Rule in %s returned %s but boolean was expected.",
SCRIPT_ENGINE,
- lua_tostring(l, -1),
- lua_typename(l, lua_type(l, -2)));
+ lua_tostring(L, -1),
+ lua_typename(L, lua_type(L, -2)));
return SCRIPT_ENGINE_LUA_ERROR;
}
- lua_pop(l, 2);
+ lua_pop(L, 2);
}
return SCRIPT_ENGINE_SUCCESS;
@@ -639,14 +702,14 @@ int process_pickScriptsForPort(
* we store target info in the thread so that the mainloop
* knows where to put the script result
* */
-int process_preparethread(lua_State* l, struct run_record rr, struct thread_record* tr){
+int process_preparethread(lua_State* L, struct run_record rr, struct thread_record* tr){
- lua_State *thread = lua_newthread(l);
+ lua_State *thread = lua_newthread(L);
- lua_rawgeti(l, -2, rr.index); // get the script closure
+ lua_rawgeti(L, -2, rr.index); // get the script closure
// move the script closure into the thread
- lua_xmove(l, thread, 1);
+ lua_xmove(L, thread, 1);
// store the target of this thread in the thread
struct run_record *rr_thread = (struct run_record*) safe_malloc(sizeof(struct run_record));
@@ -674,7 +737,7 @@ int process_preparethread(lua_State* l, struct run_record rr, struct thread_reco
// we store the thread in the registry to prevent
// garbage collection +
- tr->registry_idx = luaL_ref(l, LUA_REGISTRYINDEX);
+ tr->registry_idx = luaL_ref(L, LUA_REGISTRYINDEX);
/* if this is a host rule we don't have
* a port state
diff --git a/nse_nmaplib.cc b/nse_nmaplib.cc
index 22eb8d64b2..3f33c6f99f 100644
--- a/nse_nmaplib.cc
+++ b/nse_nmaplib.cc
@@ -14,40 +14,41 @@
#define SCRIPT_ENGINE_GETSTRING(name) \
char* name; \
- lua_getfield(l, -1, #name); \
- if(lua_isnil(l, -1)) \
+ lua_getfield(L, -1, #name); \
+ if(lua_isnil(L, -1)) \
name = NULL; \
else \
- name = strdup(lua_tostring(l, -1)); \
- lua_pop(l, 1); \
+ 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;
-extern std::map current_hosts;
+/* extern std::map current_hosts; */
+extern int current_hosts;
-void set_version(lua_State* l, struct serviceDeductions sd);
+void set_version(lua_State *L, struct serviceDeductions sd);
-static int l_exc_newtry(lua_State *l);
-static int l_port_accessor(lua_State* l);
-static int l_print_debug_unformatted(lua_State *l);
-static int l_get_port_state(lua_State* l, Target* target, Port* port);
-static int l_set_port_state(lua_State* l, Target* target, Port* port);
-static int l_set_port_version(lua_State* l, Target* target, Port* port);
+static int l_exc_newtry(lua_State *L);
+static int l_port_accessor(lua_State *L);
+static int l_print_debug_unformatted(lua_State *L);
+static int l_get_port_state(lua_State *L, Target* target, Port* port);
+static int l_set_port_state(lua_State *L, Target* target, Port* port);
+static int l_set_port_version(lua_State *L, Target* target, Port* port);
static int l_get_verbosity(lua_State *);
static int l_get_debugging(lua_State *);
-static int l_get_have_ssl(lua_State *l);
-static int l_fetchfile(lua_State *l);
+static int l_get_have_ssl(lua_State *L);
+static int l_fetchfile(lua_State *L);
-int l_clock_ms(lua_State* l);
+int l_clock_ms(lua_State *L);
/* register the nmap lib
* we assume that we can write to a table at -1 on the stack
* */
-int set_nmaplib(lua_State* l) {
+/* int set_nmaplib(lua_State *L) {
static luaL_reg nmaplib [] = {
{"get_port_state", l_port_accessor},
{"set_port_state", l_port_accessor},
@@ -67,52 +68,82 @@ int set_nmaplib(lua_State* l) {
const luaL_Reg* lib;
for (lib = nmaplib; lib->func; lib++) {
- lua_pushcfunction(l, lib->func);
- lua_setfield(l, -2, lib->name);
+ lua_pushcfunction(L, lib->func);
+ lua_setfield(L, -2, lib->name);
}
- lua_newtable(l);
- lua_setfield(l, -2, "registry");
+ lua_newtable(L);
+ lua_setfield(L, -2, "registry");
- SCRIPT_ENGINE_TRY(l_nsock_open(l));
- SCRIPT_ENGINE_TRY(l_dnet_open(l));
+ SCRIPT_ENGINE_TRY(l_nsock_open(L));
+ SCRIPT_ENGINE_TRY(l_dnet_open(L));
return SCRIPT_ENGINE_SUCCESS;
+} */
+
+int luaopen_nmap (lua_State *L)
+{
+ static luaL_reg nmaplib [] = {
+ {"get_port_state", l_port_accessor},
+ {"set_port_state", l_port_accessor},
+ {"set_port_version", l_port_accessor},
+ {"new_socket", l_nsock_new},
+ {"new_dnet", l_dnet_new},
+ {"get_interface_link", l_dnet_get_interface_link},
+ {"clock_ms", l_clock_ms},
+ {"print_debug_unformatted", l_print_debug_unformatted},
+ {"new_try", l_exc_newtry},
+ {"verbosity", l_get_verbosity},
+ {"debugging", l_get_debugging},
+ {"have_ssl", l_get_have_ssl},
+ {"fetchfile", l_fetchfile},
+ {NULL, NULL}
+ };
+
+ luaL_register(L, "nmap", nmaplib);
+
+ lua_newtable(L);
+ lua_setfield(L, -2, "registry");
+
+ SCRIPT_ENGINE_TRY(l_nsock_open(L));
+ SCRIPT_ENGINE_TRY(l_dnet_open(L));
+
+ return 0;
}
/* set some port state information onto the
* table which is currently on the stack
* */
-void set_portinfo(lua_State* l, Port* port) {
+void set_portinfo(lua_State *L, Port* port) {
struct serviceDeductions 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) {
+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");
+ 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");
@@ -169,14 +200,14 @@ void set_version(lua_State* l, struct serviceDeductions sd) {
}
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_program);
+ lua_setfield(L, -2, "rpc_program");
- lua_pushnumber(l, sd.rpc_lowver);
- lua_setfield(l, -2, "rpc_lowver");
+ lua_pushnumber(L, sd.rpc_lowver);
+ lua_setfield(L, -2, "rpc_lowver");
- lua_pushnumber(l, sd.rpc_highver);
- lua_setfield(l, -2, "rpc_highver");
+ lua_pushnumber(L, sd.rpc_highver);
+ lua_setfield(L, -2, "rpc_highver");
}
}
@@ -189,47 +220,47 @@ void set_version(lua_State* l, struct serviceDeductions sd) {
* if an os scan wasn't performed, the array
* points to nil!
* */
-void set_hostinfo(lua_State* l, Target *currenths) {
+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->targetipstr(), 1024));
+ lua_setfield(L, -2, "ip");
- lua_pushstring(l, strncpy(hostname, currenths->HostName(), 1024));
- lua_setfield(l, -2, "name");
+ 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");
+ 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");
+ 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");
+ 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");
+ 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");
+ 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");
+ 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");
+ lua_pushlstring(L, (char*)&adr, 4);
+ lua_setfield(L, -2, "bin_ip_src");
}
FingerPrintResults *FPR = NULL;
@@ -246,22 +277,22 @@ void set_hostinfo(lua_State* l, Target *currenths) {
FPR->num_perfect_matches > 0 &&
FPR->num_perfect_matches <= 8 ) {
- lua_newtable(l);
+ 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_pushstring(L, FPR->prints[i]->OS_name);
+ lua_rawseti(L, -2, i);
}
- lua_setfield(l, -2, "os");
+ lua_setfield(L, -2, "os");
}
}
-static int l_port_accessor(lua_State* l) {
+static int l_port_accessor(lua_State *L) {
int retvalues = 0;
char* function_name;
- char* target_ip;
+ const char *target_ip;
int portno;
int proto;
@@ -270,36 +301,38 @@ static int l_port_accessor(lua_State* l) {
Port* port;
lua_Debug ldebug;
- lua_getstack(l, 0, &ldebug);
- lua_getinfo(l, "n", &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 = strdup(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);
-
- std::string key = std::string(target_ip);
- std::map::iterator iter = current_hosts.find(key);
- if(iter == current_hosts.end()) {
- luaL_argerror (l, 1, "Host isn't being processed right now.");
- return 0;
- } else {
- target = (Target*) iter->second;
- }
+ 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;
@@ -311,22 +344,20 @@ static int l_port_accessor(lua_State* l) {
// if the port wasn't scanned we return nil
if(port == NULL) {
- free(target_ip);
free(function_name);
return 0;
}
- if(strcmp(function_name, "set_port_state") == MATCH)
- retvalues = l_set_port_state(l, target, port);
- else if(strcmp(function_name, "set_port_version") == MATCH)
- retvalues = l_set_port_version(l, target, port);
- else if(strcmp(function_name, "get_port_state") == MATCH)
- retvalues = l_get_port_state(l, target, port);
+ 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(target_ip);
+ lua_remove(L, 2);
+ lua_remove(L, 1);
free(function_name);
return retvalues;
}
@@ -341,9 +372,9 @@ static int l_port_accessor(lua_State* l) {
* this function is useful if we want rules which want to know
* 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);
+static int l_get_port_state(lua_State *L, Target* target, Port* port) {
+ lua_newtable(L);
+ set_portinfo(L, port);
return 1;
}
@@ -352,18 +383,18 @@ static int l_get_port_state(lua_State* l, Target* target, Port* port) {
* if for example a udp port was seen by the script as open instead of
* filtered, the script is free to say so.
* */
-static int l_set_port_state(lua_State* l, Target* target, Port* port) {
+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);
+ 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.");
+ luaL_argerror (L, 4, "Invalid port state.");
if (port->state == PORT_OPEN)
goto noset;
plist->addPort(port->portno, port->proto, NULL, PORT_OPEN);
@@ -371,14 +402,14 @@ static int l_set_port_state(lua_State* l, Target* target, Port* port) {
break;
case 'c':
if (strcmp(state, "closed"))
- luaL_argerror (l, 4, "Invalid port state.");
+ 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.");
+ luaL_argerror (L, 4, "Invalid port state.");
}
port->reason.reason_id = ER_SCRIPT;
@@ -388,15 +419,15 @@ static int l_set_port_state(lua_State* l, Target* target, Port* port) {
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);
+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");
+ lua_getfield(L, -1, "version");
SCRIPT_ENGINE_GETSTRING(name);
SCRIPT_ENGINE_GETSTRING(product);
SCRIPT_ENGINE_GETSTRING(version);
@@ -414,8 +445,8 @@ static int l_set_port_version(lua_State* l, Target* target, Port* port) {
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);
+ luaL_argerror(L, 2, "Invalid value for port.version.service_tunnel");
+ lua_pop(L, 1);
if(c_probestate == NULL)
probestate = PROBESTATE_INITIAL;
@@ -430,7 +461,7 @@ static int l_set_port_version(lua_State* l, Target* target, Port* port) {
else if(strcmp(c_probestate, "incomplete") == 0)
probestate = PROBESTATE_INCOMPLETE;
else
- luaL_argerror(l, 3, "Invalid value for probestate.");
+ luaL_argerror(L, 3, "Invalid value for probestate.");
// port->setServiceProbeResults(probestate, name,
// tunnel, product, version,
@@ -464,33 +495,33 @@ static int l_set_port_version(lua_State* l, Target* target, Port* port) {
return 0;
}
-static int l_print_debug_unformatted(lua_State *l) {
+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");
+ if (lua_gettop(L) != 2) return luaL_error(L, "Incorrect number of arguments\n");
- verbosity = luaL_checkinteger(l, 1);
+ verbosity = luaL_checkinteger(L, 1);
if (verbosity > o.verbose) return 0;
- out = luaL_checkstring(l, 2);
+ 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)) {
+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);
+ 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)) {
+ } else if(lua_isboolean(L, 1) && lua_toboolean(L, 1)) {
/* true. */
- lua_remove(l, 1);
- return lua_gettop(l);
+ 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__);
@@ -499,44 +530,44 @@ static int l_exc_finalize(lua_State *l) {
}
}
-static int l_exc_do_nothing(lua_State *l) {
- (void) l;
+static int l_exc_do_nothing(lua_State *L) {
+ (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);
+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;
}
-static int l_get_verbosity(lua_State *l)
+static int l_get_verbosity(lua_State *L)
{
- lua_pushnumber(l, o.verbose);
+ lua_pushnumber(L, o.verbose);
return 1;
}
-static int l_get_debugging(lua_State *l)
+static int l_get_debugging(lua_State *L)
{
- lua_pushnumber(l, o.debugging);
+ lua_pushnumber(L, o.debugging);
return 1;
}
-static int l_get_have_ssl(lua_State *l) {
+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;
}
-static int l_fetchfile(lua_State *l)
+static int l_fetchfile(lua_State *L)
{
char buf[FILENAME_MAX];
- const char *req = lua_tostring(l, -1);
+ const char *req = lua_tostring(L, -1);
if (!req)
goto err;
@@ -544,12 +575,12 @@ static int l_fetchfile(lua_State *l)
if (nmap_fetchfile(buf, sizeof buf, (char *) req) != 1)
goto err;
- lua_pop(l, 1);
- lua_pushstring(l, buf);
+ lua_pop(L, 1);
+ lua_pushstring(L, buf);
return 1;
err:
- lua_pop(l, 1);
- lua_pushnil(l);
+ lua_pop(L, 1);
+ lua_pushnil(L);
return 0;
}
diff --git a/nse_nmaplib.h b/nse_nmaplib.h
index fb612448d0..bfa014460d 100644
--- a/nse_nmaplib.h
+++ b/nse_nmaplib.h
@@ -10,7 +10,7 @@ extern "C" {
class Target;
class Port;
-int set_nmaplib(lua_State* l);
+int luaopen_nmap(lua_State* l);
void set_hostinfo(lua_State* l, Target* currenths);
void set_portinfo(lua_State* l, Port* port);
diff --git a/nse_nsock.cc b/nse_nsock.cc
index 3ba0ed17be..23ca643aa3 100644
--- a/nse_nsock.cc
+++ b/nse_nsock.cc
@@ -37,24 +37,24 @@ extern NmapOps o;
// defined in nse_main.cc but also declared here
// to keep the .h files clean
-int process_waiting2running(lua_State* l, int resume_arguments);
-
-static int l_nsock_connect(lua_State* l);
-static int l_nsock_connect_queued(lua_State* l);
-static int l_nsock_send(lua_State* l);
-static int l_nsock_receive(lua_State* l);
-static int l_nsock_receive_lines(lua_State* l);
-static int l_nsock_receive_bytes(lua_State* l);
-static int l_nsock_get_info(lua_State* l);
-static int l_nsock_gc(lua_State* l);
-static int l_nsock_close(lua_State* l);
-static int l_nsock_set_timeout(lua_State* l);
-static int l_nsock_receive_buf(lua_State* l);
-
-static int l_nsock_ncap_open(lua_State* l);
-static int l_nsock_ncap_close(lua_State* l);
-static int l_nsock_ncap_register(lua_State *l);
-static int l_nsock_pcap_receive(lua_State* l);
+int process_waiting2running(lua_State *L, int resume_arguments);
+
+static int l_nsock_connect(lua_State *L);
+static int l_nsock_connect_queued(lua_State *L);
+static int l_nsock_send(lua_State *L);
+static int l_nsock_receive(lua_State *L);
+static int l_nsock_receive_lines(lua_State *L);
+static int l_nsock_receive_bytes(lua_State *L);
+static int l_nsock_get_info(lua_State *L);
+static int l_nsock_gc(lua_State *L);
+static int l_nsock_close(lua_State *L);
+static int l_nsock_set_timeout(lua_State *L);
+static int l_nsock_receive_buf(lua_State *L);
+
+static int l_nsock_ncap_open(lua_State *L);
+static int l_nsock_ncap_close(lua_State *L);
+static int l_nsock_ncap_register(lua_State *L);
+static int l_nsock_pcap_receive(lua_State *L);
void l_nsock_connect_handler(nsock_pool nsp, nsock_event nse, void *lua_state);
@@ -62,9 +62,9 @@ void l_nsock_send_handler(nsock_pool nsp, nsock_event nse, void *lua_state);
void l_nsock_receive_handler(nsock_pool nsp, nsock_event nse, void *lua_state);
void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_state);
-int l_nsock_check_buf(lua_State* l);
+int l_nsock_check_buf(lua_State *L);
-int l_nsock_checkstatus(lua_State* l, nsock_event nse);
+int l_nsock_checkstatus(lua_State *L, nsock_event nse);
void l_nsock_trace(nsock_iod nsiod, const char* message, int direction);
const char* inet_ntop_both(int af, const void* v_addr, char* ipstring);
@@ -113,7 +113,7 @@ struct ncap_socket{
*/
struct ncap_request{
int suspended; /* is the thread suspended? (lua_yield) */
- lua_State *l; /* lua_State of current process
+ lua_State *L; /* lua_State of current process
* or NULL if process isn't suspended */
nsock_event_id nseid; /* nse for this specific lua_State */
struct timeval end_time;
@@ -151,18 +151,18 @@ struct l_nsock_udata {
int ncap_cback_ref;
};
-void l_nsock_clear_buf(lua_State* l, l_nsock_udata* udata);
+void l_nsock_clear_buf(lua_State *L, l_nsock_udata* udata);
-int l_nsock_open(lua_State* l) {
- luaL_newmetatable(l, "nsock");
- lua_createtable(l, 20, 0);
- luaL_register(l, NULL, l_nsock);
- lua_setfield(l, -2, "__index");
- lua_pushcclosure(l, l_nsock_gc, 0);
- lua_setfield(l, -2, "__gc");
- lua_pushliteral(l, "");
- lua_setfield(l, -2, "__metatable"); // protect metatable
- lua_pop(l, 1);
+int l_nsock_open(lua_State *L) {
+ luaL_newmetatable(L, "nsock");
+ lua_createtable(L, 0, 20);
+ luaL_register(L, NULL, l_nsock);
+ lua_setfield(L, -2, "__index");
+ lua_pushcclosure(L, l_nsock_gc, 0);
+ lua_setfield(L, -2, "__gc");
+ lua_pushliteral(L, "");
+ lua_setfield(L, -2, "__metatable"); // protect metatable
+ lua_pop(L, 1);
nsp = nsp_new(NULL);
//nsp_settrace(nsp, o.debugging, o.getStartTime());
@@ -172,11 +172,11 @@ int l_nsock_open(lua_State* l) {
return NSOCK_WRAPPER_SUCCESS;
}
-int l_nsock_new(lua_State* l) {
+int l_nsock_new(lua_State *L) {
struct l_nsock_udata* udata;
- udata = (struct l_nsock_udata*) lua_newuserdata(l, sizeof(struct l_nsock_udata));
- luaL_getmetatable(l, "nsock");
- lua_setmetatable(l, -2);
+ udata = (struct l_nsock_udata*) lua_newuserdata(L, sizeof(struct l_nsock_udata));
+ luaL_getmetatable(L, "nsock");
+ lua_setmetatable(L, -2);
udata->nsiod = NULL;
udata->ssl_session = NULL;
udata->timeout = DEFAULT_TIMEOUT;
@@ -193,12 +193,12 @@ int l_nsock_loop(int tout) {
return nsock_loop(nsp, tout);
}
-int l_nsock_checkstatus(lua_State* l, nsock_event nse) {
+int l_nsock_checkstatus(lua_State *L, nsock_event nse) {
enum nse_status status = nse_status(nse);
switch (status) {
case NSE_STATUS_SUCCESS:
- lua_pushboolean(l, true);
+ lua_pushboolean(L, true);
return NSOCK_WRAPPER_SUCCESS;
break;
case NSE_STATUS_ERROR:
@@ -206,8 +206,8 @@ int l_nsock_checkstatus(lua_State* l, nsock_event nse) {
case NSE_STATUS_CANCELLED:
case NSE_STATUS_KILL:
case NSE_STATUS_EOF:
- lua_pushnil(l);
- lua_pushstring(l, nse_status2str(status));
+ lua_pushnil(L);
+ lua_pushstring(L, nse_status2str(status));
return NSOCK_WRAPPER_ERROR;
break;
case NSE_STATUS_NONE:
@@ -222,7 +222,7 @@ int l_nsock_checkstatus(lua_State* l, nsock_event nse) {
}
-static int l_nsock_connect_queued(lua_State* l) {
+static int l_nsock_connect_queued(lua_State *L) {
/* We allow at least 10 even max_parallelism is 1 because a single
script might open a few sockets at once and we don't want it to
@@ -230,7 +230,7 @@ static int l_nsock_connect_queued(lua_State* l) {
const int max_descriptors_allowed = MAX(o.max_parallelism, 10);
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
if(udata->nsiod!=NULL){
/*should a script try to connect a socket, which is already connected
@@ -240,65 +240,65 @@ static int l_nsock_connect_queued(lua_State* l) {
if(o.scriptTrace()){
log_write(LOG_STDOUT,"%s: Trying to connect already connected socket - closing!\n",SCRIPT_ENGINE);
}
- l_nsock_close(l);
- lua_pop(l,1);
+ l_nsock_close(L);
+ lua_pop(L,1);
}
if(nsock_descriptors_used >= max_descriptors_allowed){
/* wait for free descriptor */
- nsock_connect_queue.push_back(l);
+ nsock_connect_queue.push_back(L);
/* I must know how many arguments are passed to nsock_connect.
* is there a better way? */
int arguments = 3;
- const char *how = luaL_optstring(l, 4, "");
+ const char *how = luaL_optstring(L, 4, "");
if(*how != '\0'){
arguments = 4;
- int port = luaL_optinteger(l, 5, -1);
+ int port = luaL_optinteger(L, 5, -1);
if(port!=-1)
arguments = 5;
}
if(o.scriptTrace())
- log_write(LOG_STDOUT, "NSOCK_connect_queued: thread queued (%i args) %p\n", arguments, (void *)l);
+ log_write(LOG_STDOUT, "NSOCK_connect_queued: thread queued (%i args) %p\n", arguments, (void *)L);
- return lua_yield(l, arguments);
+ return lua_yield(L, arguments);
}
- return l_nsock_connect(l);
+ return l_nsock_connect(L);
}
void l_nsock_connect_queued_handler(nsock_pool nsp, nsock_event nse, void *lua_state) {
- lua_State* l = (lua_State*) lua_state;
+ lua_State *L = (lua_State*) lua_state;
/* well, this is really hackish, we can't just do process_waiting2running, because
* nsock_connect() can do lua_yield().
* Instead, we first execute nsock_connect, and if it returns lua_yield() (ie. -1)
* than we don't do process_waiting2running.
* So, in summary we can do two lua_yield() on thread (one in l_nsock_connect_queued,
* second in l_nsock_connect). But it works for me. */
- int r = l_nsock_connect(l);
+ int r = l_nsock_connect(L);
if(r != -1)
process_waiting2running((lua_State*) lua_state, 0);
}
-static int l_nsock_connect(lua_State* l) {
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
- const char* addr = luaL_checkstring(l, 2);
- unsigned short port = (unsigned short) luaL_checkint(l, 3);
- const char *how = luaL_optstring(l, 4, "tcp");
+static int l_nsock_connect(lua_State *L) {
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
+ const char* addr = luaL_checkstring(L, 2);
+ unsigned short port = (unsigned short) luaL_checkint(L, 3);
+ const char *how = luaL_optstring(L, 4, "tcp");
const char* error;
struct addrinfo *dest;
int error_id;
- l_nsock_clear_buf(l, udata);
+ l_nsock_clear_buf(L, udata);
error_id = getaddrinfo(addr, NULL, NULL, &dest);
if (error_id) {
error = gai_strerror(error_id);
- lua_pushboolean(l, false);
- lua_pushstring(l, error);
+ lua_pushboolean(L, false);
+ lua_pushstring(L, error);
return 2;
}
@@ -309,23 +309,23 @@ static int l_nsock_connect(lua_State* l) {
case 't':
if (strcmp(how, "tcp")) goto error;
nsock_connect_tcp(nsp, udata->nsiod, l_nsock_connect_handler,
- udata->timeout, l, dest->ai_addr, dest->ai_addrlen, port);
+ udata->timeout, L, dest->ai_addr, dest->ai_addrlen, port);
break;
case 'u':
if (strcmp(how, "udp")) goto error;
nsock_connect_udp(nsp, udata->nsiod, l_nsock_connect_handler,
- l, dest->ai_addr, dest->ai_addrlen, port);
+ L, dest->ai_addr, dest->ai_addrlen, port);
break;
case 's':
if (strcmp(how, "ssl")) goto error;
#ifdef HAVE_OPENSSL
nsock_connect_ssl(nsp, udata->nsiod, l_nsock_connect_handler,
- udata->timeout, l, dest->ai_addr, dest->ai_addrlen, port,
+ udata->timeout, L, dest->ai_addr, dest->ai_addrlen, port,
udata->ssl_session);
break;
#else
- lua_pushboolean(l, false);
- lua_pushstring(l, "Sorry, you don't have OpenSSL\n");
+ lua_pushboolean(L, false);
+ lua_pushstring(L, "Sorry, you don't have OpenSSL\n");
return 2;
#endif
default:
@@ -334,39 +334,39 @@ static int l_nsock_connect(lua_State* l) {
}
freeaddrinfo(dest);
- return lua_yield(l, 0);
+ return lua_yield(L, 0);
error:
freeaddrinfo(dest);
- luaL_argerror(l, 4, "invalid connection method");
+ luaL_argerror(L, 4, "invalid connection method");
return 0;
}
void l_nsock_connect_handler(nsock_pool nsp, nsock_event nse, void *lua_state) {
- lua_State* l = (lua_State*) lua_state;
+ lua_State *L = (lua_State*) lua_state;
if(o.scriptTrace()) {
l_nsock_trace(nse_iod(nse), "CONNECT", TO);
}
- if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) {
+ if(l_nsock_checkstatus(L, nse) == NSOCK_WRAPPER_SUCCESS) {
process_waiting2running((lua_State*) lua_state, 1);
} else {
process_waiting2running((lua_State*) lua_state, 2);
}
}
-static int l_nsock_send(lua_State* l) {
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
- const char* string = luaL_checkstring(l, 2);
- size_t string_len = lua_objlen (l, 2);
+static int l_nsock_send(lua_State *L) {
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
+ const char* string = luaL_checkstring(L, 2);
+ size_t string_len = lua_objlen (L, 2);
char* hexified;
- l_nsock_clear_buf(l,udata);
+ l_nsock_clear_buf(L,udata);
if(udata->nsiod == NULL) {
- lua_pushboolean(l, false);
- lua_pushstring(l, "Trying to send through a closed socket\n");
+ lua_pushboolean(L, false);
+ lua_pushstring(L, "Trying to send through a closed socket\n");
return 2;
}
@@ -376,76 +376,76 @@ static int l_nsock_send(lua_State* l) {
free(hexified);
}
- nsock_write(nsp, udata->nsiod, l_nsock_send_handler, udata->timeout, l, string, string_len);
- return lua_yield(l, 0);
+ nsock_write(nsp, udata->nsiod, l_nsock_send_handler, udata->timeout, L, string, string_len);
+ return lua_yield(L, 0);
}
void l_nsock_send_handler(nsock_pool nsp, nsock_event nse, void *lua_state) {
- lua_State* l = (lua_State*) lua_state;
+ lua_State *L = (lua_State*) lua_state;
- if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) {
+ if(l_nsock_checkstatus(L, nse) == NSOCK_WRAPPER_SUCCESS) {
process_waiting2running((lua_State*) lua_state, 1);
} else {
process_waiting2running((lua_State*) lua_state, 2);
}
}
-static int l_nsock_receive(lua_State* l) {
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
- l_nsock_clear_buf(l, udata);
+static int l_nsock_receive(lua_State *L) {
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
+ l_nsock_clear_buf(L, udata);
if(udata->nsiod == NULL) {
- lua_pushboolean(l, false);
- lua_pushstring(l, "Trying to receive through a closed socket\n");
+ lua_pushboolean(L, false);
+ lua_pushstring(L, "Trying to receive through a closed socket\n");
return 2;
}
- nsock_read(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, l);
+ nsock_read(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, L);
- return lua_yield(l, 0);
+ return lua_yield(L, 0);
}
-static int l_nsock_receive_lines(lua_State* l) {
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
- int nlines = (int) luaL_checknumber(l, 2);
+static int l_nsock_receive_lines(lua_State *L) {
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
+ int nlines = (int) luaL_checknumber(L, 2);
- l_nsock_clear_buf(l, udata);
+ l_nsock_clear_buf(L, udata);
if(udata->nsiod == NULL) {
- lua_pushboolean(l, false);
- lua_pushstring(l, "Trying to receive lines through a closed socket\n");
+ lua_pushboolean(L, false);
+ lua_pushstring(L, "Trying to receive lines through a closed socket\n");
return 2;
}
- nsock_readlines(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, l, nlines);
+ nsock_readlines(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, L, nlines);
- return lua_yield(l, 0);
+ return lua_yield(L, 0);
}
-static int l_nsock_receive_bytes(lua_State* l) {
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
- int nbytes = (int) luaL_checknumber(l, 2);
+static int l_nsock_receive_bytes(lua_State *L) {
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
+ int nbytes = (int) luaL_checknumber(L, 2);
- l_nsock_clear_buf(l, udata);
+ l_nsock_clear_buf(L, udata);
if(udata->nsiod == NULL) {
- lua_pushboolean(l, false);
- lua_pushstring(l, "Trying to receive bytes through a closed socket\n");
+ lua_pushboolean(L, false);
+ lua_pushstring(L, "Trying to receive bytes through a closed socket\n");
return 2;
}
- nsock_readbytes(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, l, nbytes);
+ nsock_readbytes(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, L, nbytes);
- return lua_yield(l, 0);
+ return lua_yield(L, 0);
}
void l_nsock_receive_handler(nsock_pool nsp, nsock_event nse, void *lua_state) {
- lua_State* l = (lua_State*) lua_state;
+ lua_State *L = (lua_State*) lua_state;
char* rcvd_string;
int rcvd_len = 0;
char* hexified;
- if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) {
+ if(l_nsock_checkstatus(L, nse) == NSOCK_WRAPPER_SUCCESS) {
rcvd_string = nse_readbuf(nse, &rcvd_len);
if(o.scriptTrace()) {
@@ -454,7 +454,7 @@ void l_nsock_receive_handler(nsock_pool nsp, nsock_event nse, void *lua_state) {
free(hexified);
}
- lua_pushlstring(l, rcvd_string, rcvd_len);
+ lua_pushlstring(L, rcvd_string, rcvd_len);
process_waiting2running((lua_State*) lua_state, 2);
} else {
process_waiting2running((lua_State*) lua_state, 2);
@@ -532,8 +532,8 @@ unsigned short inet_port_both(int af, const void* v_addr) {
return ntohs(port);
}
-static int l_nsock_get_info(lua_State* l) {
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
+static int l_nsock_get_info(lua_State *L) {
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
int status;
int protocol; // tcp or udp
@@ -544,50 +544,50 @@ static int l_nsock_get_info(lua_State* l) {
char* ipstring_remote = (char*) safe_malloc(sizeof(char) * INET6_ADDRSTRLEN);
if(udata->nsiod == NULL) {
- lua_pushboolean(l, false);
- lua_pushstring(l, "Trying to get info from a closed socket\n");
+ lua_pushboolean(L, false);
+ lua_pushstring(L, "Trying to get info from a closed socket\n");
return 2;
}
status = nsi_getlastcommunicationinfo(udata->nsiod, &protocol, &af,
&local, &remote, sizeof(sockaddr));
- lua_pushboolean(l, true);
+ lua_pushboolean(L, true);
- lua_pushstring(l, inet_ntop_both(af, &local, ipstring_local));
- lua_pushnumber(l, inet_port_both(af, &local));
+ lua_pushstring(L, inet_ntop_both(af, &local, ipstring_local));
+ lua_pushnumber(L, inet_port_both(af, &local));
- lua_pushstring(l, inet_ntop_both(af, &remote, ipstring_remote));
- lua_pushnumber(l, inet_port_both(af, &remote));
+ lua_pushstring(L, inet_ntop_both(af, &remote, ipstring_remote));
+ lua_pushnumber(L, inet_port_both(af, &remote));
free(ipstring_local);
free(ipstring_remote);
return 5;
}
-static int l_nsock_gc(lua_State* l){
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
+static int l_nsock_gc(lua_State *L){
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
if(udata->nsiod == NULL) { //socket obviously got closed already - so no finalization needed
return 0;
}else{
//FIXME - check wheter close returned true!!
- l_nsock_close(l);
+ l_nsock_close(L);
}
return 0;
}
-static int l_nsock_close(lua_State* l) {
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
+static int l_nsock_close(lua_State *L) {
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
/* Never ever collect nse-pcap connections. */
if(udata->ncap_socket){
return 0;
}
- l_nsock_clear_buf(l, udata);
+ l_nsock_clear_buf(L, udata);
if(udata->nsiod == NULL) {
- lua_pushboolean(l, false);
- lua_pushstring(l, "Trying to close a closed socket\n");
+ lua_pushboolean(L, false);
+ lua_pushstring(L, "Trying to close a closed socket\n");
return 2;
}
@@ -615,13 +615,13 @@ static int l_nsock_close(lua_State* l) {
udata->nsiod = NULL;
- lua_pushboolean(l, true);
+ lua_pushboolean(L, true);
return 1;
}
-static int l_nsock_set_timeout(lua_State* l) {
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
- int timeout = (unsigned short) luaL_checkint(l, 2);
+static int l_nsock_set_timeout(lua_State *L) {
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
+ int timeout = (unsigned short) luaL_checkint(L, 2);
udata->timeout = timeout;
@@ -629,53 +629,53 @@ static int l_nsock_set_timeout(lua_State* l) {
}
/* buffered I/O */
-static int l_nsock_receive_buf(lua_State* l) {
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
- if(lua_gettop(l)==2){
+static int l_nsock_receive_buf(lua_State *L) {
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
+ if(lua_gettop(L)==2){
/*we were called with 2 arguments only - push the default third one*/
- lua_pushboolean(l,true);
+ lua_pushboolean(L,true);
}
if(udata->nsiod == NULL) {
- lua_pushboolean(l, false);
- lua_pushstring(l, "Trying to receive through a closed socket\n");
+ lua_pushboolean(L, false);
+ lua_pushstring(L, "Trying to receive through a closed socket\n");
return 2;
}
if(udata->bufused==0){
- lua_pushstring(l,"");
- udata->bufidx = luaL_ref(l, LUA_REGISTRYINDEX);
+ lua_pushstring(L,"");
+ udata->bufidx = luaL_ref(L, LUA_REGISTRYINDEX);
udata->bufused=1;
- nsock_read(nsp, udata->nsiod, l_nsock_receive_buf_handler, udata->timeout, l);
+ nsock_read(nsp, udata->nsiod, l_nsock_receive_buf_handler, udata->timeout, L);
}else if(udata->bufused==-1){ /*error message is inside the buffer*/
- lua_pushboolean(l,false);
- lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx);
+ lua_pushboolean(L,false);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx);
return 2;
}else{ /*buffer contains already some data */
/*we keep track here of how many calls to receive_buf are made */
udata->bufused++;
- if(l_nsock_check_buf(l)==NSOCK_WRAPPER_BUFFER_MOREREAD){
+ if(l_nsock_check_buf(L)==NSOCK_WRAPPER_BUFFER_MOREREAD){
/*if we didn't have enough data in the buffer another nsock_read()
* was scheduled - its callback will put us in running state again
*/
- return lua_yield(l,3);
+ return lua_yield(L,3);
}
return 2;
}
/*yielding with 3 arguments since we need them when the callback arrives */
- return lua_yield(l, 3);
+ return lua_yield(L, 3);
}
void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_state) {
- lua_State* l = (lua_State*) lua_state;
+ lua_State *L = (lua_State*) lua_state;
char* rcvd_string;
int rcvd_len = 0;
char* hexified;
int tmpidx;
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
- if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) {
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
+ if(l_nsock_checkstatus(L, nse) == NSOCK_WRAPPER_SUCCESS) {
//l_nsock_checkstatus pushes true on the stack in case of success
// we do this on our own here
- lua_pop(l,1);
+ lua_pop(L,1);
rcvd_string = nse_readbuf(nse, &rcvd_len);
@@ -686,12 +686,12 @@ void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_stat
}
/* push the buffer and what we received from nsock on the stack and
* concatenate both*/
- lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx);
- lua_pushlstring(l, rcvd_string, rcvd_len);
- lua_concat (l, 2);
- luaL_unref(l, LUA_REGISTRYINDEX, udata->bufidx);
- udata->bufidx = luaL_ref(l, LUA_REGISTRYINDEX);
- if(l_nsock_check_buf(l)==NSOCK_WRAPPER_BUFFER_MOREREAD){
+ lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx);
+ lua_pushlstring(L, rcvd_string, rcvd_len);
+ lua_concat (L, 2);
+ luaL_unref(L, LUA_REGISTRYINDEX, udata->bufidx);
+ udata->bufidx = luaL_ref(L, LUA_REGISTRYINDEX);
+ if(l_nsock_check_buf(L)==NSOCK_WRAPPER_BUFFER_MOREREAD){
/*if there wasn't enough data in the buffer and we've issued another
* nsock_read() the next callback will schedule the script for running
*/
@@ -705,12 +705,12 @@ void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_stat
* and clean the buffer afterwards
*/
/*save the error message inside the buffer*/
- tmpidx=luaL_ref(l, LUA_REGISTRYINDEX);
+ tmpidx=luaL_ref(L, LUA_REGISTRYINDEX);
/*pop the status (==false) of the stack*/
- lua_pop(l,1);
- lua_pushboolean(l, true);
- lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx);
- l_nsock_clear_buf(l, udata);
+ lua_pop(L,1);
+ lua_pushboolean(L, true);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx);
+ l_nsock_clear_buf(L, udata);
udata->bufidx=tmpidx;
udata->bufused=-1;
process_waiting2running((lua_State*) lua_state, 2);
@@ -720,55 +720,55 @@ void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_stat
}
}
-int l_nsock_check_buf(lua_State* l ){
+int l_nsock_check_buf(lua_State *L ){
l_nsock_udata* udata;
size_t startpos, endpos, bufsize;
const char *tmpbuf;
int tmpidx;
int keeppattern;
/*should we return the string including the pattern or without it */
- keeppattern= lua_toboolean(l,-1);
- lua_pop(l,1);
- udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
- if(lua_isfunction(l,2)){
- lua_pushvalue(l,2);
- lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx); /* the buffer is the only argument to the function */
- if(lua_pcall(l,1,2,0)!=0){
- lua_pushboolean(l,false);
- lua_pushfstring(l,"Error inside splitting-function: %s\n", lua_tostring(l,-1));
+ keeppattern= lua_toboolean(L,-1);
+ lua_pop(L,1);
+ udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
+ if(lua_isfunction(L,2)){
+ lua_pushvalue(L,2);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx); /* the buffer is the only argument to the function */
+ if(lua_pcall(L,1,2,0)!=0){
+ lua_pushboolean(L,false);
+ lua_pushfstring(L,"Error inside splitting-function: %s\n", lua_tostring(L,-1));
return NSOCK_WRAPPER_BUFFER_OK;
- //luaL_error(l,"Error inside splitting-function, given as argument to nsockobj:receive_buf: %s\n", lua_tostring(l,-1));
+ //luaL_error(L,"Error inside splitting-function, given as argument to nsockobj:receive_buf: %s\n", lua_tostring(L,-1));
}
- }else if(lua_isstring(l,2)){
- lua_getglobal(l,"string");
- lua_getfield(l,-1,"find");
- lua_remove(l, -2); /*drop the string-table, since we don't need it! */
- lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx);
- lua_pushvalue(l,2); /*the pattern we are searching for */
- if(lua_pcall(l,2,2,0)!=0){
- lua_pushboolean(l,false);
- lua_pushstring(l,"Error in string.find (nsockobj:receive_buf)!");
+ }else if(lua_isstring(L,2)){
+ lua_getglobal(L,"string");
+ lua_getfield(L,-1,"find");
+ lua_remove(L, -2); /*drop the string-table, since we don't need it! */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx);
+ lua_pushvalue(L,2); /*the pattern we are searching for */
+ if(lua_pcall(L,2,2,0)!=0){
+ lua_pushboolean(L,false);
+ lua_pushstring(L,"Error in string.find (nsockobj:receive_buf)!");
return NSOCK_WRAPPER_BUFFER_OK;
}
}else{
- lua_pushboolean(l,false);
- lua_pushstring(l,"Expected either a function or a string!");
+ lua_pushboolean(L,false);
+ lua_pushstring(L,"Expected either a function or a string!");
return NSOCK_WRAPPER_BUFFER_OK;
- //luaL_argerror(l,2,"expected either a function or a string!");
+ //luaL_argerror(L,2,"expected either a function or a string!");
}
/*the stack contains on top the indices where we want to seperate */
- if(lua_isnil(l,-1)){ /*not found anything try to read more data*/
- lua_pop(l,2);
- nsock_read(nsp, udata->nsiod, l_nsock_receive_buf_handler, udata->timeout, l);
- lua_pushboolean(l,keeppattern);
+ if(lua_isnil(L,-1)){ /*not found anything try to read more data*/
+ lua_pop(L,2);
+ nsock_read(nsp, udata->nsiod, l_nsock_receive_buf_handler, udata->timeout, L);
+ lua_pushboolean(L,keeppattern);
return NSOCK_WRAPPER_BUFFER_MOREREAD;
}else{
- startpos = (size_t) lua_tointeger(l, -2);
- endpos = (size_t) lua_tointeger(l, -1);
- lua_settop(l,0); /* clear the stack for returning */
+ startpos = (size_t) lua_tointeger(L, -2);
+ endpos = (size_t) lua_tointeger(L, -1);
+ lua_settop(L,0); /* clear the stack for returning */
if(startpos>endpos){
- lua_pushboolean(l,false);
- lua_pushstring(l,"Delimiter has negative size!");
+ lua_pushboolean(L,false);
+ lua_pushstring(L,"Delimiter has negative size!");
return NSOCK_WRAPPER_BUFFER_OK;
}else if(startpos==endpos){
/* if the delimter has a size of zero we keep it, since otherwise
@@ -776,34 +776,34 @@ int l_nsock_check_buf(lua_State* l ){
*/
keeppattern=1;
}
- lua_settop(l,0); /* clear the stack for returning */
- lua_rawgeti(l, LUA_REGISTRYINDEX, udata->bufidx);
- tmpbuf = lua_tolstring(l, -1, &bufsize);
- lua_pop(l,1); /* pop the buffer off the stack, should be safe since it
+ lua_settop(L,0); /* clear the stack for returning */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx);
+ tmpbuf = lua_tolstring(L, -1, &bufsize);
+ lua_pop(L,1); /* pop the buffer off the stack, should be safe since it
it is still in the registry */
if(tmpbuf==NULL){
fatal("%s: In: %s:%i The buffer is not a string?! - please report this to nmap-dev@insecure.org.", SCRIPT_ENGINE, __FILE__, __LINE__);
}
/*first push the remains of the buffer */
- lua_pushlstring(l,tmpbuf+endpos,(bufsize-endpos));
- tmpidx = luaL_ref(l,LUA_REGISTRYINDEX);
- lua_pushboolean(l,true);
+ lua_pushlstring(L,tmpbuf+endpos,(bufsize-endpos));
+ tmpidx = luaL_ref(L,LUA_REGISTRYINDEX);
+ lua_pushboolean(L,true);
if(keeppattern){
- lua_pushlstring(l,tmpbuf,endpos);
+ lua_pushlstring(L,tmpbuf,endpos);
}else{
- lua_pushlstring(l,tmpbuf,startpos-1);
+ lua_pushlstring(L,tmpbuf,startpos-1);
}
- luaL_unref(l,LUA_REGISTRYINDEX,udata->bufidx);
+ luaL_unref(L,LUA_REGISTRYINDEX,udata->bufidx);
udata->bufidx=tmpidx;
- //l_dumpStack(l);
+ //l_dumpStack(L);
return NSOCK_WRAPPER_BUFFER_OK;
}
assert(0);
return 1;//unreachable
}
-void l_nsock_clear_buf(lua_State* l, l_nsock_udata* udata){
- luaL_unref (l, LUA_REGISTRYINDEX, udata->bufidx);
+void l_nsock_clear_buf(lua_State *L, l_nsock_udata* udata){
+ luaL_unref (L, LUA_REGISTRYINDEX, udata->bufidx);
udata->bufidx=LUA_NOREF;
udata->bufused=0;
}
@@ -866,29 +866,29 @@ char *dnet_to_pcap_device_name(const char *device){
* 4) callback- callback function, that will create hash string from packet
* 5) bpf - berkeley packet filter, see tcpdump(8)
* */
-static int l_nsock_ncap_open(lua_State* l){
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
- const char* device = luaL_checkstring(l, 2);
- int snaplen = luaL_checkint(l, 3);
- int promisc = luaL_checkint(l, 4);
- luaL_checktype(l, 5, LUA_TFUNCTION); /* callback function that creates hash */
- const char* bpf = luaL_checkstring(l, 6);
+static int l_nsock_ncap_open(lua_State *L){
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
+ const char* device = luaL_checkstring(L, 2);
+ int snaplen = luaL_checkint(L, 3);
+ int promisc = luaL_checkint(L, 4);
+ luaL_checktype(L, 5, LUA_TFUNCTION); /* callback function that creates hash */
+ const char* bpf = luaL_checkstring(L, 6);
if(udata->nsiod || udata->ncap_request || udata->ncap_socket) {
- luaL_argerror(l, 1, "Trying to open nsock-pcap, but this connection is already opened");
+ luaL_argerror(L, 1, "Trying to open nsock-pcap, but this connection is already opened");
return 0;
}
char *pcapdev = dnet_to_pcap_device_name(device);
if(!strlen(device) || !strlen(pcapdev)) {
- luaL_argerror(l, 1, "Trying to open nsock-pcap, but you're passing empty or wrong device name.");
+ luaL_argerror(L, 1, "Trying to open nsock-pcap, but you're passing empty or wrong device name.");
return 0;
}
- lua_pop(l, 1); // pop bpf
+ lua_pop(L, 1); // pop bpf
/* take func from top of stack and store it in the Registry */
- int hash_func_ref = luaL_ref(l, LUA_REGISTRYINDEX);
+ int hash_func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
/* push function on the registry-stack */
- lua_rawgeti(l, LUA_REGISTRYINDEX, hash_func_ref);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, hash_func_ref);
struct ncap_socket *ns;
@@ -907,7 +907,7 @@ static int l_nsock_ncap_open(lua_State* l){
/* error messages are passed here */
char *emsg = nsock_pcap_open(nsp, ns->nsiod, pcapdev, snaplen, promisc, bpf);
if(emsg){
- luaL_argerror(l, 1, emsg);
+ luaL_argerror(L, 1, emsg);
return 0;
}
ncap_socket_map_set(key, ns);
@@ -921,16 +921,16 @@ static int l_nsock_ncap_open(lua_State* l){
/* (LUA) Close nsock-pcap socket.
* */
-static int l_nsock_ncap_close(lua_State* l){
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
+static int l_nsock_ncap_close(lua_State *L){
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
struct ncap_socket *ns = udata->ncap_socket;
if(!udata->nsiod || !udata->ncap_socket) {
- luaL_argerror(l, 1, "Trying to close nsock-pcap, but it was never opened.");
+ luaL_argerror(L, 1, "Trying to close nsock-pcap, but it was never opened.");
return 0;
}
if(udata->ncap_request) {
- luaL_argerror(l, 1, "Trying to close nsock-pcap, but it has active event.");
+ luaL_argerror(L, 1, "Trying to close nsock-pcap, but it has active event.");
return 0;
}
@@ -946,10 +946,10 @@ static int l_nsock_ncap_close(lua_State* l){
udata->nsiod = NULL;
udata->ncap_socket = NULL;
- lua_unref(l, udata->ncap_cback_ref);
+ lua_unref(L, udata->ncap_cback_ref);
udata->ncap_cback_ref = 0;
- lua_pushboolean(l, true);
+ lua_pushboolean(L, true);
return 1;
}
@@ -1010,19 +1010,19 @@ void ncap_request_map_add(char *key, struct ncap_request *nr){
* 1) hash - hash for packet that should be matched. or empty string if you
* want to receive first packet
* */
-static int l_nsock_ncap_register(lua_State *l){
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
+static int l_nsock_ncap_register(lua_State *L){
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
size_t testdatasz;
- const char* testdata = luaL_checklstring(l, 2, &testdatasz);
+ const char* testdata = luaL_checklstring(L, 2, &testdatasz);
struct timeval now = *nsock_gettimeofday();
if(!udata->nsiod || !udata->ncap_socket) {
- luaL_argerror(l, 1, "You can't register to nsock-pcap if it wasn't opened.");
+ luaL_argerror(L, 1, "You can't register to nsock-pcap if it wasn't opened.");
return 0;
}
if(udata->ncap_request){
- luaL_argerror(l, 1, "You are already registered to this socket.");
+ luaL_argerror(L, 1, "You are already registered to this socket.");
return 0;
}
@@ -1033,7 +1033,7 @@ static int l_nsock_ncap_register(lua_State *l){
TIMEVAL_MSEC_ADD(nr->end_time, now, udata->timeout);
nr->key = strdup(hex((char*)testdata, testdatasz));
- nr->l = l;
+ nr->L = L;
nr->ncap_cback_ref = udata->ncap_cback_ref;
/* always create new event. */
nr->nseid = nsock_pcap_read_packet(nsp,
@@ -1052,14 +1052,14 @@ static int l_nsock_ncap_register(lua_State *l){
*
* return values: status(true/false), capture_len/error_msg, layer2data, layer3data
* */
-int l_nsock_pcap_receive(lua_State *l){
- l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(l, 1, "nsock");
+int l_nsock_pcap_receive(lua_State *L){
+ l_nsock_udata* udata = (l_nsock_udata*) luaL_checkudata(L, 1, "nsock");
if(!udata->nsiod || !udata->ncap_socket) {
- luaL_argerror(l, 1, "You can't receive to nsock-pcap if it wasn't opened.");
+ luaL_argerror(L, 1, "You can't receive to nsock-pcap if it wasn't opened.");
return 0;
}
if(!udata->ncap_request){
- luaL_argerror(l, 1, "You can't it's not registered");
+ luaL_argerror(L, 1, "You can't it's not registered");
return 0;
}
@@ -1075,26 +1075,26 @@ int l_nsock_pcap_receive(lua_State *l){
/* no data yet? suspend thread */
nr->suspended = 1;
- return lua_yield(l, 0);
+ return lua_yield(L, 0);
}
/* (free) excute callback function from lua script */
-char* ncap_request_do_callback(nsock_event nse, lua_State *l, int ncap_cback_ref){
+char* ncap_request_do_callback(nsock_event nse, lua_State *L, int ncap_cback_ref){
const unsigned char *l2_data, *l3_data;
size_t l2_len, l3_len, packet_len;
nse_readpcap(nse, &l2_data, &l2_len, &l3_data, &l3_len, &packet_len, NULL);
- lua_rawgeti(l, LUA_REGISTRYINDEX, ncap_cback_ref);
- lua_pushnumber(l, packet_len);
- lua_pushlstring(l, (char*)l2_data, l2_len);
- lua_pushlstring(l, (char*)l3_data, l3_len);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, ncap_cback_ref);
+ lua_pushnumber(L, packet_len);
+ lua_pushlstring(L, (char*)l2_data, l2_len);
+ lua_pushlstring(L, (char*)l3_data, l3_len);
- lua_call(l, 3, 1);
+ lua_call(L, 3, 1);
/* get string from top of the stack*/
size_t testdatasz;
- const char* testdata = lua_tolstring(l, -1, &testdatasz);
- // lua_pop(l, 1);/* just in case [nope, it's not needed]*/
+ const char* testdata = lua_tolstring(L, -1, &testdatasz);
+ // lua_pop(L, 1);/* just in case [nope, it's not needed]*/
char *key = strdup(hex((char*)testdata, testdatasz));
return key;
@@ -1110,7 +1110,7 @@ void l_nsock_pcap_receive_handler(nsock_pool nsp, nsock_event nse, void *userdat
switch(nse_status(nse)) {
case NSE_STATUS_SUCCESS:{
- char *key = ncap_request_do_callback(nse, nr->l, nr->ncap_cback_ref);
+ char *key = ncap_request_do_callback(nse, nr->L, nr->ncap_cback_ref);
/* processes threads that receive every packet */
this_event_restored += ncap_request_set_results(nse, "");
@@ -1221,21 +1221,21 @@ void ncap_request_set_result(nsock_event nse, struct ncap_request *nr) {
/* if lua thread was suspended, restore it. If it wasn't, just return results
* (push them on the stack and return) */
int ncap_restore_lua(ncap_request *nr){
- lua_State *l = nr->l;
+ lua_State *L = nr->L;
if(nr->r_success){
- lua_pushboolean(l, true);
- lua_pushnumber(l, nr->packetsz);
- lua_pushlstring(l, (char*)nr->r_layer2, nr->r_layer2_len);
- lua_pushlstring(l, (char*)nr->r_layer3, nr->r_layer3_len);
+ lua_pushboolean(L, true);
+ lua_pushnumber(L, nr->packetsz);
+ lua_pushlstring(L, (char*)nr->r_layer2, nr->r_layer2_len);
+ lua_pushlstring(L, (char*)nr->r_layer3, nr->r_layer3_len);
}else{
- lua_pushnil(l);
- lua_pushstring(l, nr->r_status);
- lua_pushnil(l);
- lua_pushnil(l);
+ lua_pushnil(L);
+ lua_pushstring(L, nr->r_status);
+ lua_pushnil(L);
+ lua_pushnil(L);
}
bool suspended = nr->suspended;
- nr->l = NULL;
+ nr->L = NULL;
nr->ncap_cback_ref = 0; /* this ref is freed in different place (on udata->ncap_cback_ref) */
if(nr->key) free(nr->key);
if(nr->r_status) free(nr->r_status);
@@ -1245,7 +1245,7 @@ int ncap_restore_lua(ncap_request *nr){
free(nr);
if(suspended) /* lua process is suspended */
- return process_waiting2running(l, 4);
+ return process_waiting2running(L, 4);
else /* not suspended, just pass output */
return 4;
}
@@ -1254,9 +1254,9 @@ int ncap_restore_lua(ncap_request *nr){
/****************** DNET ******************************************************/
-static int l_dnet_open_ethernet(lua_State* l);
-static int l_dnet_close_ethernet(lua_State* l);
-static int l_dnet_send_ethernet(lua_State* l);
+static int l_dnet_open_ethernet(lua_State *L);
+static int l_dnet_close_ethernet(lua_State *L);
+static int l_dnet_send_ethernet(lua_State *L);
static luaL_reg l_dnet [] = {
{"ethernet_open", l_dnet_open_ethernet},
@@ -1265,14 +1265,14 @@ static luaL_reg l_dnet [] = {
{NULL, NULL}
};
-int l_dnet_open(lua_State* l) {
- luaL_newmetatable(l, "dnet");
- lua_createtable(l, 5, 0);
- luaL_register(l, NULL, l_dnet);
- lua_setfield(l, -2, "__index");
- lua_pushliteral(l, "");
- lua_setfield(l, -2, "__metatable"); // protect metatable
- lua_pop(l, 1);
+int l_dnet_open(lua_State *L) {
+ luaL_newmetatable(L, "dnet");
+ lua_createtable(L, 0, 5);
+ luaL_register(L, NULL, l_dnet);
+ lua_setfield(L, -2, "__index");
+ lua_pushliteral(L, "");
+ lua_setfield(L, -2, "__metatable"); // protect metatable
+ lua_pop(L, 1);
return NSOCK_WRAPPER_SUCCESS;
}
@@ -1281,23 +1281,23 @@ struct l_dnet_udata {
eth_t *eth;
};
-int l_dnet_new(lua_State* l) {
+int l_dnet_new(lua_State *L) {
struct l_dnet_udata* udata;
- udata = (struct l_dnet_udata*) lua_newuserdata(l, sizeof(struct l_dnet_udata));
- luaL_getmetatable(l, "dnet");
- lua_setmetatable(l, -2);
+ udata = (struct l_dnet_udata*) lua_newuserdata(L, sizeof(struct l_dnet_udata));
+ luaL_getmetatable(L, "dnet");
+ lua_setmetatable(L, -2);
udata->interface= NULL;
udata->eth = NULL;
return 1;
}
-int l_dnet_get_interface_link(lua_State* l) {
- const char* interface_name = luaL_checkstring(l, 1);
+int l_dnet_get_interface_link(lua_State *L) {
+ const char* interface_name = luaL_checkstring(L, 1);
struct interface_info *ii = getInterfaceByName((char*)interface_name);
if(!ii){
- lua_pushnil(l);
+ lua_pushnil(L);
return 1;
}
const char *s= NULL;
@@ -1317,9 +1317,9 @@ int l_dnet_get_interface_link(lua_State* l) {
break;
}
if(s)
- lua_pushstring(l, s);
+ lua_pushstring(L, s);
else
- lua_pushnil(l);
+ lua_pushnil(L);
return 1;
}
@@ -1365,13 +1365,13 @@ void ldnet_eth_close_cached(const char *device) {
return;
}
-static int l_dnet_open_ethernet(lua_State* l){
- l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(l, 1, "dnet");
- const char* interface_name = luaL_checkstring(l, 2);
+static int l_dnet_open_ethernet(lua_State *L){
+ l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(L, 1, "dnet");
+ const char* interface_name = luaL_checkstring(L, 2);
struct interface_info *ii = getInterfaceByName((char*)interface_name);
if(!ii || ii->device_type!=devt_ethernet){
- luaL_argerror(l, 2, "device is not valid ethernet interface");
+ luaL_argerror(L, 2, "device is not valid ethernet interface");
return 0;
}
udata->interface= strdup(interface_name);
@@ -1380,10 +1380,10 @@ static int l_dnet_open_ethernet(lua_State* l){
return 0;
}
-static int l_dnet_close_ethernet(lua_State* l){
- l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(l, 1, "dnet");
+static int l_dnet_close_ethernet(lua_State *L){
+ l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(L, 1, "dnet");
if(!udata->interface || !udata->eth){
- luaL_argerror(l, 1, "dnet is not valid opened ethernet interface");
+ luaL_argerror(L, 1, "dnet is not valid opened ethernet interface");
return 0;
}
@@ -1394,20 +1394,20 @@ static int l_dnet_close_ethernet(lua_State* l){
return 0;
}
-static int l_dnet_send_ethernet(lua_State* l){
- l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(l, 1, "dnet");
+static int l_dnet_send_ethernet(lua_State *L){
+ l_dnet_udata* udata = (l_dnet_udata*) luaL_checkudata(L, 1, "dnet");
size_t packetsz = 0;
- const char* packet = luaL_checklstring(l, 2, &packetsz);
+ const char* packet = luaL_checklstring(L, 2, &packetsz);
if(!udata->interface || !udata->eth){
- luaL_argerror(l, 1, "dnet is not valid opened ethernet interface");
+ luaL_argerror(L, 1, "dnet is not valid opened ethernet interface");
return 0;
}
eth_send(udata->eth, packet, packetsz);
return 0;
}
-int l_clock_ms(lua_State* l){
+int l_clock_ms(lua_State *L){
struct timeval tv;
gettimeofday(&tv, NULL);
// no rounding error
@@ -1416,10 +1416,6 @@ int l_clock_ms(lua_State* l){
usec = tv.tv_sec*1000;
usec += (int)(tv.tv_usec/1000); // make sure it's integer.
- lua_pushnumber(l, usec);
+ lua_pushnumber(L, usec);
return 1;
}
-
-
-
-