1 /* Copyright (C) 2009-2021 Greenbone Networks GmbH
2  *
3  * SPDX-License-Identifier: GPL-2.0-or-later
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 //  One of the files of gvm-libs needs to specify the meta data
21 //  for the doxygen documentation.
22 
23 /**
24  * \mainpage
25  *
26  * \section Introduction
27  * \verbinclude README.md
28  *
29  * \section Installation
30  * \verbinclude INSTALL.md
31  *
32  * \section copying License
33  * \verbinclude COPYING
34  */
35 
36 /**
37  * @file
38  * @brief Implementation of API to handle NVT Info datasets
39  *
40  * This file contains all methods to handle NVT Information datasets
41  * (nvti_t).
42  *
43  * The module consequently uses glib datatypes and api for memory
44  * management etc.
45  */
46 
47 /* For strptime in time.h. */
48 #undef _XOPEN_SOURCE
49 #define _XOPEN_SOURCE
50 #include "nvti.h"
51 
52 #include <stdio.h>   // for sscanf
53 #include <string.h>  // for strcmp
54 #include <strings.h> // for strcasecmp
55 #include <time.h>    // for strptime
56 
57 #undef G_LOG_DOMAIN
58 /**
59  * @brief GLib log domain.
60  */
61 #define G_LOG_DOMAIN "libgvm base"
62 
63 /* VT references */
64 
65 /**
66  * @brief The structure for a cross reference of a VT.
67  *
68  * The elements of this structure should only be accessed by the
69  * respective functions.
70  */
71 typedef struct vtref
72 {
73   gchar *type;     ///< Reference type ("cve", "bid", ...)
74   gchar *ref_id;   ///< Actual reference ID ("CVE-2018-1234", etc)
75   gchar *ref_text; ///< Optional additional text
76 } vtref_t;
77 
78 /**
79  * @brief Create a new vtref structure filled with the given values.
80  *
81  * @param type The type to be set.
82  *
83  * @param ref_id The actual reference to be set.
84  *
85  * @param ref_text The optional text accompanying a reference.
86  *
87  * @return NULL in case the memory could not be allocated.
88  *         Else a vtref structure which needs to be
89  *         released using @ref vtref_free .
90  */
91 vtref_t *
vtref_new(const gchar * type,const gchar * ref_id,const gchar * ref_text)92 vtref_new (const gchar *type, const gchar *ref_id, const gchar *ref_text)
93 {
94   vtref_t *ref = g_malloc0 (sizeof (vtref_t));
95 
96   if (type)
97     ref->type = g_strdup (type);
98   if (ref_id)
99     ref->ref_id = g_strdup (ref_id);
100   if (ref_text)
101     ref->ref_text = g_strdup (ref_text);
102 
103   return ref;
104 }
105 
106 /**
107  * @brief Free memory of a vtref structure.
108  *
109  * @param ref The structure to be freed.
110  */
111 void
vtref_free(vtref_t * ref)112 vtref_free (vtref_t *ref)
113 {
114   if (!ref)
115     return;
116 
117   g_free (ref->type);
118   g_free (ref->ref_id);
119   g_free (ref->ref_text);
120   g_free (ref);
121 }
122 
123 /**
124  * @brief Get the type of a reference.
125  *
126  * @param r The VT Reference structure of which the type should
127  *          be returned.
128  *
129  * @return The type string. Don't free this.
130  */
131 const gchar *
vtref_type(const vtref_t * r)132 vtref_type (const vtref_t *r)
133 {
134   return r ? r->type : NULL;
135 }
136 
137 /**
138  * @brief Get the id of a reference.
139  *
140  * @param r The VT Reference structure of which the id should
141  *          be returned.
142  *
143  * @return The id string. Don't free this.
144  */
145 const gchar *
vtref_id(const vtref_t * r)146 vtref_id (const vtref_t *r)
147 {
148   return r ? r->ref_id : NULL;
149 }
150 
151 /**
152  * @brief Get the text of a reference.
153  *
154  * @param r The VT Reference structure of which the id should
155  *          be returned.
156  *
157  * @return The id string. Don't free this.
158  */
159 const gchar *
vtref_text(const vtref_t * r)160 vtref_text (const vtref_t *r)
161 {
162   return r ? r->ref_text : NULL;
163 }
164 
165 /* VT severities */
166 
167 /**
168  * @brief The structure for a severity of a VT.
169  *
170  * VTs can have one or several severities.
171  */
172 typedef struct vtseverity
173 {
174   gchar *type;   ///< Severity type ("cvss_base_v2", ...)
175   gchar *origin; ///< Optional: Where does the severity come from
176                  ///< ("CVE-2018-1234", "Greenbone Research")
177   int date; ///< Timestamp in seconds since epoch, defaults to VT creation date.
178   double score; ///< The score derived from the value in range [0.0-10.0]
179   gchar *value; ///< The value which corresponds to the type.
180 } vtseverity_t;
181 
182 /**
183  * @brief Create a new vtseverity structure filled with the given values.
184  *
185  * @param[in]  type   The severity type to be set.
186  * @param[in]  origin The origin reference to be set, can be NULL.
187  * @param[in]  date   The date to be set.
188  * @param[in]  score  The score to be set.
189  * @param[in]  value  The value corresponding to the type.
190  *
191  * @return NULL in case the memory could not be allocated.
192  *         Else a vtref structure which needs to be
193  *         released using @ref vtref_free .
194  */
195 vtseverity_t *
vtseverity_new(const gchar * type,const gchar * origin,int date,double score,const gchar * value)196 vtseverity_new (const gchar *type, const gchar *origin, int date, double score,
197                 const gchar *value)
198 {
199   vtseverity_t *s = g_malloc0 (sizeof (vtseverity_t));
200 
201   if (type)
202     s->type = g_strdup (type);
203   if (origin)
204     s->origin = g_strdup (origin);
205   s->date = date;
206   s->score = score;
207   if (value)
208     s->value = g_strdup (value);
209 
210   return s;
211 }
212 
213 /**
214  * @brief Free memory of a vtseverity structure.
215  *
216  * @param s The structure to be freed.
217  */
218 void
vtseverity_free(vtseverity_t * s)219 vtseverity_free (vtseverity_t *s)
220 {
221   if (!s)
222     return;
223 
224   g_free (s->type);
225   g_free (s->origin);
226   g_free (s->value);
227   g_free (s);
228 }
229 
230 /**
231  * @brief Get the type of a severity.
232  *
233  * @param s The VT Severity structure of which the type should
234  *          be returned.
235  *
236  * @return The type string. Don't free this.
237  */
238 const gchar *
vtseverity_type(const vtseverity_t * s)239 vtseverity_type (const vtseverity_t *s)
240 {
241   return s ? s->type : NULL;
242 }
243 
244 /**
245  * @brief Get the origin of a severity.
246  *
247  * @param s The VT Severity structure of which the origin should
248  *          be returned.
249  *
250  * @return The origin string. Don't free this.
251  */
252 const gchar *
vtseverity_origin(const vtseverity_t * s)253 vtseverity_origin (const vtseverity_t *s)
254 {
255   return s ? s->origin : NULL;
256 }
257 
258 /**
259  * @brief Get the value of a severity.
260  *
261  * @param s The VT Severity structure of which the value should
262  *          be returned.
263  *
264  * @return The value string. Don't free this.
265  */
266 const gchar *
vtseverity_value(const vtseverity_t * s)267 vtseverity_value (const vtseverity_t *s)
268 {
269   return s ? s->value : NULL;
270 }
271 
272 /**
273  * @brief Get the date of a severity.
274  *
275  * @param s The VT Severity structure of which the date should
276  *          be returned.
277  *
278  * @return The date.
279  */
280 int
vtseverity_date(const vtseverity_t * s)281 vtseverity_date (const vtseverity_t *s)
282 {
283   return s->date;
284 }
285 
286 /**
287  * @brief Get the score of a severity.
288  *
289  * @param s The VT Severity structure of which the score should
290  *          be returned.
291  *
292  * @return The score.
293  */
294 double
vtseverity_score(const vtseverity_t * s)295 vtseverity_score (const vtseverity_t *s)
296 {
297   return s->score;
298 }
299 
300 /* Support function for timestamps */
301 
302 /**
303  * @brief Try convert an NVT tag time string into epoch time
304  *        or return 0 upon parse errors.
305  *
306  * @param[in]   str_time Time stamp as string in one of the forms used in NVTs.
307  *
308  * @return Time as seconds since the epoch.
309  */
310 static time_t
parse_nvt_timestamp(const gchar * str_time)311 parse_nvt_timestamp (const gchar *str_time)
312 {
313   time_t epoch_time;
314   int offset;
315   struct tm tm;
316 
317   if ((strcmp ((char *) str_time, "") == 0)
318       || (strcmp ((char *) str_time, "$Date: $") == 0)
319       || (strcmp ((char *) str_time, "$Date$") == 0)
320       || (strcmp ((char *) str_time, "$Date:$") == 0)
321       || (strcmp ((char *) str_time, "$Date") == 0)
322       || (strcmp ((char *) str_time, "$$") == 0))
323     {
324       return 0;
325     }
326 
327   /* Parse the time. */
328 
329   /* 2011-08-09 08:20:34 +0200 (Tue, 09 Aug 2011) */
330   /* $Date: 2012-02-17 16:05:26 +0100 (Fr, 17. Feb 2012) $ */
331   /* $Date: Fri, 11 Nov 2011 14:42:28 +0100 $ */
332   memset (&tm, 0, sizeof (struct tm));
333   if (strptime ((char *) str_time, "%F %T %z", &tm) == NULL)
334     {
335       memset (&tm, 0, sizeof (struct tm));
336       if (strptime ((char *) str_time, "$Date: %F %T %z", &tm) == NULL)
337         {
338           memset (&tm, 0, sizeof (struct tm));
339           if (strptime ((char *) str_time, "%a %b %d %T %Y %z", &tm) == NULL)
340             {
341               memset (&tm, 0, sizeof (struct tm));
342               if (strptime ((char *) str_time, "$Date: %a, %d %b %Y %T %z", &tm)
343                   == NULL)
344                 {
345                   memset (&tm, 0, sizeof (struct tm));
346                   if (strptime ((char *) str_time, "$Date: %a %b %d %T %Y %z",
347                                 &tm)
348                       == NULL)
349                     {
350                       g_warning ("%s: Failed to parse time: %s", __func__,
351                                  str_time);
352                       return 0;
353                     }
354                 }
355             }
356         }
357     }
358   epoch_time = mktime (&tm);
359   if (epoch_time == -1)
360     {
361       g_warning ("%s: Failed to make time: %s", __func__, str_time);
362       return 0;
363     }
364 
365   /* Get the timezone offset from the str_time. */
366 
367   if ((sscanf ((char *) str_time, "%*u-%*u-%*u %*u:%*u:%*u %d%*[^]]", &offset)
368        != 1)
369       && (sscanf ((char *) str_time, "$Date: %*u-%*u-%*u %*u:%*u:%*u %d%*[^]]",
370                   &offset)
371           != 1)
372       && (sscanf ((char *) str_time, "%*s %*s %*s %*u:%*u:%*u %*u %d%*[^]]",
373                   &offset)
374           != 1)
375       && (sscanf ((char *) str_time,
376                   "$Date: %*s %*s %*s %*u %*u:%*u:%*u %d%*[^]]", &offset)
377           != 1)
378       && (sscanf ((char *) str_time,
379                   "$Date: %*s %*s %*s %*u:%*u:%*u %*u %d%*[^]]", &offset)
380           != 1))
381     {
382       g_warning ("%s: Failed to parse timezone offset: %s", __func__, str_time);
383       return 0;
384     }
385 
386   /* Use the offset to convert to UTC. */
387 
388   if (offset < 0)
389     {
390       epoch_time += ((-offset) / 100) * 60 * 60;
391       epoch_time += ((-offset) % 100) * 60;
392     }
393   else if (offset > 0)
394     {
395       epoch_time -= (offset / 100) * 60 * 60;
396       epoch_time -= (offset % 100) * 60;
397     }
398 
399   return epoch_time;
400 }
401 
402 /* VT Information */
403 
404 /**
405  * @brief The structure of a information record that corresponds to a NVT.
406  */
407 typedef struct nvti
408 {
409   gchar *oid;  /**< @brief Object ID */
410   gchar *name; /**< @brief The name */
411 
412   gchar *summary;  /**< @brief The summary */
413   gchar *insight;  /**< @brief The insight */
414   gchar *affected; /**< @brief Affected systems */
415   gchar *impact;   /**< @brief Impact of vulnerability */
416 
417   time_t creation_time;     /**< @brief Time of creation, seconds since epoch */
418   time_t modification_time; /**< @brief Time of last change, sec. since epoch */
419 
420   gchar *solution;        /**< @brief The solution */
421   gchar *solution_type;   /**< @brief The solution type */
422   gchar *solution_method; /**< @brief The solution method */
423 
424   gchar *tag;       /**< @brief List of tags attached to this NVT */
425   gchar *cvss_base; /**< @brief CVSS base score for this NVT. */
426 
427   gchar *dependencies;   /**< @brief List of dependencies of this NVT */
428   gchar *required_keys;  /**< @brief List of required KB keys of this NVT */
429   gchar *mandatory_keys; /**< @brief List of mandatory KB keys of this NVT */
430   gchar *excluded_keys;  /**< @brief List of excluded KB keys of this NVT */
431   gchar *required_ports; /**< @brief List of required ports of this NVT */
432   gchar
433     *required_udp_ports; /**< @brief List of required UDP ports of this NVT*/
434 
435   gchar *detection; /**< @brief Detection description */
436   gchar *qod_type;  /**< @brief Quality of detection type */
437   gchar *qod;       /**< @brief Quality of detection */
438 
439   GSList *refs;       /**< @brief Collection of VT references */
440   GSList *severities; /**< @brief Collection of VT severities */
441   GSList *prefs;      /**< @brief Collection of NVT preferences */
442 
443   // The following are not settled yet.
444   gint timeout;  /**< @brief Default timeout time for this NVT */
445   gint category; /**< @brief The category, this NVT belongs to */
446   gchar *family; /**< @brief Family the NVT belongs to */
447 } nvti_t;
448 
449 /**
450  * @brief Add a reference to the VT Info.
451  *
452  * @param vt  The VT Info structure.
453  *
454  * @param ref The VT reference to add.
455  *
456  * @return 0 for success. Anything else indicates an error.
457  */
458 int
nvti_add_vtref(nvti_t * vt,vtref_t * ref)459 nvti_add_vtref (nvti_t *vt, vtref_t *ref)
460 {
461   if (!vt)
462     return -1;
463 
464   vt->refs = g_slist_append (vt->refs, ref);
465   return 0;
466 }
467 
468 /**
469  * @brief Add a severity to the VT Info.
470  *
471  * @param vt  The VT Info structure.
472  *
473  * @param ref The VT severity to add.
474  *
475  * @return 0 for success. Anything else indicates an error.
476  */
477 int
nvti_add_vtseverity(nvti_t * vt,vtseverity_t * s)478 nvti_add_vtseverity (nvti_t *vt, vtseverity_t *s)
479 {
480   if (!vt)
481     return -1;
482 
483   vt->severities = g_slist_append (vt->severities, s);
484   return 0;
485 }
486 
487 /* VT preferences */
488 
489 /**
490  * @brief The structure for a preference of a NVT.
491  */
492 typedef struct nvtpref
493 {
494   int id;      ///< Preference ID
495   gchar *type; ///< Preference type
496   gchar *name; ///< Name of the preference
497   gchar *dflt; ///< Default value of the preference
498 } nvtpref_t;
499 
500 /**
501  * @brief Create a new nvtpref structure filled with the given values.
502  *
503  * @param id The ID to be set.
504  *
505  * @param name The name to be set. A copy will created of this.
506  *
507  * @param type The type to be set. A copy will created of this.
508  *
509  * @param dflt The default to be set. A copy will created of this.
510  *
511  * @return NULL in case the memory could not be allocated.
512  *         Else a nvtpref structure which needs to be
513  *         released using @ref nvtpref_free .
514  */
515 nvtpref_t *
nvtpref_new(int id,gchar * name,gchar * type,gchar * dflt)516 nvtpref_new (int id, gchar *name, gchar *type, gchar *dflt)
517 {
518   nvtpref_t *np = g_malloc0 (sizeof (nvtpref_t));
519 
520   np->id = id;
521   if (name)
522     np->name = g_strdup (name);
523   if (type)
524     np->type = g_strdup (type);
525   if (dflt)
526     np->dflt = g_strdup (dflt);
527 
528   return np;
529 }
530 
531 /**
532  * @brief Free memory of a nvtpref structure.
533  *
534  * @param np The structure to be freed.
535  */
536 void
nvtpref_free(nvtpref_t * np)537 nvtpref_free (nvtpref_t *np)
538 {
539   if (!np)
540     return;
541 
542   g_free (np->name);
543   g_free (np->type);
544   g_free (np->dflt);
545   g_free (np);
546 }
547 
548 /**
549  * @brief Get the ID of a NVT Preference.
550  *
551  * @param np The NVT Pref structure of which the Name should
552  *           be returned.
553  *
554  * @return The ID value.
555  */
556 int
nvtpref_id(const nvtpref_t * np)557 nvtpref_id (const nvtpref_t *np)
558 {
559   return np ? np->id : -1;
560 }
561 
562 /**
563  * @brief Get the Name of a NVT Preference.
564  *
565  * @param np The NVT Pref structure of which the Name should
566  *           be returned.
567  *
568  * @return The name string. Don't free this.
569  */
570 gchar *
nvtpref_name(const nvtpref_t * np)571 nvtpref_name (const nvtpref_t *np)
572 {
573   return np ? np->name : NULL;
574 }
575 
576 /**
577  * @brief Get the Type of a NVT Preference.
578  *
579  * @param np The NVT Pref structure of which the Type should
580  *           be returned.
581  *
582  * @return The type string. Don't free this.
583  */
584 gchar *
nvtpref_type(const nvtpref_t * np)585 nvtpref_type (const nvtpref_t *np)
586 {
587   return np ? np->type : NULL;
588 }
589 
590 /**
591  * @brief Get the Default of a NVT Preference.
592  *
593  * @param np The NVT Pref structure of which the Default should
594  *           be returned.
595  *
596  * @return The default string. Don't free this.
597  */
598 gchar *
nvtpref_default(const nvtpref_t * np)599 nvtpref_default (const nvtpref_t *np)
600 {
601   return np ? np->dflt : NULL;
602 }
603 
604 /**
605  * @brief Create a new (empty) nvti structure.
606  *
607  * @return NULL in case the memory could not be allocated.
608  *         Else an empty nvti structure which needs to be
609  *         released using @ref nvti_free .
610  *         The whole struct is initialized with 0's.
611  */
612 nvti_t *
nvti_new(void)613 nvti_new (void)
614 {
615   return (nvti_t *) g_malloc0 (sizeof (nvti_t));
616 }
617 
618 /**
619  * @brief Free memory of a nvti structure.
620  *
621  * @param n The structure to be freed.
622  */
623 void
nvti_free(nvti_t * n)624 nvti_free (nvti_t *n)
625 {
626   if (!n)
627     return;
628 
629   g_free (n->oid);
630   g_free (n->name);
631   g_free (n->summary);
632   g_free (n->insight);
633   g_free (n->affected);
634   g_free (n->impact);
635   g_free (n->solution);
636   g_free (n->solution_type);
637   g_free (n->solution_method);
638   g_free (n->tag);
639   g_free (n->cvss_base);
640   g_free (n->dependencies);
641   g_free (n->required_keys);
642   g_free (n->mandatory_keys);
643   g_free (n->excluded_keys);
644   g_free (n->required_ports);
645   g_free (n->required_udp_ports);
646   g_free (n->detection);
647   g_free (n->qod_type);
648   g_free (n->qod);
649   g_free (n->family);
650   g_slist_free_full (n->refs, (void (*) (void *)) vtref_free);
651   g_slist_free_full (n->severities, (void (*) (void *)) vtseverity_free);
652   g_slist_free_full (n->prefs, (void (*) (void *)) nvtpref_free);
653   g_free (n);
654 }
655 
656 /**
657  * @brief Get the OID string.
658  *
659  * @param n The NVT Info structure of which the OID should
660  *          be returned.
661  *
662  * @return The OID string. Don't free this.
663  */
664 gchar *
nvti_oid(const nvti_t * n)665 nvti_oid (const nvti_t *n)
666 {
667   return n ? n->oid : NULL;
668 }
669 
670 /**
671  * @brief Get the name.
672  *
673  * @param n The NVT Info structure of which the name should
674  *          be returned.
675  *
676  * @return The name string. Don't free this.
677  */
678 gchar *
nvti_name(const nvti_t * n)679 nvti_name (const nvti_t *n)
680 {
681   return n ? n->name : NULL;
682 }
683 
684 /**
685  * @brief Get the summary.
686  *
687  * @param n The NVT Info structure of which the summary should
688  *          be returned.
689  *
690  * @return The summary string. Don't free this.
691  */
692 gchar *
nvti_summary(const nvti_t * n)693 nvti_summary (const nvti_t *n)
694 {
695   return n ? n->summary : NULL;
696 }
697 
698 /**
699  * @brief Get the text about insight.
700  *
701  * @param n The NVT Info structure of which the insight description should
702  *          be returned.
703  *
704  * @return The insight string. Don't free this.
705  */
706 gchar *
nvti_insight(const nvti_t * n)707 nvti_insight (const nvti_t *n)
708 {
709   return n ? n->insight : NULL;
710 }
711 
712 /**
713  * @brief Get the text about affected systems.
714  *
715  * @param n The NVT Info structure of which the affected description should
716  *          be returned.
717  *
718  * @return The affected string. Don't free this.
719  */
720 gchar *
nvti_affected(const nvti_t * n)721 nvti_affected (const nvti_t *n)
722 {
723   return n ? n->affected : NULL;
724 }
725 
726 /**
727  * @brief Get the text about impact.
728  *
729  * @param n The NVT Info structure of which the impact description should
730  *          be returned.
731  *
732  * @return The impact string. Don't free this.
733  */
734 gchar *
nvti_impact(const nvti_t * n)735 nvti_impact (const nvti_t *n)
736 {
737   return n ? n->impact : NULL;
738 }
739 
740 /**
741  * @brief Get the creation time.
742  *
743  * @param n The NVT Info structure of which the creation time should
744  *          be returned.
745  *
746  * @return The creation time in seconds since epoch.
747  */
748 time_t
nvti_creation_time(const nvti_t * n)749 nvti_creation_time (const nvti_t *n)
750 {
751   return n ? n->creation_time : 0;
752 }
753 
754 /**
755  * @brief Get the modification time.
756  *
757  * @param n The NVT Info structure of which the modification time should
758  *          be returned.
759  *
760  * @return The modification time in seconds since epoch.
761  */
762 time_t
nvti_modification_time(const nvti_t * n)763 nvti_modification_time (const nvti_t *n)
764 {
765   return n ? n->modification_time : 0;
766 }
767 
768 /**
769  * @brief Get the number of references of the NVT.
770  *
771  * @param n The NVT Info structure.
772  *
773  * @return The number of references.
774  */
775 guint
nvti_vtref_len(const nvti_t * n)776 nvti_vtref_len (const nvti_t *n)
777 {
778   return n ? g_slist_length (n->refs) : 0;
779 }
780 
781 /**
782  * @brief Get the n'th reference of the NVT.
783  *
784  * @param n The NVT Info structure.
785  *
786  * @param p The position of the reference to return.
787  *
788  * @return The reference. NULL on error.
789  */
790 vtref_t *
nvti_vtref(const nvti_t * n,guint p)791 nvti_vtref (const nvti_t *n, guint p)
792 {
793   return n ? g_slist_nth_data (n->refs, p) : NULL;
794 }
795 
796 /**
797  * @brief Get references as string.
798  *
799  * @param n The NVT Info structure of which the references should
800  *          be returned.
801  *
802  * @param type Optional type to collect. If NULL, all types are collected.
803  *
804  * @param exclude_types Optional CSC list of types to exclude from collection.
805  *                      If NULL, no types are excluded.
806  *
807  * @param use_types If 0, then a simple comma separated list will be returned.
808  *                  If not 0, then for each reference the syntax "type:id" is
809  *                  applied.
810  *
811  * @return The references as string. This needs to be free'd.
812  *         The format of the string depends on the "use_types" parameter.
813  *         If use_types is 0 it is a comma-separated list "id, id, id"
814  *         is returned.
815  *         If use_types is not 0 a comma-separated list like
816  *         "type:id, type:id, type:id" is returned.
817  *         NULL is returned in case n is NULL.
818  */
819 gchar *
nvti_refs(const nvti_t * n,const gchar * type,const gchar * exclude_types,guint use_types)820 nvti_refs (const nvti_t *n, const gchar *type, const gchar *exclude_types,
821            guint use_types)
822 {
823   gchar *refs, *refs2, **exclude_item;
824   vtref_t *ref;
825   guint i, exclude;
826   gchar **exclude_split;
827 
828   if (!n)
829     return NULL;
830 
831   refs = NULL;
832   refs2 = NULL;
833   exclude = 0;
834 
835   if (exclude_types && exclude_types[0])
836     exclude_split = g_strsplit (exclude_types, ",", 0);
837   else
838     exclude_split = NULL;
839 
840   for (i = 0; i < g_slist_length (n->refs); i++)
841     {
842       ref = g_slist_nth_data (n->refs, i);
843       if (type && strcasecmp (ref->type, type) != 0)
844         continue;
845 
846       if (exclude_split)
847         {
848           exclude = 0;
849           for (exclude_item = exclude_split; *exclude_item; exclude_item++)
850             {
851               if (strcasecmp (g_strstrip (*exclude_item), ref->type) == 0)
852                 {
853                   exclude = 1;
854                   break;
855                 }
856             }
857         }
858 
859       if (!exclude)
860         {
861           if (use_types)
862             {
863               if (refs)
864                 refs2 =
865                   g_strdup_printf ("%s, %s:%s", refs, ref->type, ref->ref_id);
866               else
867                 refs2 = g_strdup_printf ("%s:%s", ref->type, ref->ref_id);
868             }
869           else
870             {
871               if (refs)
872                 refs2 = g_strdup_printf ("%s, %s", refs, ref->ref_id);
873               else
874                 refs2 = g_strdup_printf ("%s", ref->ref_id);
875             }
876           g_free (refs);
877           refs = refs2;
878         }
879     }
880 
881   g_strfreev (exclude_split);
882 
883   return refs;
884 }
885 
886 /**
887  * @brief Get the number of severities of the NVT.
888  *
889  * @param n The NVT Info structure.
890  *
891  * @return The number of severities.
892  */
893 guint
nvti_vtseverities_len(const nvti_t * n)894 nvti_vtseverities_len (const nvti_t *n)
895 {
896   return n ? g_slist_length (n->severities) : 0;
897 }
898 
899 /**
900  * @brief Get the n'th reference of the NVT.
901  *
902  * @param n The NVT Info structure.
903  *
904  * @param p The position of the reference to return.
905  *
906  * @return The reference. NULL on error.
907  */
908 vtseverity_t *
nvti_vtseverity(const nvti_t * n,guint p)909 nvti_vtseverity (const nvti_t *n, guint p)
910 {
911   return n ? g_slist_nth_data (n->severities, p) : NULL;
912 }
913 
914 /**
915  * @brief Get the maximum severity score
916  *
917  * @param n The NVT Info structure.
918  *
919  * @return The severity score, -1 indicates an error.
920  */
921 double
nvti_severity_score(const nvti_t * n)922 nvti_severity_score (const nvti_t *n)
923 {
924   unsigned int i;
925   double score = -1.0;
926 
927   for (i = 0; i < nvti_vtseverities_len (n); i++)
928     {
929       vtseverity_t *severity;
930 
931       severity = nvti_vtseverity (n, i);
932       if (vtseverity_score (severity) > score)
933         score = vtseverity_score (severity);
934     }
935 
936   return score;
937 }
938 
939 /**
940  * @brief Get the solution.
941  *
942  * @param n The NVT Info structure of which the solution should
943  *          be returned.
944  *
945  * @return The solution string. Don't free this.
946  */
947 gchar *
nvti_solution(const nvti_t * n)948 nvti_solution (const nvti_t *n)
949 {
950   return n ? n->solution : NULL;
951 }
952 
953 /**
954  * @brief Get the solution type.
955  *
956  * @param n The NVT Info structure of which the solution type should
957  *          be returned.
958  *
959  * @return The solution type string. Don't free this.
960  */
961 gchar *
nvti_solution_type(const nvti_t * n)962 nvti_solution_type (const nvti_t *n)
963 {
964   return n ? n->solution_type : NULL;
965 }
966 
967 /**
968  * @brief Get the solution method.
969  *
970  * @param n The NVT Info structure of which the solution method should
971  *          be returned.
972  *
973  * @return The solution method string. Don't free this.
974  */
975 gchar *
nvti_solution_method(const nvti_t * n)976 nvti_solution_method (const nvti_t *n)
977 {
978   return n ? n->solution_method : NULL;
979 }
980 
981 /**
982  * @brief Get the tags.
983  *
984  * @param n The NVT Info structure of which the tags should
985  *          be returned.
986  *
987  * @return The tags string. Don't free this.
988  */
989 gchar *
nvti_tag(const nvti_t * n)990 nvti_tag (const nvti_t *n)
991 {
992   return n ? n->tag : NULL;
993 }
994 
995 /**
996  * @brief Get a tag value by a tag name.
997  *
998  * @param n The NVT Info structure from where to search for the tag name.
999  *
1000  * @param name The name of the tag for which to return the value.
1001  *
1002  * @return The tag value string as a copy or NULL if not found.
1003  *         Needs to be free'd.
1004  */
1005 gchar *
nvti_get_tag(const nvti_t * n,const gchar * name)1006 nvti_get_tag (const nvti_t *n, const gchar *name)
1007 {
1008   gchar **split, **point;
1009 
1010   if (!n || n->tag == NULL || !name)
1011     return NULL;
1012 
1013   split = g_strsplit (n->tag, "|", 0);
1014   point = split;
1015 
1016   while (*point)
1017     {
1018       if ((strlen (*point) > strlen (name))
1019           && (strncmp (*point, name, strlen (name)) == 0)
1020           && ((*point)[strlen (name)] == '='))
1021         {
1022           gchar *ret;
1023           ret = g_strdup (*point + strlen (name) + 1);
1024           g_strfreev (split);
1025           return ret;
1026         }
1027       point++;
1028     }
1029   g_strfreev (split);
1030   return NULL;
1031 }
1032 
1033 /**
1034  * @brief Get the CVSS base.
1035  *
1036  * @param n The NVT Info structure of which the CVSS base should
1037  *          be returned.
1038  *
1039  * @return The cvss_base string. Don't free this.
1040  */
1041 gchar *
nvti_cvss_base(const nvti_t * n)1042 nvti_cvss_base (const nvti_t *n)
1043 {
1044   return n ? n->cvss_base : NULL;
1045 }
1046 
1047 /**
1048  * @brief Get the dependencies list.
1049  *
1050  * @param n The NVT Info structure of which the name should
1051  *          be returned.
1052  *
1053  * @return The dependencies string. Don't free this.
1054  */
1055 gchar *
nvti_dependencies(const nvti_t * n)1056 nvti_dependencies (const nvti_t *n)
1057 {
1058   return n ? n->dependencies : NULL;
1059 }
1060 
1061 /**
1062  * @brief Get the required keys list.
1063  *
1064  * @param n The NVT Info structure of which the name should
1065  *          be returned.
1066  *
1067  * @return The required keys string. Don't free this.
1068  */
1069 gchar *
nvti_required_keys(const nvti_t * n)1070 nvti_required_keys (const nvti_t *n)
1071 {
1072   return n ? n->required_keys : NULL;
1073 }
1074 
1075 /**
1076  * @brief Get the mandatory keys list.
1077  *
1078  * @param n The NVT Info structure of which the name should
1079  *          be returned.
1080  *
1081  * @return The mandatory keys string. Don't free this.
1082  */
1083 gchar *
nvti_mandatory_keys(const nvti_t * n)1084 nvti_mandatory_keys (const nvti_t *n)
1085 {
1086   return n ? n->mandatory_keys : NULL;
1087 }
1088 
1089 /**
1090  * @brief Get the excluded keys list.
1091  *
1092  * @param n The NVT Info structure of which the name should
1093  *          be returned.
1094  *
1095  * @return The excluded keys string. Don't free this.
1096  */
1097 gchar *
nvti_excluded_keys(const nvti_t * n)1098 nvti_excluded_keys (const nvti_t *n)
1099 {
1100   return n ? n->excluded_keys : NULL;
1101 }
1102 
1103 /**
1104  * @brief Get the required ports list.
1105  *
1106  * @param n The NVT Info structure of which the name should
1107  *          be returned.
1108  *
1109  * @return The required ports string. Don't free this.
1110  */
1111 gchar *
nvti_required_ports(const nvti_t * n)1112 nvti_required_ports (const nvti_t *n)
1113 {
1114   return n ? n->required_ports : NULL;
1115 }
1116 
1117 /**
1118  * @brief Get the required udp ports list.
1119  *
1120  * @param n The NVT Info structure of which the name should
1121  *          be returned.
1122  *
1123  * @return The required udp ports string. Don't free this.
1124  */
1125 gchar *
nvti_required_udp_ports(const nvti_t * n)1126 nvti_required_udp_ports (const nvti_t *n)
1127 {
1128   return n ? n->required_udp_ports : NULL;
1129 }
1130 
1131 /**
1132  * @brief Get the text about detection.
1133  *
1134  * @param n The NVT Info structure of which the detection should
1135  *          be returned.
1136  *
1137  * @return The detection string. Don't free this.
1138  */
1139 gchar *
nvti_detection(const nvti_t * n)1140 nvti_detection (const nvti_t *n)
1141 {
1142   return n ? n->detection : NULL;
1143 }
1144 
1145 /**
1146  * @brief Get the QoD type.
1147  *
1148  * @param n The NVT Info structure of which the QoD type should
1149  *          be returned.
1150  *
1151  * @return The QoD type as string. Don't free this.
1152  */
1153 gchar *
nvti_qod_type(const nvti_t * n)1154 nvti_qod_type (const nvti_t *n)
1155 {
1156   return n ? n->qod_type : NULL;
1157 }
1158 
1159 /**
1160  * @brief Get the QoD.
1161  *
1162  * @param n The NVT Info structure of which the QoD should
1163  *          be returned.
1164  *
1165  * @return The QoD as string. Don't free this.
1166  */
1167 gchar *
nvti_qod(const nvti_t * n)1168 nvti_qod (const nvti_t *n)
1169 {
1170   return n ? n->qod : NULL;
1171 }
1172 
1173 /**
1174  * @brief Get the family name.
1175  *
1176  * @param n The NVT Info structure of which the name should
1177  *          be returned.
1178  *
1179  * @return The family name string. Don't free this.
1180  */
1181 gchar *
nvti_family(const nvti_t * n)1182 nvti_family (const nvti_t *n)
1183 {
1184   return n ? n->family : NULL;
1185 }
1186 
1187 /**
1188  * @brief Get the number of preferences of the NVT.
1189  *
1190  * @param n The NVT Info structure.
1191  *
1192  * @return The number of preferences.
1193  */
1194 guint
nvti_pref_len(const nvti_t * n)1195 nvti_pref_len (const nvti_t *n)
1196 {
1197   return n ? g_slist_length (n->prefs) : 0;
1198 }
1199 
1200 /**
1201  * @brief Get the n'th preferences of the NVT.
1202  *
1203  * @param n The NVT Info structure.
1204  *
1205  * @param p The position of the preference to return.
1206  *
1207  * @return The preference. NULL on error.
1208  */
1209 const nvtpref_t *
nvti_pref(const nvti_t * n,guint p)1210 nvti_pref (const nvti_t *n, guint p)
1211 {
1212   return n ? g_slist_nth_data (n->prefs, p) : NULL;
1213 }
1214 
1215 /**
1216  * @brief Get the timeout for this NVT.
1217  *
1218  * @param n The NVT Info structure of which the timeout should
1219  *          be returned.
1220  *
1221  * @return The timeout integer number. A value <= 0 indicates it is not set.
1222  */
1223 gint
nvti_timeout(const nvti_t * n)1224 nvti_timeout (const nvti_t *n)
1225 {
1226   return n ? n->timeout : -1;
1227 }
1228 
1229 /**
1230  * @brief Get the category for this NVT.
1231  *
1232  * @param n The NVT Info structure of which the category should be returned.
1233  *
1234  * @return The category integer code. A value <= 0 indicates it is not set.
1235  */
1236 gint
nvti_category(const nvti_t * n)1237 nvti_category (const nvti_t *n)
1238 {
1239   return n ? n->category : -1;
1240 }
1241 
1242 /**
1243  * @brief Set the OID of a NVT Info.
1244  *
1245  * @param n The NVT Info structure.
1246  *
1247  * @param oid The OID to set. A copy will be created from this.
1248  *
1249  * @return 0 for success. Anything else indicates an error.
1250  */
1251 int
nvti_set_oid(nvti_t * n,const gchar * oid)1252 nvti_set_oid (nvti_t *n, const gchar *oid)
1253 {
1254   if (!n)
1255     return -1;
1256 
1257   g_free (n->oid);
1258   n->oid = g_strdup (oid);
1259   return 0;
1260 }
1261 
1262 /**
1263  * @brief Set the name of a NVT.
1264  *
1265  * @param n The NVT Info structure.
1266  *
1267  * @param name The name to set. A copy will be created from this.
1268  *
1269  * @return 0 for success. Anything else indicates an error.
1270  */
1271 int
nvti_set_name(nvti_t * n,const gchar * name)1272 nvti_set_name (nvti_t *n, const gchar *name)
1273 {
1274   if (!n)
1275     return -1;
1276 
1277   g_free (n->name);
1278   n->name = g_strdup (name);
1279   return 0;
1280 }
1281 
1282 /**
1283  * @brief Set the summary of a NVT.
1284  *
1285  * @param n The NVT Info structure.
1286  *
1287  * @param solution The summary to set. A copy will be created from this.
1288  *
1289  * @return 0 for success. Anything else indicates an error.
1290  */
1291 int
nvti_set_summary(nvti_t * n,const gchar * summary)1292 nvti_set_summary (nvti_t *n, const gchar *summary)
1293 {
1294   if (!n)
1295     return -1;
1296 
1297   g_free (n->summary);
1298   n->summary = g_strdup (summary);
1299   return 0;
1300 }
1301 
1302 /**
1303  * @brief Set the insight text of a NVT.
1304  *
1305  * @param n The NVT Info structure.
1306  *
1307  * @param insight The insight text to set. A copy will be created from this.
1308  *
1309  * @return 0 for success. Anything else indicates an error.
1310  */
1311 int
nvti_set_insight(nvti_t * n,const gchar * insight)1312 nvti_set_insight (nvti_t *n, const gchar *insight)
1313 {
1314   if (!n)
1315     return -1;
1316 
1317   g_free (n->insight);
1318   n->insight = g_strdup (insight);
1319   return 0;
1320 }
1321 
1322 /**
1323  * @brief Set the affected text of a NVT.
1324  *
1325  * @param n The NVT Info structure.
1326  *
1327  * @param affected The affected text to set. A copy will be created from this.
1328  *
1329  * @return 0 for success. Anything else indicates an error.
1330  */
1331 int
nvti_set_affected(nvti_t * n,const gchar * affected)1332 nvti_set_affected (nvti_t *n, const gchar *affected)
1333 {
1334   if (!n)
1335     return -1;
1336 
1337   g_free (n->affected);
1338   n->affected = g_strdup (affected);
1339   return 0;
1340 }
1341 
1342 /**
1343  * @brief Set the impact text of a NVT.
1344  *
1345  * @param n The NVT Info structure.
1346  *
1347  * @param affected The impact text to set. A copy will be created from this.
1348  *
1349  * @return 0 for success. Anything else indicates an error.
1350  */
1351 int
nvti_set_impact(nvti_t * n,const gchar * impact)1352 nvti_set_impact (nvti_t *n, const gchar *impact)
1353 {
1354   if (!n)
1355     return -1;
1356 
1357   g_free (n->impact);
1358   n->impact = g_strdup (impact);
1359   return 0;
1360 }
1361 
1362 /**
1363  * @brief Set the creation time of a NVT.
1364  *
1365  * @param n The NVT Info structure.
1366  *
1367  * @param creation_time The creation time to set.
1368  *
1369  * @return 0 for success. Anything else indicates an error.
1370  */
1371 int
nvti_set_creation_time(nvti_t * n,const time_t creation_time)1372 nvti_set_creation_time (nvti_t *n, const time_t creation_time)
1373 {
1374   if (!n)
1375     return -1;
1376 
1377   n->creation_time = creation_time;
1378   return 0;
1379 }
1380 
1381 /**
1382  * @brief Set the modification time of a NVT.
1383  *
1384  * @param n The NVT Info structure.
1385  *
1386  * @param modification_time The modification time to set.
1387  *
1388  * @return 0 for success. Anything else indicates an error.
1389  */
1390 int
nvti_set_modification_time(nvti_t * n,const time_t modification_time)1391 nvti_set_modification_time (nvti_t *n, const time_t modification_time)
1392 {
1393   if (!n)
1394     return -1;
1395 
1396   n->modification_time = modification_time;
1397   return 0;
1398 }
1399 
1400 /**
1401  * @brief Set the solution of a NVT.
1402  *
1403  * @param n The NVT Info structure.
1404  *
1405  * @param solution The solution to set. A copy will be created from this.
1406  *
1407  * @return 0 for success. Anything else indicates an error.
1408  */
1409 int
nvti_set_solution(nvti_t * n,const gchar * solution)1410 nvti_set_solution (nvti_t *n, const gchar *solution)
1411 {
1412   if (!n)
1413     return -1;
1414 
1415   g_free (n->solution);
1416   n->solution = g_strdup (solution);
1417   return 0;
1418 }
1419 
1420 /**
1421  * @brief Set the solution type of a NVT.
1422  *
1423  * @param n The NVT Info structure.
1424  *
1425  * @param solution_type The solution type to set. A copy will be created
1426  *                      from this.
1427  *
1428  * @return 0 for success. Anything else indicates an error.
1429  */
1430 int
nvti_set_solution_type(nvti_t * n,const gchar * solution_type)1431 nvti_set_solution_type (nvti_t *n, const gchar *solution_type)
1432 {
1433   if (!n)
1434     return -1;
1435 
1436   g_free (n->solution_type);
1437   n->solution_type = g_strdup (solution_type);
1438   return 0;
1439 }
1440 
1441 /**
1442  * @brief Set the solution method of a NVT.
1443  *
1444  * @param n The NVT Info structure.
1445  *
1446  * @param solution_method The solution method to set. A copy will be created
1447  *                        from this.
1448  *
1449  * @return 0 for success. Anything else indicates an error.
1450  */
1451 int
nvti_set_solution_method(nvti_t * n,const gchar * solution_method)1452 nvti_set_solution_method (nvti_t *n, const gchar *solution_method)
1453 {
1454   if (!n)
1455     return -1;
1456 
1457   g_free (n->solution_method);
1458   n->solution_method = g_strdup (solution_method);
1459   return 0;
1460 }
1461 
1462 /**
1463  * @brief Add a tag to the NVT tags.
1464  *        The tag names "severity_date", "last_modification" and
1465  *        "creation_date" are treated special: The value is expected
1466  *        to be a timestamp  and it is being converted to seconds
1467  *        since epoch before added as a tag value.
1468  *        The tag name "cvss_base" will be ignored and not added.
1469  *
1470  * @param n     The NVT Info structure.
1471  *
1472  * @param name  The tag name. A copy will be created from this.
1473  *
1474  * @param value The tag value. A copy will be created from this.
1475  *
1476  * @return 0 for success. Anything else indicates an error.
1477  */
1478 int
nvti_add_tag(nvti_t * n,const gchar * name,const gchar * value)1479 nvti_add_tag (nvti_t *n, const gchar *name, const gchar *value)
1480 {
1481   gchar *newvalue = NULL;
1482 
1483   if (!n)
1484     return -1;
1485 
1486   if (!name || !name[0])
1487     return -2;
1488 
1489   if (!value || !value[0])
1490     return -3;
1491 
1492   if (!strcmp (name, "last_modification"))
1493     {
1494       nvti_set_modification_time (n, parse_nvt_timestamp (value));
1495       newvalue = g_strdup_printf ("%i", (int) nvti_modification_time (n));
1496     }
1497   else if (!strcmp (name, "creation_date"))
1498     {
1499       nvti_set_creation_time (n, parse_nvt_timestamp (value));
1500       newvalue = g_strdup_printf ("%i", (int) nvti_creation_time (n));
1501     }
1502   else if (!strcmp (name, "severity_date"))
1503     newvalue = g_strdup_printf ("%i", (int) parse_nvt_timestamp (value));
1504   else if (!strcmp (name, "cvss_base"))
1505     {
1506       /* Ignore this tag because it is not being used.
1507        * It is redundant with the tag cvss_base_vector from which
1508        * it is computed.
1509        * Once GOS 6 and GVM 11 are retired, all set_tag commands
1510        * in the NASL scripts can be removed that set "cvss_base".
1511        * Once this happened this exception can be removed from the code.
1512        */
1513       return 0;
1514     }
1515 
1516   if (n->tag)
1517     {
1518       gchar *newtag;
1519 
1520       newtag =
1521         g_strconcat (n->tag, "|", name, "=", newvalue ? newvalue : value, NULL);
1522       g_free (n->tag);
1523       n->tag = newtag;
1524     }
1525   else
1526     n->tag = g_strconcat (name, "=", newvalue ? newvalue : value, NULL);
1527 
1528   g_free (newvalue);
1529 
1530   return 0;
1531 }
1532 
1533 /**
1534  * @brief Set the tags of a NVT.
1535  *
1536  * @param n The NVT Info structure.
1537  *
1538  * @param tag The tags to set. A copy will be created from this.
1539  *
1540  * @return 0 for success. Anything else indicates an error.
1541  */
1542 int
nvti_set_tag(nvti_t * n,const gchar * tag)1543 nvti_set_tag (nvti_t *n, const gchar *tag)
1544 {
1545   if (!n)
1546     return -1;
1547 
1548   g_free (n->tag);
1549   if (tag && tag[0])
1550     n->tag = g_strdup (tag);
1551   else
1552     n->tag = NULL;
1553   return 0;
1554 }
1555 
1556 /**
1557  * @brief Set the CVSS base of an NVT.
1558  *
1559  * @param n The NVT Info structure.
1560  *
1561  * @param cvss_base The CVSS base to set. A copy will be created from this.
1562  *
1563  * @return 0 for success. Anything else indicates an error.
1564  */
1565 int
nvti_set_cvss_base(nvti_t * n,const gchar * cvss_base)1566 nvti_set_cvss_base (nvti_t *n, const gchar *cvss_base)
1567 {
1568   if (!n)
1569     return -1;
1570 
1571   g_free (n->cvss_base);
1572   if (cvss_base && cvss_base[0])
1573     n->cvss_base = g_strdup (cvss_base);
1574   else
1575     n->cvss_base = NULL;
1576   return 0;
1577 }
1578 
1579 /**
1580  * @brief Set the dependencies of a NVT.
1581  *
1582  * @param n The NVT Info structure.
1583  *
1584  * @param dependencies The dependencies to set. A copy will be created from
1585  * this.
1586  *
1587  * @return 0 for success. Anything else indicates an error.
1588  */
1589 int
nvti_set_dependencies(nvti_t * n,const gchar * dependencies)1590 nvti_set_dependencies (nvti_t *n, const gchar *dependencies)
1591 {
1592   if (!n)
1593     return -1;
1594 
1595   g_free (n->dependencies);
1596   if (dependencies && dependencies[0])
1597     n->dependencies = g_strdup (dependencies);
1598   else
1599     n->dependencies = NULL;
1600   return 0;
1601 }
1602 
1603 /**
1604  * @brief Set the required keys of a NVT.
1605  *
1606  * @param n The NVT Info structure.
1607  *
1608  * @param required_keys The required keys to set. A copy will be created from
1609  * this.
1610  *
1611  * @return 0 for success. Anything else indicates an error.
1612  */
1613 int
nvti_set_required_keys(nvti_t * n,const gchar * required_keys)1614 nvti_set_required_keys (nvti_t *n, const gchar *required_keys)
1615 {
1616   if (!n)
1617     return -1;
1618 
1619   g_free (n->required_keys);
1620   if (required_keys && required_keys[0])
1621     n->required_keys = g_strdup (required_keys);
1622   else
1623     n->required_keys = NULL;
1624   return 0;
1625 }
1626 
1627 /**
1628  * @brief Set the mandatory keys of a NVT.
1629  *
1630  * @param n The NVT Info structure.
1631  *
1632  * @param mandatory_keys The mandatory keys to set. A copy will be created from
1633  * this.
1634  *
1635  * @return 0 for success. Anything else indicates an error.
1636  */
1637 int
nvti_set_mandatory_keys(nvti_t * n,const gchar * mandatory_keys)1638 nvti_set_mandatory_keys (nvti_t *n, const gchar *mandatory_keys)
1639 {
1640   if (!n)
1641     return -1;
1642 
1643   g_free (n->mandatory_keys);
1644   if (mandatory_keys && mandatory_keys[0])
1645     n->mandatory_keys = g_strdup (mandatory_keys);
1646   else
1647     n->mandatory_keys = NULL;
1648   return 0;
1649 }
1650 
1651 /**
1652  * @brief Set the excluded keys of a NVT.
1653  *
1654  * @param n The NVT Info structure.
1655  *
1656  * @param excluded_keys The excluded keys to set. A copy will be created from
1657  * this.
1658  *
1659  * @return 0 for success. Anything else indicates an error.
1660  */
1661 int
nvti_set_excluded_keys(nvti_t * n,const gchar * excluded_keys)1662 nvti_set_excluded_keys (nvti_t *n, const gchar *excluded_keys)
1663 {
1664   if (!n)
1665     return -1;
1666 
1667   g_free (n->excluded_keys);
1668   if (excluded_keys && excluded_keys[0])
1669     n->excluded_keys = g_strdup (excluded_keys);
1670   else
1671     n->excluded_keys = NULL;
1672   return 0;
1673 }
1674 
1675 /**
1676  * @brief Set the required ports of a NVT.
1677  *
1678  * @param n The NVT Info structure.
1679  *
1680  * @param required_ports The required ports to set. A copy will be created from
1681  * this.
1682  *
1683  * @return 0 for success. Anything else indicates an error.
1684  */
1685 int
nvti_set_required_ports(nvti_t * n,const gchar * required_ports)1686 nvti_set_required_ports (nvti_t *n, const gchar *required_ports)
1687 {
1688   if (!n)
1689     return -1;
1690 
1691   g_free (n->required_ports);
1692   if (required_ports && required_ports[0])
1693     n->required_ports = g_strdup (required_ports);
1694   else
1695     n->required_ports = NULL;
1696   return 0;
1697 }
1698 
1699 /**
1700  * @brief Set the required udp ports of a NVT.
1701  *
1702  * @param n The NVT Info structure.
1703  *
1704  * @param required_udp_ports The required udp ports to set. A copy will be
1705  * created from this.
1706  *
1707  * @return 0 for success. Anything else indicates an error.
1708  */
1709 int
nvti_set_required_udp_ports(nvti_t * n,const gchar * required_udp_ports)1710 nvti_set_required_udp_ports (nvti_t *n, const gchar *required_udp_ports)
1711 {
1712   if (!n)
1713     return -1;
1714 
1715   g_free (n->required_udp_ports);
1716   if (required_udp_ports && required_udp_ports[0])
1717     n->required_udp_ports = g_strdup (required_udp_ports);
1718   else
1719     n->required_udp_ports = NULL;
1720   return 0;
1721 }
1722 
1723 /**
1724  * @brief Set the detection text of a NVT.
1725  *
1726  * @param n The NVT Info structure.
1727  *
1728  * @param detection The detection text to set. A copy will be created from this.
1729  *
1730  * @return 0 for success. Anything else indicates an error.
1731  */
1732 int
nvti_set_detection(nvti_t * n,const gchar * detection)1733 nvti_set_detection (nvti_t *n, const gchar *detection)
1734 {
1735   if (!n)
1736     return -1;
1737 
1738   g_free (n->detection);
1739   n->detection = g_strdup (detection);
1740   return 0;
1741 }
1742 
1743 /**
1744  * @brief Set the QoD type of a NVT.
1745  *
1746  * @param n The NVT Info structure.
1747  *
1748  * @param qod_type The QoD type to set. A copy will be created from this.
1749  *                 The string is not checked, any string is accepted as type.
1750  *
1751  * @return 0 for success. Anything else indicates an error.
1752  */
1753 int
nvti_set_qod_type(nvti_t * n,const gchar * qod_type)1754 nvti_set_qod_type (nvti_t *n, const gchar *qod_type)
1755 {
1756   if (!n)
1757     return -1;
1758 
1759   g_free (n->qod_type);
1760   if (qod_type && qod_type[0])
1761     n->qod_type = g_strdup (qod_type);
1762   else
1763     n->qod_type = NULL;
1764   return 0;
1765 }
1766 
1767 /**
1768  * @brief Set the QoD of a NVT.
1769  *
1770  * @param n The NVT Info structure.
1771  *
1772  * @param qod The QoD to set. A copy will be created from this.
1773  *                 The string is not checked, any string is accepted as type.
1774  *
1775  * @return 0 for success. Anything else indicates an error.
1776  */
1777 int
nvti_set_qod(nvti_t * n,const gchar * qod)1778 nvti_set_qod (nvti_t *n, const gchar *qod)
1779 {
1780   if (!n)
1781     return -1;
1782 
1783   g_free (n->qod);
1784   if (qod && qod[0])
1785     n->qod = g_strdup (qod);
1786   else
1787     n->qod = NULL;
1788   return 0;
1789 }
1790 
1791 /**
1792  * @brief Set the family of a NVT.
1793  *
1794  * @param n The NVT Info structure.
1795  *
1796  * @param family The family to set. A copy will be created from this.
1797  *
1798  * @return 0 for success. Anything else indicates an error.
1799  */
1800 int
nvti_set_family(nvti_t * n,const gchar * family)1801 nvti_set_family (nvti_t *n, const gchar *family)
1802 {
1803   if (!n)
1804     return -1;
1805 
1806   g_free (n->family);
1807   n->family = g_strdup (family);
1808   return 0;
1809 }
1810 
1811 /**
1812  * @brief Set the timeout of a NVT Info.
1813  *
1814  * @param n The NVT Info structure.
1815  *
1816  * @param timeout The timeout to set. Values <= 0 will indicate it is not set.
1817  *
1818  * @return 0 for success. Anything else indicates an error.
1819  */
1820 int
nvti_set_timeout(nvti_t * n,const gint timeout)1821 nvti_set_timeout (nvti_t *n, const gint timeout)
1822 {
1823   if (!n)
1824     return -1;
1825 
1826   n->timeout = timeout;
1827   return 0;
1828 }
1829 
1830 /**
1831  * @brief Set the category type of a NVT Info.
1832  *
1833  * @param n The NVT Info structure.
1834  *
1835  * @param category The category to set. Values <= 0 will indicate it is not set.
1836  *
1837  * @return 0 for success. Anything else indicates an error.
1838  */
1839 int
nvti_set_category(nvti_t * n,const gint category)1840 nvti_set_category (nvti_t *n, const gint category)
1841 {
1842   if (!n)
1843     return -1;
1844 
1845   n->category = category;
1846   return 0;
1847 }
1848 
1849 /**
1850  * @brief Add many new vtref from a comma-separated list.
1851  *
1852  * @param n The NVTI where to add the references.
1853  *
1854  * @param type The type for all references. If NULL, then for ref_ids
1855  *             a syntax is expected that includes the type like
1856  *             "type:id,type:id".
1857  *
1858  * @param ref_ids A CSV of reference to be added.
1859  *
1860  * @param ref_text The optional text accompanying all references.
1861  *
1862  * @return 0 for success. 1 if n was NULL, 2 if ref_ids was NULL.
1863  */
1864 int
nvti_add_refs(nvti_t * n,const gchar * type,const gchar * ref_ids,const gchar * ref_text)1865 nvti_add_refs (nvti_t *n, const gchar *type, const gchar *ref_ids,
1866                const gchar *ref_text)
1867 {
1868   gchar **split, **item;
1869 
1870   if (!n)
1871     return 1;
1872 
1873   if (!ref_ids)
1874     return 2;
1875 
1876   split = g_strsplit (ref_ids, ",", 0);
1877 
1878   for (item = split; *item; item++)
1879     {
1880       gchar *id;
1881 
1882       id = *item;
1883       g_strstrip (id);
1884 
1885       if (strcmp (id, "") == 0)
1886         continue;
1887 
1888       if (type)
1889         {
1890           nvti_add_vtref (n, vtref_new (type, id, ref_text));
1891         }
1892       else
1893         {
1894           gchar **split2;
1895 
1896           split2 = g_strsplit (id, ":", 2);
1897           if (split2[0] && split2[1])
1898             nvti_add_vtref (n, vtref_new (split2[0], split2[1], ""));
1899           g_strfreev (split2);
1900         }
1901     }
1902   g_strfreev (split);
1903 
1904   return 0;
1905 }
1906 
1907 /**
1908  * @brief Add a required key of a NVT.
1909  *
1910  * @param n The NVT Info structure.
1911  *
1912  * @param key The required key to add. A copy will be created from this.
1913  *
1914  * @return 0 for success. 1 if n was NULL. 2 if key was NULL.
1915  */
1916 int
nvti_add_required_keys(nvti_t * n,const gchar * key)1917 nvti_add_required_keys (nvti_t *n, const gchar *key)
1918 {
1919   gchar *old;
1920 
1921   if (!n)
1922     return 1;
1923   if (!key)
1924     return 2;
1925 
1926   old = n->required_keys;
1927 
1928   if (old)
1929     {
1930       n->required_keys = g_strdup_printf ("%s, %s", old, key);
1931       g_free (old);
1932     }
1933   else
1934     n->required_keys = g_strdup (key);
1935 
1936   return 0;
1937 }
1938 
1939 /**
1940  * @brief Add a mandatory key of a NVT.
1941  *
1942  * @param n The NVT Info structure.
1943  *
1944  * @param key The mandatory key to add. A copy will be created from this.
1945  *
1946  * @return 0 for success. 1 if n was NULL. 2 if key was NULL.
1947  */
1948 int
nvti_add_mandatory_keys(nvti_t * n,const gchar * key)1949 nvti_add_mandatory_keys (nvti_t *n, const gchar *key)
1950 {
1951   gchar *old;
1952 
1953   if (!n)
1954     return 1;
1955   if (!key)
1956     return 2;
1957 
1958   old = n->mandatory_keys;
1959 
1960   if (old)
1961     {
1962       n->mandatory_keys = g_strdup_printf ("%s, %s", old, key);
1963       g_free (old);
1964     }
1965   else
1966     n->mandatory_keys = g_strdup (key);
1967 
1968   return 0;
1969 }
1970 
1971 /**
1972  * @brief Add a excluded key of a NVT.
1973  *
1974  * @param n The NVT Info structure.
1975  *
1976  * @param key The excluded key to add. A copy will be created from this.
1977  *
1978  * @return 0 for success. 1 if n was NULL. 2 if key was NULL.
1979  */
1980 int
nvti_add_excluded_keys(nvti_t * n,const gchar * key)1981 nvti_add_excluded_keys (nvti_t *n, const gchar *key)
1982 {
1983   gchar *old;
1984 
1985   if (!n)
1986     return 1;
1987   if (!key)
1988     return 2;
1989 
1990   old = n->excluded_keys;
1991 
1992   if (old)
1993     {
1994       n->excluded_keys = g_strdup_printf ("%s, %s", old, key);
1995       g_free (old);
1996     }
1997   else
1998     n->excluded_keys = g_strdup (key);
1999 
2000   return 0;
2001 }
2002 
2003 /**
2004  * @brief Add a required port of a NVT.
2005  *
2006  * @param n The NVT Info structure.
2007  *
2008  * @param port The required port to add. A copy will be created from this.
2009  *
2010  * @return 0 for success. 1 if n was NULL. 2 if port was NULL.
2011  */
2012 int
nvti_add_required_ports(nvti_t * n,const gchar * port)2013 nvti_add_required_ports (nvti_t *n, const gchar *port)
2014 {
2015   gchar *old;
2016 
2017   if (!n)
2018     return 1;
2019   if (!port)
2020     return 2;
2021 
2022   old = n->required_ports;
2023 
2024   if (old)
2025     {
2026       n->required_ports = g_strdup_printf ("%s, %s", old, port);
2027       g_free (old);
2028     }
2029   else
2030     n->required_ports = g_strdup (port);
2031 
2032   return 0;
2033 }
2034 
2035 /**
2036  * @brief Add a required udp port of a NVT.
2037  *
2038  * @param n The NVT Info structure.
2039  *
2040  * @param port The required udp port to add. A copy will be created from this.
2041  *
2042  * @return 0 for success. 1 if n was NULL. 2 if port was NULL.
2043  */
2044 int
nvti_add_required_udp_ports(nvti_t * n,const gchar * port)2045 nvti_add_required_udp_ports (nvti_t *n, const gchar *port)
2046 {
2047   gchar *old;
2048 
2049   if (!n)
2050     return 1;
2051   if (!port)
2052     return 2;
2053 
2054   old = n->required_udp_ports;
2055 
2056   if (old)
2057     {
2058       n->required_udp_ports = g_strdup_printf ("%s, %s", old, port);
2059       g_free (old);
2060     }
2061   else
2062     n->required_udp_ports = g_strdup (port);
2063 
2064   return 0;
2065 }
2066 
2067 /**
2068  * @brief Add a preference to the NVT Info.
2069  *
2070  * @param n The NVT Info structure.
2071  *
2072  * @param np The NVT preference to add.
2073  *
2074  * @return 0 for success. Anything else indicates an error.
2075  */
2076 int
nvti_add_pref(nvti_t * n,nvtpref_t * np)2077 nvti_add_pref (nvti_t *n, nvtpref_t *np)
2078 {
2079   if (!n)
2080     return -1;
2081 
2082   n->prefs = g_slist_append (n->prefs, np);
2083   return 0;
2084 }
2085 
2086 /* Collections of nvtis. */
2087 
2088 /**
2089  * @brief Free an NVT Info, for g_hash_table_destroy.
2090  *
2091  * @param nvti The NVT Info.
2092  */
2093 static void
free_nvti_for_hash_table(gpointer nvti)2094 free_nvti_for_hash_table (gpointer nvti)
2095 {
2096   nvti_free ((nvti_t *) nvti);
2097 }
2098 
2099 /**
2100  * @brief Make a collection of NVT Infos.
2101  *
2102  * @return An empty collection of NVT Infos.
2103  */
2104 nvtis_t *
nvtis_new(void)2105 nvtis_new (void)
2106 {
2107   return g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
2108                                 free_nvti_for_hash_table);
2109 }
2110 
2111 /**
2112  * @brief Free a collection of NVT Infos.
2113  *
2114  * @param nvtis The collection of NVT Infos.
2115  */
2116 void
nvtis_free(nvtis_t * nvtis)2117 nvtis_free (nvtis_t *nvtis)
2118 {
2119   if (nvtis)
2120     g_hash_table_destroy (nvtis);
2121 }
2122 
2123 /**
2124  * @brief Add an NVT Info to a collection of NVT Infos.
2125  *
2126  * @param nvtis The collection of NVT Infos.
2127  * @param nvti  The NVT Info to add.
2128  */
2129 void
nvtis_add(nvtis_t * nvtis,nvti_t * nvti)2130 nvtis_add (nvtis_t *nvtis, nvti_t *nvti)
2131 {
2132   if (nvti)
2133     g_hash_table_insert (
2134       nvtis, (gpointer) (nvti_oid (nvti) ? g_strdup (nvti_oid (nvti)) : NULL),
2135       (gpointer) nvti);
2136 }
2137 
2138 /**
2139  * @brief Add an NVT Info to a collection of NVT Infos.
2140  *
2141  * @param nvtis The collection of NVT Infos.
2142  * @param oid   The OID of the NVT.
2143  *
2144  * @return The NVT Info, if found, else NULL.
2145  */
2146 nvti_t *
nvtis_lookup(nvtis_t * nvtis,const char * oid)2147 nvtis_lookup (nvtis_t *nvtis, const char *oid)
2148 {
2149   return g_hash_table_lookup (nvtis, oid);
2150 }
2151