nse_init.cc

来自「Ubuntu packages of security software。 相」· CC 代码 · 共 816 行 · 第 1/2 页

CC
816
字号
	return SCRIPT_ENGINE_SUCCESS;}int init_loadcategories(lua_State* l, std::vector<std::string> categories, std::vector<std::string> &unusedTags) {	std::vector<std::string>::iterator iter;	std::vector<std::string> 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;}int init_fetchfile(char *path, size_t path_len, char* file) {	int type;	type = nmap_fetchfile(path, path_len, file);	// lets look in <nmap>/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);				}	return type;}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 a modification of init_fetchfile that first looks for an * absolute file name. */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);}/* 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 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;}int init_loaddir(lua_State* l, char* dirname) {	std::vector<std::string> files;	char* c_iter;	SCRIPT_ENGINE_TRY(init_scandir(dirname, files, FILES));		std::vector<std::string>::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);	}	return SCRIPT_ENGINE_SUCCESS;}#ifdef WIN32int init_scandir(char* dirname, std::vector<std::string>& 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;}#elseint init_scandir(char* dirname, std::vector<std::string>& 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;}#endif/* 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_getglobal(l, "_G");	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);	std::string buf = 	 (std::string("err = \"Attempted to change the global '\" .. select(2, ...) .. \"' in ") 	 + std::string(filename)	 + std::string(" - use nmap.registry if you really want to share data between scripts.\"")	 + std::string("error(err)"));	SCRIPT_ENGINE_LUA_TRY(luaL_loadbuffer(l, buf.c_str(), buf.length(), "Global Access"));	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<std::string> required_fields;	required_fields.push_back(std::string(ACTION));	required_fields.push_back(std::string(DESCRIPTION));	std::vector<std::string>::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;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?