nse_nsock.cc

来自「Ubuntu packages of security software。 相」· CC 代码 · 共 1,410 行 · 第 1/3 页

CC
1,410
字号
#include "nse_nsock.h"#include "nse_auxiliar.h"#include "nse_macros.h"#include "nse_string.h"#include "nse_debug.h"#include "nsock.h"#include "nmap_error.h"/* #include "osscan.h" */#include "NmapOps.h"#include <stdio.h>#include <stdlib.h>#include <errno.h>#include "utils.h"#include "tcpip.h"#if HAVE_OPENSSL#include <openssl/ssl.h>#endif#define SCRIPT_ENGINE			"SCRIPT ENGINE"#define NSOCK_WRAPPER			"NSOCK WRAPPER"#define NSOCK_WRAPPER_SUCCESS		0 #define NSOCK_WRAPPER_ERROR		2 #define NSOCK_WRAPPER_BUFFER_OK 1#define NSOCK_WRAPPER_BUFFER_MOREREAD 2#define FROM 	1#define TO 	2#define DEFAULT_TIMEOUT 30000extern NmapOps o;// defined in nse_main.cc but also declared here// to keep the .h files cleanint process_waiting2running(lua_State* l, int resume_arguments);static int l_nsock_connect(lua_State* l);static int l_nsock_connect_queued(lua_State* l);static int l_nsock_send(lua_State* l);static int l_nsock_receive(lua_State* l);static int l_nsock_receive_lines(lua_State* l);static int l_nsock_receive_bytes(lua_State* l);static int l_nsock_get_info(lua_State* l);static int l_nsock_gc(lua_State* l);static int l_nsock_close(lua_State* l);static int l_nsock_set_timeout(lua_State* l);static int l_nsock_receive_buf(lua_State* l);static int l_nsock_ncap_open(lua_State* l);static int l_nsock_ncap_close(lua_State* l);static int l_nsock_ncap_register(lua_State *l);static int l_nsock_pcap_receive(lua_State* l);void l_nsock_connect_handler(nsock_pool nsp, nsock_event nse, void *lua_state);void l_nsock_send_handler(nsock_pool nsp, nsock_event nse, void *lua_state);void l_nsock_receive_handler(nsock_pool nsp, nsock_event nse, void *lua_state);void l_nsock_receive_buf_handler(nsock_pool nsp, nsock_event nse, void *lua_state);int l_nsock_check_buf(lua_State* l);int l_nsock_checkstatus(lua_State* l, nsock_event nse);void l_nsock_trace(nsock_iod nsiod, char* message, int direction);char* inet_ntop_both(int af, const void* v_addr, char* ipstring);unsigned short inet_port_both(int af, const void* v_addr);static luaL_reg l_nsock [] = {	{"connect", l_nsock_connect_queued},	{"send", l_nsock_send},	{"receive", l_nsock_receive},	{"receive_lines", l_nsock_receive_lines},	{"receive_bytes", l_nsock_receive_bytes},	{"receive_buf", l_nsock_receive_buf},	{"get_info", l_nsock_get_info},	{"close", l_nsock_close},	{"set_timeout", l_nsock_set_timeout},	{"__gc",l_nsock_gc},	{"pcap_open",  		l_nsock_ncap_open},	{"pcap_close", 		l_nsock_ncap_close},	{"pcap_register",	l_nsock_ncap_register},	{"pcap_receive",  	l_nsock_pcap_receive},//	{"callback_test", l_nsock_pcap_callback_test},	{NULL, NULL}};static nsock_pool nsp;/* There can't be more opened descriptors than max_descriptors_allowed * (search below) If there are no more free slots, lua thread is * freezed and saved to nsock_connect_queue. It's restored when when a * descriptor becomes availble (after nsock_close). */static int nsock_descriptors_used; /* nsock descriptors currently in use */std::list<lua_State* > nsock_connect_queue; /* list of freezed threads waiting for desc *//* * Structure with nsock pcap descriptor. * shared between many lua threads */struct ncap_socket{	nsock_iod nsiod;	/* nsock pcap desc */	int references;		/* how many lua threads use this */	char *key;		/* (free) zero-terminated key used in map to 				 * address this structure. */};/* * */ struct ncap_request{	int suspended;		/* is the thread suspended? (lua_yield) */	lua_State *l;		/* lua_State of current process				 * or NULL if process isn't suspended */ 	nsock_event_id nseid;	/* nse for this specific lua_State */	struct timeval end_time;	char *key;		/* (free) zero-terminated key used in map to 				 * address this structure (hexified 'test') */                bool	 	received;   /* are results ready? */                bool	        r_success;  /* true-> okay,data ready to pass to user        			     * flase-> this statusstring contains error description */        char *          r_status;   /* errorstring */                unsigned char  *r_layer2;        size_t          r_layer2_len;        unsigned char  *r_layer3;        size_t          r_layer3_len;        size_t          packetsz;                int ncap_cback_ref; 	/* just copy of udata->ncap_cback_ref        			 * because we don't have access to udata in place        			 * we need to use this. */ };struct l_nsock_udata {	int timeout;	nsock_iod nsiod;	void *ssl_session;	/*used for buffered reading */	int bufidx; /*index inside lua's registry */	int bufused;		struct ncap_socket  *ncap_socket;	struct ncap_request *ncap_request;	int ncap_cback_ref;};void l_nsock_clear_buf(lua_State* l, l_nsock_udata* udata);int l_nsock_open(lua_State* l) {	auxiliar_newclass(l, "nsock", l_nsock);        nsp = nsp_new(NULL);	//nsp_settrace(nsp, o.debugging, o.getStartTime());	if (o.scriptTrace())		nsp_settrace(nsp, 5, o.getStartTime());	return NSOCK_WRAPPER_SUCCESS;}int l_nsock_new(lua_State* l) {	struct l_nsock_udata* udata;	udata = (struct l_nsock_udata*) lua_newuserdata(l, sizeof(struct l_nsock_udata));	auxiliar_setclass(l, "nsock", -1);	udata->nsiod = NULL;	udata->ssl_session = NULL;	udata->timeout = DEFAULT_TIMEOUT;	udata->bufidx = LUA_NOREF;	udata->bufused= 0;	udata->ncap_socket	= NULL;	udata->ncap_request	= NULL;	udata->ncap_cback_ref	= 0;		return 1;}int l_nsock_loop(int tout) {	return nsock_loop(nsp, tout);}int l_nsock_checkstatus(lua_State* l, nsock_event nse) {	enum nse_status status = nse_status(nse);	switch (status) {		case NSE_STATUS_SUCCESS:			lua_pushboolean(l, true);			return NSOCK_WRAPPER_SUCCESS;			break;		case NSE_STATUS_ERROR:		case NSE_STATUS_TIMEOUT:		case NSE_STATUS_CANCELLED:		case NSE_STATUS_KILL:		case NSE_STATUS_EOF:			lua_pushnil(l);			lua_pushstring(l, nse_status2str(status));			return NSOCK_WRAPPER_ERROR;			break;		case NSE_STATUS_NONE:		default:			fatal("%s: In: %s:%i This should never happen.", 					NSOCK_WRAPPER, __FILE__, __LINE__);			break;			}	return -1;}static int l_nsock_connect_queued(lua_State* l) {  /* We allow at least 10 even max_parallelism is 1 because a single     script might open a few sockets at once and we don't want it to     deadlock when it tries to open the 2nd one. */	const int max_descriptors_allowed = MAX(o.max_parallelism, 10);			l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1);		if(udata->nsiod!=NULL){		/*should a script try to connect a socket, which is already connected		 * we close the old connection, since it would have no access to it 		 * anyways		 */		if(o.scriptTrace()){			log_write(LOG_STDOUT,"%s: Trying to connect already connected socket - closing!\n",SCRIPT_ENGINE);		}		l_nsock_close(l);		lua_pop(l,1);	}			if(nsock_descriptors_used >= max_descriptors_allowed){		/* wait for free descriptor */		nsock_connect_queue.push_back(l);		/* I must know how many arguments are passed to nsock_connect. 		 * is there a better way? */		int arguments = 3;		const char *how = luaL_optstring(l, 4, "");		if(how != ""){			arguments = 4;			int port = luaL_optinteger(l, 5, -1);			if(port!=-1)				arguments = 5;		}				if(o.scriptTrace())			log_write(LOG_STDOUT, "NSOCK_connect_queued: thread queued (%i args) %p\n", arguments, (void *)l); 		return lua_yield(l, arguments);	}	return l_nsock_connect(l);}void l_nsock_connect_queued_handler(nsock_pool nsp, nsock_event nse, void *lua_state) {	lua_State* l = (lua_State*) lua_state;	/* well, this is really hackish, we can't just do process_waiting2running, because	 * nsock_connect() can do lua_yield().	 * Instead, we first execute nsock_connect, and if it returns lua_yield() (ie. -1)	 * than we don't do process_waiting2running. 	 * So, in summary we can do two lua_yield() on thread (one in l_nsock_connect_queued,	 * second in l_nsock_connect). But it works for me. */	int r = l_nsock_connect(l);	if(r != -1)		process_waiting2running((lua_State*) lua_state, 0);}static int l_nsock_connect(lua_State* l) {	l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1);	const char* addr = luaL_checkstring(l, 2);	unsigned short port = (unsigned short) luaL_checkint(l, 3);	const char *how = luaL_optstring(l, 4, "tcp");	const char* error;	struct addrinfo *dest;	int error_id;		l_nsock_clear_buf(l, udata);		error_id = getaddrinfo(addr, NULL, NULL, &dest);	if (error_id) {		error = gai_strerror(error_id);		lua_pushboolean(l, false);		lua_pushstring(l, error);		return 2;	}	udata->nsiod = nsi_new(nsp, NULL);	nsock_descriptors_used++;	switch (how[0]) {		case 't':			if (strcmp(how, "tcp")) goto error;			nsock_connect_tcp(nsp, udata->nsiod, l_nsock_connect_handler, 					udata->timeout, l, dest->ai_addr, dest->ai_addrlen, port);			break;		case 'u':			if (strcmp(how, "udp")) goto error;			nsock_connect_udp(nsp, udata->nsiod, l_nsock_connect_handler, 					l, dest->ai_addr, dest->ai_addrlen, port);			break;		case 's':			if (strcmp(how, "ssl")) goto error;#ifdef HAVE_OPENSSL			nsock_connect_ssl(nsp, udata->nsiod, l_nsock_connect_handler, 					udata->timeout, l, dest->ai_addr, dest->ai_addrlen, port, 					udata->ssl_session);			break;#else			lua_pushboolean(l, false);			lua_pushstring(l, "Sorry, you don't have OpenSSL\n");			return 2;#endif		default:			goto error;			break;	}	freeaddrinfo(dest);	return lua_yield(l, 0);error:	freeaddrinfo(dest);	luaL_argerror(l, 4, "invalid connection method");	return 0;}void l_nsock_connect_handler(nsock_pool nsp, nsock_event nse, void *lua_state) {	lua_State* l = (lua_State*) lua_state;	if(o.scriptTrace()) {		l_nsock_trace(nse_iod(nse), "CONNECT", TO);	}	if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) {		process_waiting2running((lua_State*) lua_state, 1);	} else {		process_waiting2running((lua_State*) lua_state, 2);	}}static int l_nsock_send(lua_State* l) {	l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1);	const char* string = luaL_checkstring(l, 2);	size_t string_len = lua_objlen (l, 2);	char* hexified;		l_nsock_clear_buf(l,udata); 	if(udata->nsiod == NULL) {		lua_pushboolean(l, false);		lua_pushstring(l, "Trying to send through a closed socket\n");		return 2;		}	if(o.scriptTrace()) {		hexified = nse_hexify((const void*)string, string_len);		l_nsock_trace(udata->nsiod, hexified, TO);		free(hexified);	}	nsock_write(nsp, udata->nsiod, l_nsock_send_handler, udata->timeout, l, string, string_len);	return lua_yield(l, 0);}void l_nsock_send_handler(nsock_pool nsp, nsock_event nse, void *lua_state) {	lua_State* l = (lua_State*) lua_state;		if(l_nsock_checkstatus(l, nse) == NSOCK_WRAPPER_SUCCESS) {		process_waiting2running((lua_State*) lua_state, 1);	} else {		process_waiting2running((lua_State*) lua_state, 2);	}}static int l_nsock_receive(lua_State* l) {	l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1);	l_nsock_clear_buf(l, udata);	if(udata->nsiod == NULL) {		lua_pushboolean(l, false);		lua_pushstring(l, "Trying to receive through a closed socket\n");		return 2;		}	nsock_read(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, l);	return lua_yield(l, 0);}static int l_nsock_receive_lines(lua_State* l) {	l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1);	int nlines = (int) luaL_checknumber(l, 2);	l_nsock_clear_buf(l, udata);		if(udata->nsiod == NULL) {		lua_pushboolean(l, false);		lua_pushstring(l, "Trying to receive lines through a closed socket\n");		return 2;		}	nsock_readlines(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, l, nlines);	return lua_yield(l, 0);}static int l_nsock_receive_bytes(lua_State* l) {	l_nsock_udata* udata = (l_nsock_udata*) auxiliar_checkclass(l, "nsock", 1);	int nbytes = (int) luaL_checknumber(l, 2);		l_nsock_clear_buf(l, udata);	if(udata->nsiod == NULL) {		lua_pushboolean(l, false);		lua_pushstring(l, "Trying to receive bytes through a closed socket\n");		return 2;		}	nsock_readbytes(nsp, udata->nsiod, l_nsock_receive_handler, udata->timeout, l, nbytes);	return lua_yield(l, 0);}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);		}		lua_pushlstring(l, rcvd_string, rcvd_len);		process_waiting2running((lua_State*) lua_state, 2);	} else {		process_waiting2running((lua_State*) lua_state, 2);	}}void l_nsock_trace(nsock_iod nsiod, char* message, int direction) { 	int status; 	int protocol; 	int af; 	struct sockaddr local; 	struct sockaddr remote; 	char* ipstring_local = (char*) safe_malloc(sizeof(char) * INET6_ADDRSTRLEN);	char* ipstring_remote = (char*) safe_malloc(sizeof(char) * INET6_ADDRSTRLEN);	if(!nsi_is_pcap(nsiod)){		status =  nsi_getlastcommunicationinfo(nsiod, &protocol, &af,			&local, &remote, sizeof(sockaddr)); 		log_write(LOG_STDOUT, "SCRIPT ENGINE: %s %s:%d %s %s:%d | %s\n", 			(protocol == IPPROTO_TCP)? "TCP" : "UDP",

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?