Greenbone Vulnerability Management Libraries 22.29.3
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
39{
40 gchar *type;
41 gchar *service;
42 gchar *port;
43 GHashTable *auth_data;
44};
45
50{
51 gchar *scan_id;
52 GSList *credentials;
54 gchar *hosts;
55 gchar *ports;
57 gboolean icmp;
58 gboolean tcp_syn;
59 gboolean tcp_ack;
60 gboolean arp;
61 gboolean consider_alive;
64};
65
70{
71 gchar *vt_id;
72 GHashTable *vt_values;
73};
74
82http_scanner_resp_t
83openvasd_get_vt_stream_init (http_scanner_connector_t conn)
84{
85 GString *path;
86 http_scanner_resp_t response = NULL;
87
88 path = g_string_new ("/vts?information=1");
89 response = http_scanner_init_request_multi (conn, path->str);
90
91 g_string_free (path, TRUE);
92
93 return response;
94}
95
107int
108openvasd_get_vt_stream (http_scanner_connector_t conn)
109{
110 return http_scanner_process_request_multi (conn, 5000);
111}
112
121http_scanner_resp_t
122openvasd_get_vts (http_scanner_connector_t conn)
123{
124 GString *path;
125 http_scanner_resp_t response = NULL;
126
127 path = g_string_new ("/vts?information=1");
128 response =
129 http_scanner_send_request (conn, HTTP_SCANNER_GET, path->str, NULL, NULL);
130
131 g_string_free (path, TRUE);
132
133 if (response->code != RESP_CODE_ERR)
134 response->body = g_strdup (http_scanner_stream_str (conn));
135
136 http_scanner_reset_stream (conn);
137 return response;
138}
139
148http_scanner_resp_t
149openvasd_get_performance (http_scanner_connector_t conn,
151{
152 http_scanner_resp_t response;
153 gchar *query;
154 time_t now;
155
156 time (&now);
157
158 if (!opts.titles || !strcmp (opts.titles, "") || opts.start < 0
159 || opts.start > now || opts.end < 0 || opts.end > now)
160 {
161 response = g_malloc0 (sizeof (struct http_scanner_response));
162 response->code = RESP_CODE_ERR;
163 response->body =
164 g_strdup ("{\"error\": \"Couldn't send get_performance command "
165 "to scanner. Bad or missing parameters.\"}");
166 return response;
167 }
168
169 query = g_strdup_printf ("/health/performance?start=%d&end=%d&titles=%s",
170 opts.start, opts.end, opts.titles);
171 response =
172 http_scanner_send_request (conn, HTTP_SCANNER_GET, query, NULL, NULL);
173 g_free (query);
174
175 if (response->code != RESP_CODE_ERR)
176 response->body = g_strdup (http_scanner_stream_str (conn));
177 else
178 {
179 response->body = g_strdup (
180 "{\"error\": \"Not possible to get performance information.\"}");
181 g_warning ("%s: Not possible to get performance information", __func__);
182 }
183
184 http_scanner_reset_stream (conn);
185 return response;
186}
187
198int
199openvasd_parsed_performance (http_scanner_connector_t conn,
201 gchar **graph, gchar **err)
202{
203 http_scanner_resp_t resp = NULL;
204 cJSON *parser;
205 cJSON *item;
206 int ret = 0;
207 resp = openvasd_get_performance (conn, opts);
208
209 // No results. No information.
210 parser = cJSON_Parse (resp->body);
211 if (parser == NULL)
212 {
213 *err = g_strdup ("Unable to parse sensor performance data");
214 ret = -1;
215 }
216 else if (resp->code != 200)
217 {
218 parser = cJSON_Parse (resp->body);
219 item = cJSON_GetObjectItem (parser, "error");
220 if (item != NULL)
221 *err = g_strdup (cJSON_GetStringValue (item));
222 ret = -1;
223 }
224 else
225 {
226 item = cJSON_GetArrayItem (parser, 0);
227 if (item != NULL)
228 *graph = g_strdup (cJSON_GetStringValue (item));
229 }
230
231 http_scanner_response_cleanup (resp);
232 cJSON_Delete (parser);
233
234 return ret;
235}
236
237// Scan config builder.
238
245static void
246add_port_to_scan_json (gpointer range, gpointer p_array)
247{
248 range_t *ports = range;
249
250 cJSON *port = cJSON_CreateObject ();
251 if (ports->type == 1)
252 cJSON_AddStringToObject (port, "protocol", "udp");
253 else
254 cJSON_AddStringToObject (port, "protocol", "tcp");
255
256 cJSON *ranges_array = cJSON_CreateArray ();
257 cJSON *range_obj = cJSON_CreateObject ();
258 cJSON_AddNumberToObject (range_obj, "start", ports->start);
259
260 if (ports->end > ports->start && ports->end < 65535)
261 cJSON_AddNumberToObject (range_obj, "end", ports->end);
262 else
263 cJSON_AddNumberToObject (range_obj, "end", ports->start);
264 cJSON_AddItemToArray (ranges_array, range_obj);
265 cJSON_AddItemToObject (port, "range", ranges_array);
266 cJSON_AddItemToArray ((cJSON *) p_array, port);
267}
268
275static void
276add_credential_to_scan_json (gpointer credentials, gpointer cred_array)
277{
278 GHashTableIter auth_data_iter;
279 gchar *auth_data_name, *auth_data_value;
280 cJSON *cred_obj = NULL;
281
282 openvasd_credential_t *cred = credentials;
283
284 cred_obj = cJSON_CreateObject ();
285 cJSON_AddStringToObject (cred_obj, "service", cred->service);
286
287 if (cred->port)
288 {
289 cJSON_AddNumberToObject (cred_obj, "port", atoi (cred->port));
290 }
291
292 cJSON *cred_type_obj = cJSON_CreateObject ();
293 g_hash_table_iter_init (&auth_data_iter, cred->auth_data);
294 while (g_hash_table_iter_next (&auth_data_iter, (gpointer *) &auth_data_name,
295 (gpointer *) &auth_data_value))
296 cJSON_AddStringToObject (cred_type_obj, auth_data_name, auth_data_value);
297 cJSON_AddItemToObject (cred_obj, cred->type, cred_type_obj);
298
299 cJSON_AddItemToArray ((cJSON *) cred_array, cred_obj);
300}
301
309static void
310add_scan_preferences_to_scan_json (gpointer key, gpointer val,
311 gpointer scan_prefs_array)
312{
313 cJSON *pref_obj = cJSON_CreateObject ();
314 cJSON_AddStringToObject (pref_obj, "id", key);
315 cJSON_AddStringToObject (pref_obj, "value", val);
316 cJSON_AddItemToArray (scan_prefs_array, pref_obj);
317}
318
325static void
326add_vts_to_scan_json (gpointer single_vt, gpointer vts_array)
327{
328 GHashTableIter vt_data_iter;
329 gchar *vt_param_id, *vt_param_value;
330
331 openvasd_vt_single_t *vt = single_vt;
332
333 cJSON *vt_obj = cJSON_CreateObject ();
334
335 cJSON_AddStringToObject (vt_obj, "oid", vt->vt_id);
336
337 if (g_hash_table_size (vt->vt_values))
338 {
339 cJSON *params_array = cJSON_CreateArray ();
340
341 g_hash_table_iter_init (&vt_data_iter, vt->vt_values);
342 while (g_hash_table_iter_next (&vt_data_iter, (gpointer *) &vt_param_id,
343 (gpointer *) &vt_param_value))
344 {
345 cJSON *param_obj = cJSON_CreateObject ();
346 cJSON_AddNumberToObject (param_obj, "id", atoi (vt_param_id));
347 cJSON_AddStringToObject (param_obj, "value", vt_param_value);
348 cJSON_AddItemToArray (params_array, param_obj);
349 }
350 cJSON_AddItemToObject (vt_obj, "parameters", params_array);
351 }
352 cJSON_AddItemToArray (vts_array, vt_obj);
353}
354
367char *
369 GHashTable *scan_preferences, GSList *vts)
370{
371 cJSON *scan_obj = NULL;
372 cJSON *target_obj = NULL;
373 cJSON *hosts_array = NULL;
374 cJSON *exclude_hosts_array = NULL;
375 cJSON *finished_hosts_array = NULL;
376 gchar *json_str = NULL;
377
378 /* Build the message in json format to be published. */
379 scan_obj = cJSON_CreateObject ();
380
381 if (target->scan_id && target->scan_id[0] != '\0')
382 cJSON_AddStringToObject (scan_obj, "scan_id", target->scan_id);
383
384 // begin target
385 target_obj = cJSON_CreateObject ();
386
387 // hosts
388 hosts_array = cJSON_CreateArray ();
389 gchar **hosts_list = g_strsplit (target->hosts, ",", 0);
390 for (int i = 0; hosts_list[i] != NULL; i++)
391 {
392 cJSON *host_item = NULL;
393 host_item = cJSON_CreateString (hosts_list[i]);
394 cJSON_AddItemToArray (hosts_array, host_item);
395 }
396 g_strfreev (hosts_list);
397 cJSON_AddItemToObject (target_obj, "hosts", hosts_array);
398
399 // exclude hosts
400 if (target->exclude_hosts && target->exclude_hosts[0] != '\0')
401 {
402 exclude_hosts_array = cJSON_CreateArray ();
403 gchar **exclude_hosts_list = g_strsplit (target->exclude_hosts, ",", 0);
404 for (int i = 0; exclude_hosts_list[i] != NULL; i++)
405 {
406 cJSON *exclude_host_item = NULL;
407 exclude_host_item = cJSON_CreateString (exclude_hosts_list[i]);
408 cJSON_AddItemToArray (exclude_hosts_array, exclude_host_item);
409 }
410 g_strfreev (exclude_hosts_list);
411 cJSON_AddItemToObject (target_obj, "excluded_hosts", exclude_hosts_array);
412 }
413
414 // finished hosts
415 if (target->finished_hosts && target->finished_hosts[0] != '\0')
416 {
417 finished_hosts_array = cJSON_CreateArray ();
418 gchar **finished_hosts_list = g_strsplit (target->finished_hosts, ",", 0);
419 for (int i = 0; finished_hosts_list[i] != NULL; i++)
420 {
421 cJSON *finished_host_item = NULL;
422 finished_host_item = cJSON_CreateString (finished_hosts_list[i]);
423 cJSON_AddItemToArray (finished_hosts_array, finished_host_item);
424 }
425 g_strfreev (hosts_list);
426 cJSON_AddItemToObject (target_obj, "finished_hosts",
427 finished_hosts_array);
428 }
429
430 // ports
431 if (target->ports && target->ports[0] != '\0')
432 {
433 cJSON *ports_array = cJSON_CreateArray ();
434 array_t *ports = port_range_ranges (target->ports);
435 g_ptr_array_foreach (ports, add_port_to_scan_json, ports_array);
436 array_free (ports);
437 cJSON_AddItemToObject (target_obj, "ports", ports_array);
438 }
439
440 // credentials
441 cJSON *credentials = cJSON_CreateArray ();
442 g_slist_foreach (target->credentials, add_credential_to_scan_json,
443 credentials);
444 cJSON_AddItemToObject (target_obj, "credentials", credentials);
445
446 // reverse lookup
447 if (target->reverse_lookup_unify)
448 cJSON_AddBoolToObject (target_obj, "reverse_lookup_unify", cJSON_True);
449 else
450 cJSON_AddBoolToObject (target_obj, "reverse_lookup_unify", cJSON_False);
451
452 if (target->reverse_lookup_only)
453 cJSON_AddBoolToObject (target_obj, "reverse_lookup_only", cJSON_True);
454 else
455 cJSON_AddBoolToObject (target_obj, "reverse_lookup_only", cJSON_False);
456
457 // alive test methods
458 cJSON *alive_test_methods = cJSON_CreateArray ();
459 if (target->arp)
460 cJSON_AddItemToArray (alive_test_methods, cJSON_CreateString ("arp"));
461 if (target->tcp_ack)
462 cJSON_AddItemToArray (alive_test_methods, cJSON_CreateString ("tcp_ack"));
463 if (target->tcp_syn)
464 cJSON_AddItemToArray (alive_test_methods, cJSON_CreateString ("tcp_syn"));
465 if (target->consider_alive)
466 cJSON_AddItemToArray (alive_test_methods,
467 cJSON_CreateString ("consider_alive"));
468 if (target->icmp)
469 cJSON_AddItemToArray (alive_test_methods, cJSON_CreateString ("icmp"));
470 cJSON_AddItemToObject (target_obj, "alive_test_methods", alive_test_methods);
471
472 cJSON_AddItemToObject (scan_obj, "target", target_obj);
473
474 // Begin Scan Preferences
475 cJSON *scan_prefs_array = cJSON_CreateArray ();
476 g_hash_table_foreach (scan_preferences, add_scan_preferences_to_scan_json,
477 scan_prefs_array);
478 cJSON_AddItemToObject (scan_obj, "scan_preferences", scan_prefs_array);
479
480 // Begin VTs
481 cJSON *vts_array = cJSON_CreateArray ();
482 g_slist_foreach (vts, add_vts_to_scan_json, vts_array);
483 cJSON_AddItemToObject (scan_obj, "vts", vts_array);
484
485 json_str = cJSON_Print (scan_obj);
486 cJSON_Delete (scan_obj);
487 if (json_str == NULL)
488 g_warning ("%s: Error while creating JSON.", __func__);
489
490 return json_str;
491}
492
503openvasd_credential_new (const gchar *type, const gchar *service,
504 const gchar *port)
505{
506 openvasd_credential_t *new_credential;
507
508 new_credential = g_malloc0 (sizeof (openvasd_credential_t));
509
510 new_credential->type = type ? g_strdup (type) : NULL;
511 new_credential->service = service ? g_strdup (service) : NULL;
512 new_credential->port = port ? g_strdup (port) : NULL;
513 new_credential->auth_data =
514 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
515
516 return new_credential;
517}
518
524void
526{
527 if (!credential)
528 return;
529
530 g_free (credential->type);
531 g_free (credential->service);
532 g_free (credential->port);
533 g_hash_table_destroy (credential->auth_data);
534 g_free (credential);
535}
536
544void
546 const gchar *name, const gchar *value)
547{
548 if (credential == NULL || name == NULL)
549 return;
550
551 if (g_regex_match_simple ("^[[:alpha:]][[:alnum:]_]*$", name, 0, 0))
552 {
553 if (value)
554 g_hash_table_replace (credential->auth_data, g_strdup (name),
555 g_strdup (value));
556 else
557 g_hash_table_remove (credential->auth_data, name);
558 }
559 else
560 {
561 g_warning ("%s: Invalid auth data name: %s", __func__, name);
562 }
563}
564
578openvasd_target_new (const gchar *scanid, const gchar *hosts,
579 const gchar *ports, const gchar *exclude_hosts,
580 int reverse_lookup_unify, int reverse_lookup_only)
581{
582 openvasd_target_t *new_target;
583 new_target = g_malloc0 (sizeof (openvasd_target_t));
584
585 if (scanid && *scanid)
586 new_target->scan_id = g_strdup (scanid);
587
588 new_target->exclude_hosts = exclude_hosts ? g_strdup (exclude_hosts) : NULL;
589 new_target->finished_hosts = NULL;
590 new_target->hosts = hosts ? g_strdup (hosts) : NULL;
591 new_target->ports = ports ? g_strdup (ports) : NULL;
592 new_target->reverse_lookup_unify =
593 reverse_lookup_unify ? reverse_lookup_unify : 0;
594 new_target->reverse_lookup_only =
595 reverse_lookup_only ? reverse_lookup_only : 0;
596
597 return new_target;
598}
599
606void
608 const gchar *finished_hosts)
609{
610 g_free (target->finished_hosts);
611 target->finished_hosts = finished_hosts ? g_strdup (finished_hosts) : NULL;
612}
613
619void
621{
622 if (!target)
623 return;
624
625 g_slist_free_full (target->credentials,
626 (GDestroyNotify) openvasd_credential_free);
627 g_free (target->exclude_hosts);
628 g_free (target->finished_hosts);
629 g_free (target->scan_id);
630 g_free (target->hosts);
631 g_free (target->ports);
632 g_free (target);
633 target = NULL;
634}
635
646void
648 gboolean icmp, gboolean tcp_syn,
649 gboolean tcp_ack, gboolean arp,
650 gboolean consider_alive)
651{
652 if (!target)
653 return;
654
655 target->icmp = icmp;
656 target->tcp_syn = tcp_syn;
657 target->tcp_ack = tcp_ack;
658 target->arp = arp;
659 target->consider_alive = consider_alive;
660}
661
668void
670 openvasd_credential_t *credential)
671{
672 if (!target || !credential)
673 return;
674
675 target->credentials = g_slist_prepend (target->credentials, credential);
676}
677
686openvasd_vt_single_new (const gchar *vt_id)
687{
688 openvasd_vt_single_t *new_vt_single;
689 new_vt_single = g_malloc0 (sizeof (openvasd_vt_single_t));
690
691 new_vt_single->vt_id = vt_id ? g_strdup (vt_id) : NULL;
692 new_vt_single->vt_values =
693 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
694
695 return new_vt_single;
696}
697
703void
705{
706 if (!vt_single)
707 return;
708
709 g_hash_table_destroy (vt_single->vt_values);
710
711 g_free (vt_single->vt_id);
712 g_free (vt_single);
713}
714
724void
726 const gchar *name, const gchar *value)
727{
728 g_hash_table_replace (vt_single->vt_values, g_strdup (name),
729 g_strdup (value));
730}
void array_free(GPtrArray *array)
Free global array value.
Definition array.c:50
Array utilities.
GPtrArray array_t
Definition array.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
void openvasd_target_add_credential(openvasd_target_t *target, openvasd_credential_t *credential)
Add a credential to an openvasd target.
Definition openvasd.c:669
#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:199
void openvasd_credential_set_auth_data(openvasd_credential_t *credential, const gchar *name, const gchar *value)
Get authentication data from an openvasd credential.
Definition openvasd.c:545
void openvasd_target_free(openvasd_target_t *target)
Free an openvasd target, including all added credentials.
Definition openvasd.c:620
http_scanner_resp_t openvasd_get_vts(http_scanner_connector_t conn)
Get VT's metadata.
Definition openvasd.c:122
void openvasd_credential_free(openvasd_credential_t *credential)
Free an openvasd credential.
Definition openvasd.c:525
openvasd_credential_t * openvasd_credential_new(const gchar *type, const gchar *service, const gchar *port)
Allocate and initialize a new openvasd credential.
Definition openvasd.c:503
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:368
static void add_credential_to_scan_json(gpointer credentials, gpointer cred_array)
Add a credential to the scan json object.
Definition openvasd.c:276
http_scanner_resp_t openvasd_get_vt_stream_init(http_scanner_connector_t conn)
Fetch feed metadata chunk by chunk.
Definition openvasd.c:83
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:578
static void add_port_to_scan_json(gpointer range, gpointer p_array)
Add a port range to the scan json object.
Definition openvasd.c:246
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:607
void openvasd_vt_single_free(openvasd_vt_single_t *vt_single)
Free a single openvasd VT, including all preference values.
Definition openvasd.c:704
int openvasd_get_vt_stream(http_scanner_connector_t conn)
Get a new feed metadata chunk.
Definition openvasd.c:108
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:310
static void add_vts_to_scan_json(gpointer single_vt, gpointer vts_array)
Add a VT to the scan json object.
Definition openvasd.c:326
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:725
http_scanner_resp_t openvasd_get_performance(http_scanner_connector_t conn, openvasd_get_performance_opts_t opts)
Get performance data.
Definition openvasd.c:149
void openvasd_target_add_alive_test_methods(openvasd_target_t *target, gboolean icmp, gboolean tcp_syn, gboolean tcp_ack, gboolean arp, gboolean consider_alive)
Add alive test methods to openvasd target.
Definition openvasd.c:647
openvasd_vt_single_t * openvasd_vt_single_new(const gchar *vt_id)
Create a new single openvasd VT.
Definition openvasd.c:686
API for Openvas Daemon communication.
struct openvasd_credential openvasd_credential_t
Definition openvasd.h:44
struct openvasd_vt_single openvasd_vt_single_t
Definition openvasd.h:42
struct openvasd_target openvasd_target_t
Definition openvasd.h:40
Struct credential information for openvasd.
Definition openvasd.c:39
gchar * type
Definition openvasd.c:40
gchar * port
Definition openvasd.c:42
gchar * service
Definition openvasd.c:41
GHashTable * auth_data
Definition openvasd.c:43
Definition openvasd.h:23
const gchar * titles
Definition openvasd.h:26
int end
Definition openvasd.h:25
int start
Definition openvasd.h:24
Struct holding target information.
Definition openvasd.c:50
int reverse_lookup_only
Definition openvasd.c:63
gboolean icmp
Definition openvasd.c:57
gchar * ports
Definition openvasd.c:55
gboolean tcp_ack
Definition openvasd.c:59
gchar * exclude_hosts
Definition openvasd.c:53
int reverse_lookup_unify
Definition openvasd.c:62
gboolean arp
Definition openvasd.c:60
GSList * credentials
Definition openvasd.c:52
gboolean tcp_syn
Definition openvasd.c:58
gboolean consider_alive
Definition openvasd.c:61
gchar * finished_hosts
Definition openvasd.c:56
gchar * hosts
Definition openvasd.c:54
gchar * scan_id
Definition openvasd.c:51
Struct holding vt information.
Definition openvasd.c:70
gchar * vt_id
Definition openvasd.c:71
GHashTable * vt_values
Definition openvasd.c:72
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