tree_cell* nasl_make_list(lex_ctxt* lexic) { tree_cell *retc = NULL; int i, j, vi; anon_nasl_var *v; named_nasl_var *vn; nasl_array *a, *a2; retc = alloc_tree_cell(0, NULL); retc->type = DYN_ARRAY; retc->x.ref_val = a = emalloc(sizeof(nasl_array)); for (i = vi = 0; (v = nasl_get_var_by_num(&lexic->ctx_vars, vi, 0)) != NULL; vi ++) { switch (v->var_type) { case VAR2_INT: case VAR2_STRING: case VAR2_DATA: add_var_to_list(a, i ++, v); break; case VAR2_ARRAY: a2 = &v->v.v_arr; for (j = 0; j < a2->max_idx; j ++) if (add_var_to_list(a, i, a2->num_elt[j]) >= 1) i ++; if (a2->hash_elt != NULL) { #if NASL_DEBUG > 1 nasl_perror(lexic, "make_list: named arguments in array have no order\n"); #endif for (j = 0; j < VAR_NAME_HASH; j++) for (vn = a2->hash_elt[j]; vn != NULL; vn = vn->next_var) if (vn->u.var_type != VAR2_UNDEF) if (add_var_to_list(a, i , &vn->u) >= 1) i ++; } break; case VAR2_UNDEF: nasl_perror(lexic, "nasl_make_list: undefined variable #%d skipped\n", i); continue; default: nasl_perror(lexic, "nasl_make_list: unhandled variable type 0x%x - skipped\n", v->var_type); continue; } } return retc; }
tree_cell* nasl_keys(lex_ctxt* lexic) { tree_cell *retc = NULL; anon_nasl_var *v, myvar; named_nasl_var *vn; nasl_array *a, *a2; int i, j, vi; retc = alloc_tree_cell(0, NULL); retc->type = DYN_ARRAY; retc->x.ref_val = a2 = emalloc(sizeof(nasl_array)); bzero(&myvar, sizeof(myvar)); for (i = vi = 0; (v = nasl_get_var_by_num(&lexic->ctx_vars, vi, 0)) != NULL; vi ++) { if (v->var_type == VAR2_ARRAY) { a = &v->v.v_arr; /* First the numerical index */ for (j = 0; j < a->max_idx; j ++) if (a->num_elt[j] != NULL && a->num_elt[j]->var_type != VAR2_UNDEF) { myvar.var_type = VAR2_INT; myvar.v.v_int = j; add_var_to_list(a2, i ++, &myvar); } /* Then the string index */ if (a->hash_elt != NULL) for (j = 0; j < VAR_NAME_HASH; j++) for (vn = a->hash_elt[j]; vn != NULL; vn = vn->next_var) if (vn->u.var_type != VAR2_UNDEF) { myvar.var_type = VAR2_STRING; myvar.v.v_str.s_val = vn->var_name; myvar.v.v_str.s_siz = strlen(vn->var_name); add_var_to_list(a2, i ++, &myvar); } } else nasl_perror(lexic, "nasl_keys: bad variable #%d skipped\n", vi); } return retc; }
tree_cell* nasl_make_array(lex_ctxt* lexic) { tree_cell *retc = NULL; int i, vi; anon_nasl_var *v, *v2; nasl_array *a; retc = alloc_tree_cell(0, NULL); retc->type = DYN_ARRAY; retc->x.ref_val = a = emalloc(sizeof(nasl_array)); i = vi = 0; while ((v = nasl_get_var_by_num(&lexic->ctx_vars, vi ++, 0)) != NULL) { v2 = nasl_get_var_by_num(&lexic->ctx_vars, vi ++, 0); if (v2 == NULL) { nasl_perror(lexic, "make_array: odd number (%d) of argument?\n", vi); break; } switch (v2->var_type) { case VAR2_INT: case VAR2_STRING: case VAR2_DATA: switch (v->var_type) { case VAR2_INT: add_var_to_list(a, v->v.v_int, v2); break; case VAR2_STRING: case VAR2_DATA: add_var_to_array(a, (char*)var2str(v) , v2); break; } break; case VAR2_UNDEF: default: nasl_perror(lexic, "make_array: bad value type %d for arg #%d\n", v2->var_type, vi); break; } } return retc; }
/* * This function returns an array */ tree_cell* nasl_eregmatch(lex_ctxt* lexic) { char *pattern = get_str_local_var_by_name(lexic, "pattern"); char *string = get_str_local_var_by_name(lexic, "string"); int icase = get_int_local_var_by_name(lexic, "icase", 0); int copt = 0, i; tree_cell *retc; regex_t re; regmatch_t subs[NS]; anon_nasl_var v; nasl_array *a; if(icase != 0) copt = REG_ICASE; if(pattern == NULL || string == NULL) return NULL; nasl_re_set_syntax(RE_SYNTAX_POSIX_EGREP); if(nasl_regcomp(&re, pattern, REG_EXTENDED|copt)) { nasl_perror(lexic, "regmatch() : regcomp() failed\n"); return NULL; } if(nasl_regexec(&re, string, (size_t)NS, subs, 0) != 0) return NULL; retc = alloc_tree_cell(0, NULL); retc->type = DYN_ARRAY; retc->x.ref_val = a = emalloc(sizeof(nasl_array)); for (i = 0; i < NS; i ++) if (subs[i].rm_so != -1) { v.var_type = VAR2_DATA; v.v.v_str.s_siz = subs[i].rm_eo - subs[i].rm_so; v.v.v_str.s_val = string + subs[i].rm_so; (void) add_var_to_list(a, i, &v); } nasl_regfree(&re); return retc; }
tree_cell* nasl_func_named_args(lex_ctxt* lexic) { nasl_func *f; char *s; int i; tree_cell *retc; nasl_array *a; anon_nasl_var v; s = get_str_var_by_num(lexic, 0); if (s == NULL) { nasl_perror(lexic, "func_named_args: missing parameter\n"); return NULL; } f = get_func_ref_by_name(lexic, s); if (f == NULL) { nasl_perror(lexic, "func_named_args: unknown function \"%s\"\n", s); return NULL; } retc = alloc_typed_cell(DYN_ARRAY); retc->x.ref_val = a = emalloc(sizeof(nasl_array)); memset(&v, 0, sizeof(v)); v.var_type = VAR2_STRING; for (i = 0; i < f->nb_named_args; i ++) { v.v.v_str.s_val = f->args_names[i]; v.v.v_str.s_siz = strlen(f->args_names[i]); if (add_var_to_list(a, i, &v) < 0) nasl_perror(lexic, "func_named_args: add_var_to_list failed (internal error)\n"); } return retc; }
/** * @brief Get info pertaining to a socket. * @naslfn{get_sock_info} * * This function is used to retrieve various information about an * active socket. It requires the NASL socket number and a string to * select the information to retrieve. * * Supported keywords are: * * - @a dport Return the destination port. This is an integer. NOTE: * Not yet implemented. * * - @a sport Return the source port. This is an integer. NOTE: Not * yet implemented. * * - @a encaps Return the encapsulation of the socket. Example * output: "TLScustom". * * - @a tls-proto Return a string with the actual TLS protocol in use. * n/a" is returned if no SSL/TLS session is active. Example * output: "TLSv1". * * - @a tls-kx Return a string describing the key exchange algorithm. * Example output: "RSA". * * - @a tls-certtype Return the type of the certificate in use by the * session. Example output: "X.509" * * - @a tls-cipher Return the cipher algorithm in use by the session; * Example output: "AES-256-CBC". * * - @a tls-mac Return the message authentication algorithms used by * the session. Example output: "SHA1". * * - @a tls-comp Return the compression algorithms in use by the * session. Example output: "DEFLATE". * * - @a tls-auth Return the peer's authentication type. Example * output: "CERT". * * - @a tls-cert Return the peer's certificates for an SSL or TLS * connection. This is an array of binary strings or NULL if no * certificate is known. * * @nasluparam * * - A NASL socket * * - A string keyword; see above. * * @naslnparam * * - @a asstring If true return a human readable string instead of * an integer. Used only with these keywords: encaps. * * @naslret An integer or a string or NULL on error. * * @param[in] lexic Lexical context of the NASL interpreter. * * @return A tree cell. */ tree_cell * nasl_get_sock_info (lex_ctxt * lexic) { int sock; int type; int err; const char *keyword, *s; tree_cell *retc; int as_string; int transport; gnutls_session_t tls_session; char *strval; int intval; sock = get_int_var_by_num (lexic, 0, -1); if (sock <= 0) { nasl_perror (lexic, "error: socket %d is not valid\n"); return NULL; } keyword = get_str_var_by_num (lexic, 1); if (!keyword || !((type = get_var_type_by_num (lexic, 1)) == VAR2_STRING || type == VAR2_DATA)) { nasl_perror (lexic, "error: second argument is not of type string\n"); return NULL; } as_string = !!get_int_local_var_by_name (lexic, "asstring", 0); transport = 0; strval = NULL; intval = 0; retc = FAKE_CELL; /* Dummy value to detect retc == NULL. */ { void *tmp = NULL; err = get_sock_infos (sock, &transport, &tmp); tls_session = tmp; } if (err) { nasl_perror (lexic, "error retrieving infos for socket %d: %s\n", sock, strerror (err)); retc = NULL; } else if (!strcmp (keyword, "encaps")) { if (as_string) strval = estrdup (get_encaps_name (transport)); else intval = transport; } else if (!strcmp (keyword, "tls-proto")) { if (!tls_session) s = "n/a"; else s = gnutls_protocol_get_name (gnutls_protocol_get_version (tls_session)); strval = estrdup (s?s:"[?]"); } else if (!strcmp (keyword, "tls-kx")) { if (!tls_session) s = "n/a"; else s = gnutls_kx_get_name (gnutls_kx_get (tls_session)); strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-certtype")) { if (!tls_session) s = "n/a"; else s = gnutls_certificate_type_get_name (gnutls_certificate_type_get (tls_session)); strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-cipher")) { if (!tls_session) s = "n/a"; else s = gnutls_cipher_get_name (gnutls_cipher_get (tls_session)); strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-mac")) { if (!tls_session) s = "n/a"; else s = gnutls_mac_get_name (gnutls_mac_get (tls_session)); strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-comp")) { if (!tls_session) s = "n/a"; else s = gnutls_compression_get_name (gnutls_compression_get (tls_session)); strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-auth")) { if (!tls_session) s = "n/a"; else { switch (gnutls_auth_get_type (tls_session)) { case GNUTLS_CRD_ANON: s = "ANON"; break; case GNUTLS_CRD_CERTIFICATE: s = "CERT"; break; case GNUTLS_CRD_PSK: s = "PSK"; break; case GNUTLS_CRD_SRP: s = "SRP"; break; default: s = "[?]"; break; } } strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-cert")) { /* We only support X.509 for now. GNUTLS also allows for OpenPGP, but we are not prepared for that. */ if (!tls_session || gnutls_certificate_type_get (tls_session) != GNUTLS_CRT_X509) s = "n/a"; else { const gnutls_datum_t *list; unsigned int nlist = 0; int i; nasl_array *a; anon_nasl_var v; list = gnutls_certificate_get_peers (tls_session, &nlist); if (!list) retc = NULL; /* No certificate or other error. */ else { retc = alloc_tree_cell (0, NULL); retc->type = DYN_ARRAY; retc->x.ref_val = a = emalloc (sizeof *a); for (i=0; i < nlist; i++) { memset (&v, 0, sizeof v); v.var_type = VAR2_DATA; v.v.v_str.s_val = list[i].data; v.v.v_str.s_siz = list[i].size; add_var_to_list (a, i, &v); } } } } else { nasl_perror (lexic, "unknown keyword '%s'\n", keyword); retc = NULL; } if (!retc) ; else if (retc != FAKE_CELL) ; /* Already allocated. */ else if (strval) { retc = alloc_typed_cell (CONST_STR); retc->x.str_val = strval; retc->size = strlen (strval); } else { retc = alloc_typed_cell (CONST_INT); retc->x.i_val = intval; } 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; }