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; }
/** * @brief Seek in file. */ tree_cell * nasl_file_seek (lex_ctxt * lexic) { tree_cell *retc; int fd; int foffset; foffset = get_int_local_var_by_name (lexic, "offset", 0); fd = get_int_local_var_by_name (lexic, "fp", -1); if (fd < 0) { nasl_perror (lexic, "file_seek: need one arguments 'fp'\n"); return NULL; } if (lseek (fd, foffset, SEEK_SET) < 0) { nasl_perror (lexic, "fseek: %s\n", strerror (errno)); return NULL; } retc = alloc_typed_cell (CONST_INT); retc->x.i_val = 0; return retc; }
tree_cell* nasl_get_source_port(lex_ctxt* lexic) { struct sockaddr_in ia; int i, s, fd, l; tree_cell *retc; s = get_int_var_by_num(lexic, 0, -1); if (s < 0) { nasl_perror(lexic, "get_source_port: missing socket parameter\n"); return NULL; } fd = nessus_get_socket_from_connection(s); if (fd < 0) { nasl_perror(lexic, "get_source_port: invalid socket parameter %d\n", s); return NULL; } l = sizeof(ia); if (getsockname(fd, (struct sockaddr*)&ia, &l) < 0) { nasl_perror(lexic, "get_source_port: getsockname(%d): %s\n", fd, strerror(errno)); return NULL; } retc = alloc_typed_cell(CONST_INT); retc->x.i_val = ntohs(ia.sin_port); 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_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* nasl_mktime(lex_ctxt* lexic) { struct tm tm; tree_cell *retc; time_t tictac; tm.tm_sec = get_int_local_var_by_name(lexic, "sec", 0); /* seconds */ tm.tm_min = get_int_local_var_by_name(lexic, "min", 0); /* minutes */ tm.tm_hour = get_int_local_var_by_name(lexic, "hour", 0); /* hours */ tm.tm_mday = get_int_local_var_by_name(lexic, "mday", 0); /* day of the month */ tm.tm_mon = get_int_local_var_by_name(lexic, "mon", 1); /* month */ tm.tm_mon -= 1; tm.tm_year = get_int_local_var_by_name(lexic, "year", 0); /* year */ if (tm.tm_year >= 1900) tm.tm_year -= 1900; tm.tm_isdst = get_int_local_var_by_name(lexic, "isdst", -1); /* daylight saving time */ errno = 0; tictac = mktime(&tm); if (tictac == (time_t)(-1)) { nasl_perror(lexic, "mktime(sec=%02d min=%02d hour=%02d mday=%02d mon=%02d year=%04d isdst=%d): %s\n", tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mday, tm.tm_mon+1, tm.tm_year+1900, tm.tm_isdst, errno ? strerror(errno): "invalid value?"); return NULL; } retc = alloc_typed_cell(CONST_INT); retc->x.i_val = tictac; 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_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; }
tree_cell* nasl_unixtime(lex_ctxt* lexic) { tree_cell *retc; retc = alloc_typed_cell(CONST_INT); retc->x.i_val = time(NULL); return retc; }
tree_cell * nasl_telnet_init(lex_ctxt * lexic) { int soc = get_int_var_by_num(lexic, 0, -1); int opts; /* number of options recorded */ unsigned char buffer[1024]; #define iac buffer[0] #define code buffer[1] #define option buffer[2] tree_cell * retc; int n = 0, n2; if(soc <= 0 ) { nasl_perror(lexic, "Syntax error in the telnet_init() function\n"); nasl_perror(lexic, "Correct syntax is : output = telnet_init(<socket>)\n"); return NULL; } iac = 255; opts = 0; while(iac == 255) { n = read_stream_connection_min(soc, buffer, 3, 3); if((iac!=255)||(n<=0)||(n!=3))break; if((code == 251)||(code == 252))code = 254; /* WILL , WONT -> DON'T */ else if((code == 253)||(code == 254))code = 252; /* DO,DONT -> WONT */ write_stream_connection(soc, buffer,3); opts++; if (opts>100) break; } if (n <= 0) { if (opts == 0) return NULL; else n = 0; } if (opts>100) /* remote telnet server is crazy */ { nasl_perror(lexic, "More than 100 options received by telnet_init() function! exiting telnet_init.\n"); return NULL; } n2 = read_stream_connection(soc, buffer + n, sizeof(buffer) - n); if (n2 > 0) n += n2; retc = alloc_typed_cell(CONST_DATA); retc->size = n; retc->x.str_val = strndup(buffer, n); #undef iac #undef data #undef option return retc; }
/** * @brief Return the current time in ISO format * @naslfn{isotime_now} * * @nasluparam * * - None * * @naslret A string with the ISO time. If the current time is not * available an empty string is returned. * * @param[in] lexic Lexical context of the NASL interpreter. * * @return A tree cell. */ tree_cell * nasl_isotime_now (lex_ctxt *lexic) { tree_cell *retc; my_isotime_t timebuf; get_current_isotime (timebuf); retc = alloc_typed_cell (CONST_STR); retc->x.str_val = estrdup (timebuf); retc->size = strlen (timebuf); return retc; }
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 Read file */ tree_cell * nasl_file_read (lex_ctxt * lexic) { tree_cell *retc; char *buf; int fd; int flength; int n; fd = get_int_local_var_by_name (lexic, "fp", -1); if (fd < 0) { nasl_perror (lexic, "file_read: need file pointer argument\n"); return NULL; } flength = get_int_local_var_by_name (lexic, "length", 0); buf = emalloc (flength + 1); if (buf == NULL) { nasl_perror (lexic, "file_read: cannot malloc %d bytes\n", flength); goto error; } for (n = 0; n < flength;) { int e; errno = 0; e = read (fd, buf + n, flength - n); if (e < 0 && errno == EINTR) continue; else if (e <= 0) break; else n += e; } retc = alloc_typed_cell (CONST_DATA); retc->size = n; retc->x.str_val = buf; return retc; error: efree (&buf); return NULL; }
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* 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* nasl_open_sock_kdc(lex_ctxt* lexic) { tree_cell *retc; struct timeval t; int timeout = 30; int port = 88; char *hostname = NULL; /* Domain name for windows */ int tcp = 0; int ret; struct arglist *script_infos, *prefs; char *_port = NULL, *_tcp = NULL; char * val; int type; script_infos = lexic->script_infos; hostname = plug_get_key(script_infos, "Secret/kdc_hostname", &type); if ( ! hostname || type != KB_TYPE_STR ) return NULL; port = (int)plug_get_key(script_infos, "Secret/kdc_port", &type); if ( port <= 0 || type != KB_TYPE_INT ) return NULL; tcp = (int)plug_get_key(script_infos, "Secret/kdc_use_tcp", &type); if ( tcp < 0 || type != KB_TYPE_INT ) tcp = 0; if (tcp == 0) ret = open_sock_opt_hn(hostname, port, SOCK_DGRAM, IPPROTO_UDP, timeout); else ret = open_sock_opt_hn(hostname, port, SOCK_STREAM, IPPROTO_TCP, timeout); if (ret < 0) return NULL; retc = alloc_typed_cell(CONST_INT); retc->x.i_val = ret; return retc; }
tree_cell* nasl_localtime(lex_ctxt* lexic) { tree_cell *retc; struct tm *ptm; time_t tictac; int utc; nasl_array *a; anon_nasl_var v; tictac = get_int_var_by_num(lexic, 0, 0); if (tictac == 0) tictac = time(NULL); utc = get_int_local_var_by_name(lexic, "utc", 0); if (utc) ptm = gmtime(&tictac); else ptm = localtime(&tictac); if (ptm == NULL) { nasl_perror(lexic, "localtime(%d,utc=%d): %s\n", tictac, utc, strerror(errno)); 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_INT; v.v.v_int = ptm->tm_sec; add_var_to_array(a, "sec", &v); /* seconds */ v.v.v_int = ptm->tm_min; add_var_to_array(a, "min", &v); /* minutes */ v.v.v_int = ptm->tm_hour; add_var_to_array(a, "hour", &v); /* hours */ v.v.v_int = ptm->tm_mday; add_var_to_array(a, "mday", &v); /* day of the month */ v.v.v_int = ptm->tm_mon+1; add_var_to_array(a, "mon", &v); /* month */ v.v.v_int = ptm->tm_year+1900; add_var_to_array(a, "year", &v); /* year */ v.v.v_int = ptm->tm_wday; add_var_to_array(a, "wday", &v); /* day of the week */ v.v.v_int = ptm->tm_yday+1; add_var_to_array(a, "yday", &v); /* day in the year */ v.v.v_int = ptm->tm_isdst; add_var_to_array(a, "isdst", &v); /* daylight saving time */ 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_gettimeofday(lex_ctxt* lexic) { tree_cell *retc; struct timeval t; char str[64]; if (gettimeofday(&t, NULL) < 0) { nasl_perror(lexic, "gettimeofday: %s\n", strerror(errno)); return NULL; } sprintf(str, "%u.%06u", t.tv_sec, t.tv_usec); retc = alloc_typed_cell(CONST_DATA); retc->size = strlen(str); retc->x.str_val = emalloc(retc->size); strcpy(retc->x.str_val, str); return retc; }
tree_cell * nasl_socket_get_error (lex_ctxt * lexic) { int soc = get_int_var_by_num (lexic, 0, -1); tree_cell *retc; int err; if (soc < 0 || !fd_is_stream (soc)) return NULL; err = stream_get_err (soc); retc = alloc_typed_cell (CONST_INT); switch (err) { case 0: retc->x.i_val = NASL_ERR_NOERR; break; case ETIMEDOUT: retc->x.i_val = NASL_ERR_ETIMEDOUT; break; case EBADF: case EPIPE: #ifdef ECONNRESET case ECONNRESET: #endif #ifdef ENOTSOCK case ENOTSOCK: #endif retc->x.i_val = NASL_ERR_ECONNRESET; break; case ENETUNREACH: case EHOSTUNREACH: retc->x.i_val = NASL_ERR_EUNREACH; break; default: log_legacy_write ("Unknown error %d %s\n", err, strerror (err)); } return retc; }
/** * @brief Write file */ tree_cell * nasl_file_write (lex_ctxt * lexic) { tree_cell *retc; char *content; int len; int fd; int n; content = get_str_local_var_by_name (lexic, "data"); fd = get_int_local_var_by_name (lexic, "fp", -1); if (content == NULL || fd < 0) { nasl_perror (lexic, "file_write: need two arguments 'fp' and 'data'\n"); return NULL; } len = get_var_size_by_name (lexic, "data"); for (n = 0; n < len;) { int e; errno = 0; e = write (fd, content + n, len - n); if (e < 0 && errno == EINTR) continue; else if (e <= 0) { nasl_perror (lexic, "file_write: write() failed - %s\n", strerror (errno)); break; } else n += e; } retc = alloc_typed_cell (CONST_INT); retc->x.i_val = n; return retc; }
tree_cell * nasl_get_tmp_dir (lex_ctxt * lexic) { tree_cell *retc; char path[MAXPATHLEN]; snprintf (path, sizeof (path), "%s/", g_get_tmp_dir ()); if (access (path, R_OK | W_OK | X_OK) < 0) { nasl_perror (lexic, "get_tmp_dir(): %s not available - check your OpenVAS installation\n", path); return NULL; } retc = alloc_typed_cell (CONST_DATA); retc->x.str_val = strdup (path); retc->size = strlen (retc->x.str_val); return retc; }
/** * @brief Stat file * @ingroup nasl_implement */ tree_cell * nasl_file_stat (lex_ctxt * lexic) { tree_cell *retc; char *fname; struct stat st; fname = get_str_var_by_num (lexic, 0); if (fname == NULL) { nasl_perror (lexic, "file_stat: need one argument (file name)\n"); return NULL; } if (stat (fname, &st) < 0) return NULL; retc = alloc_typed_cell (CONST_INT); retc->x.i_val = (int) st.st_size; return retc; }
/* Fixme: Merge this into nasl_get_sock_info. */ tree_cell * nasl_get_source_port (lex_ctxt * lexic) { struct sockaddr_in ia; int s, fd; unsigned int l; tree_cell *retc; int type; unsigned int type_len = sizeof (type); s = get_int_var_by_num (lexic, 0, -1); if (s < 0) { nasl_perror (lexic, "get_source_port: missing socket parameter\n"); return NULL; } if (!fd_is_stream (s) && getsockopt (s, SOL_SOCKET, SO_TYPE, &type, &type_len) == 0 && type == SOCK_DGRAM) fd = s; else fd = openvas_get_socket_from_connection (s); if (fd < 0) { nasl_perror (lexic, "get_source_port: invalid socket parameter %d\n", s); return NULL; } l = sizeof (ia); if (getsockname (fd, (struct sockaddr *) &ia, &l) < 0) { nasl_perror (lexic, "get_source_port: getsockname(%d): %s\n", fd, strerror (errno)); return NULL; } retc = alloc_typed_cell (CONST_INT); retc->x.i_val = ntohs (ia.sin_port); 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 Close file */ tree_cell * nasl_file_close (lex_ctxt * lexic) { tree_cell *retc; int fd; fd = get_int_var_by_num (lexic, 0, -1); if (fd < 0) { nasl_perror (lexic, "file_close: need file pointer argument\n"); return NULL; } if (close (fd) < 0) { nasl_perror (lexic, "file_close: %s\n", strerror (errno)); return NULL; } retc = alloc_typed_cell (CONST_INT); retc->x.i_val = 0; return retc; }
/** @todo Supspects to glib replacements, all path related stuff. */ tree_cell * nasl_pread (lex_ctxt * lexic) { tree_cell *retc = NULL, *a; anon_nasl_var *v; nasl_array *av; int i, j, n, sz, sz2, cd, nice; char **args = NULL, *cmd, *str, *str2, buf[8192]; FILE *fp; char cwd[MAXPATHLEN], newdir[MAXPATHLEN]; if (pid != 0) { nasl_perror (lexic, "nasl_pread is not reentrant!\n"); return NULL; } a = get_variable_by_name (lexic, "argv"); cmd = get_str_local_var_by_name (lexic, "cmd"); if (cmd == NULL || a == NULL || (v = a->x.ref_val) == NULL) { nasl_perror (lexic, "pread() usage: cmd:..., argv:...\n"); return NULL; } nice = get_int_local_var_by_name (lexic, "nice", 0); if (v->var_type == VAR2_ARRAY) av = &v->v.v_arr; else { nasl_perror (lexic, "pread: argv element must be an array (0x%x)\n", v->var_type); return NULL; } cd = get_int_local_var_by_name (lexic, "cd", 0); cwd[0] = '\0'; if (cd) { char *p; if (cmd[0] == '/') { strncpy (newdir, cmd, sizeof (newdir) - 1); /* Flawfinder: ignore (\0-termination taken care of) */ p = strrchr (newdir, '/'); if (p != newdir) *p = '\0'; } else { p = find_in_path (cmd, 0); if (p != NULL) strncpy (newdir, p, sizeof (newdir) - 1); /* Flawfinder: ignore (\0-termination taken care of) */ else { nasl_perror (lexic, "pread: '%s' not found in $PATH\n", cmd); return NULL; } } newdir[sizeof (newdir) - 1] = '\0'; if (getcwd (cwd, sizeof (cwd)) == NULL) { nasl_perror (lexic, "pread(): getcwd: %s\n", strerror (errno)); *cwd = '\0'; } if (chdir (newdir) < 0) { nasl_perror (lexic, "pread: could not chdir to %s\n", newdir); return NULL; } if (cmd[0] != '/' && strlen (newdir) + strlen (cmd) + 1 < sizeof (newdir)) { strcat (newdir, "/"); /* Flawfinder: ignore (if-command above checks for size) */ strcat (newdir, cmd); /* Flawfinder: ignore (if-command above checks for size) */ cmd = newdir; } } if (av->hash_elt != NULL) nasl_perror (lexic, "pread: named elements in 'cmd' are ignored!\n"); n = av->max_idx; args = emalloc (sizeof (char **) * (n + 2)); /* Last arg is NULL */ for (j = 0, i = 0; i < n; i++) { str = (char *) var2str (av->num_elt[i]); if (str != NULL) args[j++] = estrdup (str); } args[j++] = NULL; old_sig_t = signal (SIGTERM, sig_h); old_sig_i = signal (SIGINT, sig_h); old_sig_c = signal (SIGCHLD, sig_c); fp = openvas_popen4 ((const char *) cmd, args, &pid, nice); for (i = 0; i < n; i++) efree (&args[i]); efree (&args); if (fp != NULL) { sz = 0; str = emalloc (1); errno = 0; while ((n = fread (buf, 1, sizeof (buf), fp)) > 0 || errno == EINTR) /* && kill(pid, 0) >= 0) */ { if (errno == EINTR) { errno = 0; continue; } sz2 = sz + n; str2 = erealloc (str, sz2); if (str2 == NULL) { nasl_perror (lexic, "nasl_pread: erealloc failed\n"); break; } str = str2; memcpy (str + sz, buf, n); sz = sz2; } if (ferror (fp) && errno != EINTR) nasl_perror (lexic, "nasl_pread: fread(): %s\n", strerror (errno)); (void) openvas_pclose (fp, pid); pid = 0; if (*cwd != '\0') if (chdir (cwd) < 0) nasl_perror (lexic, "pread(): chdir(%s): %s\n", cwd, strerror (errno)); retc = alloc_typed_cell (CONST_DATA); retc->x.str_val = str; retc->size = sz; } signal (SIGINT, old_sig_i); signal (SIGTERM, old_sig_t); signal (SIGCHLD, old_sig_c); return retc; }
tree_cell* nasl_join_multicast_group(lex_ctxt *lexic) { char *a; int s, i, j; //struct ip_mreq m; tree_cell *retc = NULL; void *p; a = get_str_var_by_num(lexic, 0); if (a == NULL) { nasl_perror(lexic, "join_multicast_group: missing parameter\n"); return NULL; } /*if (! inet_aton(a, &m.imr_multiaddr)) { nasl_perror(lexic, "join_multicast_group: invalid parameter '%s'\n", a); return NULL; } m.imr_interface.s_addr = INADDR_ANY; j = -1; for (i = 0; i < jmg_max; i ++) if (jmg_desc[i].in.s_addr == m.imr_multiaddr.s_addr && jmg_desc[i].count > 0) { jmg_desc[i].count ++; break; } else if (jmg_desc[i].count <= 0) j = i; if (i >= jmg_max) { s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { nasl_perror(lexic, "join_multicast_group: socket: %s\n", strerror(errno)); return NULL; } if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &m, sizeof(m)) < 0) { nasl_perror(lexic, "join_multicast_group: setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno)); closesocket(s); return NULL; } if (j < 0) { p = erealloc(jmg_desc, sizeof(*jmg_desc) * (jmg_max + 1)); if (p == NULL) { nasl_perror(lexic, "join_multicast_group: realloc failed\n"); closesocket(s); return NULL; } jmg_desc = p; j = jmg_max ++; } jmg_desc[j].s = s; jmg_desc[j].in = m.imr_multiaddr; jmg_desc[j].count = 1; }*/ retc = alloc_typed_cell(CONST_INT); retc->x.i_val = 1; 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; }