mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Moved the includes for Lua headers to the .cc files so they are not needlessly, repeatedly included. Similarly, moved some standard headers to the .cc files and reorganized includes to be uniform for all nse_* source files. Fixed whitespace (removed tabs).
196 lines
5.2 KiB
C++
196 lines
5.2 KiB
C++
|
|
extern "C" {
|
|
#include "lua.h"
|
|
#include "lauxlib.h"
|
|
}
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
const char *dirname = luaL_checkstring(L, 1);
|
|
int files_or_dirs = luaL_checkint(L, 2);
|
|
|
|
lua_createtable(L, 100, 0); // 100 files average
|
|
|
|
dir = FindFirstFile((std::string(dirname) + "\\*").c_str(), &entry);
|
|
|
|
if (dir == INVALID_HANDLE_VALUE)
|
|
{
|
|
error("%s: No files in '%s\\*'", SCRIPT_ENGINE, dirname);
|
|
return SCRIPT_ENGINE_ERROR;
|
|
}
|
|
|
|
while(!(morefiles == FALSE && GetLastError() == ERROR_NO_MORE_FILES)) {
|
|
// if we are looking for files and this file doesn't end with .nse or
|
|
// is a directory, then we don't look further at it
|
|
if(files_or_dirs == FILES) {
|
|
if(!((nse_check_extension(SCRIPT_ENGINE_EXTENSION, entry.cFileName))
|
|
&& !(entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
)) {
|
|
morefiles = FindNextFile(dir, &entry);
|
|
continue;
|
|
}
|
|
|
|
// if we are looking for dirs and this dir
|
|
// isn't a directory, then we don't look further at it
|
|
} else if(files_or_dirs == DIRS) {
|
|
if(!(entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
|
morefiles = FindNextFile(dir, &entry);
|
|
continue;
|
|
}
|
|
|
|
// they have passed an invalid value for files_or_dirs
|
|
} else {
|
|
fatal("%s: In: %s:%i This should never happen.",
|
|
SCRIPT_ENGINE, __FILE__, __LINE__);
|
|
}
|
|
|
|
// otherwise we add it to the results
|
|
// we assume that dirname ends with a directory separator of some kind
|
|
path = std::string(dirname) + "\\" + std::string(entry.cFileName);
|
|
lua_pushstring(L, path.c_str());
|
|
lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
|
|
morefiles = FindNextFile(dir, &entry);
|
|
}
|
|
|
|
|
|
return 1;
|
|
}
|
|
|
|
#else
|
|
|
|
int nse_scandir (lua_State *L) {
|
|
DIR* dir;
|
|
struct dirent* entry;
|
|
struct stat stat_entry;
|
|
const char *dirname = luaL_checkstring(L, 1);
|
|
int files_or_dirs = luaL_checkint(L, 2);
|
|
|
|
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
|