preparse.c

来自「大国补丁后的nessus2.2.8的源代码」· C语言 代码 · 共 718 行

C
718
字号
/* 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. * */#include <includes.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 "nasl_regex.h"#include "nasl_debug.h"#ifdef ENABLE_PLUGIN_SERVERextern int naslparse( naslctxt * ); 	/*---------------------------------------------------------------------------*/struct fd_ctx {	char * buf;	unsigned int  allocated_size;	unsigned int  ptr;	};static int fdctx_init(struct fd_ctx * ctx) { ctx->allocated_size = 512; ctx->ptr = 0; ctx->buf = emalloc(ctx->allocated_size); if ( ctx->buf == NULL ) 	return -1; else 	return 0;}static int fdctx_free(struct fd_ctx * ctx){ efree(&(ctx->buf)); ctx->ptr = ctx->allocated_size = 0; return 0;}static int fdctx_write(struct fd_ctx * ctx, const void * data, unsigned int len){ if ( ctx == NULL )  	return -1;  if ( ctx->allocated_size < (ctx->ptr + len ) ) {  ctx->allocated_size *= 2;  if ( ctx->allocated_size < ctx->ptr + len )	ctx->allocated_size += ctx->ptr + len;  ctx->buf = erealloc(ctx->buf, ctx->allocated_size); }  memcpy(&ctx->buf[ctx->ptr], data, len); ctx->ptr += len; return len;}static int fdctx_eof(struct fd_ctx * ctx){ return ctx->ptr >= ctx->allocated_size;}static int fdctx_read(struct fd_ctx * ctx, void * buf, unsigned int len){ if ( ctx->ptr + len > ctx->allocated_size )  {	return -1; }	 memcpy(buf, &(ctx->buf[ctx->ptr]), len); ctx->ptr += len; return len;}static int fdctx_save(struct fd_ctx * ctx, int fd ){ int n = 0;  while ( n != ctx->ptr ) {  int e = write(fd, ctx->buf + n, ctx->ptr - n);  if ( e < 0 && errno != EINTR )   {    perror("write ");    return  -1;  }  else if ( e > 0 ) n += e; } return n;}static int fdctx_load(struct fd_ctx * ctx, int fd){ struct stat st; unsigned int n = 0, l; if ( fstat(fd, &st) < 0 )	return -1; l = (unsigned int) st.st_size; ctx->allocated_size = l; ctx->buf = emalloc(l); ctx->ptr = 0; while ( n != l ) {  int e;    e = read(fd, ctx->buf + n, l - n );  if ( e < 0 && errno != EINTR ) return -1;  else if ( e > 0 ) n += e; } return l;}static int fdctx_init_with_buf(struct fd_ctx * ctx, char * buf, unsigned int len){ bzero(ctx, sizeof(*ctx)); ctx->allocated_size = len; ctx->buf = buf; ctx->ptr = 0; return len;}/*---------------------------------------------------------------------*/#define DICTIONNARY_MAGIC 1297#define DICTIONNARY_EOF   424242struct dictionnary {	unsigned int id;	unsigned int len;	char * word;	struct dictionnary * next;};static unsigned int dictionnary_hash ( char * word ){ unsigned int ret = 0; while ( word[0] != '\0' )	{	ret += word[0];	word ++;	} return ret % DICTIONNARY_MAGIC;}static struct dictionnary ** dictionnary_init(){ return emalloc(sizeof(struct dictionnary *) * DICTIONNARY_MAGIC); }static void dictionnary_free(struct dictionnary ** dict ){ int i; for ( i = 0 ; i < DICTIONNARY_MAGIC ; i ++ ) {  struct dictionnary * d;  d = dict[i];  while ( d != NULL )  {   struct dictionnary * next;   efree(&d->word);   next = d->next;   efree(&d);   d = next;   } } efree(&dict);}static char * dictionnary_get_word( struct dictionnary ** dict, unsigned int id ){ struct dictionnary * d; unsigned int h; h = id & 0xffff0000; h = h >> 16; if ( h > DICTIONNARY_MAGIC ) {  fprintf(stderr, "Bad dictionnary\n");  return NULL; } d = dict[h]; while ( d != NULL ) {  if ( d->id == id ) return d->word;  d = d->next; } return NULL;}static unsigned int dictionnary_add_word(struct dictionnary ** dict, char * word ){ unsigned int h = dictionnary_hash(word); struct dictionnary * d; unsigned int id; d = dict[h]; while ( d != NULL ) {  if ( strcmp(d->word, word) == 0 ) return d->id;  d = d->next; } id = h << 16; if ( dict[h] != NULL ) id |= ( (dict[h]->id << 16) >> 16 ); id ++; d = emalloc(sizeof(*d)); d->word = strdup(word); d->len  = strlen(word); d->id   = id; d->next = dict[h]; dict[h] = d; return d->id;}static void dictionnary_save ( struct dictionnary ** dict, int fd ){ int i; unsigned int eof; for ( i = 0 ; i < DICTIONNARY_MAGIC ; i ++ ) {  struct dictionnary * d = dict[i];  while ( d != NULL )  {   write(fd, &d->id, sizeof(d->id));   write(fd, &d->len, sizeof(d->len));   write(fd, d->word, d->len);   d = d->next;  } }  eof = DICTIONNARY_EOF; write(fd, &eof, sizeof(eof));}static struct dictionnary ** dictionnary_load( struct fd_ctx * ctx ){ struct dictionnary ** ret = dictionnary_init(); for ( ;; ) {  unsigned int l;  unsigned int id;  char * word;  unsigned int h;  struct dictionnary * d;  fdctx_read(ctx, &id, sizeof(id));  if ( id == DICTIONNARY_EOF ) break;  if ( fdctx_read(ctx, &l, sizeof(l)) < 0 )	return NULL;  word = emalloc(l + 1);  if ( fdctx_read(ctx, word, l) < 0 )	return NULL;  h =  id  >> 16;  if ( h > DICTIONNARY_MAGIC )  {   fprintf(stderr, "Badly formed dictionnary file\n");    exit(1);  }  d = emalloc( sizeof(struct dictionnary) );  d->word = word;  d->id   = id;  d->len  = l;  d->next = ret[h];  ret[h]  = d; } return ret;}/*---------------------------------------------------------------------*/static intnasl_saved_parsed_cell(struct fd_ctx * ctx, const tree_cell* tc, struct dictionnary ** dico){  unsigned char	typ;  int		l, i;  unsigned char flag;  if (tc == NULL || tc == FAKE_CELL)    {      typ = NODE_EMPTY;      if (fdctx_write(ctx, &typ, sizeof(typ)) < 0 )	goto write_error;      return 0;    }  typ = tc->type;  if (fdctx_write(ctx, &typ, sizeof(typ)) < 0 ||       fdctx_write(ctx, &tc->line_nb, sizeof(short)) < 0)    goto write_error;  switch (typ)    {    case CONST_INT:      if (fdctx_write(ctx, &tc->x.i_val, sizeof(int)) < 0 )	goto write_error;      break;          case CONST_STR:    case CONST_DATA:    case NODE_VAR:    case NODE_FUN_DEF:    case NODE_FUN_CALL:    case NODE_DECL:    case NODE_ARG:    case NODE_ARRAY_EL:    case NODE_FOREACH:    case CONST_REGEX:    case COMP_RE_MATCH:    case COMP_RE_NOMATCH:      if (tc->x.str_val != NULL || tc->x.ref_val != NULL)	{          char * buf = NULL;  	  unsigned int id;	            if ( typ == CONST_REGEX ||               typ == COMP_RE_MATCH ||               typ == COMP_RE_NOMATCH  ) 		{	         if ( tc->x.ref_val != NULL )                 {		    buf = nasl_regorig(tc->x.ref_val);                  }		}	   else		buf = tc->x.str_val;                    id = dictionnary_add_word(dico, buf);	  if ( fdctx_write(ctx, &id, sizeof(id)) < 0 )	    goto write_error;	}      else	{	  l = 0;	  if ( fdctx_write(ctx, &l, sizeof(l) ) < 0 ) 	    goto write_error;	}      break;    }  flag = 0;  for (i = 0; i < 4; i ++)    {       if ( tc->link[i] != NULL ) flag = flag | ( 1 << i );    }  fdctx_write(ctx, &flag, 1);  for ( i = 0 ; i < 4 ; i ++ )    {     if ( tc->link[i] != NULL )     {      if (nasl_saved_parsed_cell(ctx, tc->link[i], dico) < 0)      return -1;     }    }  return 0; write_error:  perror("fwrite");  return -1;}intnasl_saved_parsed_tree(const char* fname, const tree_cell* tc){  int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, 0644);  int	err = 0;  struct fd_ctx ctx;  struct dictionnary ** dico = dictionnary_init();  if ( fd < 0 )  {   perror(fname);   return -1;  }  if( fdctx_init(&ctx) < 0 )   {   perror("fdctx_init ");   return -1;  }  if (nasl_saved_parsed_cell(&ctx, tc, dico) < 0)    err ++;  dictionnary_save(dico, fd);  dictionnary_free(dico);  fdctx_save(&ctx, fd);  if (close(fd) < 0)    {      perror(fname);      err++;    }  fdctx_free(&ctx);   return err ? -1 : 0;}static intnasl_load_parsed_cell(struct fd_ctx * ctx, tree_cell** pc, struct dictionnary ** dico, const char * fname){  char*	buf = NULL;  int	buflen = 0;  tree_cell	*tc = NULL;  unsigned char	typ = 0;  short		line = 0;  char		*s;  int		i;  unsigned 	int 		id;  unsigned	char		flag;    if (fdctx_read(ctx, &typ, sizeof(typ)) < 0)  {    if (fdctx_eof(ctx))      return 0;    else      goto read_error;  }  if (typ == NODE_EMPTY)    {      *pc = NULL;      return 0;    }  if (fdctx_read(ctx, &line, sizeof(line)) < 0)    goto read_error;  tc = alloc_tree_cell(line, NULL);  switch(typ)    {    case CONST_INT:      if (fdctx_read(ctx, &i, sizeof(i)) < 0)	goto read_error;      tc->x.i_val = i;      break;    case CONST_STR:    case CONST_DATA:    case NODE_VAR:    case NODE_FUN_DEF:    case NODE_FUN_CALL:    case NODE_DECL:    case NODE_ARG:    case NODE_ARRAY_EL:    case NODE_FOREACH:    case CONST_REGEX:    case COMP_RE_MATCH:    case COMP_RE_NOMATCH:      if ( fdctx_read(ctx, &id, sizeof(id)) < 0 )	goto read_error;      if ( id != 0 )      {       buf = dictionnary_get_word ( dico, id );       if ( buf == NULL ) goto read_error;       buflen = strlen(buf);       s = buf = strdup(buf);       }      else {	s = NULL;	buf = NULL;	buflen = 0;	}      tc->x.str_val = buf;        if (typ == CONST_DATA || typ == CONST_STR)	{	  tc->size = buflen;	  if (s == NULL)		 tc->x.str_val = estrdup("");	}      if ( s != NULL && (typ == CONST_REGEX || typ == COMP_RE_MATCH || typ == COMP_RE_NOMATCH ))	{	 regex_t * re = emalloc ( sizeof(regex_t) );         int e;                  e = nasl_regcomp(re, s, REG_EXTENDED|REG_NOSUB|REG_ICASE);         if ( e == 0 ) tc->x.ref_val = re;         else { 	  efree (&re);	  tc->x.ref_val = NULL; 	  nasl_perror(NULL, "%s:Line %d: Cannot compile regex: %s (error = %d)\n", fname, tc->line_nb, s, e);	 }	 efree(&s);	}      break;    }  tc->type = typ;  fdctx_read(ctx, &flag, 1);  for (i = 0; i < 4; i ++)    {      if ( flag & ( 1 << i ) )      {        if (nasl_load_parsed_cell(ctx, &tc->link[i], dico, fname) < 0)       {	deref_cell(tc);	return -1;       }     }    }  *pc = tc;  return 0; read_error:  perror("fread");  deref_cell(tc);  return -1;  }tree_cell*nasl_load_parsed_tree(const char* fname){  tree_cell	*tc = NULL;  int fd;  struct fd_ctx ctx;  struct dictionnary ** dico;  if ((fd = open(fname, O_RDONLY)) < 0 )    {      perror(fname);      return NULL;    }  if ( fdctx_load(&ctx, fd) < 0 )   {     perror("fdctx_load ");     return NULL;    }  dico = dictionnary_load(&ctx);  if ( dico == NULL ) return NULL;  close(fd);  if (nasl_load_parsed_cell(&ctx, &tc, dico, fname) < 0)    {      deref_cell(tc);      tc = NULL;    }  dictionnary_free(dico);  return tc;}intnasl_load_parsed_tree_buf(naslctxt * naslctx, char* buf, unsigned int len, const char * fname){  tree_cell	*tc = NULL;  struct fd_ctx ctx;  struct dictionnary ** dico;  memset(naslctx, 0, sizeof(*naslctx));   if ( fdctx_init_with_buf(&ctx, buf, len) < 0 )   {     perror("fdctx_init_with_buf ");     return -1;    }  dico = dictionnary_load(&ctx);  if ( dico == NULL ) return -1;  if (nasl_load_parsed_cell(&ctx, &tc, dico, fname) < 0)    {      deref_cell(tc);      return -1;    } dictionnary_free(dico); naslctx->tree = tc; return 0; }#endif /* ENABLE_PLUGIN_SERVER */intnasl_load_or_parse(naslctxt* ctx, const char* name1, const char * basename, const char * cache_dir){#ifdef ENABLE_PLUGIN_SERVER  char		name2[MAXPATHLEN];  struct stat	st1, st2;  if ( cache_dir != NULL )  {   snprintf(name2, sizeof(name2), "%s/%s", cache_dir, basename);   if (stat(name1, &st1) >= 0 && stat(name2, &st2) >= 0)   {    if (st2.st_mtime > st1.st_mtime)    {      memset(ctx, 0, sizeof(*ctx));      if ((ctx->tree = nasl_load_parsed_tree(name2)) != NULL)	return 0;    }   }  }#endif  if (init_nasl_ctx(ctx, name1) < 0)    return -1;  if (naslparse(ctx))    {      fprintf(stderr, "\nParse error at or near line %d\n", ctx->line_nb);      nasl_clean_ctx(ctx);      return -1;    }  #ifdef ENABLE_PLUGIN_SERVER  if ( cache_dir != NULL )  {   if (nasl_saved_parsed_tree(name2, ctx->tree) < 0)    {      fprintf(stderr, "Could not dump tree to %s\n", name2);      if (unlink(name2) < 0)	perror(name2);    }  }#endif  return 0;}#ifdef ENABLE_PLUGIN_SERVERintnasl_parse_and_dump(const char* name1, const char * basename, const char * cache_dir){  char		name2[MAXPATHLEN];  struct stat	st1, st2;  naslctxt ctx;  if ( cache_dir == NULL )  return -1;  snprintf(name2, sizeof(name2), "%s/%s", cache_dir, basename);  if (stat(name1, &st1) >= 0 && stat(name2, &st2) >= 0)  {    if (st2.st_mtime > st1.st_mtime)	return 0;  }  if (init_nasl_ctx(&ctx, name1) < 0)    return -1;  if (naslparse(&ctx))    {      fprintf(stderr, "\nParse error at or near line %d\n", ctx.line_nb);      nasl_clean_ctx(&ctx);      return -1;    }    if (nasl_saved_parsed_tree(name2, ctx.tree) < 0)    {      fprintf(stderr, "Could not dump tree to %s\n", name2);      if (unlink(name2) < 0)	perror(name2);    }   nasl_clean_ctx(&ctx);  return 0;}#endif

⌨️ 快捷键说明

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