nse_main.cc

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

CC
680
字号
	return SCRIPT_ENGINE_SUCCESS;}// If the target still has scripts in either running_scripts// or waiting_scripts then it is still runningint has_target_finished(Target *target) {	std::list<struct thread_record>::iterator iter;	for (iter = waiting_scripts.begin(); iter != waiting_scripts.end(); iter++)		if (target == iter->rr->host) return 0;	for (iter = running_scripts.begin(); iter != running_scripts.end(); iter++)		if (target == iter->rr->host) return 0;	return 1;}int process_finalize(lua_State* l, unsigned int registry_idx) {	luaL_unref(l, LUA_REGISTRYINDEX, registry_idx);	struct thread_record thr = running_scripts.front();	running_scripts.pop_front();	if (has_target_finished(thr.rr->host))		thr.rr->host->stopTimeOutClock(NULL);	return SCRIPT_ENGINE_SUCCESS;}int process_waiting2running(lua_State* l, int resume_arguments) {	std::list<struct thread_record>::iterator iter;	// find the lua state which has received i/o	for(	iter = waiting_scripts.begin(); 		(*iter).thread != l;		iter++) {		// It is very unlikely that a thread which		// is not in the waiting queue tries to		// continue		// it does happen when they try to do socket i/o		// inside a pcall		// This also happens when we timeout a script		// In this case, the script is still in the waiting		// queue and we will have manually removed it from		// the waiting queue so we just return.		if(iter == waiting_scripts.end())			return SCRIPT_ENGINE_SUCCESS;	}	(*iter).resume_arguments = resume_arguments;	// put the thread back into the running	// queue	running_scripts.push_front((*iter));	waiting_scripts.erase(iter);	return SCRIPT_ENGINE_SUCCESS;}/* Tries to get the script id and store it in the script scan result structure * if no 'id' field is found, the filename field is used which we set in the  * setup phase. If someone changed the filename field to a nonstring we complain * */int process_getScriptId(lua_State* l, struct script_scan_result *ssr) {	lua_getfield(l, -2, "id");	lua_getfield(l, -3, "filename");	if(lua_isstring(l, -2)) {		ssr->id = strdup(lua_tostring (l, -2));	} else if(lua_isstring(l, -1)) {		ssr->id = strdup(lua_tostring (l, -1));	} else {		error("%s: The script has no 'id' entry, the 'filename' entry was changed to:",			SCRIPT_ENGINE);		l_dumpValue(l, -1);		return SCRIPT_ENGINE_ERROR;	}	lua_pop(l, 2);	return SCRIPT_ENGINE_SUCCESS;}/* try all host and all port rules against the  * state of the current target * make a list with run records for the scripts * which want to run * process all scripts in the list * */int process_preparehost(lua_State* l, Target* target, std::list<struct thread_record>& torun_threads) {	PortList* plist = &(target->ports);	Port* current = NULL;	size_t rules_count;	unsigned int i;	std::vector<run_record> torun;	std::vector<run_record>::iterator iter;	struct run_record rr;	if (!target->timeOutClockRunning())		target->startTimeOutClock(NULL);	/* find the matching hostrules	 * */	lua_getglobal(l, HOSTTESTS);	rules_count = lua_objlen(l, -1);	for(i = 1; i <= rules_count; i++) {		lua_rawgeti(l, -1, i);		lua_getfield(l, -1, "hostrule");		lua_newtable(l);		set_hostinfo(l, target);		SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 1, 1, 0));		if(lua_isboolean (l, -1) && lua_toboolean(l, -1)) {			rr.type = 0;			rr.index = i;			rr.port = NULL;			rr.host = target;			torun.push_back(rr);			SCRIPT_ENGINE_DEBUGGING(				lua_getfield(l, -2, "filename");				log_write(LOG_STDOUT, "%s: Will run %s against %s\n",					SCRIPT_ENGINE,					lua_tostring(l, -1),					target->targetipstr());				lua_pop(l, 1);			)		}		lua_pop(l, 2);	}	/* find the matching port rules	 * */	lua_getglobal(l, PORTTESTS);	/* we only publish hostinfo once per portrule */	lua_newtable(l);	set_hostinfo(l, target);	/* because of the port iteration API we need to awkwardly iterate	 * over the kinds of ports we're interested in explictely.	 * */	current = NULL;	while((current = plist->nextPort(current, TCPANDUDP, PORT_OPEN)) != NULL) {		SCRIPT_ENGINE_TRY(process_pickScriptsForPort(l, target, current, torun));	}	while((current = plist->nextPort(current, TCPANDUDP, PORT_OPENFILTERED)) != NULL) {		SCRIPT_ENGINE_TRY(process_pickScriptsForPort(l, target, current, torun));	}	// pop the hostinfo, we don't need it anymore	lua_pop(l, 1);	/* ok, let's setup threads for the scripts which said they'd like	 * to run 	 * Remember:	 * we have the hosttestset and the porttestset on the stack!	 * */	struct thread_record tr;	for(iter = torun.begin(); iter != torun.end(); iter++) {		/* If it is a host rule, execute the action		 * and append the output to the host output i		 * If it is a port rule, append the output to		 * the port and increase the number of scripts		 * which produced output. We need that number		 * to generate beautiful output later.		 * */		switch((*iter).type) {			case 0: // this script runs against a host				lua_pushvalue(l, -2);				SCRIPT_ENGINE_TRY(process_preparethread(l, (*iter), &tr));				lua_pop(l, 1);				break;			case 1: // this script runs against a port				lua_pushvalue(l, -1);				SCRIPT_ENGINE_TRY(process_preparethread(l, (*iter), &tr));				lua_pop(l, 1);				break;			default:				fatal("%s: In: %s:%i This should never happen.", 						SCRIPT_ENGINE, __FILE__, __LINE__);		}		torun_threads.push_back(tr);	}	lua_pop(l, 2);	torun.clear();	return SCRIPT_ENGINE_SUCCESS;}int process_preparerunlevels(std::list<struct thread_record> torun_threads) {	std::list<struct thread_record> current_runlevel;	std::list<struct thread_record>::iterator runlevel_iter;	double runlevel_idx = 0.0;		torun_threads.sort(CompareRunlevels());	for(	runlevel_iter = torun_threads.begin(); 		runlevel_iter != torun_threads.end(); 		runlevel_iter++) {		if(runlevel_idx < (*runlevel_iter).runlevel) {			runlevel_idx = (*runlevel_iter).runlevel;			current_runlevel.clear();			//push_back an empty list in which we store all scripts of the 			//current runlevel...			torun_scripts.push_back(current_runlevel);		}		torun_scripts.back().push_back(*runlevel_iter);	}	return SCRIPT_ENGINE_SUCCESS;}/* Because we can't iterate over all ports of interest in one go * we need to du port matching in a separate function (unlike host * rule matching) * Note that we assume that at -2 on the stack we can find the portrules * and at -1 the hostinfo table * */int process_pickScriptsForPort(		lua_State* l, 		Target* target, 		Port* port,		std::vector<run_record>& torun) {	size_t rules_count = lua_objlen(l, -2);	struct run_record rr;	unsigned int i;	for(i = 1; i <= rules_count; i++) {		lua_rawgeti(l, -2, i);		lua_getfield(l, -1, PORTRULE);		lua_pushvalue(l, -3);		lua_newtable(l);		set_portinfo(l, port);		SCRIPT_ENGINE_LUA_TRY(lua_pcall(l, 2, 1, 0));		if(lua_isboolean (l, -1) && lua_toboolean(l, -1)) {			rr.type = 1;			rr.index = i;			rr.port = port;			rr.host = target;			torun.push_back(rr);			SCRIPT_ENGINE_DEBUGGING(					lua_getfield(l, -2, "filename");					log_write(LOG_STDOUT, "%s: Will run %s against %s:%d\n",						SCRIPT_ENGINE,						lua_tostring(l, -1),						target->targetipstr(),						port->portno);					lua_pop(l, 1);					)		} else if(!lua_isboolean (l, -1)) {			lua_getfield(l, -2, "filename");			error("%s: Rule in %s returned %s but boolean was expected.",					SCRIPT_ENGINE,					lua_tostring(l, -1),					lua_typename(l, lua_type(l, -2)));			return SCRIPT_ENGINE_LUA_ERROR;		}		lua_pop(l, 2);	}	return SCRIPT_ENGINE_SUCCESS;}/* Create a new lua thread and prepare it for execution * we store target info in the thread so that the mainloop * knows where to put the script result * */int process_preparethread(lua_State* l, struct run_record rr, struct thread_record* tr){	lua_State *thread = lua_newthread(l);	lua_rawgeti(l, -2, rr.index); // get the script closure	// move the script closure into the thread	lua_xmove(l, thread, 1); 	// store the target of this thread in the thread	struct run_record *rr_thread = (struct run_record*) safe_malloc(sizeof(struct run_record));	rr_thread->type = rr.type;	rr_thread->index = rr.index;	rr_thread->host = rr.host;	rr_thread->port = rr.port;		lua_getfield(thread, -1, RUNLEVEL);	tr->runlevel = lua_tonumber(thread, -1);	lua_pop(thread, 1);	// prepare the thread for a resume by	// pushing the action method onto the stack	lua_getfield(thread, -1, ACTION);	// make the info table	lua_newtable(thread); 	set_hostinfo(thread, rr.host);	tr->thread = thread;	tr->rr = rr_thread;	tr->resume_arguments = 1;	// we store the thread in the registry to prevent	// garbage collection +	tr->registry_idx = luaL_ref(l, LUA_REGISTRYINDEX);	/* if this is a host rule we don't have	 * a port state	 * */	if(rr.port != NULL) {		lua_newtable(thread);		set_portinfo(thread, rr.port);		tr->resume_arguments = 2;	}	return SCRIPT_ENGINE_SUCCESS;}

⌨️ 快捷键说明

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