Greenbone Vulnerability Management Libraries 22.18.1
vtparser.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#define _GNU_SOURCE /* See feature_test_macros(7) */
12#define _FILE_OFFSET_BITS 64
13#include "../base/cvss.h"
14#include "../util/jsonpull.h"
15#include "openvasd.h"
16
17#include <cjson/cJSON.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <unistd.h>
21
39
47static int
48get_category_from_name (const gchar *cat)
49{
50 if (!g_strcmp0 (cat, "init"))
51 return ACT_INIT;
52 else if (!g_strcmp0 (cat, "scanner"))
53 return ACT_SCANNER;
54 else if (!g_strcmp0 (cat, "settings"))
55 return ACT_SETTINGS;
56 else if (!g_strcmp0 (cat, "gather_info"))
57 return ACT_GATHER_INFO;
58 else if (!g_strcmp0 (cat, "attack"))
59 return ACT_ATTACK;
60 else if (!g_strcmp0 (cat, "mixed_attack"))
61 return ACT_MIXED_ATTACK;
62 else if (!g_strcmp0 (cat, "destructive_attack"))
64 else if (!g_strcmp0 (cat, "denial"))
65 return ACT_DENIAL;
66 else if (!g_strcmp0 (cat, "kill_host"))
67 return ACT_KILL_HOST;
68 else if (!g_strcmp0 (cat, "flood"))
69 return ACT_FLOOD;
70 else if (!g_strcmp0 (cat, "end"))
71 return ACT_END;
72
73 return -1;
74}
75
76static void
77add_tags_to_nvt (nvti_t *nvt, cJSON *tag_obj)
78{
79 if (cJSON_IsObject (tag_obj))
80 {
81 gchar *severity_vector, *str;
82
83 if (!gvm_json_obj_check_str (tag_obj, "affected", &str))
84 nvti_set_affected (nvt, str);
85
86 nvti_set_creation_time (nvt, gvm_json_obj_double (tag_obj, "creation_date"));
87
88 nvti_set_modification_time (nvt, gvm_json_obj_double (tag_obj, "last_modification"));
89
90 if (!gvm_json_obj_check_str (tag_obj, "insight", &str))
91 nvti_set_insight (nvt, str);
92
93 if (!gvm_json_obj_check_str (tag_obj, "impact", &str))
94 nvti_set_impact (nvt, str);
95
96 if (!gvm_json_obj_check_str (tag_obj, "qod", &str))
97 nvti_set_qod (nvt, str);
98
99 if (!gvm_json_obj_check_str (tag_obj, "qod_type", &str))
100 nvti_set_qod_type (nvt, str);
101
102 if (!gvm_json_obj_check_str (tag_obj, "solution", &str))
103 {
104 nvti_set_solution (nvt, str);
105
106 if (gvm_json_obj_check_str (tag_obj, "solution_type", &str))
107 g_debug ("%s: SOLUTION: missing type for OID: %s", __func__,
108 nvti_oid (nvt));
109 else
110 nvti_set_solution_type (nvt, str);
111
112 if (!gvm_json_obj_check_str (tag_obj, "solution_method", &str))
113 nvti_set_solution_method (nvt, str);
114 }
115
116 if (!gvm_json_obj_check_str (tag_obj, "summary", &str))
117 nvti_set_summary (nvt, str);
118
119 if (!gvm_json_obj_check_str (tag_obj, "vuldetect", &str))
120 nvti_set_detection (nvt, str);
121
122 // Parse severity
123
124 severity_vector = gvm_json_obj_str (tag_obj, "severity_vector");
125 if (!severity_vector)
126 severity_vector = gvm_json_obj_str (tag_obj, "cvss_base_vector");
127
128 if (severity_vector)
129 {
130 gchar *severity_type, *cvss_base;
131 double cvss_base_dbl;
132
133 if (g_strrstr (severity_vector, "CVSS:3"))
134 severity_type = g_strdup ("cvss_base_v3");
135 else
136 severity_type = g_strdup ("cvss_base_v2");
137
138 cvss_base_dbl = get_cvss_score_from_base_metrics (severity_vector);
139
141 nvt, vtseverity_new (severity_type,
142 gvm_json_obj_str (tag_obj, "severity_origin"),
143 gvm_json_obj_double (tag_obj, "severity_date"),
144 cvss_base_dbl, severity_vector));
145
146 nvti_add_tag (nvt, "cvss_base_vector", severity_vector);
147
148 cvss_base = g_strdup_printf (
149 "%.1f", get_cvss_score_from_base_metrics (severity_vector));
150 nvti_set_cvss_base (nvt, cvss_base);
151
152 g_free (cvss_base);
153 g_free (severity_type);
154 // end parsing severity
155 }
156 else
157 {
158 g_warning ("%s: SEVERITY missing value element", __func__);
159 nvti_free (nvt);
160 nvt = NULL;
161 }
162 } // end tag
163}
164
165static void
166parse_references (nvti_t *nvt, cJSON *vt_obj)
167{
168 cJSON *item;
169
170 item = cJSON_GetObjectItem (vt_obj, "references");
171 if (item != NULL
172 && cJSON_IsArray (item))
173 {
174 cJSON *ref_obj;
175 cJSON_ArrayForEach (ref_obj, item)
176 {
177 gchar *id, *class;
178
179 if (!cJSON_IsObject (ref_obj))
180 g_debug ("%s: Error reading VT/REFS reference object", __func__);
181
182 else if (gvm_json_obj_check_str (ref_obj, "class", &class))
183 g_warning ("%s: REF missing class attribute", __func__);
184
185 else if (gvm_json_obj_check_str (ref_obj, "id", &id))
186 g_warning ("%s: REF missing ID attribute", __func__);
187
188 else
189 nvti_add_vtref (nvt, vtref_new (class, id, NULL));
190 }
191 } // end references
192}
193
194static void
195add_preferences_to_nvt (nvti_t *nvt, cJSON *vt_obj)
196{
197 cJSON *item;
198
199 item = cJSON_GetObjectItem (vt_obj, "preferences");
200 if (item != NULL)
201 {
202 if (!cJSON_IsArray (item))
203 g_debug ("%s: Error reading VT/REFS array", __func__);
204 else
205 {
206 cJSON *prefs_obj = NULL;
207
208 cJSON_ArrayForEach (prefs_obj, item)
209 {
210 gchar *class, *name, *default_val;
211 int id;
212
213 if (!cJSON_IsObject (prefs_obj))
214 g_debug ("%s: Error reading VT/PREFS preference object",
215 __func__);
216
217 else if (gvm_json_obj_check_str (prefs_obj, "class", &class))
218 g_warning ("%s: PREF missing class attribute", __func__);
219
220 else if (gvm_json_obj_check_int (prefs_obj, "id", &id))
221 g_warning ("%s: PREF missing id attribute", __func__);
222
223 else if (gvm_json_obj_check_str (prefs_obj, "name", &name))
224 g_warning ("%s: PREF missing name attribute", __func__);
225
226 else if (gvm_json_obj_check_str (prefs_obj, "default", &default_val))
227 g_warning ("%s: PREF missing default attribute", __func__);
228
229 else
230 nvti_add_pref (nvt, nvtpref_new (id, name, class, default_val));
231 } // end each prefs
232 } // end prefs array
233 } // end preferences
234}
235
245nvti_t *
247{
248 nvti_t *nvt = NULL;
249 cJSON *vt_obj = NULL;
250 gchar *str, *error_message = NULL;
251
252 gvm_json_pull_parser_next (parser, event);
253
254 // Handle start/end of json array
255 gchar *path = gvm_json_path_to_string (event->path);
256 if (!g_strcmp0 (path, "$") && event->type == GVM_JSON_PULL_EVENT_ARRAY_START)
257 {
258 gvm_json_pull_parser_next (parser, event);
259 g_debug ("%s: Start parsing feed", __func__);
260 }
261 else if (!g_strcmp0 (path, "$")
263 || event->type == GVM_JSON_PULL_EVENT_EOF))
264 {
265 g_debug ("%s: Finish parsing feed", __func__);
266 g_free (path);
267 return NULL;
268 }
269 g_free (path);
270
271 // It is an NVT object
273 {
274 g_warning ("%s: Error reading VT object", __func__);
275 return NULL;
276 }
277
278 vt_obj = gvm_json_pull_expand_container (parser, &error_message);
279 if (!cJSON_IsObject (vt_obj))
280 {
281 g_free (error_message);
282 cJSON_Delete (vt_obj);
283 return NULL;
284 }
285 g_free (error_message);
286
287 nvt = nvti_new ();
288
289 if (gvm_json_obj_check_str (vt_obj, "oid", &str))
290 {
291 g_warning ("%s: VT missing OID", __func__);
292 cJSON_Delete (vt_obj);
293 nvti_free (nvt);
294 return NULL;
295 }
296 nvti_set_oid (nvt, str);
297
298 if (gvm_json_obj_check_str (vt_obj, "name", &str))
299 {
300 g_warning ("%s: VT missing NAME", __func__);
301 cJSON_Delete (vt_obj);
302 nvti_free (nvt);
303 return NULL;
304 }
305 nvti_set_name (nvt, str);
306
307 if (gvm_json_obj_check_str (vt_obj, "family", &str))
308 {
309 g_warning ("%s: VT missing FAMILY", __func__);
310 cJSON_Delete (vt_obj);
311 nvti_free (nvt);
312 return NULL;
313 }
314 nvti_set_family (nvt, str);
315
316 if (gvm_json_obj_check_str (vt_obj, "category", &str))
317 {
318 g_warning ("%s: VT missing CATEGORY", __func__);
319 cJSON_Delete (vt_obj);
320 nvti_free (nvt);
321 return NULL;
322 }
324
325 cJSON *tag_obj = cJSON_GetObjectItem (vt_obj, "tag");
326 if (tag_obj)
327 add_tags_to_nvt (nvt, tag_obj);
328
329 parse_references (nvt, vt_obj);
330 add_preferences_to_nvt (nvt, vt_obj);
331 cJSON_Delete (vt_obj);
332 return nvt;
333}
double get_cvss_score_from_base_metrics(const char *cvss_str)
Calculate CVSS Score.
Definition cvss.c:585
Protos for CVSS utility functions.
double gvm_json_obj_double(cJSON *obj, const gchar *key)
Get a double field from a JSON object.
Definition json.c:75
int gvm_json_obj_check_int(cJSON *obj, const gchar *key, int *val)
Get an int field from a JSON object.
Definition json.c:97
gchar * gvm_json_obj_str(cJSON *obj, const gchar *key)
Get a string field from a JSON object.
Definition json.c:165
int gvm_json_obj_check_str(cJSON *obj, const gchar *key, gchar **val)
Get a string field from a JSON object.
Definition json.c:142
void gvm_json_pull_parser_next(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event)
Get the next event from a JSON pull parser.
Definition jsonpull.c:669
gchar * gvm_json_path_to_string(GQueue *path)
Converts a path as used by a JSON pull parser to a JSONPath string.
Definition jsonpull.c:902
cJSON * gvm_json_pull_expand_container(gvm_json_pull_parser_t *parser, gchar **error_message)
Expands the current array or object of a JSON pull parser.
Definition jsonpull.c:744
@ GVM_JSON_PULL_EVENT_OBJECT_START
Definition jsonpull.h:45
@ GVM_JSON_PULL_EVENT_EOF
Definition jsonpull.h:51
@ GVM_JSON_PULL_EVENT_ARRAY_END
Definition jsonpull.h:44
@ GVM_JSON_PULL_EVENT_ARRAY_START
Definition jsonpull.h:43
nvti_t * nvti_new(void)
Create a new (empty) nvti structure.
Definition nvti.c:559
int nvti_set_qod(nvti_t *n, const gchar *qod)
Set the QoD of a NVT.
Definition nvti.c:1880
int nvti_set_solution(nvti_t *n, const gchar *solution)
Set the solution of a NVT.
Definition nvti.c:1472
int nvti_set_solution_type(nvti_t *n, const gchar *solution_type)
Set the solution type of a NVT.
Definition nvti.c:1513
struct nvti nvti_t
The structure of a information record that corresponds to a NVT.
int nvti_set_qod_type(nvti_t *n, const gchar *qod_type)
Set the QoD type of a NVT.
Definition nvti.c:1856
int nvti_set_oid(nvti_t *n, const gchar *oid)
Set the OID of a NVT Info.
Definition nvti.c:1214
int nvti_set_cvss_base(nvti_t *n, const gchar *cvss_base)
Set the CVSS base of an NVT.
Definition nvti.c:1648
int nvti_set_impact(nvti_t *n, const gchar *impact)
Set the impact text of a NVT.
Definition nvti.c:1394
int nvti_set_summary(nvti_t *n, const gchar *summary)
Set the summary of a NVT.
Definition nvti.c:1274
gchar * nvti_oid(const nvti_t *n)
Get the OID string.
Definition nvti.c:611
nvtpref_t * nvtpref_new(int id, const gchar *name, const gchar *type, const gchar *dflt)
Create a new nvtpref structure filled with the given values.
Definition nvti.c:463
int nvti_add_pref(nvti_t *n, nvtpref_t *np)
Add a preference to the NVT Info.
Definition nvti.c:2180
int nvti_set_insight(nvti_t *n, const gchar *insight)
Set the insight text of a NVT.
Definition nvti.c:1314
vtref_t * vtref_new(const gchar *type, const gchar *ref_id, const gchar *ref_text)
Create a new vtref structure filled with the given values.
Definition nvti.c:77
int nvti_add_vtseverity(nvti_t *vt, vtseverity_t *s)
Add a severity to the VT Info.
Definition nvti.c:426
int nvti_set_solution_method(nvti_t *n, const gchar *solution_method)
Set the solution method of a NVT.
Definition nvti.c:1534
int nvti_set_name(nvti_t *n, const gchar *name)
Set the name of a NVT.
Definition nvti.c:1234
vtseverity_t * vtseverity_new(const gchar *type, const gchar *origin, int date, double score, const gchar *value)
Create a new vtseverity structure filled with the given values.
Definition nvti.c:180
int nvti_set_modification_time(nvti_t *n, const time_t modification_time)
Set the modification time of a NVT.
Definition nvti.c:1453
int nvti_set_creation_time(nvti_t *n, const time_t creation_time)
Set the creation time of a NVT.
Definition nvti.c:1434
int nvti_set_family(nvti_t *n, const gchar *family)
Set the family of a NVT.
Definition nvti.c:1903
int nvti_set_affected(nvti_t *n, const gchar *affected)
Set the affected text of a NVT.
Definition nvti.c:1354
int nvti_add_tag(nvti_t *n, const gchar *name, const gchar *value)
Add a tag to the NVT tags. The tag names "severity_date", "last_modification" and "creation_date" are...
Definition nvti.c:1561
int nvti_set_detection(nvti_t *n, const gchar *detection)
Set the detection text of a NVT.
Definition nvti.c:1815
int nvti_set_category(nvti_t *n, const gint category)
Set the category type of a NVT Info.
Definition nvti.c:1943
void nvti_free(nvti_t *n)
Free memory of a nvti structure.
Definition nvti.c:570
int nvti_add_vtref(nvti_t *vt, vtref_t *ref)
Add a reference to the VT Info.
Definition nvti.c:408
API for Openvas Daemon communication.
Event generated by the JSON pull parser.
Definition jsonpull.h:59
GQueue * path
Path to the event value.
Definition jsonpull.h:61
gvm_json_pull_event_type_t type
Type of event.
Definition jsonpull.h:60
A json pull parser.
Definition jsonpull.h:86
static void add_preferences_to_nvt(nvti_t *nvt, cJSON *vt_obj)
Definition vtparser.c:195
static int get_category_from_name(const gchar *cat)
Get the VT category type given the category as string.
Definition vtparser.c:48
nvt_category
VT categories.
Definition vtparser.c:26
@ ACT_KILL_HOST
Definition vtparser.c:35
@ ACT_DESTRUCTIVE_ATTACK
Definition vtparser.c:33
@ ACT_SCANNER
Definition vtparser.c:28
@ ACT_END
Definition vtparser.c:37
@ ACT_FLOOD
Definition vtparser.c:36
@ ACT_GATHER_INFO
Definition vtparser.c:30
@ ACT_DENIAL
Definition vtparser.c:34
@ ACT_ATTACK
Definition vtparser.c:31
@ ACT_SETTINGS
Definition vtparser.c:29
@ ACT_MIXED_ATTACK
Definition vtparser.c:32
@ ACT_INIT
Definition vtparser.c:27
static void parse_references(nvti_t *nvt, cJSON *vt_obj)
Definition vtparser.c:166
static void add_tags_to_nvt(nvti_t *nvt, cJSON *tag_obj)
Definition vtparser.c:77
nvti_t * openvasd_parse_vt(gvm_json_pull_parser_t *parser, gvm_json_pull_event_t *event)
Parse a VT element given in json format.
Definition vtparser.c:246