⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nasl_socket.c

📁 大国补丁后的nessus2.2.8的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Nessus Attack Scripting Language  * * Copyright (C) 2002 - 2004 Tenable Network Security * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */    /* -------------------------------------------------------------------- *  * This file contains all the functions related to the handling of the  *  * sockets within a NASL script - namely, this is the implementation    *  * of open_(priv_)?sock_(udp|tcp)(), send(), recv(), recv_line() and    *  * close().								 *  *----------------------------------------------------------------------*/      /*--------------------------------------------------------------------------*/#include <includes.h>#include "nasl.h"#include "nasl_tree.h"#include "nasl_global_ctxt.h"#include "nasl_func.h"#include "nasl_var.h"#include "nasl_lex_ctxt.h"#include "exec.h"#include "strutils.h"#include "nasl_packet_forgery.h"#include "nasl_debug.h"#ifndef EADDRNOTAVAIL#define EADDRNOTAVAIL EADDRINUSE#endif/*----------------------- Private functions ---------------------------*/static int unblock_socket(int soc){  int   flags =  fcntl(soc, F_GETFL, 0);  if (flags < 0)    {      perror("fcntl(F_GETFL)");      return -1;    }  if (fcntl(soc, F_SETFL, O_NONBLOCK | flags) < 0)    {      perror("fcntl(F_SETFL,O_NONBLOCK)");      return -1;    }  return 0;}static int block_socket(int soc){  int   flags =  fcntl(soc, F_GETFL, 0);  if (flags < 0)    {      perror("fcntl(F_GETFL)");      return -1;    }  if (fcntl(soc, F_SETFL, (~O_NONBLOCK) & flags) < 0)    {      perror("fcntl(F_SETFL,~O_NONBLOCK)");      return -1;    }  return 0;}/* * NASL automatically re-send data when a recv() on a UDP packet * fails. The point is to take care of packets lost en route. * * To do this, we store a copy of the data sent by a given socket * each time send() is called, and we re-send() it each time  * recv() is called and fails * */ /* add udp data in our cache */static int add_udp_data(struct arglist * script_infos, int soc, char * data, int len){ harglst * udp_data = arg_get_value(script_infos, "udp_data"); char name[12]; if(udp_data == NULL) {  udp_data = harg_create(123);  arg_add_value(script_infos, "udp_data", ARG_PTR, -1, udp_data); } snprintf(name, sizeof(name), "%d", soc);  if(harg_get_blob(udp_data, name) != NULL)  harg_set_blob(udp_data, name, len, data); else  harg_add_blob( udp_data, name, len, data); return 0;}/* get the udp data for socket <soc> */static char * get_udp_data(struct arglist * script_infos, int soc, int * len){ harglst * udp_data = arg_get_value(script_infos, "udp_data"); char name[12]; char * ret;  if(udp_data == NULL)  return NULL;  snprintf(name, sizeof(name), "%d", soc); ret = harg_get_blob(udp_data, name); if(ret == NULL)  return NULL;  *len = harg_get_size(udp_data, name); return ret;}/* remove the udp data for socket <soc> */static void rm_udp_data(struct arglist * script_infos, int soc){ harglst * udp_data = arg_get_value(script_infos, "udp_data"); char name[12];  if(udp_data == NULL)  return;  snprintf(name, sizeof(name), "%d", soc); harg_remove(udp_data, name);}/*-------------------------------------------------------------------*/static tree_cell * nasl_open_privileged_socket(lex_ctxt * lexic, int proto){ struct arglist * script_infos = lexic->script_infos; int sport, current_sport = -1; int dport; int sock; int e; struct sockaddr_in addr, daddr; struct in_addr * p; int to = get_int_local_var_by_name(lexic, "timeout", lexic->recv_timeout); tree_cell * retc; struct timeval tv; fd_set rd; int opt; unsigned int opt_sz;    sport = get_int_local_var_by_name(lexic, "sport", -1); dport = get_int_local_var_by_name(lexic, "dport", -1); if(dport <= 0)   {     nasl_perror(lexic, "open_private_socket: missing or undefined parameter dport!\n");     return NULL;   }  if(sport < 0) current_sport = 1023;restart:  bzero(&addr, sizeof(addr)); if(proto == IPPROTO_TCP)  sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); else  sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);     /*  * We will bind to a privileged port. Let's declare  * our socket ready for reuse  */  if(sock < 0)	 return NULL;tryagain : if ( current_sport < 128 && sport < 0 ) return NULL; e =  set_socket_source_addr(sock, sport > 0 ? sport : current_sport--);  /*  * bind() failed - try again on a lower port  */ if(e < 0) {  close ( sock );  if(sport > 0)     return NULL;   else      goto tryagain; }   /*  * Connect to the other end  */ p = plug_get_host_ip(script_infos); bzero(&daddr, sizeof(daddr)); daddr.sin_addr = *p; daddr.sin_port = htons(dport); daddr.sin_family = AF_INET; unblock_socket(sock); e = connect(sock, (struct sockaddr*)&daddr, sizeof(daddr)); if ( e < 0 ) {   if ( errno == EADDRINUSE || errno == EADDRNOTAVAIL )   {     close(sock);     if ( sport < 0 )           goto restart;     else            return NULL;   }   else if ( errno != EINPROGRESS )   {      close(sock);     return NULL;   } }  do {  tv.tv_sec = to;  tv.tv_usec = 0;  FD_ZERO(&rd);  FD_SET(sock, &rd);  e = select(sock + 1, NULL, &rd, NULL, to > 0 ? &tv:NULL);  } while ( e < 0 && errno == EINTR ); if ( e <= 0 )  {   close ( sock );   return FAKE_CELL; } block_socket(sock); opt_sz = sizeof(opt); if ( getsockopt(sock, SOL_SOCKET, SO_ERROR, &opt, &opt_sz) < 0 ) {  fprintf(stderr, "[%d] open_priv_sock()->getsockopt() failed : %s\n", getpid(), strerror(errno));  close(sock);  return NULL; }  switch ( opt ) {   case EADDRINUSE:   case EADDRNOTAVAIL:     close ( sock );     if ( sport < 0 ) 	 goto restart;      else          return FAKE_CELL;   case 0:	break;   default:       close ( sock );       return FAKE_CELL;       break; }  if(proto == IPPROTO_TCP)   sock = nessus_register_connection(sock, NULL);  retc = alloc_tree_cell(0, NULL);  retc->type = CONST_INT;  retc->x.i_val = sock < 0 ? 0 : sock;  return retc;}tree_cell * nasl_open_priv_sock_tcp(lex_ctxt * lexic){ return nasl_open_privileged_socket(lexic, IPPROTO_TCP);}tree_cell * nasl_open_priv_sock_udp(lex_ctxt * lexic){ return nasl_open_privileged_socket(lexic, IPPROTO_UDP);} /*--------------------------------------------------------------------------*/tree_cell * nasl_open_sock_tcp_bufsz(lex_ctxt * lexic, int bufsz){ int soc = -1; struct arglist *  script_infos = lexic->script_infos; int	to, port, transport = -1; tree_cell * retc; to = get_int_local_var_by_name(lexic, "timeout", lexic->recv_timeout*2); if(to < 0) 	to = 10;	 transport = get_int_local_var_by_name(lexic, "transport", -1); if (bufsz < 0)   bufsz = get_int_local_var_by_name(lexic, "bufsz", 0);   port = get_int_var_by_num(lexic, 0, -1); if(port < 0)	 return NULL;  if(transport < 0)   soc =  open_stream_auto_encaps(script_infos, port, to); else   soc  = open_stream_connection(script_infos, port, transport, to); if (bufsz > 0 && soc >= 0 ) {   if (stream_set_buffer(soc, bufsz) < 0)     nasl_perror(lexic, "stream_set_buffer: soc=%d,bufsz=%d\n", soc, bufsz); }  retc = alloc_tree_cell(0, NULL);  retc->type = CONST_INT;  retc->x.i_val = soc < 0 ? 0 : soc;  return retc;}tree_cell * nasl_open_sock_tcp(lex_ctxt * lexic){  return nasl_open_sock_tcp_bufsz(lexic, -1);}/* * Opening a UDP socket is a little more tricky, since * UDP works in a way which is different from TCP... *  * Our goal is to hide this difference for the end-user */tree_cell * nasl_open_sock_udp(lex_ctxt * lexic){ int soc; tree_cell * retc; int port; struct sockaddr_in soca; struct arglist *  script_infos = lexic->script_infos; struct in_addr * ia; port = get_int_var_by_num(lexic, 0, -1); if(port < 0)	 return NULL;    ia = plug_get_host_ip(script_infos); if ( ia == NULL ) return NULL; bzero(&soca, sizeof(soca)); soca.sin_addr.s_addr = ia->s_addr; soca.sin_port = htons(port); soca.sin_family = AF_INET; soc = socket(AF_INET, SOCK_DGRAM, 0);  set_socket_source_addr(soc, 0);  connect(soc, (struct sockaddr*)&soca, sizeof(soca)); retc = alloc_tree_cell(0, NULL); retc->type = CONST_INT; retc->x.i_val = soc < 0 ? 0 : soc; return retc;}/*---------------------------------------------------------------------*/tree_cell * nasl_recv(lex_ctxt * lexic){ char * data; int len = get_int_local_var_by_name(lexic, "length", -1); int min_len = get_int_local_var_by_name(lexic, "min", -1); int soc = get_int_local_var_by_name(lexic, "socket", 0); int to  = get_int_local_var_by_name(lexic, "timeout", lexic->recv_timeout); fd_set rd; struct timeval tv; int new_len = 0; tree_cell * retc; int type = -1; unsigned int opt_len = sizeof(type); int e;  if(len <= 0 || soc <= 0)	 return NULL; tv.tv_sec = to; tv.tv_usec = 0;  data = emalloc(len); if ( !fd_is_stream(soc) ) 	e = getsockopt(soc, SOL_SOCKET, SO_TYPE, &type, &opt_len);  else	e = -1;

⌨️ 快捷键说明

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