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