From 3ae4bcfa9e6a052fe1c592ca114a97dfd45c31fe Mon Sep 17 00:00:00 2001 From: batrick Date: Mon, 7 Jul 2008 17:31:38 +0000 Subject: [PATCH] Removed nse_string. Equivalent procedures are placed in nse_main and nse_nsock. nse_main now uses Lua to create printable output while a cleaner hexify procedure has been placed in nsock. nse_string is removed as a result. --- Makefile.in | 6 ++-- mswin32/nmap.vcproj | 8 ----- nse_init.cc | 46 ------------------------- nse_macros.h | 10 ------ nse_main.cc | 33 ++++++++++++++---- nse_nsock.cc | 65 +++++++++++++++++++++++++----------- nse_string.cc | 81 --------------------------------------------- nse_string.h | 8 ----- 8 files changed, 76 insertions(+), 181 deletions(-) delete mode 100644 nse_string.cc delete mode 100644 nse_string.h diff --git a/Makefile.in b/Makefile.in index 8587401a6..e8990e993 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_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 +NSE_SRC=nse_main.cc nse_nsock.cc nse_init.cc nse_fs.cc nse_nmaplib.cc nse_debug.cc nse_pcrelib.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_OBJS=nse_main.o nse_nsock.o nse_init.o nse_fs.o nse_nmaplib.o nse_debug.o nse_pcrelib.o NSESTDLIB=nsestdlib endif diff --git a/mswin32/nmap.vcproj b/mswin32/nmap.vcproj index f33e478d0..732a8ed78 100644 --- a/mswin32/nmap.vcproj +++ b/mswin32/nmap.vcproj @@ -286,10 +286,6 @@ RelativePath="..\nse_pcrelib.cc" > - - @@ -475,10 +471,6 @@ RelativePath="..\nse_pcrelib.h" > - - diff --git a/nse_init.cc b/nse_init.cc index b1b427152..f041f0ca0 100644 --- a/nse_init.cc +++ b/nse_init.cc @@ -22,26 +22,6 @@ extern NmapOps o; 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: @@ -65,16 +45,6 @@ static int error_function (lua_State *L) // for use with lua_pcall return 1; } -/* 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 @@ -109,22 +79,6 @@ static int loadfile (lua_State *L) 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 diff --git a/nse_macros.h b/nse_macros.h index e099a2479..d6c5ac8a5 100644 --- a/nse_macros.h +++ b/nse_macros.h @@ -47,15 +47,5 @@ #define MAX_FILENAME_LEN 4096 -#define NOT_PRINTABLE '.' - -// if the character is not printable -// and the character is not a tab -// and the character is not a new line -// and the character is not a carriage return -// return 0 -// otherwise return 1 -#define ISPRINT(c) ((!(c > 31 && c < 127) && c != 9 && c != 10 && c != 13)? 0 : 1) - #endif diff --git a/nse_main.cc b/nse_main.cc index 84d8ca7f2..c661e8560 100644 --- a/nse_main.cc +++ b/nse_main.cc @@ -5,7 +5,6 @@ #include "nse_nmaplib.h" #include "nse_debug.h" #include "nse_macros.h" -#include "nse_string.h" #include "nmap.h" #include "nmap_error.h" @@ -74,6 +73,21 @@ static int panic (lua_State *L) return 0; } +/* int escape_char (lua_State *L) + * + * This function is called via Lua through string.gsub. It's purpose is to + * escape characters. So the first sole character is changed to "\xxx". + */ +static int escape_char (lua_State *L) +{ + const char *a = luaL_checkstring(L, 1); + lua_pushliteral(L, "\\"); + lua_pushinteger(L, (int) *a); + lua_concat(L, 2); + return 1; +} + + int script_updatedb (void) { int status; @@ -381,17 +395,24 @@ int process_mainloop(lua_State *L) { // then we release the thread and remove it from the // running_scripts list - if(lua_isstring (current.thread, -1)) { - SCRIPT_ENGINE_TRY(process_getScriptId(current.thread, &ssr)); - ssr.output = nse_printable - (lua_tostring(current.thread, -1), lua_objlen(current.thread, -1)); + if(lua_isstring (current.thread, -1)) { // FIXME + lua_State *thread = current.thread; + SCRIPT_ENGINE_TRY(process_getScriptId(thread, &ssr)); + lua_getglobal(thread, "string"); + lua_getfield(thread, -1, "gsub"); + lua_replace(thread, -2); // remove string table + lua_pushvalue(thread, -2); // output FIXME + lua_pushliteral(thread, "[^%w%s%p]"); + lua_pushcclosure(thread, escape_char, 0); + lua_call(thread, 3, 1); + ssr.output = strdup(lua_tostring(thread, -1)); if(current.rr->type == 0) { current.rr->host->scriptResults.push_back(ssr); } else if(current.rr->type == 1) { current.rr->port->scriptResults.push_back(ssr); current.rr->host->ports.numscriptresults++; } - lua_pop(current.thread, 2); + lua_pop(thread, 2); } SCRIPT_ENGINE_TRY(process_finalize(L, current.registry_idx)); diff --git a/nse_nsock.cc b/nse_nsock.cc index 266af3888..f2885738f 100644 --- a/nse_nsock.cc +++ b/nse_nsock.cc @@ -1,6 +1,5 @@ #include "nse_nsock.h" #include "nse_macros.h" -#include "nse_string.h" #include "nse_debug.h" @@ -12,6 +11,8 @@ #include #include #include +#include +#include #include "utils.h" #include "tcpip.h" @@ -70,6 +71,44 @@ 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); unsigned short inet_port_both(int af, const void* v_addr); + +static std::string hexify (const char *str, size_t len) +{ + size_t num = 0; + std::ostringstream ret; + + // If more than 95% of the chars are printable, we escape unprintable chars + for (size_t i = 0; i < len; i++) + if (isprint(str[i])) + num++; + if ((double) num / (double) len >= 0.95) + { + for (size_t i = 0; i < len; i++) + { + if (isprint(str[i]) || isspace(str[i])) + ret << str[i]; + else + ret << std::setw(3) << "\\" << (unsigned int) str[i]; + } + return ret.str(); + } + + ret << std::setbase(16) << std::setfill('0'); + for (size_t i = 0; i < len; i += 16) + { + ret << std::setw(8) << i << ": "; + for (size_t j = i; j < i + 16; j++) + if (j < len) + ret << std::setw(2) << (unsigned int) str[j] << " "; + else + ret << " "; + for (size_t j = i; j < i + 16 && j < len; j++) + ret.put(isgraph(str[j]) ? (unsigned char) str[j] : ' '); + ret << std::endl; + } + return ret.str(); +} + static luaL_reg l_nsock [] = { {"connect", l_nsock_connect_queued}, {"send", l_nsock_send}, @@ -360,7 +399,6 @@ 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); @@ -370,11 +408,8 @@ static int l_nsock_send(lua_State *L) { return 2; } - if(o.scriptTrace()) { - hexified = nse_hexify((const void*)string, string_len); - l_nsock_trace(udata->nsiod, hexified, TO); - free(hexified); - } + if(o.scriptTrace()) + l_nsock_trace(udata->nsiod, hexify(string, string_len).c_str(), TO); nsock_write(nsp, udata->nsiod, l_nsock_send_handler, udata->timeout, L, string, string_len); return lua_yield(L, 0); @@ -443,16 +478,12 @@ void l_nsock_receive_handler(nsock_pool nsp, nsock_event nse, void *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) { rcvd_string = nse_readbuf(nse, &rcvd_len); - if(o.scriptTrace()) { - hexified = nse_hexify((const void*) rcvd_string, (size_t) rcvd_len); - l_nsock_trace(nse_iod(nse), hexified, FROM); - free(hexified); - } + if(o.scriptTrace()) + l_nsock_trace(nse_iod(nse), hexify(rcvd_string, (size_t) rcvd_len).c_str(), FROM); lua_pushlstring(L, rcvd_string, rcvd_len); process_waiting2running((lua_State*) lua_state, 2); @@ -668,7 +699,6 @@ void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_stat 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) { @@ -679,11 +709,8 @@ void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_stat rcvd_string = nse_readbuf(nse, &rcvd_len); - if(o.scriptTrace()) { - hexified = nse_hexify((const void*) rcvd_string, (size_t) rcvd_len); - l_nsock_trace(nse_iod(nse), hexified, FROM); - free(hexified); - } + if(o.scriptTrace()) + l_nsock_trace(nse_iod(nse), hexify(rcvd_string, (size_t) rcvd_len).c_str(), FROM); /* push the buffer and what we received from nsock on the stack and * concatenate both*/ lua_rawgeti(L, LUA_REGISTRYINDEX, udata->bufidx); diff --git a/nse_string.cc b/nse_string.cc deleted file mode 100644 index 6a334b920..000000000 --- a/nse_string.cc +++ /dev/null @@ -1,81 +0,0 @@ -#include "nse_string.h" - -#include "nbase.h" -#include "nse_macros.h" - -#include -#include - -int nse_isprint(int c) { - return ISPRINT(c); -} - -char* nse_printable(const void *data, unsigned int data_len) { - const unsigned char* c_data = (const unsigned char*) data; - char* result = (char*) safe_malloc((data_len+1)*sizeof(char)); - unsigned int i; - - for(i = 0; i < data_len; i++) { - if(nse_isprint(c_data[i])) - result[i] = c_data[i]; - else - result[i] = NOT_PRINTABLE; - } - - result[i] = '\0'; - - return result; -} - -char* nse_hexify(const void *data, unsigned int data_len) { - std::ostringstream osDump; - std::ostringstream osNums; - std::ostringstream osChars; - - const unsigned char* c_data = (const unsigned char*) data; - - unsigned long i; - unsigned int width = 16; - unsigned long printable_chars = 0; - - // if more than 95% of all characters are printable, we don't hexify - for(i = 0; i < data_len; i++) { - if(nse_isprint(c_data[i])) - printable_chars++; - } - - if((double)printable_chars > (double)data_len * 95.0 / 100.0) { - return nse_printable(data, data_len); - } - - osDump << std::endl; - for(i = 0; i < data_len; i++) - { - if(i < data_len) - { - char c = c_data[i]; - unsigned short n = (unsigned short)c_data[i]; - osNums << std::setbase(16) << std::setw(2) << std::setfill('0') << n << " "; - osChars << ((n < 32) || (n > 126) ? NOT_PRINTABLE : c); - } - if(((i % width) == width - 1) || ((i == data_len) && (osNums.str().size() > 0))) - { - osDump << std::setbase(16) - << std::setw(8) - << std::setfill('0') - << (i - (i % width)) << ": " - << std::setfill(' ') - << std::setiosflags(std::ios_base::left) - << std::setw(3 * width) - << osNums.str() - << osChars.str() - << std::resetiosflags(std::ios_base::left) - << std::endl; - osNums.str(""); - osChars.str(""); - } - } - - return strdup(osDump.str().c_str()); -} - diff --git a/nse_string.h b/nse_string.h deleted file mode 100644 index 24e4e9464..000000000 --- a/nse_string.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef NSE_STRING -#define NSE_STRING - -int nse_isprint(int c); -char* nse_hexify(const void *data, unsigned int data_len); -char* nse_printable(const void *data, unsigned int data_len); - -#endif