nasl_grammar.y
来自「大国补丁后的nessus2.2.8的源代码」· Y 代码 · 共 1,217 行 · 第 1/2 页
Y
1,217 行
%pure_parser%expect 1%{/* Nessus Attack Scripting Language version 2 * * Copyright (C) 2002 - 2004 Michel Arboi and Renaud Deraison * * 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. */#define YYPARSE_PARAM parm#define YYLEX_PARAM parm#define LNB (((naslctxt*)parm)->line_nb)#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 "nasl_debug.h"static void naslerror(const char *);#define YYERROR_VERBOSE%}%union { int num; char *str; struct asciiz { char *val; int len; } data; tree_cell *node;}%token IF%token ELSE%token EQ%token NEQ%token SUPEQ%token INFEQ%token OR%token AND%token MATCH%token NOMATCH%token REP%token FOR%token REPEAT%token UNTIL%token FOREACH%token WHILE%token BREAK%token CONTINUE%token FUNCTION%token RETURN%token INCLUDE%token LOCAL%token GLOBAL%token PLUS_PLUS%token MINUS_MINUS%token L_SHIFT%token R_SHIFT%token R_USHIFT%token EXPO%token PLUS_EQ%token MINUS_EQ%token MULT_EQ%token DIV_EQ%token MODULO_EQ%token L_SHIFT_EQ%token R_SHIFT_EQ%token R_USHIFT_EQ%token RE_MATCH%token RE_NOMATCH%token ARROW%token <str> IDENT%token <data> STRING1%token <str> STRING2%token <num> INTEGER%type <node> arg_list_1 arg_list arg%type <node> arg_decl_1 arg_decl%type <node> func_call func_decl%type <node> instr instr_list instr_decl instr_decl_list simple_instr%type <node> if_block block loop for_loop while_loop foreach_loop repeat_loop%type <node> aff rep ret expr aff_func array_index array_elem lvalue var%type <node> ipaddr post_pre_incr%type <node> inc loc glob%type <node> atom const_array list_array_data array_data simple_array_data%type <str> identifier string var_name/* Priority of all operators */%right '=' PLUS_EQ MINUS_EQ MULT_EQ DIV_EQ MODULO_EQ L_SHIFT_EQ R_SHIFT_EQ R_USHIFT_EQ%left OR%left AND%nonassoc '<' '>' EQ NEQ SUPEQ INFEQ MATCH NOMATCH RE_MATCH RE_NOMATCH%left '|'%left '^'%left '&'%nonassoc R_SHIFT R_USHIFT L_SHIFT%left '+' '-' %left '*' '/' '%'%nonassoc NOT%nonassoc UMINUS BIT_NOT%right EXPO%nonassoc PLUS_PLUS MINUS_MINUS%nonassoc ARROW%start tiptop%%tiptop: instr_decl_list { ((naslctxt*)parm)->tree = $1; } ; instr_decl_list: instr_decl { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_INSTR_L; $$->link[0] = $1; } | instr_decl instr_decl_list { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_INSTR_L; $$->link[0] = $1; $$->link[1] = $2; };instr_decl: instr | func_decl;/* Function declaration */func_decl: FUNCTION identifier '(' arg_decl ')' block { $$ = alloc_tree_cell(LNB, $2); $$->type = NODE_FUN_DEF; $$->link[0] = $4; $$->link[1] = $6; };arg_decl: { $$ = NULL; } | arg_decl_1 { $$ = $1; };arg_decl_1: identifier { $$ = alloc_tree_cell(LNB, $1); $$->type = NODE_DECL; } | identifier ',' arg_decl_1 { $$ = alloc_tree_cell(LNB, $1); $$->type = NODE_DECL; $$->link[0] = $3; };/* Block */block: '{' instr_list '}' { $$ = $2; } | '{' '}' { $$ = NULL; };instr_list: instr | instr instr_list { if ($1 == NULL) $$ = $2; else { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_INSTR_L; $$->link[0] = $1; $$->link[1] = $2; } } ;/* Instructions */instr: simple_instr ';' { $$ = $1; } | block | if_block | loop ;/* "simple" instruction */simple_instr : aff | post_pre_incr | rep | func_call | ret | inc | loc | glob | BREAK { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_BREAK; } | CONTINUE { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_CONTINUE; } | /* nop */ { $$ = NULL; };/* return */ret: RETURN expr { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_RETURN; $$->link[0] = $2; } | RETURN { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_RETURN; } ;/* If block */if_block: IF '(' expr ')' instr { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_IF_ELSE; $$->link[0] = $3; $$->link[1] = $5; } | IF '(' expr ')' instr ELSE instr { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_IF_ELSE; $$->link[0] = $3; $$->link[1] = $5; $$->link[2] = $7; };/* Loops */loop : for_loop | while_loop | repeat_loop | foreach_loop ;for_loop : FOR '(' aff_func ';' expr ';' aff_func ')' instr { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_FOR; $$->link[0] = $3; $$->link[1] = $5; $$->link[2] = $7; $$->link[3] = $9; } ;while_loop : WHILE '(' expr ')' instr { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_WHILE; $$->link[0] = $3; $$->link[1] = $5; } ;repeat_loop : REPEAT instr UNTIL expr ';' { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_REPEAT_UNTIL; $$->link[0] = $2; $$->link[1] = $4; } ;foreach_loop : FOREACH identifier '(' expr ')' instr { $$ = alloc_tree_cell(LNB, $2); $$->type = NODE_FOREACH; $$->link[0] = $4; $$->link[1] = $6; } ;/* affectation or function call */aff_func: aff | post_pre_incr | func_call | /*nop */ { $$ = NULL; };/* repetition */rep: func_call REP expr { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_REPEATED; $$->link[0] = $1; $$->link[1] = $3; } ;string : STRING1 { $$ = $1.val; } | STRING2 ;/* include */inc: INCLUDE '(' string ')' { naslctxt subctx; int x; subctx.always_authenticated = ((naslctxt*)parm)->always_authenticated; x = init_nasl_ctx(&subctx, $3); $$ = NULL; if (x >= 0) { if (! naslparse(&subctx)) { $$ = subctx.tree; } else nasl_perror(NULL, "%s: Parse error at or near line %d\n", $3, subctx.line_nb); efree(&subctx.buffer); fclose(subctx.fp); subctx.fp = NULL; /* If we are an authenticated script and the script we include is *NOT* authenticated, then we lose our authentication status */ if ( ((naslctxt*)parm)->always_authenticated == 0 && ((naslctxt*)parm)->authenticated != 0 && subctx.authenticated == 0 ) { ((naslctxt*)parm)->authenticated = 0; nasl_perror(NULL, "Including %s which is not authenticated - losing our authenticated status\n", $3); } } efree(& $3); } ;/* Function call */func_call: identifier '(' arg_list ')' { $$ = alloc_tree_cell(LNB, $1); $$->type = NODE_FUN_CALL; $$->link[0] = $3; };arg_list : arg_list_1 | { $$ = NULL; };arg_list_1: arg | arg ',' arg_list_1 { $1->link[1] = $3; $$ = $1; } ;arg : expr { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_ARG; $$->link[0] = $1; } | identifier ':' expr { $$ = alloc_tree_cell(LNB, $1); $$->type = NODE_ARG; $$->link[0] = $3; } ;/* Affectation */aff: lvalue '=' expr { $$ = alloc_expr_cell(LNB, NODE_AFF, $1, $3); } | lvalue PLUS_EQ expr { $$ = alloc_expr_cell(LNB, NODE_PLUS_EQ, $1, $3); } | lvalue MINUS_EQ expr { $$ = alloc_expr_cell(LNB, NODE_MINUS_EQ, $1, $3); } | lvalue MULT_EQ expr { $$ = alloc_expr_cell(LNB, NODE_MULT_EQ, $1, $3); } | lvalue DIV_EQ expr { $$ = alloc_expr_cell(LNB, NODE_DIV_EQ, $1, $3); } | lvalue MODULO_EQ expr { $$ = alloc_expr_cell(LNB, NODE_MODULO_EQ, $1, $3); } | lvalue R_SHIFT_EQ expr { $$ = alloc_expr_cell(LNB, NODE_R_SHIFT_EQ, $1, $3); } | lvalue R_USHIFT_EQ expr { $$ = alloc_expr_cell(LNB, NODE_R_USHIFT_EQ, $1, $3); } | lvalue L_SHIFT_EQ expr { $$ = alloc_expr_cell(LNB, NODE_L_SHIFT_EQ, $1, $3); } ;lvalue: identifier { $$ = alloc_tree_cell(LNB, $1); $$->type = NODE_VAR; } | array_elem ;identifier: IDENT | REP { $$ = strdup("x"); } ; /* => For "x" */array_elem: identifier '[' array_index ']' { $$ = alloc_tree_cell(LNB, $1); $$->type = NODE_ARRAY_EL; $$->link[0] = $3; } ;array_index: expr ;post_pre_incr: PLUS_PLUS lvalue { $$ = alloc_expr_cell(LNB, EXPR_INCR, NULL, $2); } | MINUS_MINUS lvalue {$$ = alloc_expr_cell(LNB, EXPR_DECR, NULL, $2); } | lvalue PLUS_PLUS { $$= alloc_expr_cell(LNB, EXPR_INCR, $1, NULL); } | lvalue MINUS_MINUS { $$= alloc_expr_cell(LNB, EXPR_DECR, $1, NULL); };/* expression. We accepte affectations inside parenthesis */expr: '(' expr ')' { $$ = $2; } | expr AND expr { $$ = alloc_expr_cell(LNB, EXPR_AND, $1, $3); } | '!' expr %prec NOT { $$ = alloc_expr_cell(LNB, EXPR_NOT, $2, NULL); } | expr OR expr { $$ = alloc_expr_cell(LNB, EXPR_OR, $1, $3); } | expr '+' expr { $$ = alloc_expr_cell(LNB, EXPR_PLUS, $1, $3); } | expr '-' expr { $$ = alloc_expr_cell(LNB, EXPR_MINUS, $1, $3); } | '-' expr %prec UMINUS { $$ = alloc_expr_cell(LNB, EXPR_U_MINUS, $2, NULL);} | '~' expr %prec BIT_NOT { $$ = alloc_expr_cell(LNB, EXPR_BIT_NOT, $2, NULL);} | expr '*' expr { $$ = alloc_expr_cell(LNB, EXPR_MULT, $1, $3); } | expr EXPO expr { $$ = alloc_expr_cell(LNB, EXPR_EXPO, $1, $3); } | expr '/' expr { $$ = alloc_expr_cell(LNB, EXPR_DIV, $1, $3); } | expr '%' expr { $$ = alloc_expr_cell(LNB, EXPR_MODULO, $1, $3); } | expr '&' expr { $$ = alloc_expr_cell(LNB, EXPR_BIT_AND, $1, $3); } | expr '^' expr { $$ = alloc_expr_cell(LNB, EXPR_BIT_XOR, $1, $3); } | expr '|' expr { $$ = alloc_expr_cell(LNB, EXPR_BIT_OR, $1, $3); } | expr R_SHIFT expr { $$ = alloc_expr_cell(LNB, EXPR_R_SHIFT, $1, $3); } | expr R_USHIFT expr { $$ = alloc_expr_cell(LNB, EXPR_R_USHIFT, $1, $3); } | expr L_SHIFT expr { $$ = alloc_expr_cell(LNB, EXPR_L_SHIFT, $1, $3); } | post_pre_incr | expr MATCH expr { $$ = alloc_expr_cell(LNB, COMP_MATCH, $1, $3); } | expr NOMATCH expr { $$ = alloc_expr_cell(LNB, COMP_NOMATCH, $1, $3); } | expr RE_MATCH string { $$ = alloc_RE_cell(LNB, COMP_RE_MATCH, $1, $3); } | expr RE_NOMATCH string { $$ = alloc_RE_cell(LNB, COMP_RE_NOMATCH, $1, $3); } | expr '<' expr { $$ = alloc_expr_cell(LNB, COMP_LT, $1, $3); } | expr '>' expr { $$ = alloc_expr_cell(LNB, COMP_GT, $1, $3); } | expr EQ expr { $$ = alloc_expr_cell(LNB, COMP_EQ, $1, $3); } | expr NEQ expr { $$ = alloc_expr_cell(LNB, COMP_NE, $1, $3); } | expr SUPEQ expr { $$ = alloc_expr_cell(LNB, COMP_GE, $1, $3); } | expr INFEQ expr { $$ = alloc_expr_cell(LNB, COMP_LE, $1, $3); } | var | aff | ipaddr | atom | const_array ;const_array: '[' list_array_data ']' { $$ = make_array_from_elems($2); } ;list_array_data: array_data { $$ = $1; } | array_data ',' list_array_data { $1->link[1] = $3; $$ = $1; };array_data: simple_array_data { $$ = alloc_typed_cell(ARRAY_ELEM); $$->link[0] = $1; } | string ARROW simple_array_data { $$ = alloc_typed_cell(ARRAY_ELEM); $$->link[0] = $3; $$->x.str_val = $1; } ;atom: INTEGER { $$ = alloc_typed_cell(CONST_INT); $$->x.i_val = $1; } | STRING2 { $$ = alloc_typed_cell(CONST_STR); $$->x.str_val = $1; $$->size = strlen($1); } | STRING1 { $$ = alloc_typed_cell(CONST_DATA); $$->x.str_val = $1.val; $$->size = $1.len; } ;simple_array_data: atom;var: var_name { $$ = alloc_tree_cell(LNB, $1); $$->type = NODE_VAR; } | array_elem | func_call;var_name: identifier;ipaddr: INTEGER '.' INTEGER '.' INTEGER '.' INTEGER { char *s = emalloc(44); snprintf(s, 44, "%d.%d.%d.%d", $1, $3, $5, $7); $$ = alloc_tree_cell(LNB, s); $$->type = CONST_STR; $$->size = strlen(s); };/* Local variable declaration */loc: LOCAL arg_decl { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_LOCAL; $$->link[0] = $2; };/* Global variable declaration */glob: GLOBAL arg_decl { $$ = alloc_tree_cell(LNB, NULL); $$->type = NODE_GLOBAL; $$->link[0] = $2; };%%#include <stdio.h>#include <stdlib.h>static void naslerror(const char *s){ fputs(s, stderr);}intinit_nasl_ctx(naslctxt* pc, const char* name){ char line[1024]; char full_name[MAXPATHLEN];#ifdef MULTIPLE_INCLUDE_DIRS static const char* inc_dirs[] = { ".", "/tmp" }; /* TBD */#endif pc->line_nb = 1; pc->tree = NULL; pc->buffer = emalloc(80); pc->maxlen = 80; pc->authenticated = 0;#ifdef MULTIPLE_INCLUDE_DIRS if (name[0] == '/') /* absolute path */#endif { /* Shouldn't we reject the file? */ if ((pc->fp = fopen(name, "r")) == NULL) { perror(name); return -1; } strncpy(full_name, name, sizeof(full_name) - 1); goto authenticate; }#ifdef MULTIPLE_INCLUDE_DIRS else { int i; for (i = 0; i < sizeof(inc_dirs) / sizeof(*inc_dirs); i ++) { snprintf(full_name, sizeof(full_name), "%s/%s", inc_dirs[i], name); if ((pc->fp = fopen(full_name, "r")) != NULL) goto authenticate; perror(full_name); } return -1; }#endifauthenticate: if ( pc->always_authenticated ) pc->authenticated = 1; else { fgets(line, sizeof(line) - 1, pc->fp); line[sizeof(line) - 1] = '\0'; if ( strncmp(line, "#TRUSTED", strlen("#TRUSTED") ) == 0 ) { int sig; full_name[sizeof(full_name) - 1] = '\0'; sig = verify_script_signature(full_name); if ( sig == 0 ) pc->authenticated = 1; else pc->authenticated = 0; if ( sig > 0 ) { fprintf(stderr, "%s: bad signature. Will not execute this script\n", full_name); fclose(pc->fp); pc->fp = NULL; return -1; } else if ( sig < 0 ) fprintf(stderr, "%s: Could not verify the signature - this script will be run in non-authenticated mode\n", full_name); } rewind(pc->fp); } return 0;}voidnasl_clean_ctx(naslctxt* c){#if 0 nasl_dump_tree(c->tree);#endif deref_cell(c->tree); efree(&c->buffer); if (c->fp) { fclose(c->fp); c->fp = NULL; }}#if 0intmain(int argc,char **argv){ naslctxt ctx; ctx.line_nb = 1; ctx.tree = NULL; if (argc != 2) { nasl_perror(NULL, "Usage : nasl <input_file>\n"); return 1; } if ((ctx.fp = fopen(argv[1], "r")) == NULL) { perror(argv[1]); return 1; } return naslparse((void*) &ctx);}#endifenum lex_state { ST_START = 0, ST_SPACE, ST_IDENT, ST_ZERO, ST_ZEROX, ST_OCT, ST_DEC, ST_HEX, ST_COMMENT, ST_SUP, ST_INF, ST_SUP_EXCL, ST_STRING1, ST_STRING1_ESC, ST_STRING2, ST_PLUS, ST_MINUS, ST_MULT, ST_DIV, ST_MODULO,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?