mirror of
https://github.com/nmap/nmap.git
synced 2025-12-09 22:21:29 +00:00
186 lines
5.1 KiB
C++
186 lines
5.1 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;
|
|
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
|