Greenbone Vulnerability Management Libraries: util/vtparser.c Source File

Greenbone Vulnerability Management Libraries 23.7.0

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