Greenbone Vulnerability Management Libraries 23.7.0
openvasd.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Greenbone AG
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
10
11#include "openvasd.h"
12
13#include "../base/array.h"
14#include "../base/networking.h"
15#include "../http/httputils.h"
16#include "../http_scanner/http_scanner.h"
17#include "../util/json.h"
18
19#include <cjson/cJSON.h>
20#include <netinet/in.h>
21#include <stddef.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <unistd.h>
25
26#undef G_LOG_DOMAIN
30#define G_LOG_DOMAIN "libgvm ovd"
31
32#define RESP_CODE_ERR -1
33#define RESP_CODE_OK 0
34
50
55{
56 gchar *vt_id;
57 GHashTable *vt_values;
58};
59
67http_scanner_resp_t
68openvasd_get_vt_stream_init (http_scanner_connector_t conn)
69{
70 GString *path;
71 http_scanner_resp_t response = NULL;
72
73 path = g_string_new ("/vts?information=1");
74 response = http_scanner_init_request_multi (conn, path->str);
75
76 g_string_free (path, TRUE);
77
78 return response;
79}
80
92int
93openvasd_get_vt_stream (http_scanner_connector_t conn)
94{
95 return http_scanner_process_request_multi (conn, 5000);
96}
97
106http_scanner_resp_t
107openvasd_get_vts (http_scanner_connector_t conn)
108{
109 GString *path;
110 http_scanner_resp_t response = NULL;
111
112 path = g_string_new ("/vts?information=1");
113 response =
114 http_scanner_send_request (conn, HTTP_SCANNER_GET, path->str, NULL, NULL);
115
116 g_string_free (path, TRUE);
117
118 if (response->code != RESP_CODE_ERR)
119 response->body = g_strdup (http_scanner_stream_str (conn));
120
121 http_scanner_reset_stream (conn);
122 return response;
123}
124
133http_scanner_resp_t
134openvasd_get_performance (http_scanner_connector_t conn,
136{
137 http_scanner_resp_t response;
138 gchar *query;
139 time_t now;
140
141 time (&now);
142
143 if (!opts.titles || !strcmp (opts.titles, "") || opts.start < 0
144 || opts.start > now || opts.end < 0 || opts.end > now)
145 {
146 response = g_malloc0 (sizeof (struct http_scanner_response));
147 response->code = RESP_CODE_ERR;
148 response->body =
149 g_strdup ("{\"error\": \"Couldn't send get_performance command "
150 "to scanner. Bad or missing parameters.\"}");
151 return response;
152 }
153
154 query = g_strdup_printf ("/health/performance?start=%d&end=%d&titles=%s",
155 opts.start, opts.end, opts.titles);
156 response =
157 http_scanner_send_request (conn, HTTP_SCANNER_GET, query, NULL, NULL);
158 g_free (query);
159
160 if (response->code != RESP_CODE_ERR)
161 response->body = g_strdup (http_scanner_stream_str (conn));
162 else
163 {
164 response->body = g_strdup (
165 "{\"error\": \"Not possible to get performance information.\"}");
166 g_warning ("%s: Not possible to get performance information", __func__);
167 }
168
169 http_scanner_reset_stream (conn);
170 return response;
171}
172
183int
184openvasd_parsed_performance (http_scanner_connector_t conn,
186 gchar **graph, gchar **err)
187{
188 http_scanner_resp_t resp = NULL;
189 cJSON *parser;
190 cJSON *item;
191 int ret = 0;
192 resp = openvasd_get_performance (conn, opts);
193
194 // No results. No information.
195 parser = cJSON_Parse (resp->body);
196 if (parser == NULL)
197 {
198 *err = g_strdup ("Unable to parse sensor performance data");
199 ret = -1;
200 }
201 else if (resp->code != 200)
202 {
203 parser = cJSON_Parse (resp->body);
204 item = cJSON_GetObjectItem (parser, "error");
205 if (item != NULL)
206 *err = g_strdup (cJSON_GetStringValue (item));
207 ret = -1;
208 }
209 else
210 {
211 item = cJSON_GetArrayItem (parser, 0);
212 if (item != NULL)
213 *graph = g_strdup (cJSON_GetStringValue (item));
214 }
215
216 http_scanner_response_cleanup (resp);
217 cJSON_Delete (parser);
218
219 return ret;
220}
221
222// Scan config builder.
223
230static void
231add_port_to_scan_json (gpointer range, gpointer p_array)
232{
233 range_t *ports = range;
234
235 cJSON *port = cJSON_CreateObject ();
236 if (ports->type == 1)
237 cJSON_AddStringToObject (port, "protocol", "udp");
238 else
239 cJSON_AddStringToObject (port, "protocol", "tcp");
240
241 cJSON *ranges_array = cJSON_CreateArray ();
242 cJSON *range_obj = cJSON_CreateObject ();
243 cJSON_AddNumberToObject (range_obj, "start", ports->start);
244
245 if (ports->end > ports->start && ports->end < 65535)
246 cJSON_AddNumberToObject (range_obj, "end", ports->end);
247 else
248 cJSON_AddNumberToObject (range_obj, "end", ports->start);
249 cJSON_AddItemToArray (ranges_array, range_obj);
250 cJSON_AddItemToObject (port, "range", ranges_array);
251 cJSON_AddItemToArray ((cJSON *) p_array, port);
252}
253
261static void
262add_auth_data_key_value_as_json (const char *key, const char *value,
263 void *json_obj)
264{
265 if (!key || !value || !json_obj)
266 return;
267 cJSON_AddStringToObject ((cJSON *) json_obj, key, value);
268}
269
276static void
277add_credential_to_scan_json (gpointer credentials, gpointer cred_array)
278{
279 cJSON *cred_obj = NULL;
280
281 scan_credential_t *cred = credentials;
282
283 const gchar *type = scan_credential_get_type (cred);
284 const gchar *service = scan_credential_get_service (cred);
285 const gchar *port = scan_credential_get_port (cred);
286
287 cred_obj = cJSON_CreateObject ();
288 cJSON_AddStringToObject (cred_obj, "service", service ? service : "");
289
290 if (port)
291 {
292 cJSON_AddNumberToObject (cred_obj, "port", atoi (port));
293 }
294
295 cJSON *cred_type_obj = cJSON_CreateObject ();
297 cred_type_obj);
298 cJSON_AddItemToObject (cred_obj, type ? type : "", cred_type_obj);
299
300 cJSON_AddItemToArray ((cJSON *) cred_array, cred_obj);
301}
302
310static void
311add_scan_preferences_to_scan_json (gpointer key, gpointer val,
312 gpointer scan_prefs_array)
313{
314 cJSON *pref_obj = cJSON_CreateObject ();
315 cJSON_AddStringToObject (pref_obj, "id", key);
316 cJSON_AddStringToObject (pref_obj, "value", val);
317 cJSON_AddItemToArray (scan_prefs_array, pref_obj);
318}
319
326static void
327add_vts_to_scan_json (gpointer single_vt, gpointer vts_array)
328{
329 GHashTableIter vt_data_iter;
330 gchar *vt_param_id, *vt_param_value;
331
332 openvasd_vt_single_t *vt = single_vt;
333
334 cJSON *vt_obj = cJSON_CreateObject ();
335
336 cJSON_AddStringToObject (vt_obj, "oid", vt->vt_id);
337
338 if (g_hash_table_size (vt->vt_values))
339 {
340 cJSON *params_array = cJSON_CreateArray ();
341
342 g_hash_table_iter_init (&vt_data_iter, vt->vt_values);
343 while (g_hash_table_iter_next (&vt_data_iter, (gpointer *) &vt_param_id,
344 (gpointer *) &vt_param_value))
345 {
346 cJSON *param_obj = cJSON_CreateObject ();
347 cJSON_AddNumberToObject (param_obj, "id", atoi (vt_param_id));
348 cJSON_AddStringToObject (param_obj, "value", vt_param_value);
349 cJSON_AddItemToArray (params_array, param_obj);
350 }
351 cJSON_AddItemToObject (vt_obj, "parameters", params_array);
352 }
353 cJSON_AddItemToArray (vts_array, vt_obj);
354}
355
368char *
370 GHashTable *scan_preferences, GSList *vts)
371{
372 cJSON *scan_obj = NULL;
373 cJSON *target_obj = NULL;
374 cJSON *hosts_array = NULL;
375 cJSON *exclude_hosts_array = NULL;
376 cJSON *finished_hosts_array = NULL;
377 gchar *json_str = NULL;
378
379 /* Build the message in json format to be published. */
380 scan_obj = cJSON_CreateObject ();
381
382 if (target->scan_id && target->scan_id[0] != '\0')
383 cJSON_AddStringToObject (scan_obj, "scan_id", target->scan_id);
384
385 // begin target
386 target_obj = cJSON_CreateObject ();
387
388 // hosts
389 hosts_array = cJSON_CreateArray ();
390 gchar **hosts_list = g_strsplit (target->hosts, ",", 0);
391 for (int i = 0; hosts_list[i] != NULL; i++)
392 {
393 cJSON *host_item = NULL;
394 host_item = cJSON_CreateString (hosts_list[i]);
395 cJSON_AddItemToArray (hosts_array, host_item);
396 }
397 g_strfreev (hosts_list);
398 cJSON_AddItemToObject (target_obj, "hosts", hosts_array);
399
400 // exclude hosts
401 if (target->exclude_hosts && target->exclude_hosts[0] != '\0')
402 {
403 exclude_hosts_array = cJSON_CreateArray ();
404 gchar **exclude_hosts_list = g_strsplit (target->exclude_hosts, ",", 0);
405 for (int i = 0; exclude_hosts_list[i] != NULL; i++)
406 {
407 cJSON *exclude_host_item = NULL;
408 exclude_host_item = cJSON_CreateString (exclude_hosts_list[i]);
409 cJSON_AddItemToArray (exclude_hosts_array, exclude_host_item);
410 }
411 g_strfreev (exclude_hosts_list);
412 cJSON_AddItemToObject (target_obj, "excluded_hosts", exclude_hosts_array);
413 }
414
415 // finished hosts
416 if (target->finished_hosts && target->finished_hosts[0] != '\0')
417 {
418 finished_hosts_array = cJSON_CreateArray ();
419 gchar **finished_hosts_list = g_strsplit (target->finished_hosts, ",", 0);
420 for (int i = 0; finished_hosts_list[i] != NULL; i++)
421 {
422 cJSON *finished_host_item = NULL;
423 finished_host_item = cJSON_CreateString (finished_hosts_list[i]);
424 cJSON_AddItemToArray (finished_hosts_array, finished_host_item);
425 }
426 g_strfreev (hosts_list);
427 cJSON_AddItemToObject (target_obj, "finished_hosts",
428 finished_hosts_array);
429 }
430
431 // ports
432 if (target->ports && target->ports[0] != '\0')
433 {
434 cJSON *ports_array = cJSON_CreateArray ();
435 array_t *ports = port_range_ranges (target->ports);
436 g_ptr_array_foreach (ports, add_port_to_scan_json, ports_array);
437 array_free (ports);
438 cJSON_AddItemToObject (target_obj, "ports", ports_array);
439 }
440
441 // credentials
442 cJSON *credentials = cJSON_CreateArray ();
443 g_slist_foreach (target->credentials, add_credential_to_scan_json,
444 credentials);
445 cJSON_AddItemToObject (target_obj, "credentials", credentials);
446
447 // reverse lookup
448 if (target->reverse_lookup_unify)
449 cJSON_AddBoolToObject (target_obj, "reverse_lookup_unify", 1);
450 else
451 cJSON_AddBoolToObject (target_obj, "reverse_lookup_unify", 0);
452
453 if (target->reverse_lookup_only)
454 cJSON_AddBoolToObject (target_obj, "reverse_lookup_only", 1);
455 else
456 cJSON_AddBoolToObject (target_obj, "reverse_lookup_only", 0);
457
458 // alive test methods
459 cJSON *alive_test_methods = cJSON_CreateArray ();
460 if (target->alive_test_methods.arp)
461 cJSON_AddItemToArray (alive_test_methods, cJSON_CreateString ("arp"));
462 if (target->alive_test_methods.tcp_ack)
463 cJSON_AddItemToArray (alive_test_methods, cJSON_CreateString ("tcp_ack"));
464 if (target->alive_test_methods.tcp_syn)
465 cJSON_AddItemToArray (alive_test_methods, cJSON_CreateString ("tcp_syn"));
467 cJSON_AddItemToArray (alive_test_methods,
468 cJSON_CreateString ("consider_alive"));
469 if (target->alive_test_methods.icmp)
470 cJSON_AddItemToArray (alive_test_methods, cJSON_CreateString ("icmp"));
472 cJSON_AddItemToArray (alive_test_methods,
473 cJSON_CreateString ("host_discovery_ipv6"));
474
475 cJSON_AddItemToObject (target_obj, "alive_test_methods", alive_test_methods);
476
477 cJSON_AddItemToObject (scan_obj, "target", target_obj);
478
479 // Begin Scan Preferences
480 cJSON *scan_prefs_array = cJSON_CreateArray ();
481 g_hash_table_foreach (scan_preferences, add_scan_preferences_to_scan_json,
482 scan_prefs_array);
483 cJSON_AddItemToObject (scan_obj, "scan_preferences", scan_prefs_array);
484
485 // Begin VTs
486 cJSON *vts_array = cJSON_CreateArray ();
487 g_slist_foreach (vts, add_vts_to_scan_json, vts_array);
488 cJSON_AddItemToObject (scan_obj, "vts", vts_array);
489
490 json_str = cJSON_Print (scan_obj);
491 cJSON_Delete (scan_obj);
492 if (json_str == NULL)
493 g_warning ("%s: Error while creating JSON.", __func__);
494
495 return json_str;
496}
497
511openvasd_target_new (const gchar *scanid, const gchar *hosts,
512 const gchar *ports, const gchar *exclude_hosts,
513 int reverse_lookup_unify, int reverse_lookup_only)
514{
515 openvasd_target_t *new_target;
516 new_target = g_malloc0 (sizeof (openvasd_target_t));
517
518 if (scanid && *scanid)
519 new_target->scan_id = g_strdup (scanid);
520
521 new_target->exclude_hosts = exclude_hosts ? g_strdup (exclude_hosts) : NULL;
522 new_target->finished_hosts = NULL;
523 new_target->hosts = hosts ? g_strdup (hosts) : NULL;
524 new_target->ports = ports ? g_strdup (ports) : NULL;
525 new_target->reverse_lookup_unify =
526 reverse_lookup_unify ? reverse_lookup_unify : 0;
527 new_target->reverse_lookup_only =
528 reverse_lookup_only ? reverse_lookup_only : 0;
529
530 return new_target;
531}
532
539void
541 const gchar *finished_hosts)
542{
543 g_free (target->finished_hosts);
544 target->finished_hosts = finished_hosts ? g_strdup (finished_hosts) : NULL;
545}
546
552void
554{
555 if (!target)
556 return;
557
558 g_slist_free_full (target->credentials,
559 (GDestroyNotify) scan_credential_free);
560 g_free (target->exclude_hosts);
561 g_free (target->finished_hosts);
562 g_free (target->scan_id);
563 g_free (target->hosts);
564 g_free (target->ports);
565 g_free (target);
566 target = NULL;
567}
568
575void
577 openvasd_target_t *target, const openvasd_alive_test_methods_t *methods)
578{
579 if (!target || !methods)
580 return;
581
582 if (methods->host_discovery_ipv6)
583 {
584 target->alive_test_methods =
585 (openvasd_alive_test_methods_t){.host_discovery_ipv6 = TRUE};
586 return;
587 }
588
589 target->alive_test_methods = *methods;
590}
591
598void
600 scan_credential_t *credential)
601{
602 if (!target || !credential)
603 return;
604
605 target->credentials = g_slist_prepend (target->credentials, credential);
606}
607
616openvasd_vt_single_new (const gchar *vt_id)
617{
618 openvasd_vt_single_t *new_vt_single;
619 new_vt_single = g_malloc0 (sizeof (openvasd_vt_single_t));
620
621 new_vt_single->vt_id = vt_id ? g_strdup (vt_id) : NULL;
622 new_vt_single->vt_values =
623 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
624
625 return new_vt_single;
626}
627
633void
635{
636 if (!vt_single)
637 return;
638
639 g_hash_table_destroy (vt_single->vt_values);
640
641 g_free (vt_single->vt_id);
642 g_free (vt_single);
643}
644
654void
656 const gchar *name, const gchar *value)
657{
658 g_hash_table_replace (vt_single->vt_values, g_strdup (name),
659 g_strdup (value));
660}
void array_free(GPtrArray *array)
Free global array value.
Definition array.c:50
Array utilities.
GPtrArray array_t
Definition array.h:16
const gchar * scan_credential_get_port(scan_credential_t *credential)
Get the port of a scan credential.
Definition credentialutils.c:93
void scan_credential_free(scan_credential_t *credential)
Free a scan credential.
Definition credentialutils.c:134
const gchar * scan_credential_get_type(scan_credential_t *credential)
Get the type of a scan credential.
Definition credentialutils.c:63
void scan_credential_foreach_auth_data(scan_credential_t *credential, void(*func)(const char *name, const char *value, void *user_data), void *user_data)
Iterate over each authentication data item in a scan credential.
Definition credentialutils.c:109
const gchar * scan_credential_get_service(scan_credential_t *credential)
Get the service of a scan credential.
Definition credentialutils.c:78
struct scan_credential scan_credential_t
Definition credentialutils.h:16
array_t * port_range_ranges(const char *port_range)
Create a range array from a port_range string.
Definition networking.c:601
GVM Networking related API.
struct range range_t
Definition networking.h:43
#define RESP_CODE_ERR
Definition openvasd.c:32
int openvasd_parsed_performance(http_scanner_connector_t conn, openvasd_get_performance_opts_t opts, gchar **graph, gchar **err)
Parse performance data.
Definition openvasd.c:184
void openvasd_target_free(openvasd_target_t *target)
Free an openvasd target, including all added credentials.
Definition openvasd.c:553
http_scanner_resp_t openvasd_get_vts(http_scanner_connector_t conn)
Get VT's metadata.
Definition openvasd.c:107
static void add_auth_data_key_value_as_json(const char *key, const char *value, void *json_obj)
Add authentication data key value to a JSON object.
Definition openvasd.c:262
void openvasd_target_add_credential(openvasd_target_t *target, scan_credential_t *credential)
Add a credential to an openvasd target.
Definition openvasd.c:599
char * openvasd_build_scan_config_json(openvasd_target_t *target, GHashTable *scan_preferences, GSList *vts)
Build a json object with data necessary to start a scan.
Definition openvasd.c:369
static void add_credential_to_scan_json(gpointer credentials, gpointer cred_array)
Add a credential to the scan json object.
Definition openvasd.c:277
http_scanner_resp_t openvasd_get_vt_stream_init(http_scanner_connector_t conn)
Fetch feed metadata chunk by chunk.
Definition openvasd.c:68
openvasd_target_t * openvasd_target_new(const gchar *scanid, const gchar *hosts, const gchar *ports, const gchar *exclude_hosts, int reverse_lookup_unify, int reverse_lookup_only)
Create a new openvasd target.
Definition openvasd.c:511
void openvasd_target_set_alive_test_methods(openvasd_target_t *target, const openvasd_alive_test_methods_t *methods)
Add alive test methods to openvasd target.
Definition openvasd.c:576
static void add_port_to_scan_json(gpointer range, gpointer p_array)
Add a port range to the scan json object.
Definition openvasd.c:231
void openvasd_target_set_finished_hosts(openvasd_target_t *target, const gchar *finished_hosts)
Set the finished hosts of an openvasd target.
Definition openvasd.c:540
void openvasd_vt_single_free(openvasd_vt_single_t *vt_single)
Free a single openvasd VT, including all preference values.
Definition openvasd.c:634
int openvasd_get_vt_stream(http_scanner_connector_t conn)
Get a new feed metadata chunk.
Definition openvasd.c:93
static void add_scan_preferences_to_scan_json(gpointer key, gpointer val, gpointer scan_prefs_array)
Add a scan preference to the scan json object.
Definition openvasd.c:311
static void add_vts_to_scan_json(gpointer single_vt, gpointer vts_array)
Add a VT to the scan json object.
Definition openvasd.c:327
void openvasd_vt_single_add_value(openvasd_vt_single_t *vt_single, const gchar *name, const gchar *value)
Add a preference value to an openvasd VT.
Definition openvasd.c:655
http_scanner_resp_t openvasd_get_performance(http_scanner_connector_t conn, openvasd_get_performance_opts_t opts)
Get performance data.
Definition openvasd.c:134
openvasd_vt_single_t * openvasd_vt_single_new(const gchar *vt_id)
Create a new single openvasd VT.
Definition openvasd.c:616
API for Openvas Daemon communication.
struct openvasd_vt_single openvasd_vt_single_t
Definition openvasd.h:56
struct openvasd_target openvasd_target_t
Definition openvasd.h:54
struct openvasd_alive_test_methods openvasd_alive_test_methods_t
Struct holding alive test method options.
gboolean host_discovery_ipv6
Definition openvasd.h:40
gboolean arp
Definition openvasd.h:38
gboolean tcp_ack
Definition openvasd.h:37
gboolean icmp
Definition openvasd.h:35
gboolean tcp_syn
Definition openvasd.h:36
gboolean consider_alive
Definition openvasd.h:39
Definition openvasd.h:24
const gchar * titles
Definition openvasd.h:27
int end
Definition openvasd.h:26
int start
Definition openvasd.h:25
Struct holding target information.
Definition openvasd.c:39
int reverse_lookup_only
Definition openvasd.c:48
gchar * ports
Definition openvasd.c:44
openvasd_alive_test_methods_t alive_test_methods
Definition openvasd.c:46
gchar * exclude_hosts
Definition openvasd.c:42
int reverse_lookup_unify
Definition openvasd.c:47
GSList * credentials
Definition openvasd.c:41
gchar * finished_hosts
Definition openvasd.c:45
gchar * hosts
Definition openvasd.c:43
gchar * scan_id
Definition openvasd.c:40
Struct holding vt information.
Definition openvasd.c:55
gchar * vt_id
Definition openvasd.c:56
GHashTable * vt_values
Definition openvasd.c:57
A port range.
Definition networking.h:35
int start
Definition networking.h:40
port_protocol_t type
Definition networking.h:41
int end
Definition networking.h:38