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; }
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; }
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_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_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; }
/** * @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; }
/** * @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; }
/** * @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; }
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* nasl_strlen(lex_ctxt* lexic) { int len = get_var_size_by_num(lexic, 0); tree_cell * retc; retc = emalloc(sizeof(tree_cell)); retc->ref_count = 1; retc->type = CONST_INT; retc->x.i_val = len; return retc; }
/** * @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; }
/*---------------------------------------------------------------------*/ tree_cell * nasl_toupper(lex_ctxt * lexic) { tree_cell * retc; char * str = get_str_var_by_num(lexic, 0); int str_len = get_var_size_by_num(lexic, 0); int i; if(str == NULL) return NULL; str = strndup(str, str_len); for(i=0;i<str_len;i++) str[i] = toupper(str[i]); retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->size = str_len; retc->x.str_val = str; return retc; }
tree_cell * nasl_nt_owf_gen (lex_ctxt * lexic) { char *pass = get_str_var_by_num (lexic, 0); int pass_len = get_var_size_by_num (lexic, 0); char pwd[130]; short upwd[130], *dst; short val; char *src; int i; if (pass_len < 0 || pass == NULL) { nasl_perror (lexic, "Syntax : nt_owf_gen(cryptkey:<c>, password:<p>)\n"); return NULL; } dst = upwd; src = pass; for (i = 0; i < pass_len; i++) { val = *src; #if __BYTE_ORDER == __BIG_ENDIAN *dst = val << 8; #else *dst = val; #endif dst++; src++; if (val == 0) break; } bzero (pwd, sizeof (pwd)); memcpy (pwd, upwd, sizeof (pwd) < pass_len * 2 ? sizeof (pwd) : pass_len * 2); return nasl_gcrypt_hash (lexic, GCRY_MD_MD4, pwd, pass_len * 2 > 128 ? 128 : pass_len * 2, NULL, 0); }
/* * Syntax: substr(s, i1) or substr(s, i1, i2) * Returns character from string s starting for position i1 till the end or * position i2 (start of string is 0) */ tree_cell* nasl_substr(lex_ctxt* lexic) { char *s1; int sz1, sz2, i1, i2, typ; tree_cell *retc; s1 = get_str_var_by_num(lexic, 0); sz1 = get_var_size_by_num(lexic, 0); typ = get_var_type_by_num(lexic, 0); i1 = get_int_var_by_num(lexic, 1, -1); #ifndef MAX_INT #define MAX_INT (~(1 << (sizeof(int) * 8 - 1))) #endif i2 = get_int_var_by_num(lexic, 2, MAX_INT); if (i2 > sz1) i2 = sz1-1; if (s1 == NULL || i1 < 0) { nasl_perror(lexic, "Usage: substr(string, idx_start [,idx_end])\n"); return NULL; } retc = alloc_tree_cell(0, NULL); retc->type = (typ == CONST_STR ? CONST_STR : CONST_DATA); if (i1 > i2) { retc->x.str_val = emalloc(0); retc->size = 0; return retc; } sz2 = i2 - i1 + 1; retc->size = sz2; retc->x.str_val = emalloc(sz2); memcpy(retc->x.str_val, s1 + i1, sz2); return retc; }
tree_cell* nasl_split(lex_ctxt* lexic) { tree_cell *retc; nasl_array *a; char *p, *str, *sep; int i, i0, j, len, sep_len = 0, keep = 1; anon_nasl_var v; str = get_str_var_by_num(lexic, 0); if (str == NULL) return NULL; len = get_var_size_by_num(lexic, 0); sep = get_str_local_var_by_name(lexic, "sep"); if (sep != NULL) sep_len = get_var_size_by_name(lexic, "sep"); keep = get_int_local_var_by_name(lexic, "keep", 1); retc = alloc_tree_cell(0, NULL); retc->type = DYN_ARRAY; retc->x.ref_val = a = emalloc(sizeof(nasl_array)); bzero(&v, sizeof(v)); v.var_type = VAR2_DATA; if (sep != NULL) { i = 0; j = 0; for(;;) { if ((p = (char*)memmem(str + i, len - i, sep, sep_len)) == NULL) { v.v.v_str.s_siz = len - i; v.v.v_str.s_val = str + i; (void) add_var_to_list(a, j ++, &v); return retc; } else { if (keep) v.v.v_str.s_siz = (p - (str + i)) + sep_len; else v.v.v_str.s_siz = p - (str + i); v.v.v_str.s_val = str + i; (void) add_var_to_list(a, j ++, &v); i = (p - str) + sep_len; if (i >= len) return retc; } } } /* Otherwise, we detect the end of line. A little more subtle */ for (i = i0 = j = 0; i < len; i ++) { if (str[i] == '\r' && str[i+1] == '\n') { i ++; if (keep) v.v.v_str.s_siz = i - i0 + 1; else v.v.v_str.s_siz = i - i0 - 1; v.v.v_str.s_val = str + i0; i0 = i + 1; (void) add_var_to_list(a, j ++, &v); } else if (str[i] == '\n') { if (keep) v.v.v_str.s_siz = i - i0 + 1; else v.v.v_str.s_siz = i - i0; v.v.v_str.s_val = str + i0; i0 = i + 1; (void) add_var_to_list(a, j ++, &v); } } if (i > i0) { v.v.v_str.s_siz = i - i0; v.v.v_str.s_val = str + i0; (void) add_var_to_list(a, j ++, &v); } return retc; }
tree_cell* nasl_rawstring(lex_ctxt* lexic) { tree_cell *retc; int vi, vn, i, j, x; int sz, typ; const char *s; int total_len = 0; retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->size = 0; retc->x.str_val = emalloc(RAW_STR_LEN); vn = array_max_index(&lexic->ctx_vars); for (vi = 0; vi < vn && total_len < RAW_STR_LEN-1; vi ++) { if ((typ = get_var_type_by_num(lexic, vi)) == VAR2_UNDEF) continue; sz = get_var_size_by_num(lexic, vi); if (typ == VAR2_INT) { x = get_int_var_by_num(lexic, vi, 0); retc->x.str_val[total_len ++] = x; } else { int current_len = sz; char str[RAW_STR_LEN]; s = get_str_var_by_num(lexic, vi); if (sz <= 0) sz = strlen(s); if (sz >= RAW_STR_LEN) { nasl_perror(lexic, "Error. Too long argument in raw_string()\n"); break; } /* Should we test if the variable is composed only of digits? */ if(typ == VAR2_STRING) { /* TBD:I should decide at last if we keep those "purified" * string or not, and if we do, if "CONST_STR" & "VAR2_STR" are * "not pure" strings */ for(i=0, j=0; i < sz; i++) { if(s[i]=='\\') { if (s[i+1] == 'n') { str[j++]='\n'; i++; } else if (s[i+1] == 't') { str[j++]='\t'; i++; } else if (s[i+1] == 'r') { str[j++] = '\r'; i++; } else if (s[i+1] == 'x' && isxdigit(s[i+2]) && isxdigit(s[i+3])) { x = 0; if(isdigit(s[i+2])) x = (s[i+2]-'0')*16; else x=(10+tolower(s[i+2])-'a')*16; if(isdigit(s[i+3])) x += s[i+3]-'0'; else x += tolower(s[i+3])+10-'a'; str[j++]=x; i+=3; } else if(s[i+1] == '\\') { str[j++] = s[i]; i++; } else i++; } else str[j++] = s[i]; } current_len = j; } else { memcpy(str, s, sz); str[sz] = '\0'; current_len = sz; } if(total_len + current_len > RAW_STR_LEN) { nasl_perror(lexic, "Error. Too long argument in raw_string()\n"); break; } bcopy(str, retc->x.str_val + total_len, current_len); total_len += current_len; } } retc->size = total_len; return retc; }
tree_cell* nasl_string(lex_ctxt* lexic) { tree_cell *retc; int vi, vn, newlen; int sz, typ; const char *s, *p1; char *p2; 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 ++) { if ((typ = get_var_type_by_num(lexic, vi)) == VAR2_UNDEF) continue; s = get_str_var_by_num(lexic, vi); 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); p2 = retc->x.str_val + retc->size; p1 = s; retc->size = newlen; if (typ != VAR2_STRING) { memcpy(p2, p1, sz); p2[sz] = '\0'; } else while (*p1 != '\0') { if(*p1 == '\\' && p1[1] != '\0') { switch (p1[1]) { case 'n': *p2 ++ = '\n'; break; case 't': *p2 ++ = '\t'; break; case 'r': *p2++ = '\r'; break; case '\\': *p2++ = '\\'; break; case 'x': if (isxdigit(p1[2]) && isxdigit(p1[3])) { *p2++ = 16 * (isdigit(p1[2]) ? p1[2]-'0' : 10+tolower(p1[2])-'a') + (isdigit(p1[3]) ? p1[3]-'0' : 10+tolower(p1[3])-'a'); p1 += 2; retc->size -= 2; } else { nasl_perror(lexic, "Buggy hex value '\\x%c%c' skipped\n", isprint(p1[2]) ? p1[2] : '.', isprint(p1[3]) ? p1[3] : '.' ); /* We do not increment p1 by 4, we may miss the end of the string */ } break; default: nasl_perror(lexic, "Unknown%d escape sequence '\\%c'\n", getpid(), isprint(p1[1]) ? p1[1] : '.' ); retc->size --; break; } p1 += 2; retc->size --; } else *p2++ = *p1++; } } retc->x.str_val[retc->size] = '\0'; return retc; }