mirror of
https://github.com/nmap/nmap.git
synced 2026-02-07 22:16:33 +00:00
Now does most of it's work through Lua:
From Nmap-dev: "Many of the changes consist of changing how Nmap interfaces
with Lua that were sometimes awkward or inflexible. Most of the functions
have been made to be callable directly by Lua which offers many technical
advantages: stack management is alleviated, errors are handled cleanly and
are more descriptive, and there is increased reusability."
Additionally:
-- Moved all lua_State * symbols from "l" to "L". This is to maintain
consistency with other Lua libraries (convention) and to make our macros portable.
-- Moved file system manipulation over to nse_fs.cc (from nse_init.cc)
191 lines
5.0 KiB
C++
191 lines
5.0 KiB
C++
#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 <nmap>/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
|