tree_cell* nasl_strstr(lex_ctxt * lexic) { char * a = get_str_var_by_num(lexic, 0); char * b = get_str_var_by_num(lexic, 1); int sz_a = get_var_size_by_num(lexic, 0); int sz_b = get_var_size_by_num(lexic, 1); char * c; tree_cell * retc; if(a == NULL || b == NULL) return NULL; if(sz_b > sz_a) return NULL; c = (char*)memmem(a, sz_a, b, sz_b); if(c == NULL) return FAKE_CELL; retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->size = sz_a - (c - a); retc->x.str_val = strndup(c, retc->size); return retc; }
tree_cell* nasl_stridx(lex_ctxt * lexic) { char *a = get_str_var_by_num(lexic, 0); int sz_a = get_var_size_by_num(lexic, 0); char *b = get_str_var_by_num(lexic, 1); int sz_b = get_var_size_by_num(lexic, 1); char *c; int start = get_int_var_by_num(lexic, 2, 0); tree_cell *retc = alloc_typed_cell(CONST_INT); retc->x.i_val = -1; if (a == NULL || b == NULL) { nasl_perror(lexic, "stridx(string, substring [, start])\n"); return retc; } if(start < 0 || start > sz_a) { nasl_perror(lexic, "stridx(string, substring [, start])\n"); return retc; } if ((sz_a == start) || (sz_b > sz_a + start)) return retc; c = (char*)memmem(a + start, sz_a - start, b, sz_b); if(c != NULL) retc->x.i_val = c - a; return retc; }
/* * Syntax: insstr(s1, s2, i1, i2) or insstr(s1, s2, i1) * Insert string s2 into slice [i1:i2] of string s1 and returns the result * Warning: returns a CONST_DATA! */ tree_cell* nasl_insstr(lex_ctxt* lexic) { char *s1, *s2, *s3; int sz1, sz2, sz3, i1, i2; tree_cell *retc; s1 = get_str_var_by_num(lexic, 0); sz1 = get_var_size_by_num(lexic, 0); s2 = get_str_var_by_num(lexic, 1); sz2 = get_var_size_by_num(lexic, 1); i1 = get_int_var_by_num(lexic, 2, -1); i2 = get_int_var_by_num(lexic, 3, -1); if (i2 > sz1 || i2 == -1) i2 = sz1-1; if (s1 == NULL || s2 == NULL || i1 < 0 || i2 < 0) { nasl_perror(lexic, "Usage: insstr(str1, str2, idx_start [,idx_end])\n"); return NULL; } if (i1 > sz1) { nasl_perror(lexic, "insstr: cannot insert string2 after end of string1\n"); return NULL; } retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; if (i1 > i2) { nasl_perror(lexic," insstr: warning! 1st index %d greater than 2nd index %d\n", i1, i2); sz3 = sz2; } else sz3 = sz1 + i1 - i2 - 1 + sz2; s3 = retc->x.str_val = emalloc(sz3); retc->size = sz3; if (i1 <= sz1) { memcpy(s3, s1, i1); s3 += i1; } memcpy(s3, s2, sz2); s3 += sz2; if (i2 < sz1 - 1) memcpy(s3, s1 + i2 +1, sz1 - 1 - i2); return retc; }
/* * TODO: support multiple bugtraq entries */ tree_cell* script_bugtraq_id(lex_ctxt* lexic) { struct arglist * script_infos = lexic->script_infos; char * bid = get_str_var_by_num(lexic, 0); int i; for (i = 0; bid != NULL ; i ++) { plug_set_bugtraq_id(script_infos, bid); bid = get_str_var_by_num(lexic, i + 1); } return FAKE_CELL; }
tree_cell* nasl_func_has_arg(lex_ctxt* lexic) { nasl_func *f; char *s; int vt, i, flag = 0; tree_cell *retc; s = get_str_var_by_num(lexic, 0); if (s == NULL) { nasl_perror(lexic, "func_has_arg: missing parameter\n"); return NULL; } f = get_func_ref_by_name(lexic, s); if (f == NULL) { nasl_perror(lexic, "func_args: unknown function \"%s\"\n", s); return NULL; } vt = get_var_type_by_num(lexic, 1); switch(vt) { case VAR2_INT: i = get_int_var_by_num(lexic, 1, -1); if (i >= 0 && i < f->nb_unnamed_args) flag = 1; break; case VAR2_STRING: case VAR2_DATA: s = get_str_var_by_num(lexic, 1); for (i = 0; i < f->nb_named_args && ! flag; i ++) if (strcmp(s, f->args_names[i]) == 0) flag = 1; break; default: nasl_perror(lexic, "func_has_arg: string or integer expected as 2nd parameter\n"); return NULL; } retc = alloc_typed_cell(CONST_INT); retc->x.i_val = flag; return retc; }
/** * @brief Convert a string into an ISO time string. * @naslfn{isotime_scan} * * * @nasluparam * * - A string * * @naslret A ISO time string on success or NULL on error. * * @param[in] lexic Lexical context of the NASL interpreter. * * @return A tree cell. */ tree_cell * nasl_isotime_scan (lex_ctxt *lexic) { tree_cell *retc; my_isotime_t timebuf; int datalen; const char *string; *timebuf = 0; string = get_str_var_by_num (lexic, 0); if (!string) return NULL; switch (get_var_type_by_num (lexic, 0)) { case VAR2_DATA: datalen = get_var_size_by_num (lexic, 0); if (datalen < ISOTIME_SIZE - 1) return NULL; /* Too short */ memcpy (timebuf, string, ISOTIME_SIZE - 1); timebuf[ISOTIME_SIZE - 1] = 0; string = timebuf; /* FALLTHRU */ case VAR2_STRING: if (!string2isotime (timebuf, string)) return NULL; break; default: return NULL; } retc = alloc_typed_cell (CONST_STR); retc->x.str_val = estrdup (timebuf); retc->size = strlen (timebuf); return retc; }
/** * @brief Check whether an ISO time string is valid * @naslfn{isotime_is_valid} * * * @nasluparam * * - A string. Both, the standard 15 byte string and the better human * readable up to 19 byte format are accepted here. If a plain data * type is is provided only the 15 byte format is accepted. * * @naslret True is this is an ISO string; false if not. * * @param[in] lexic Lexical context of the NASL interpreter. * * @return A tree cell. */ tree_cell * nasl_isotime_is_valid (lex_ctxt *lexic) { int result = 0; tree_cell *retc; my_isotime_t timebuf; const char *string; int datalen; string = get_str_var_by_num (lexic, 0); if (string) { switch (get_var_type_by_num (lexic, 0)) { case VAR2_DATA: datalen = get_var_size_by_num (lexic, 0); if (datalen < ISOTIME_SIZE - 1) break; /* Too short */ memcpy (timebuf, string, ISOTIME_SIZE - 1); timebuf[ISOTIME_SIZE -1] = 0; string = timebuf; /* FALLTHRU */ case VAR2_STRING: if (isotime_p (string) || isotime_human_p (string)) result = 1; break; default: break; } } retc = alloc_typed_cell (CONST_INT); retc->x.i_val = result; return retc; }
tree_cell* nasl_hexstr(lex_ctxt * lexic) { tree_cell * retc; char *s = get_str_var_by_num(lexic, 0); int len = get_var_size_by_num(lexic, 0); char * ret; int i; if(s == NULL) return NULL; ret = emalloc(len * 2 + 1); for(i=0;i<len;i++) { char tmp[3]; snprintf(tmp, sizeof(tmp), "%02x", (unsigned char)s[i]); strcat(ret, tmp); } retc = alloc_tree_cell(0, NULL); retc->type = CONST_STR; retc->size = strlen(ret); retc->x.str_val = ret; return retc; }
tree_cell* nasl_strcat(lex_ctxt* lexic) { tree_cell *retc; char *s; int vi, vn, newlen; int sz; retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->size = 0; retc->x.str_val = emalloc(0); vn = array_max_index(&lexic->ctx_vars); for (vi = 0; vi < vn; vi ++) { s = get_str_var_by_num(lexic, vi); if (s == NULL) continue; sz = get_var_size_by_num(lexic, vi); if (sz <= 0) sz = strlen(s); newlen = retc->size + sz; retc->x.str_val = erealloc(retc->x.str_val, newlen + 1); memcpy(retc->x.str_val + retc->size, s, sz); retc->size = newlen; } retc->x.str_val[retc->size] = '\0'; return retc; }
/** * @brief Add days or seconds to an ISO time string. * @naslfn{isotime_add} * * This function adds days or seconds to an ISO time string and * returns the resulting time string. The number of days or seconds * are given using the named parameters; if none are given nothing is * added; if both are given both additions are performed. This * function won't work for dates before the Gregorian calendar switch. * * @nasluparam * * - An ISO time string * * @naslnparam * * - @a years An integer with the number of years to add to the timestamp. * * - @a days An integer with the number of days to add to the timestamp. * * - @a seconds An integer with the number of seconds to add to the * timestamp. * * @naslret The resulting ISO time string or NULL if the provided ISO * time string is not valid or the result would overflow * (i.e. year > 9999). * * @param[in] lexic Lexical context of the NASL interpreter. * * @return A tree cell. */ tree_cell * nasl_isotime_add (lex_ctxt *lexic) { tree_cell *retc; my_isotime_t timebuf; const char *string; int nyears, ndays, nseconds; string = get_str_var_by_num (lexic, 0); if (!string || get_var_size_by_num (lexic, 0) < ISOTIME_SIZE -1 || check_isotime (string)) return NULL; memcpy (timebuf, string, ISOTIME_SIZE -1); timebuf[ISOTIME_SIZE - 1] = 0; nyears = get_int_local_var_by_name (lexic, "years", 0); ndays = get_int_local_var_by_name (lexic, "days", 0); nseconds = get_int_local_var_by_name (lexic, "seconds", 0); if (nyears && add_years_to_isotime (timebuf, nyears)) return NULL; if (ndays && add_days_to_isotime (timebuf, ndays)) return NULL; if (nseconds && add_seconds_to_isotime (timebuf, nseconds)) return NULL; /* If nothing was added, explicitly add 0 years. */ if (!nyears && !ndays && !nseconds && add_years_to_isotime (timebuf, 0)) return NULL; retc = alloc_typed_cell (CONST_STR); retc->x.str_val = estrdup (timebuf); retc->size = strlen (timebuf); return retc; }
tree_cell* nasl_chomp(lex_ctxt* lexic) { tree_cell *retc; char *p = NULL, *str; int i, len; str = get_str_var_by_num(lexic, 0); if (str == NULL) return NULL; len = get_var_size_by_num(lexic, 0); retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; for (i = 0; i < len; i ++) if (isspace(str[i])) { if (p == NULL) p = str + i; } else p = NULL; if (p != NULL) len = (p - str); retc->x.str_val = emalloc(len); retc->size = len; memcpy(retc->x.str_val, str, len); retc->x.str_val[len] = '\0'; return retc; }
tree_cell * nasl_get_preference(lex_ctxt * lexic) { tree_cell *retc; char *name, *value; struct arglist *script_infos, *prefs; script_infos = lexic->script_infos; prefs = arg_get_value(script_infos, "preferences"); if (prefs == NULL) { nasl_perror(lexic, "get_preference: not preferences\n"); return NULL; } name = get_str_var_by_num(lexic, 0); if (name == NULL) { nasl_perror(lexic, "get_preference: no name\n"); return NULL; } value = arg_get_value(prefs, name); if (value == NULL) return NULL; retc = alloc_typed_cell(CONST_DATA); retc->x.str_val = strdup(value); retc->size = strlen(value); return retc; }
tree_cell* nasl_func_unnamed_args(lex_ctxt* lexic) { nasl_func *f; char *s; tree_cell *retc; s = get_str_var_by_num(lexic, 0); if (s == NULL) { nasl_perror(lexic, "func_unnamed_args: missing parameter\n"); return NULL; } f = get_func_ref_by_name(lexic, s); if (f == NULL) { nasl_perror(lexic, "func_unnamed_args: unknown function \"%s\"\n", s); return NULL; } retc = alloc_typed_cell(CONST_INT); retc->x.i_val = f->nb_unnamed_args; return retc; }
tree_cell * script_get_preference(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; tree_cell * retc; char * pref = get_str_var_by_num(lexic, 0); char * value; if(pref == NULL){ nasl_perror(lexic, "Argument error in the function script_get_preference()\n"); nasl_perror(lexic, "Function usage is : pref = script_get_preference(<name>)\n"); return FAKE_CELL; } value = get_plugin_preference(script_infos, pref); if(value != NULL) { retc = alloc_tree_cell(0, NULL); if(isalldigit(value, strlen(value))) { retc->type = CONST_INT; retc->x.i_val = atoi(value); } else { retc->type = CONST_DATA; retc->size = strlen(value); retc->x.str_val = estrdup(value); } return retc; } else return FAKE_CELL; }
static tree_cell * script_elem(lex_ctxt* lexic, script_register_func_t script_register_func) { struct arglist * script_infos = lexic->script_infos; char * lang = g_language;//NULL; char * str; char * dfl = "english"; if( lang == NULL ) lang = dfl; str = get_str_local_var_by_name(lexic, lang); if(str == NULL){ str = get_str_local_var_by_name(lexic, "english"); if( str == NULL ){ str = get_str_var_by_num(lexic, 0); if( str == NULL ) return FAKE_CELL; } } //script_register_func(script_infos, str, NULL); script_register_func(script_infos, str, lang); return FAKE_CELL; }
/* * TODO: support multiple CVE entries */ tree_cell* script_cve_id(lex_ctxt* lexic) { struct arglist * script_infos = lexic->script_infos; char * cve = get_str_var_by_num(lexic, 0); int i; for (i = 0; cve != NULL ; i ++) { plug_set_cve_id(script_infos, cve); cve = get_str_var_by_num(lexic, i + 1); } return FAKE_CELL; }
tree_cell * nasl_lm_owf_gen (lex_ctxt * lexic) { char *pass = get_str_var_by_num (lexic, 0); int pass_len = get_var_size_by_num (lexic, 0); tree_cell *retc; uchar pwd[15]; uchar p16[16]; int i; if (pass_len < 0 || pass == NULL) { nasl_perror (lexic, "Syntax : nt_lm_gen(cryptkey:<c>, password:<p>)\n"); return NULL; } bzero (pwd, sizeof (pwd)); strncpy ((char *) pwd, pass, sizeof (pwd) - 1); for (i = 0; i < sizeof (pwd); i++) pwd[i] = toupper (pwd[i]); E_P16 (pwd, p16); retc = alloc_tree_cell (0, NULL); retc->type = CONST_DATA; retc->size = 16; retc->x.str_val = g_memdup (p16, 17); return retc; }
tree_cell* nasl_leave_multicast_group(lex_ctxt *lexic) { char *a; struct in_addr ia; int i; a = get_str_var_by_num(lexic, 0); if (a == NULL) { nasl_perror(lexic, "leave_multicast_group: missing parameter\n"); return NULL; } if (! inet_aton(a, &ia)) { nasl_perror(lexic, "leave_multicast_group: invalid parameter '%s'\n", a); return NULL; } for (i = 0; i < jmg_max; i ++) if (jmg_desc[i].count > 0 && jmg_desc[i].in.s_addr == ia.s_addr) { if (-- jmg_desc[i].count <= 0) closesocket(jmg_desc[i].s); return FAKE_CELL; } nasl_perror(lexic, "leave_multicast_group: never joined group %s\n", a); return NULL; }
static tree_cell * nasl_hash (lex_ctxt * lexic, int algorithm) { char *data = get_str_var_by_num (lexic, 0); int len = get_var_size_by_num (lexic, 0); return nasl_gcrypt_hash (lexic, algorithm, data, len, NULL, 0); }
tree_cell * script_exclude_keys(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; int i; char * keys = get_str_var_by_num(lexic, 0); for(i=0;keys != NULL;i++) { keys = get_str_var_by_num(lexic, i); if(keys != NULL) { plug_exclude_key(script_infos, keys); } } return FAKE_CELL; }
/* * Instead of reading the local copy of the KB, we ask the upstream * father the "newest" value of a given KB item. This is especially useful * when dealing with shared sockets and SSH */ tree_cell * get_kb_fresh_item(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; char * kb_entry = get_str_var_by_num(lexic, 0); char * val; tree_cell * retc; int type; if(kb_entry == NULL) return NULL; if (! lexic->authenticated && strncmp(kb_entry, SECRET_KB_PREFIX, sizeof(SECRET_KB_PREFIX) - 1) == 0) { nasl_perror(lexic, "Untrusted script cannot read protected KB entry %s\n", kb_entry); return NULL; } val = plug_get_fresh_key(script_infos,kb_entry, &type); if ( val == NULL && type == -1 ) return NULL; retc = alloc_tree_cell(0, NULL); if( type == KB_TYPE_INT ) { retc->type = CONST_INT; retc->x.i_val = (int)val; return retc; } else { retc->type = CONST_DATA; if ( val != NULL ) { retc->size = strlen(val); retc->x.str_val = val; /* Do NOT estrdup() the value, since plug_get_fresh_key() allocated the memory already */ } else { retc->size = 0; retc->x.str_val = NULL; } } return retc; }
tree_cell * script_dependencie(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; char * dep = get_str_var_by_num(lexic, 0); int i; if(dep == NULL){ nasl_perror(lexic, "Argument error in function script_dependencie()\n"); nasl_perror(lexic, "Function usage is : script_dependencie(<name>)\n"); nasl_perror(lexic, "Where <name> is the name of another script\n"); return FAKE_CELL; } for(i=0;dep != NULL;i++) { dep = get_str_var_by_num(lexic, i); if(dep != NULL) plug_set_dep(script_infos, dep); } return FAKE_CELL; }
tree_cell * script_require_keys(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; char * keys = get_str_var_by_num(lexic, 0); int i; if(keys == NULL){ nasl_perror(lexic, "Argument error in function script_require_keys()\n"); nasl_perror(lexic, "Function usage is : script_require_keys(<name>)\n"); nasl_perror(lexic, "Where <name> is the name of a key\n"); return FAKE_CELL; } for(i=0; keys != NULL;i++) { keys = get_str_var_by_num(lexic, i); if(keys != NULL) plug_require_key(script_infos, keys); } return FAKE_CELL; }
tree_cell* script_get_preference_file_location(lex_ctxt* lexic) { struct arglist *script_infos = lexic->script_infos; tree_cell *retc; char *pref = get_str_var_by_num(lexic, 0); const char *value, *local; int len; /* * Getting the local file name is not dangerous, but * only signed scripts can access files uploaded by the user */ if (check_authenticated(lexic) < 0) { nasl_perror(lexic, "script_get_preference_file_location: script is not authenticated!\n"); return NULL; } if(pref == NULL) { nasl_perror(lexic, "script_get_preference_file_location: no preference name!\n"); return NULL; } value = get_plugin_preference(script_infos, pref); if(value == NULL) { nasl_perror(lexic, "script_get_preference_file_location: could not get preference %s\n", pref); return NULL; } local = get_plugin_preference_fname(script_infos, value); if(local == NULL) { nasl_perror(lexic, "script_get_preference_file_location: could not get local file name from preference %s\n", pref); return NULL; } len = strlen(local); retc = alloc_typed_cell(CONST_DATA); retc->size = len; retc->x.str_val = emalloc(len+1); memcpy(retc->x.str_val, local, len+1); return retc; }
tree_cell * script_require_udp_ports(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; int i; char * port; for ( i = 0; ; i ++) { port = get_str_var_by_num(lexic, i); if(port != NULL) plug_require_udp_port(script_infos, port); else break; } return FAKE_CELL; }
tree_cell * script_version(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; char * version = get_str_var_by_num(lexic, 0); if(version == NULL){ nasl_perror(lexic, "Argument error in function script_version()\n"); nasl_perror(lexic, "Function usage is : script_version(<name>)\n"); nasl_perror(lexic, "Where <name> is the name of another script\n"); } else plug_set_version(script_infos, version); return FAKE_CELL; }
/*---------------------------------------------------------------------*/ tree_cell* nasl_ord(lex_ctxt* lexic) { tree_cell *retc; unsigned char *val = get_str_var_by_num(lexic, 0); if (val == NULL) { nasl_perror(lexic, "ord() usage : ord(char)\n"); return NULL; } retc = alloc_tree_cell(0, NULL); retc->type = CONST_INT; retc->x.i_val = val[0]; return retc; }
tree_cell * nasl_find_in_path (lex_ctxt * lexic) { tree_cell *retc; char *cmd; cmd = get_str_var_by_num (lexic, 0); if (cmd == NULL) { nasl_perror (lexic, "find_in_path() usage: cmd\n"); return NULL; } retc = alloc_typed_cell (CONST_INT); retc->x.i_val = (find_in_path (cmd, 0) != NULL); return retc; }
tree_cell * nasl_shared_socket_release( lex_ctxt * lexic ) { char * name = get_str_var_by_num(lexic, 0); int fd; struct arglist * script_infos = lexic->script_infos; if ( name == NULL ) { fprintf(stderr, "Usage: shared_socket_release(<name>)\n"); return NULL; } if ( strncmp(name, SECRET_SOCKET_PREFIX, strlen(SECRET_SOCKET_PREFIX)) == 0 && check_authenticated(lexic) < 0 ) return NULL; shared_socket_release(script_infos, name); return NULL; }
/** * @brief Convert an SIO time string into a better readable string * @naslfn{isotime_print} * * @nasluparam * * - An ISO time string. * * @naslret A string in the format "YYYY-MM-DD HH:MM:SS" or "[none]" * if the provided time string is not valid. * * @param[in] lexic Lexical context of the NASL interpreter. * * @return A tree cell. */ tree_cell * nasl_isotime_print (lex_ctxt *lexic) { tree_cell *retc; const char *string; char helpbuf[20]; string = get_str_var_by_num (lexic, 0); if (!string || get_var_size_by_num (lexic, 0) < 15 || check_isotime (string)) strcpy (helpbuf, "[none]"); else snprintf (helpbuf, sizeof helpbuf, "%.4s-%.2s-%.2s %.2s:%.2s:%.2s", string, string+4, string+6, string+9, string+11, string+13); retc = alloc_typed_cell (CONST_STR); retc->x.str_val = estrdup (helpbuf); retc->size = strlen (helpbuf); return retc; }