int execute_nasl_script(struct arglist * script_infos, const char* name, int mode) { naslctxt ctx; nasl_func *pf; int err = 0; tree_cell *ret; lex_ctxt *lexic; char old_dir[MAXPATHLEN+1]; char *newdir; char *old; tree_cell description; struct arglist* prefs = arg_get_value(script_infos, "preferences"); char *str; int to; srand48(getpid() + getppid() + (long)time(NULL)); old_dir[sizeof(old_dir) - 1] = '\0'; getcwd(old_dir, sizeof(old_dir) - 1); #if NASL_DEBUG > 2 nasl_trace_fp = stderr; #endif if((old = arg_get_value(script_infos, "script_name")) == NULL) arg_add_value(script_infos, "script_name", ARG_STRING, strlen(name), estrdup(name)); else { efree(&old); arg_set_value(script_infos, "script_name", strlen(name), estrdup(name)); } newdir = strrchr(name, '/'); if(newdir != NULL) { char dir[MAXPATHLEN+1]; char *s; dir[sizeof(dir) - 1] = '\0'; strncpy(dir, name, sizeof(dir) - 1); s = strrchr(dir, '/'); s[0] = '\0'; chdir(dir); } if (init_nasl_ctx(&ctx, name) < 0) { chdir(old_dir); return -1; } if (naslparse(&ctx)) { nasl_perror(NULL, "\nParse error at or near line %d\n", ctx.line_nb); nasl_clean_ctx(&ctx); chdir(old_dir); return -1; } #if NASL_DEBUG > 4 nasl_dump_tree(ctx.tree); #endif lexic = init_empty_lex_ctxt(); lexic->script_infos = script_infos; str = arg_get_value(prefs, "checks_read_timeout"); if( str != NULL ) to = atoi(str); else to = 5; if(to <= 0)to = 5; lexic->recv_timeout = to; init_nasl_library(lexic); if (! (mode & NASL_EXEC_PARSE_ONLY)) { bzero(&description, sizeof(description)); description.type = CONST_INT; description.x.i_val = (mode & NASL_EXEC_DESCR) != 0; add_named_var_to_ctxt(lexic, "description", &description); truc = (lex_ctxt*)ctx.tree; if ((ret = nasl_exec(lexic, ctx.tree)) == NULL) err = -1; else deref_cell(ret); if ((pf = get_func_ref_by_name(lexic, "on_exit")) != NULL) nasl_func_call(lexic, pf, NULL); } #if NASL_DEBUG > 2 { struct rusage ru; if (getrusage(RUSAGE_SELF, &ru) < 0) perror("getrusage"); else { nasl_perror(lexic, "rusage: utime=%d.%02d stime=%d.%02d minflt=%d majflt=%d\n", ru.ru_utime.tv_sec, ru.ru_utime.tv_usec / 10000, ru.ru_stime.tv_sec, ru.ru_stime.tv_usec / 10000, ru.ru_minflt, ru.ru_majflt); } } #endif #if NASL_DEBUG > 3 nasl_dump_tree(ctx.tree); #endif nasl_clean_ctx(&ctx); free_lex_ctxt(lexic); chdir(old_dir); return err; }
int execute_nasl_script(struct arglist * script_infos, const char* name, const char * cache_dir, int mode) { naslctxt ctx; nasl_func *pf; int err = 0; tree_cell *ret; lex_ctxt *lexic; char old_dir[MAXPATHLEN+1]; char *newdir; char *old; tree_cell tc; struct arglist* prefs = arg_get_value(script_infos, "preferences"); char *str; int to; char * basename; #ifdef ENABLE_PLUGIN_SERVER char * cached_script = NULL; unsigned int cached_script_len = 0; #endif srand48(getpid() + getppid() + (long)time(NULL)); old_dir[sizeof(old_dir) - 1] = '\0'; getcwd(old_dir, sizeof(old_dir) - 1); #if NASL_DEBUG > 2 nasl_trace_fp = stderr; #endif if((old = arg_get_value(script_infos, "script_name")) == NULL) arg_add_value(script_infos, "script_name", ARG_STRING, strlen(name), estrdup(name)); else { efree(&old); arg_set_value(script_infos, "script_name", strlen(name), estrdup(name)); } newdir = strrchr(name, '/'); if(newdir != NULL) { char dir[MAXPATHLEN+1]; char *s; dir[sizeof(dir) - 1] = '\0'; strncpy(dir, name, sizeof(dir) - 1); s = strrchr(dir, '/'); s[0] = '\0'; chdir(dir); basename = newdir + 1; } else basename = (char*)name; bzero(&ctx, sizeof(ctx)); if ( mode & NASL_ALWAYS_SIGNED ) ctx.always_authenticated = 1; #ifdef ENABLE_PLUGIN_SERVER if ( nasl_index_fetch(basename, &cached_script, &cached_script_len) >= 0 ) { if ( nasl_load_parsed_tree_buf(&ctx, cached_script, cached_script_len, basename) < 0 ) { printf("Could not load plugin\n"); efree(&cached_script); chdir(old_dir); return -1; } efree(&cached_script); } else #endif { if (nasl_load_or_parse(&ctx, name, basename, cache_dir) < 0 ) { chdir(old_dir); return -1; } } #if NASL_DEBUG > 4 nasl_dump_tree(ctx.tree); #endif lexic = init_empty_lex_ctxt(); lexic->script_infos = script_infos; if ( mode & NASL_ALWAYS_SIGNED ) lexic->authenticated = 1; else lexic->authenticated = ctx.authenticated; str = arg_get_value(prefs, "checks_read_timeout"); if( str != NULL ) to = atoi(str); else to = 5; if(to <= 0)to = 5; lexic->recv_timeout = to; init_nasl_library(lexic); if (mode & NASL_LINT) { if (nasl_lint(lexic, ctx.tree) == NULL) err --; } else if (! (mode & NASL_EXEC_PARSE_ONLY)) { char *p; bzero(&tc, sizeof(tc)); tc.type = CONST_INT; tc.x.i_val = (mode & NASL_COMMAND_LINE) != 0; add_named_var_to_ctxt(lexic, "COMMAND_LINE", &tc); bzero(&tc, sizeof(tc)); tc.type = CONST_INT; tc.x.i_val = (mode & NASL_EXEC_DESCR) != 0; add_named_var_to_ctxt(lexic, "description", &tc); tc.type = CONST_DATA; p = strrchr(name, '/'); if (p == NULL) p = (char*)name; else p ++; tc.x.str_val = p; tc.size = strlen(p); add_named_var_to_ctxt(lexic, "SCRIPT_NAME", &tc); truc = (lex_ctxt*)ctx.tree; if ((ret = nasl_exec(lexic, ctx.tree)) == NULL) err = -1; else deref_cell(ret); if ((pf = get_func_ref_by_name(lexic, "on_exit")) != NULL) nasl_func_call(lexic, pf, NULL); } #if NASL_DEBUG > 2 { struct rusage ru; if (getrusage(RUSAGE_SELF, &ru) < 0) perror("getrusage"); else { nasl_perror(lexic, "rusage: utime=%d.%03d stime=%d.%03d minflt=%d majflt=%d nswap=%d\n", ru.ru_utime.tv_sec, ru.ru_utime.tv_usec / 1000, ru.ru_stime.tv_sec, ru.ru_stime.tv_usec / 1000, ru.ru_minflt, ru.ru_majflt, ru.ru_nswap); } } #endif #if NASL_DEBUG > 3 nasl_dump_tree(ctx.tree); #endif chdir(old_dir); if ( mode & NASL_EXEC_DONT_CLEANUP ) return err; nasl_clean_ctx(&ctx); free_lex_ctxt(lexic); return err; }
tree_cell* nasl_func_call(lex_ctxt* lexic, const nasl_func* f, tree_cell* arg_list) { #if 0 return FAKE_CELL; #else int nb_u = 0, nb_n = 0, nb_a = 0; tree_cell *pc = NULL, *pc2 = NULL, *retc = NULL; lex_ctxt *lexic2 = NULL; char *trace_buf = NULL; int trace_buf_len = 0, tn; #define TRACE_BUF_SZ 255 #if 0 nasl_dump_tree(arg_list); #endif /* 1. Create a new context */ lexic2 = init_empty_lex_ctxt(); lexic2->script_infos = lexic->script_infos; lexic2->authenticated = lexic->authenticated; lexic2->recv_timeout = lexic->recv_timeout; lexic2->fct_ctxt = 1; if (nasl_trace_fp != NULL) { trace_buf = emalloc(TRACE_BUF_SZ); tn = snprintf(trace_buf, TRACE_BUF_SZ, "Call %s(", f->func_name); if (tn > 0) trace_buf_len += tn; } if (! (f->flags & FUNC_FLAG_COMPAT)) { for (pc = arg_list; pc != NULL; pc = pc->link[1]) if (pc->x.str_val == NULL) nb_u ++; else { size_t num = f->nb_named_args; if (lfind(&pc->x.str_val, f->args_names, &num, sizeof(char*), stringcompare) != NULL) nb_n ++; } if (nb_n + nb_u > f->nb_unnamed_args + f->nb_named_args) nasl_perror(lexic, "Too many args for function '%s' [%dN+%dU > %dN+%dU]\n", f->func_name, nb_n, nb_u, f->nb_unnamed_args, f->nb_named_args); /* * I should look exactly how unnamed arguments works... * Or maybe I should remove this feature? */ for (nb_u = 0, pc = arg_list; pc != NULL; pc = pc->link[1]) { #if 0 pc2 = pc->link[0]; ref_cell(pc2); do { pc22 = nasl_exec(lexic, pc2); deref_cell(pc2); pc2 = pc22; } while (! nasl_is_leaf(pc2)); #else pc2 = cell2atom(lexic, pc->link[0]); #endif if (pc->x.str_val == NULL) { /* 2. Add unnamed (numbered) variables for unnamed args */ if (add_numbered_var_to_ctxt(lexic2, nb_u, pc2) == NULL) goto error; nb_u ++; if (nasl_trace_fp != NULL && trace_buf_len < TRACE_BUF_SZ) { tn = snprintf(trace_buf + trace_buf_len, TRACE_BUF_SZ - trace_buf_len, "%s%d: %s", nb_a > 0 ? ", " : "", nb_u, dump_cell_val(pc2)); if (tn > 0) trace_buf_len += tn; } nb_a ++; } else { /* 3. and add named variables for named args */ if (add_named_var_to_ctxt(lexic2, pc->x.str_val, pc2) == NULL) goto error; if (nasl_trace_fp != NULL && trace_buf_len < TRACE_BUF_SZ) { tn = snprintf(trace_buf + trace_buf_len, TRACE_BUF_SZ - trace_buf_len, "%s%s: %s", nb_a > 0 ? ", " : "", pc->x.str_val, dump_cell_val(pc2)); if (tn > 0) trace_buf_len += tn; } nb_a ++; } deref_cell(pc2); } if (nasl_trace_fp != NULL) { if (trace_buf_len < TRACE_BUF_SZ) nasl_trace(lexic, "NASL> %s)\n", trace_buf); else nasl_trace(lexic, "NASL> %s ...)\n", trace_buf); trace_buf_len = 0; efree(&trace_buf); } /* 4. Chain new context to old (lexic) */ lexic2->up_ctxt = lexic; /* 5. Execute */ if (f->flags & FUNC_FLAG_INTERNAL) { tree_cell* (*pf2)(lex_ctxt*) = f->block; retc = pf2(lexic2); } else { retc = nasl_exec(lexic2, f->block); deref_cell(retc); retc = FAKE_CELL; } if ((retc == NULL || retc == FAKE_CELL) && (lexic2->ret_val != NULL && lexic2->ret_val != FAKE_CELL)) { #if 0 nasl_perror(lexic, "nasl_func_call: nasl_exec(%s) returns NULL or FAKE value, but context disagrees. Fixing...\n", f->func_name); nasl_dump_tree(retc); #endif retc = lexic2->ret_val; ref_cell(retc); } if(nasl_trace_enabled())nasl_trace(lexic, "NASL> Return %s: %s\n", f->func_name, dump_cell_val(retc)); #if 1 if (! nasl_is_leaf(retc)) { nasl_perror(lexic, "nasl_func_call: return value from %s is not atomic!\n", f->func_name); nasl_dump_tree(retc); } #endif free_lex_ctxt(lexic2); lexic2 = NULL; return retc; } error: free_lex_ctxt(lexic2); return NULL; #endif }