1 /* Copyright (C) 2009-2021 Greenbone Networks GmbH
2 *
3 * SPDX-License-Identifier: AGPL-3.0-or-later
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * 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 Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /**
20 * @file manage_sql_nvts.c
21 * @brief GVM management layer: NVTs
22 *
23 * The NVT parts of the GVM management layer.
24 */
25
26 /**
27 * @brief Enable extra GNU functions.
28 */
29 #define _GNU_SOURCE
30
31 #include <assert.h>
32 #include <errno.h>
33 #include <math.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37
38 #include <gvm/base/cvss.h>
39
40 #include "manage_sql_nvts.h"
41 #include "manage_preferences.h"
42 #include "manage_sql.h"
43 #include "manage_sql_configs.h"
44 #include "sql.h"
45 #include "utils.h"
46
47 #undef G_LOG_DOMAIN
48 /**
49 * @brief GLib log domain.
50 */
51 #define G_LOG_DOMAIN "md manage"
52
53
54 /* NVT related global options */
55
56 /**
57 * @brief File socket for OSP NVT update.
58 */
59 static gchar *osp_vt_update_socket = NULL;
60
61 /**
62 * @brief Get the current file socket for OSP NVT update.
63 *
64 * @return The path of the file socket for OSP NVT update.
65 */
66 const gchar *
get_osp_vt_update_socket()67 get_osp_vt_update_socket ()
68 {
69 return osp_vt_update_socket;
70 }
71
72 /**
73 * @brief Set the file socket for OSP NVT update.
74 *
75 * @param new_socket The new path of the file socket for OSP NVT update.
76 */
77 void
set_osp_vt_update_socket(const char * new_socket)78 set_osp_vt_update_socket (const char *new_socket)
79 {
80 if (new_socket)
81 {
82 g_free (osp_vt_update_socket);
83 osp_vt_update_socket = g_strdup (new_socket);
84 }
85 }
86
87 /**
88 * @brief Check the files socket used for OSP NVT update.
89 *
90 * @return 0 success, 1 no socket found.
91 */
92 int
check_osp_vt_update_socket()93 check_osp_vt_update_socket ()
94 {
95 if (get_osp_vt_update_socket () == NULL)
96 {
97 char *default_socket;
98
99 /* Try to get OSP VT update socket from default scanner. */
100
101 default_socket = openvas_default_scanner_host ();
102 if (default_socket == NULL)
103 return 1;
104
105 g_debug ("%s: Using OSP VT update socket from default OpenVAS"
106 " scanner: %s",
107 __func__,
108 default_socket);
109 set_osp_vt_update_socket (default_socket);
110 free (default_socket);
111 }
112
113 return 0;
114 }
115
116
117 /* NVT's. */
118
119 /**
120 * @brief Ensures the sanity of nvts cache in DB.
121 */
122 void
check_db_nvts()123 check_db_nvts ()
124 {
125 /* Ensure the nvti cache update flag exists and is clear. */
126 if (sql_int ("SELECT count(*) FROM %s.meta"
127 " WHERE name = 'update_nvti_cache';",
128 sql_schema ()))
129 sql ("UPDATE %s.meta SET value = 0 WHERE name = 'update_nvti_cache';",
130 sql_schema ());
131 else
132 sql ("INSERT INTO %s.meta (name, value)"
133 " VALUES ('update_nvti_cache', 0);",
134 sql_schema ());
135 }
136
137 /**
138 * @brief Get the name of an NVT.
139 *
140 * @param[in] nvt NVT.
141 *
142 * @return Freshly allocated name of NVT if possible, else NULL.
143 */
144 char *
manage_nvt_name(nvt_t nvt)145 manage_nvt_name (nvt_t nvt)
146 {
147 return sql_string ("SELECT name FROM nvts WHERE id = %llu;", nvt);
148 }
149
150 /**
151 * @brief Get the name of an NVT given its OID.
152 *
153 * @param[in] oid OID of NVT.
154 *
155 * @return Name of NVT if possible, else NULL.
156 */
157 char *
nvt_name(const char * oid)158 nvt_name (const char *oid)
159 {
160 gchar *quoted_oid = sql_quote (oid);
161 char *ret = sql_string ("SELECT name FROM nvts WHERE oid = '%s' LIMIT 1;",
162 quoted_oid);
163 g_free (quoted_oid);
164 return ret;
165 }
166
167 /**
168 * @brief Return feed version of the plugins in the plugin cache.
169 *
170 * @return Feed version of plugins if the plugins are cached, else NULL.
171 */
172 char*
nvts_feed_version()173 nvts_feed_version ()
174 {
175 return sql_string ("SELECT value FROM %s.meta"
176 " WHERE name = 'nvts_feed_version';",
177 sql_schema ());
178 }
179
180 /**
181 * @brief Return feed version of the plugins as seconds since epoch.
182 *
183 * @return Feed version in seconds since epoch of plugins.
184 */
185 time_t
nvts_feed_version_epoch()186 nvts_feed_version_epoch ()
187 {
188 gchar *feed_version;
189 struct tm tm;
190
191 feed_version = nvts_feed_version ();
192
193 if (feed_version == NULL)
194 return 0;
195
196 memset (&tm, 0, sizeof (struct tm));
197 strptime (feed_version, "%Y%m%d%H%M%S", &tm);
198
199 g_free (feed_version);
200
201 return mktime (&tm);
202 }
203
204 /**
205 * @brief Set the feed version of the plugins in the plugin cache.
206 *
207 * @param[in] feed_version New feed version.
208 *
209 * Also queue an update to the nvti cache.
210 */
211 void
set_nvts_feed_version(const char * feed_version)212 set_nvts_feed_version (const char *feed_version)
213 {
214 gchar* quoted = sql_quote (feed_version);
215 sql ("DELETE FROM %s.meta WHERE name = 'nvts_feed_version';",
216 sql_schema ());
217 sql ("INSERT INTO %s.meta (name, value)"
218 " VALUES ('nvts_feed_version', '%s');",
219 sql_schema (),
220 quoted);
221 g_free (quoted);
222 }
223
224 /**
225 * @brief Find an NVT given an identifier.
226 *
227 * @param[in] oid An NVT identifier.
228 * @param[out] nvt NVT return, 0 if successfully failed to find task.
229 *
230 * @return FALSE on success (including if failed to find NVT), TRUE on error.
231 */
232 gboolean
find_nvt(const char * oid,nvt_t * nvt)233 find_nvt (const char* oid, nvt_t* nvt)
234 {
235 gchar *quoted_oid;
236 int ret;
237
238 quoted_oid = sql_quote (oid);
239 ret = sql_int64 (nvt,
240 "SELECT id FROM nvts WHERE oid = '%s';",
241 quoted_oid);
242 g_free (quoted_oid);
243 switch (ret)
244 {
245 case 0:
246 break;
247 case 1: /* Too few rows in result of query. */
248 *nvt = 0;
249 break;
250 default: /* Programming error. */
251 assert (0);
252 case -1:
253 return TRUE;
254 break;
255 }
256
257 return FALSE;
258 }
259
260 /**
261 * @brief Insert an NVT.
262 *
263 * @param[in] nvti NVT Information.
264 */
265 static void
insert_nvt(const nvti_t * nvti)266 insert_nvt (const nvti_t *nvti)
267 {
268 gchar *qod_str, *qod_type, *cve;
269 gchar *quoted_name, *quoted_summary, *quoted_insight, *quoted_affected;
270 gchar *quoted_impact, *quoted_detection, *quoted_cve, *quoted_tag;
271 gchar *quoted_cvss_base, *quoted_qod_type, *quoted_family;
272 gchar *quoted_solution, *quoted_solution_type, *quoted_solution_method;
273 int qod, i;
274 double highest;
275
276 cve = nvti_refs (nvti, "cve", "", 0);
277
278 quoted_name = sql_quote (nvti_name (nvti) ? nvti_name (nvti) : "");
279 quoted_summary = sql_quote (nvti_summary (nvti) ? nvti_summary (nvti) : "");
280 quoted_insight = sql_quote (nvti_insight (nvti) ? nvti_insight (nvti) : "");
281 quoted_affected = sql_quote (nvti_affected (nvti) ?
282 nvti_affected (nvti) : "");
283 quoted_impact = sql_quote (nvti_impact (nvti) ? nvti_impact (nvti) : "");
284
285 quoted_cve = sql_quote (cve ? cve : "");
286 g_free (cve);
287
288 quoted_solution = sql_quote (nvti_solution (nvti) ?
289 nvti_solution (nvti) : "");
290 quoted_solution_type = sql_quote (nvti_solution_type (nvti) ?
291 nvti_solution_type (nvti) : "");
292 quoted_solution_method = sql_quote (nvti_solution_method (nvti) ?
293 nvti_solution_method (nvti) : "");
294 quoted_detection = sql_quote (nvti_detection (nvti) ?
295 nvti_detection (nvti) : "");
296
297 quoted_tag = sql_quote (nvti_tag (nvti) ? nvti_tag (nvti) : "");
298
299 quoted_cvss_base = sql_quote (nvti_cvss_base (nvti) ? nvti_cvss_base (nvti) : "");
300
301 qod_str = nvti_qod (nvti);
302 qod_type = nvti_qod_type (nvti);
303
304 if (qod_str == NULL || sscanf (qod_str, "%d", &qod) != 1)
305 qod = qod_from_type (qod_type);
306
307 quoted_qod_type = sql_quote (qod_type ? qod_type : "");
308
309 quoted_family = sql_quote (nvti_family (nvti) ? nvti_family (nvti) : "");
310
311 if (sql_int ("SELECT EXISTS (SELECT * FROM nvts WHERE oid = '%s');",
312 nvti_oid (nvti)))
313 sql ("DELETE FROM nvts WHERE oid = '%s';", nvti_oid (nvti));
314
315 sql ("INSERT into nvts (oid, name, summary, insight, affected,"
316 " impact, cve, tag, category, family, cvss_base,"
317 " creation_time, modification_time, uuid, solution_type,"
318 " solution_method, solution, detection, qod, qod_type)"
319 " VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s',"
320 " '%s', %i, '%s', '%s', %i, %i, '%s', '%s', '%s', '%s', '%s', %d, '%s');",
321 nvti_oid (nvti), quoted_name, quoted_summary, quoted_insight,
322 quoted_affected, quoted_impact, quoted_cve, quoted_tag,
323 nvti_category (nvti), quoted_family, quoted_cvss_base,
324 nvti_creation_time (nvti), nvti_modification_time (nvti),
325 nvti_oid (nvti), quoted_solution_type, quoted_solution_method,
326 quoted_solution, quoted_detection, qod, quoted_qod_type);
327
328 sql ("DELETE FROM vt_refs where vt_oid = '%s';", nvti_oid (nvti));
329
330 for (i = 0; i < nvti_vtref_len (nvti); i++)
331 {
332 vtref_t *ref;
333 gchar *quoted_type, *quoted_id, *quoted_text;
334
335 ref = nvti_vtref (nvti, i);
336 quoted_type = sql_quote (vtref_type (ref));
337 quoted_id = sql_quote (vtref_id (ref));
338 quoted_text = sql_quote (vtref_text (ref) ? vtref_text (ref) : "");
339
340 sql ("INSERT into vt_refs (vt_oid, type, ref_id, ref_text)"
341 " VALUES ('%s', '%s', '%s', '%s');",
342 nvti_oid (nvti), quoted_type, quoted_id, quoted_text);
343
344 g_free (quoted_type);
345 g_free (quoted_id);
346 g_free (quoted_text);
347 }
348
349 sql ("DELETE FROM vt_severities where vt_oid = '%s';", nvti_oid (nvti));
350
351 highest = 0;
352
353 for (i = 0; i < nvti_vtseverities_len (nvti); i++)
354 {
355 vtseverity_t *severity;
356 gchar *quoted_origin, *quoted_value;
357
358 severity = nvti_vtseverity (nvti, i);
359 quoted_origin = sql_quote (vtseverity_origin (severity) ?
360 vtseverity_origin (severity) : "");
361 quoted_value = sql_quote (vtseverity_value (severity) ?
362 vtseverity_value (severity) : "");
363
364 sql ("INSERT into vt_severities (vt_oid, type, origin, date, score,"
365 " value)"
366 " VALUES ('%s', '%s', '%s', %i, %0.1f, '%s');",
367 nvti_oid (nvti), vtseverity_type (severity),
368 quoted_origin, vtseverity_date (severity),
369 vtseverity_score (severity), quoted_value);
370 if (vtseverity_score (severity) > highest)
371 highest = vtseverity_score (severity);
372
373 g_free (quoted_origin);
374 g_free (quoted_value);
375 }
376
377 sql ("UPDATE nvts SET cvss_base = %0.1f WHERE oid = '%s';",
378 highest,
379 nvti_oid (nvti));
380
381 g_free (quoted_name);
382 g_free (quoted_summary);
383 g_free (quoted_insight);
384 g_free (quoted_affected);
385 g_free (quoted_impact);
386 g_free (quoted_cve);
387 g_free (quoted_tag);
388 g_free (quoted_cvss_base);
389 g_free (quoted_family);
390 g_free (quoted_solution);
391 g_free (quoted_solution_type);
392 g_free (quoted_solution_method);
393 g_free (quoted_detection);
394 g_free (quoted_qod_type);
395 }
396
397 /**
398 * @brief Initialise an NVT iterator.
399 *
400 * @param[in] iterator Iterator.
401 * @param[in] get GET data.
402 * @param[in] name Name of the info
403 *
404 * @return 0 success, 1 failed to find NVT, 2 failed to find filter,
405 * -1 error.
406 */
407 int
init_nvt_info_iterator(iterator_t * iterator,get_data_t * get,const char * name)408 init_nvt_info_iterator (iterator_t* iterator, get_data_t *get, const char *name)
409 {
410 static const char *filter_columns[] = NVT_INFO_ITERATOR_FILTER_COLUMNS;
411 static column_t columns[] = NVT_ITERATOR_COLUMNS;
412 gchar *clause = NULL;
413 int ret;
414
415 if (get->id)
416 {
417 gchar *quoted = sql_quote (get->id);
418 clause = g_strdup_printf (" AND uuid = '%s'", quoted);
419 g_free (quoted);
420 }
421 else if (name)
422 {
423 gchar *quoted = sql_quote (name);
424 clause = g_strdup_printf (" AND name = '%s'", quoted);
425 g_free (quoted);
426 /* The entry is specified by name, so filtering just gets in the way. */
427 g_free (get->filter);
428 get->filter = NULL;
429 }
430
431 ret = init_get_iterator (iterator,
432 "nvt",
433 get,
434 /* Columns. */
435 columns,
436 /* Columns for trashcan. */
437 NULL,
438 filter_columns,
439 0,
440 NULL,
441 clause,
442 0);
443
444 g_free (clause);
445 return ret;
446 }
447
448 /**
449 * @brief Get NVT iterator SELECT columns.
450 *
451 * @return SELECT columns
452 */
453 static gchar *
nvt_iterator_columns()454 nvt_iterator_columns ()
455 {
456 static column_t select_columns[] = NVT_ITERATOR_COLUMNS;
457 static gchar *columns = NULL;
458 if (columns == NULL)
459 columns = columns_build_select (select_columns);
460 return columns;
461 }
462
463 /**
464 * @brief Get NVT iterator SELECT columns.
465 *
466 * @return SELECT columns
467 */
468 static gchar *
nvt_iterator_columns_nvts()469 nvt_iterator_columns_nvts ()
470 {
471 static column_t select_columns[] = NVT_ITERATOR_COLUMNS_NVTS;
472 static gchar *columns = NULL;
473 if (columns == NULL)
474 columns = columns_build_select (select_columns);
475 return columns;
476 }
477
478 /**
479 * @brief Count number of nvt.
480 *
481 * @param[in] get GET params.
482 *
483 * @return Total number of cpes in filtered set.
484 */
485 int
nvt_info_count(const get_data_t * get)486 nvt_info_count (const get_data_t *get)
487 {
488 static const char *extra_columns[] = NVT_INFO_ITERATOR_FILTER_COLUMNS;
489 static column_t columns[] = NVT_ITERATOR_COLUMNS;
490 return count ("nvt", get, columns, NULL, extra_columns, 0, 0, 0,
491 FALSE);
492 }
493
494 /**
495 * @brief Count number of nvts created or modified after a given time.
496 *
497 * @param[in] get GET params.
498 * @param[in] count_time Time NVTs must be created or modified after.
499 * @param[in] get_modified Whether to get the modification time.
500 *
501 * @return Total number of nvts in filtered set.
502 */
503 int
nvt_info_count_after(const get_data_t * get,time_t count_time,gboolean get_modified)504 nvt_info_count_after (const get_data_t *get, time_t count_time,
505 gboolean get_modified)
506 {
507 static const char *filter_columns[] = NVT_INFO_ITERATOR_FILTER_COLUMNS;
508 static column_t columns[] = NVT_ITERATOR_COLUMNS;
509 gchar *extra_where;
510 int ret;
511
512 if (get_modified)
513 extra_where = g_strdup_printf (" AND modification_time > %ld"
514 " AND creation_time <= %ld",
515 count_time,
516 count_time);
517 else
518 extra_where = g_strdup_printf (" AND creation_time > %ld",
519 count_time);
520
521 ret = count ("nvt", get, columns, NULL, filter_columns, 0, 0, extra_where,
522 FALSE);
523
524 g_free (extra_where);
525 return ret;
526 }
527
528 /**
529 * @brief Return SQL for selecting NVT's of a config from one family.
530 *
531 * @param[in] config Config.
532 * @param[in] family Family to limit selection to.
533 * @param[in] ascending Whether to sort ascending or descending.
534 * @param[in] sort_field Field to sort on, or NULL for "nvts.id".
535 *
536 * @return Freshly allocated SELECT statement on success, or NULL on error.
537 */
538 static gchar *
select_config_nvts(const config_t config,const char * family,int ascending,const char * sort_field)539 select_config_nvts (const config_t config, const char* family, int ascending,
540 const char* sort_field)
541 {
542 gchar *quoted_selector, *quoted_family, *sql;
543 char *selector;
544
545 selector = config_nvt_selector (config);
546 if (selector == NULL)
547 /* The config should always have a selector. */
548 return NULL;
549
550 quoted_selector = sql_quote (selector);
551 free (selector);
552
553 quoted_family = sql_quote (family);
554
555 if (config_nvts_growing (config))
556 {
557 int constraining;
558
559 /* The number of NVT's can increase. */
560
561 constraining = config_families_growing (config);
562
563 if (constraining)
564 {
565 /* Constraining the universe. */
566
567 if (sql_int ("SELECT COUNT(*) FROM nvt_selectors WHERE name = '%s';",
568 quoted_selector)
569 == 1)
570 /* There is one selector, it should be the all selector. */
571 sql = g_strdup_printf
572 ("SELECT %s"
573 " FROM nvts WHERE family = '%s'"
574 " ORDER BY %s %s;",
575 nvt_iterator_columns (),
576 quoted_family,
577 sort_field ? sort_field : "name",
578 ascending ? "ASC" : "DESC");
579 else
580 {
581 /* There are multiple selectors. */
582
583 if (sql_int ("SELECT COUNT(*) FROM nvt_selectors"
584 " WHERE name = '%s' AND exclude = 1"
585 " AND type = "
586 G_STRINGIFY (NVT_SELECTOR_TYPE_FAMILY)
587 " AND family_or_nvt = '%s'"
588 ";",
589 quoted_selector,
590 quoted_family))
591 /* The family is excluded, just iterate the NVT includes. */
592 sql = g_strdup_printf
593 ("SELECT %s"
594 " FROM nvts, nvt_selectors"
595 " WHERE"
596 " nvts.family = '%s'"
597 " AND nvt_selectors.name = '%s'"
598 " AND nvt_selectors.family = '%s'"
599 " AND nvt_selectors.type = "
600 G_STRINGIFY (NVT_SELECTOR_TYPE_NVT)
601 " AND nvt_selectors.exclude = 0"
602 " AND nvts.oid = nvt_selectors.family_or_nvt"
603 " ORDER BY %s %s;",
604 nvt_iterator_columns_nvts (),
605 quoted_family,
606 quoted_selector,
607 quoted_family,
608 sort_field ? sort_field : "nvts.name",
609 ascending ? "ASC" : "DESC");
610 else
611 /* The family is included.
612 *
613 * Iterate all NVT's minus excluded NVT's. */
614 sql = g_strdup_printf
615 ("SELECT %s"
616 " FROM nvts"
617 " WHERE family = '%s'"
618 " EXCEPT"
619 " SELECT %s"
620 " FROM nvt_selectors, nvts"
621 " WHERE"
622 " nvts.family = '%s'"
623 " AND nvt_selectors.name = '%s'"
624 " AND nvt_selectors.family = '%s'"
625 " AND nvt_selectors.type = "
626 G_STRINGIFY (NVT_SELECTOR_TYPE_NVT)
627 " AND nvt_selectors.exclude = 1"
628 " AND nvts.oid = nvt_selectors.family_or_nvt"
629 " ORDER BY %s %s;",
630 nvt_iterator_columns (),
631 quoted_family,
632 nvt_iterator_columns_nvts (),
633 quoted_family,
634 quoted_selector,
635 quoted_family,
636 /* This works around "ERROR: missing FROM-clause" from
637 * Postgres when using nvts.name. */
638 sort_field && strcmp (sort_field, "nvts.name")
639 ? sort_field : "3", /* 3 is nvts.name. */
640 ascending ? "ASC" : "DESC");
641 }
642 }
643 else
644 {
645 int all;
646
647 /* Generating from empty. */
648
649 all = sql_int ("SELECT COUNT(*) FROM nvt_selectors"
650 " WHERE name = '%s' AND exclude = 0"
651 " AND type = "
652 G_STRINGIFY (NVT_SELECTOR_TYPE_FAMILY)
653 " AND family_or_nvt = '%s';",
654 quoted_selector,
655 quoted_family);
656
657 if (all)
658 /* There is a family include for this family. */
659 sql = g_strdup_printf
660 ("SELECT %s"
661 " FROM nvts"
662 " WHERE family = '%s'"
663 " EXCEPT"
664 " SELECT %s"
665 " FROM nvt_selectors, nvts"
666 " WHERE"
667 " nvts.family = '%s'"
668 " AND nvt_selectors.name = '%s'"
669 " AND nvt_selectors.family = '%s'"
670 " AND nvt_selectors.type = "
671 G_STRINGIFY (NVT_SELECTOR_TYPE_NVT)
672 " AND nvt_selectors.exclude = 1"
673 " AND nvts.oid = nvt_selectors.family_or_nvt"
674 " ORDER BY %s %s;",
675 nvt_iterator_columns (),
676 quoted_family,
677 nvt_iterator_columns_nvts (),
678 quoted_family,
679 quoted_selector,
680 quoted_family,
681 /* This works around "ERROR: missing FROM-clause" from
682 * Postgres when using nvts.name. */
683 sort_field && strcmp (sort_field, "nvts.name")
684 ? sort_field : "3", /* 3 is nvts.name. */
685 ascending ? "ASC" : "DESC");
686 else
687 sql = g_strdup_printf
688 (" SELECT %s"
689 " FROM nvt_selectors, nvts"
690 " WHERE"
691 " nvts.family = '%s'"
692 " AND nvt_selectors.name = '%s'"
693 " AND nvt_selectors.family = '%s'"
694 " AND nvt_selectors.type = "
695 G_STRINGIFY (NVT_SELECTOR_TYPE_NVT)
696 " AND nvt_selectors.exclude = 0"
697 " AND nvts.oid = nvt_selectors.family_or_nvt"
698 " ORDER BY %s %s;",
699 nvt_iterator_columns_nvts (),
700 quoted_family,
701 quoted_selector,
702 quoted_family,
703 sort_field ? sort_field : "nvts.name",
704 ascending ? "ASC" : "DESC");
705 }
706 }
707 else
708 {
709 /* The number of NVT's is static. Assume a simple list of NVT
710 * includes. */
711
712 sql = g_strdup_printf
713 ("SELECT %s"
714 " FROM nvt_selectors, nvts"
715 " WHERE nvts.family = '%s'"
716 " AND nvt_selectors.exclude = 0"
717 " AND nvt_selectors.type = " G_STRINGIFY (NVT_SELECTOR_TYPE_NVT)
718 " AND nvt_selectors.name = '%s'"
719 " AND nvts.oid = nvt_selectors.family_or_nvt"
720 " ORDER BY %s %s;",
721 nvt_iterator_columns_nvts (),
722 quoted_family,
723 quoted_selector,
724 sort_field ? sort_field : "nvts.id",
725 ascending ? "ASC" : "DESC");
726 }
727
728 g_free (quoted_selector);
729 g_free (quoted_family);
730
731 return sql;
732 }
733
734 /**
735 * @brief Initialise an NVT iterator.
736 *
737 * @param[in] iterator Iterator.
738 * @param[in] nvt NVT to iterate over, all if 0.
739 * @param[in] config Config to limit selection to. NULL for all NVTs.
740 * Overridden by \arg nvt.
741 * @param[in] family Family to limit selection to. NULL for all NVTs.
742 * Overridden by \arg config.
743 * @param[in] category Category to limit selection to. NULL for all.
744 * @param[in] ascending Whether to sort ascending or descending.
745 * @param[in] sort_field Field to sort on, or NULL for "id".
746 */
747 void
init_nvt_iterator(iterator_t * iterator,nvt_t nvt,config_t config,const char * family,const char * category,int ascending,const char * sort_field)748 init_nvt_iterator (iterator_t* iterator, nvt_t nvt, config_t config,
749 const char* family, const char *category, int ascending,
750 const char* sort_field)
751 {
752 assert ((nvt && family) == 0);
753
754 if (nvt)
755 {
756 gchar* sql;
757 sql = g_strdup_printf ("SELECT %s"
758 " FROM nvts WHERE id = %llu;",
759 nvt_iterator_columns (),
760 nvt);
761 init_iterator (iterator, "%s", sql);
762 g_free (sql);
763 }
764 else if (config)
765 {
766 gchar* sql;
767 if (family == NULL) abort ();
768 sql = select_config_nvts (config, family, ascending, sort_field);
769 if (sql)
770 {
771 init_iterator (iterator, "%s", sql);
772 g_free (sql);
773 }
774 else
775 init_iterator (iterator,
776 "SELECT %s"
777 " FROM nvts LIMIT 0;",
778 nvt_iterator_columns ());
779 }
780 else if (family)
781 {
782 gchar *quoted_family = sql_quote (family);
783 init_iterator (iterator,
784 "SELECT %s"
785 " FROM nvts"
786 " WHERE family = '%s'"
787 " ORDER BY %s %s;",
788 nvt_iterator_columns (),
789 quoted_family,
790 sort_field ? sort_field : "name",
791 ascending ? "ASC" : "DESC");
792 g_free (quoted_family);
793 }
794 else if (category)
795 {
796 gchar *quoted_category;
797 quoted_category = sql_quote (category);
798 init_iterator (iterator,
799 "SELECT %s"
800 " FROM nvts"
801 " WHERE category = '%s'"
802 " ORDER BY %s %s;",
803 nvt_iterator_columns (),
804 quoted_category,
805 sort_field ? sort_field : "name",
806 ascending ? "ASC" : "DESC");
807 g_free (quoted_category);
808 }
809 else
810 init_iterator (iterator,
811 "SELECT %s"
812 " FROM nvts"
813 " ORDER BY %s %s;",
814 nvt_iterator_columns (),
815 sort_field ? sort_field : "name",
816 ascending ? "ASC" : "DESC");
817 }
818
819 /**
820 * @brief Initialise an NVT iterator, for NVTs of a certain CVE.
821 *
822 * @param[in] iterator Iterator.
823 * @param[in] cve CVE name.
824 * @param[in] ascending Whether to sort ascending or descending.
825 * @param[in] sort_field Field to sort on, or NULL for "id".
826 */
827 void
init_cve_nvt_iterator(iterator_t * iterator,const char * cve,int ascending,const char * sort_field)828 init_cve_nvt_iterator (iterator_t* iterator, const char *cve, int ascending,
829 const char* sort_field)
830 {
831 init_iterator (iterator,
832 "SELECT %s"
833 " FROM nvts"
834 " WHERE cve %s '%%%s, %%'"
835 " OR cve %s '%%%s'"
836 " ORDER BY %s %s;",
837 nvt_iterator_columns (),
838 sql_ilike_op (),
839 cve ? cve : "",
840 sql_ilike_op (),
841 cve ? cve : "",
842 sort_field ? sort_field : "name",
843 ascending ? "ASC" : "DESC");
844 }
845
846 /**
847 * @brief Get the OID from an NVT iterator.
848 *
849 * @param[in] iterator Iterator.
850 *
851 * @return OID, or NULL if iteration is complete. Freed by
852 * cleanup_iterator.
853 */
854 DEF_ACCESS (nvt_iterator_oid, GET_ITERATOR_COLUMN_COUNT);
855
856 /**
857 * @brief Get the name from an NVT iterator.
858 *
859 * @param[in] iterator Iterator.
860 *
861 * @return Name, or NULL if iteration is complete. Freed by
862 * cleanup_iterator.
863 */
864 DEF_ACCESS (nvt_iterator_name, GET_ITERATOR_COLUMN_COUNT + 2);
865
866 /**
867 * @brief Get the tag from an NVT iterator.
868 *
869 * @param[in] iterator Iterator.
870 *
871 * @return Tag, or NULL if iteration is complete. Freed by
872 * cleanup_iterator.
873 */
874 DEF_ACCESS (nvt_iterator_tag, GET_ITERATOR_COLUMN_COUNT + 4);
875
876 /**
877 * @brief Get the category from an NVT iterator.
878 *
879 * @param[in] iterator Iterator.
880 *
881 * @return Category.
882 */
883 int
nvt_iterator_category(iterator_t * iterator)884 nvt_iterator_category (iterator_t* iterator)
885 {
886 int ret;
887 if (iterator->done) return -1;
888 ret = iterator_int (iterator, GET_ITERATOR_COLUMN_COUNT + 5);
889 return ret;
890 }
891
892 /**
893 * @brief Get the family from an NVT iterator.
894 *
895 * @param[in] iterator Iterator.
896 *
897 * @return Family, or NULL if iteration is complete. Freed by
898 * cleanup_iterator.
899 */
900 DEF_ACCESS (nvt_iterator_family, GET_ITERATOR_COLUMN_COUNT + 6);
901
902 /**
903 * @brief Get the cvss_base from an NVT iterator.
904 *
905 * @param[in] iterator Iterator.
906 *
907 * @return Cvss_base, or NULL if iteration is complete. Freed by
908 * cleanup_iterator.
909 */
910 DEF_ACCESS (nvt_iterator_cvss_base, GET_ITERATOR_COLUMN_COUNT + 7);
911
912 /**
913 * @brief Get the qod from an NVT iterator.
914 *
915 * @param[in] iterator Iterator.
916 *
917 * @return QoD, or NULL if iteration is complete. Freed by
918 * cleanup_iterator.
919 */
920 DEF_ACCESS (nvt_iterator_qod, GET_ITERATOR_COLUMN_COUNT + 10);
921
922 /**
923 * @brief Get the qod_type from an NVT iterator.
924 *
925 * @param[in] iterator Iterator.
926 *
927 * @return QoD type, or NULL if iteration is complete. Freed by
928 * cleanup_iterator.
929 */
930 DEF_ACCESS (nvt_iterator_qod_type, GET_ITERATOR_COLUMN_COUNT + 11);
931
932 /**
933 * @brief Get the solution_type from an NVT iterator.
934 *
935 * @param[in] iterator Iterator.
936 *
937 * @return Solution Type, or NULL if iteration is complete. Freed by
938 * cleanup_iterator.
939 */
940 DEF_ACCESS (nvt_iterator_solution_type, GET_ITERATOR_COLUMN_COUNT + 12);
941
942 /**
943 * @brief Get the solution from an NVT iterator.
944 *
945 * @param[in] iterator Iterator.
946 *
947 * @return Solution, or NULL if iteration is complete. Freed by
948 * cleanup_iterator.
949 */
950 DEF_ACCESS (nvt_iterator_solution, GET_ITERATOR_COLUMN_COUNT + 14);
951
952 /**
953 * @brief Get the summary from an NVT iterator.
954 *
955 * @param[in] iterator Iterator.
956 *
957 * @return Summary, or NULL if iteration is complete. Freed by
958 * cleanup_iterator.
959 */
960 DEF_ACCESS (nvt_iterator_summary, GET_ITERATOR_COLUMN_COUNT + 15);
961
962 /**
963 * @brief Get the insight from an NVT iterator.
964 *
965 * @param[in] iterator Iterator.
966 *
967 * @return Insight, or NULL if iteration is complete. Freed by
968 * cleanup_iterator.
969 */
970 DEF_ACCESS (nvt_iterator_insight, GET_ITERATOR_COLUMN_COUNT + 16);
971
972 /**
973 * @brief Get the affected from an NVT iterator.
974 *
975 * @param[in] iterator Iterator.
976 *
977 * @return Affected, or NULL if iteration is complete. Freed by
978 * cleanup_iterator.
979 */
980 DEF_ACCESS (nvt_iterator_affected, GET_ITERATOR_COLUMN_COUNT + 17);
981
982 /**
983 * @brief Get the impact from an NVT iterator.
984 *
985 * @param[in] iterator Iterator.
986 *
987 * @return Impact, or NULL if iteration is complete. Freed by
988 * cleanup_iterator.
989 */
990 DEF_ACCESS (nvt_iterator_impact, GET_ITERATOR_COLUMN_COUNT + 18);
991
992 /**
993 * @brief Get the detection from an NVT iterator.
994 *
995 * @param[in] iterator Iterator.
996 *
997 * @return Detection, or NULL if iteration is complete. Freed by
998 * cleanup_iterator.
999 */
1000 DEF_ACCESS (nvt_iterator_detection, GET_ITERATOR_COLUMN_COUNT + 19);
1001
1002 /**
1003 * @brief Get the solution method from an NVT iterator.
1004 *
1005 * @param[in] iterator Iterator.
1006 *
1007 * @return Solution method, or NULL if iteration is complete. Freed by
1008 * cleanup_iterator.
1009 */
1010 DEF_ACCESS (nvt_iterator_solution_method, GET_ITERATOR_COLUMN_COUNT + 20);
1011
1012 /**
1013 * @brief Get the default timeout of an NVT.
1014 *
1015 * @param[in] oid The OID of the NVT to get the timeout of.
1016 *
1017 * @return Newly allocated string of the timeout in seconds or NULL.
1018 */
1019 char *
nvt_default_timeout(const char * oid)1020 nvt_default_timeout (const char* oid)
1021 {
1022 return sql_string ("SELECT value FROM nvt_preferences"
1023 " WHERE name = '%s:0:entry:Timeout'",
1024 oid);
1025 }
1026
1027 /**
1028 * @brief Get the family of an NVT.
1029 *
1030 * @param[in] oid The OID of the NVT.
1031 *
1032 * @return Newly allocated string of the family, or NULL.
1033 */
1034 char *
nvt_family(const char * oid)1035 nvt_family (const char *oid)
1036 {
1037 gchar *quoted_oid;
1038 char *ret;
1039
1040 quoted_oid = sql_quote (oid);
1041 ret = sql_string ("SELECT family FROM nvts WHERE oid = '%s' LIMIT 1;",
1042 quoted_oid);
1043 g_free (quoted_oid);
1044 return ret;
1045 }
1046
1047 /**
1048 * @brief Get the number of NVTs in one or all families.
1049 *
1050 * @param[in] family Family name. NULL for all families.
1051 *
1052 * @return Number of NVTs in family, or total number of nvts.
1053 */
1054 int
family_nvt_count(const char * family)1055 family_nvt_count (const char *family)
1056 {
1057 gchar *quoted_family;
1058
1059 if (family == NULL)
1060 {
1061 static int nvt_count = -1;
1062 if (nvt_count == -1)
1063 nvt_count = sql_int ("SELECT COUNT(*) FROM nvts"
1064 " WHERE family != 'Credentials';");
1065 return nvt_count;
1066 }
1067
1068 quoted_family = sql_quote (family);
1069 int ret = sql_int ("SELECT COUNT(*) FROM nvts WHERE family = '%s';",
1070 quoted_family);
1071 g_free (quoted_family);
1072 return ret;
1073 }
1074
1075 /**
1076 * @brief Get the number of families.
1077 *
1078 * @return Total number of families.
1079 */
1080 int
family_count()1081 family_count ()
1082 {
1083 return sql_int ("SELECT COUNT(distinct family) FROM nvts"
1084 " WHERE family != 'Credentials';");
1085 }
1086
1087 /**
1088 * @brief Insert a NVT preferences.
1089 *
1090 * @param[in] nvt_preference Preference.
1091 * @param[in] dummy Dummy arg for g_list_foreach.
1092 *
1093 */
1094 static void
insert_nvt_preference(gpointer nvt_preference,gpointer dummy)1095 insert_nvt_preference (gpointer nvt_preference, gpointer dummy)
1096 {
1097 preference_t *preference;
1098
1099 if (nvt_preference == NULL)
1100 return;
1101
1102 preference = (preference_t*) nvt_preference;
1103 manage_nvt_preference_add (preference->name, preference->value);
1104 }
1105
1106 /**
1107 * @brief Inserts NVT preferences in DB from a list of nvt_preference_t structures.
1108 *
1109 * @param[in] nvt_preferences_list List of nvts to be inserted.
1110 */
1111 static void
insert_nvt_preferences_list(GList * nvt_preferences_list)1112 insert_nvt_preferences_list (GList *nvt_preferences_list)
1113 {
1114 g_list_foreach (nvt_preferences_list, insert_nvt_preference, NULL);
1115 }
1116
1117 /**
1118 * @brief Set the NVT update check time in the meta table.
1119 *
1120 * @param[in] count_new Number of new VTs with current update.
1121 * @param[in] count_modified Number of modified VTs with current update.
1122 */
1123 static void
set_nvts_check_time(int count_new,int count_modified)1124 set_nvts_check_time (int count_new, int count_modified)
1125 {
1126 if (sql_int ("SELECT NOT EXISTS (SELECT * FROM meta"
1127 " WHERE name = 'nvts_check_time')"))
1128 sql ("INSERT INTO meta (name, value)"
1129 " VALUES ('nvts_check_time', m_now ());");
1130 else if (sql_int ("SELECT value = '0' FROM meta"
1131 " WHERE name = 'nvts_check_time';"))
1132 sql ("UPDATE meta SET value = m_now ()"
1133 " WHERE name = 'nvts_check_time';");
1134 else
1135 {
1136 if (count_new > 0)
1137 event (EVENT_NEW_SECINFO, "nvt", 0, 0);
1138
1139 if (count_modified > 0)
1140 event (EVENT_UPDATED_SECINFO, "nvt", 0, 0);
1141
1142 sql ("UPDATE meta SET value = m_now ()"
1143 " WHERE name = 'nvts_check_time';");
1144 }
1145 }
1146
1147 /**
1148 * @brief Update NVT from VT XML.
1149 *
1150 * @param[in] vt OSP GET_VTS VT element.
1151 * @param[in] oid OID of NVT.
1152 * @param[in] preferences All NVT preferences.
1153 *
1154 * @return 0 success, -1 error.
1155 */
1156 static int
update_preferences_from_vt(entity_t vt,const gchar * oid,GList ** preferences)1157 update_preferences_from_vt (entity_t vt, const gchar *oid, GList **preferences)
1158 {
1159 entity_t params, param;
1160 entities_t children;
1161
1162 assert (preferences);
1163
1164 params = entity_child (vt, "params");
1165 if (params == NULL)
1166 return 0;
1167
1168 children = params->entities;
1169 while ((param = first_entity (children)))
1170 {
1171 if (strcasecmp (entity_name (param), "param") == 0)
1172 {
1173 const gchar *type, *id;
1174 entity_t name, def;
1175
1176 type = entity_attribute (param, "type");
1177 id = entity_attribute (param, "id");
1178 name = entity_child (param, "name");
1179 def = entity_child (param, "default");
1180
1181 if (type == NULL)
1182 {
1183 GString *debug = g_string_new ("");
1184 g_warning ("%s: PARAM missing type attribute", __func__);
1185 print_entity_to_string (param, debug);
1186 g_warning ("%s: PARAM: %s", __func__, debug->str);
1187 g_string_free (debug, TRUE);
1188 }
1189 else if (id == NULL)
1190 {
1191 GString *debug = g_string_new ("");
1192 g_warning ("%s: PARAM missing id attribute", __func__);
1193 print_entity_to_string (param, debug);
1194 g_warning ("%s: PARAM: %s", __func__, debug->str);
1195 g_string_free (debug, TRUE);
1196 }
1197 else if (name == NULL)
1198 {
1199 GString *debug = g_string_new ("");
1200 g_warning ("%s: PARAM missing NAME", __func__);
1201 print_entity_to_string (param, debug);
1202 g_warning ("%s: PARAM: %s", __func__, debug->str);
1203 g_string_free (debug, TRUE);
1204 }
1205 else
1206 {
1207 gchar *full_name;
1208 preference_t *preference;
1209
1210 full_name = g_strdup_printf ("%s:%s:%s:%s",
1211 oid,
1212 id,
1213 type,
1214 entity_text (name));
1215
1216 blank_control_chars (full_name);
1217 preference = g_malloc0 (sizeof (preference_t));
1218 preference->name = full_name;
1219 if (def)
1220 preference->value = g_strdup (entity_text (def));
1221 else
1222 preference->value = g_strdup ("");
1223 *preferences = g_list_prepend (*preferences, preference);
1224 }
1225 }
1226
1227 children = next_entities (children);
1228 }
1229
1230 return 0;
1231 }
1232
1233 /**
1234 * @brief Create NVTI structure from VT XML.
1235 *
1236 * @param[in] vt OSP GET_VTS VT element.
1237 *
1238 * @return The NVTI object on success (needs to be free'd), NULL on error.
1239 */
1240 static nvti_t *
nvti_from_vt(entity_t vt)1241 nvti_from_vt (entity_t vt)
1242 {
1243 nvti_t *nvti = nvti_new ();
1244 const char *id;
1245 entity_t name, summary, insight, affected, impact, detection, solution;
1246 entity_t creation_time, modification_time;
1247 entity_t refs, ref, custom, family, category, deprecated;
1248 entity_t severities, severity;
1249
1250 entities_t children;
1251
1252 id = entity_attribute (vt, "id");
1253 if (id == NULL)
1254 {
1255 g_warning ("%s: VT missing id attribute", __func__);
1256 nvti_free (nvti);
1257 return NULL;
1258 }
1259 nvti_set_oid (nvti, id);
1260
1261 name = entity_child (vt, "name");
1262 if (name == NULL)
1263 {
1264 g_warning ("%s: VT missing NAME", __func__);
1265 nvti_free (nvti);
1266 return NULL;
1267 }
1268 nvti_set_name (nvti, entity_text (name));
1269
1270 summary = entity_child (vt, "summary");
1271 if (summary)
1272 nvti_set_summary (nvti, entity_text (summary));
1273
1274 insight = entity_child (vt, "insight");
1275 if (insight)
1276 nvti_set_insight (nvti, entity_text (insight));
1277
1278 affected = entity_child (vt, "affected");
1279 if (affected)
1280 nvti_set_affected (nvti, entity_text (affected));
1281
1282 impact = entity_child (vt, "impact");
1283 if (impact)
1284 nvti_set_impact (nvti, entity_text (impact));
1285
1286 creation_time = entity_child (vt, "creation_time");
1287 if (creation_time)
1288 nvti_set_creation_time (nvti, strtol (entity_text (creation_time),
1289 NULL, 10));
1290
1291 modification_time = entity_child (vt, "modification_time");
1292 if (modification_time)
1293 nvti_set_modification_time (nvti, strtol (entity_text (modification_time),
1294 NULL, 10));
1295
1296 detection = entity_child (vt, "detection");
1297 if (detection)
1298 {
1299 const gchar *qod;
1300
1301 nvti_set_detection (nvti, entity_text (detection));
1302
1303 qod = entity_attribute (detection, "qod");
1304 if (qod == NULL)
1305 nvti_set_qod_type (nvti, entity_attribute (detection, "qod_type"));
1306 else
1307 nvti_set_qod (nvti, qod);
1308 }
1309
1310 solution = entity_child (vt, "solution");
1311 if (solution)
1312 {
1313 const gchar *type, *method;
1314
1315 nvti_set_solution (nvti, entity_text (solution));
1316
1317 type = entity_attribute (solution, "type");
1318 if (type == NULL)
1319 g_debug ("%s: SOLUTION missing type", __func__);
1320 else
1321 nvti_set_solution_type (nvti, type);
1322
1323 method = entity_attribute (solution, "method");
1324 if (method)
1325 nvti_set_solution_method (nvti, method);
1326 }
1327
1328 severities = entity_child (vt, "severities");
1329 if (severities == NULL)
1330 {
1331 g_warning ("%s: VT missing SEVERITIES", __func__);
1332 nvti_free (nvti);
1333 return NULL;
1334 }
1335
1336 children = severities->entities;
1337 while ((severity = first_entity (children)))
1338 {
1339 const gchar *severity_type;
1340
1341 severity_type = entity_attribute (severity, "type");
1342
1343 if (severity_type == NULL)
1344 {
1345 GString *debug = g_string_new ("");
1346 g_warning ("%s: SEVERITY missing type attribute", __func__);
1347 print_entity_to_string (severity, debug);
1348 g_warning ("%s: severity: %s", __func__, debug->str);
1349 g_string_free (debug, TRUE);
1350 }
1351 else
1352 {
1353 entity_t value;
1354
1355 value = entity_child (severity, "value");
1356
1357 if (!value)
1358 {
1359 GString *debug = g_string_new ("");
1360 g_warning ("%s: SEVERITY missing value element", __func__);
1361 print_entity_to_string (severity, debug);
1362 g_warning ("%s: severity: %s", __func__, debug->str);
1363 g_string_free (debug, TRUE);
1364 }
1365 else
1366 {
1367 entity_t origin, severity_date;
1368 double cvss_base_dbl;
1369 gchar * cvss_base;
1370 time_t parsed_severity_date;
1371
1372 cvss_base_dbl
1373 = get_cvss_score_from_base_metrics (entity_text (value));
1374
1375 origin
1376 = entity_child (severity, "origin");
1377 severity_date
1378 = entity_child (severity, "date");
1379
1380 if (severity_date)
1381 parsed_severity_date = strtol (entity_text (severity_date),
1382 NULL, 10);
1383 else
1384 parsed_severity_date = nvti_creation_time (nvti);
1385
1386 nvti_add_vtseverity (nvti,
1387 vtseverity_new (severity_type,
1388 origin ? entity_text (origin) : NULL,
1389 parsed_severity_date,
1390 cvss_base_dbl,
1391 entity_text (value)));
1392
1393 nvti_add_tag (nvti, "cvss_base_vector", entity_text (value));
1394
1395 cvss_base = g_strdup_printf ("%.1f",
1396 get_cvss_score_from_base_metrics (entity_text (value)));
1397 nvti_set_cvss_base (nvti, cvss_base);
1398 g_free (cvss_base);
1399 }
1400 }
1401
1402 children = next_entities (children);
1403 }
1404
1405 refs = entity_child (vt, "refs");
1406 if (refs)
1407 {
1408 children = refs->entities;
1409 while ((ref = first_entity (children)))
1410 {
1411 const gchar *ref_type;
1412
1413 ref_type = entity_attribute (ref, "type");
1414 if (ref_type == NULL)
1415 {
1416 GString *debug = g_string_new ("");
1417 g_warning ("%s: REF missing type attribute", __func__);
1418 print_entity_to_string (ref, debug);
1419 g_warning ("%s: ref: %s", __func__, debug->str);
1420 g_string_free (debug, TRUE);
1421 }
1422 else
1423 {
1424 const gchar *ref_id;
1425
1426 ref_id = entity_attribute (ref, "id");
1427 if (ref_id == NULL)
1428 {
1429 GString *debug = g_string_new ("");
1430 g_warning ("%s: REF missing id attribute", __func__);
1431 print_entity_to_string (ref, debug);
1432 g_warning ("%s: ref: %s", __func__, debug->str);
1433 g_string_free (debug, TRUE);
1434 }
1435 else
1436 {
1437 nvti_add_vtref (nvti, vtref_new (ref_type, ref_id, NULL));
1438 }
1439 }
1440
1441 children = next_entities (children);
1442 }
1443 }
1444
1445 custom = entity_child (vt, "custom");
1446 if (custom == NULL)
1447 {
1448 g_warning ("%s: VT missing CUSTOM", __func__);
1449 nvti_free (nvti);
1450 return NULL;
1451 }
1452
1453 family = entity_child (custom, "family");
1454 if (family == NULL)
1455 {
1456 g_warning ("%s: VT/CUSTOM missing FAMILY", __func__);
1457 nvti_free (nvti);
1458 return NULL;
1459 }
1460 nvti_set_family (nvti, entity_text (family));
1461
1462 category = entity_child (custom, "category");
1463 if (category == NULL)
1464 {
1465 g_warning ("%s: VT/CUSTOM missing CATEGORY", __func__);
1466 nvti_free (nvti);
1467 return NULL;
1468 }
1469 nvti_set_category (nvti, atoi (entity_text (category)));
1470
1471 deprecated = entity_child (custom, "deprecated");
1472 if (deprecated)
1473 {
1474 nvti_add_tag (nvti, "deprecated", entity_text (deprecated));
1475 }
1476
1477 return nvti;
1478 }
1479
1480 /**
1481 * @brief Update NVTs from VTs XML.
1482 *
1483 * @param[in] get_vts_response OSP GET_VTS response.
1484 * @param[in] scanner_feed_version Version of feed from scanner.
1485 *
1486 * @return 0 success, 1 VT integrity check failed, -1 error
1487 */
1488 static int
update_nvts_from_vts(entity_t * get_vts_response,const gchar * scanner_feed_version)1489 update_nvts_from_vts (entity_t *get_vts_response,
1490 const gchar *scanner_feed_version)
1491 {
1492 entity_t vts, vt;
1493 entities_t children;
1494 GList *preferences;
1495 int count_modified_vts, count_new_vts;
1496 time_t feed_version_epoch;
1497 const char *osp_vt_hash;
1498
1499 count_modified_vts = 0;
1500 count_new_vts = 0;
1501
1502 feed_version_epoch = nvts_feed_version_epoch();
1503
1504 vts = entity_child (*get_vts_response, "vts");
1505 if (vts == NULL)
1506 {
1507 g_warning ("%s: VTS missing", __func__);
1508 return -1;
1509 }
1510
1511 osp_vt_hash = entity_attribute (vts, "sha256_hash");
1512
1513 sql_begin_immediate ();
1514
1515 if (sql_int ("SELECT coalesce ((SELECT CAST (value AS INTEGER)"
1516 " FROM meta"
1517 " WHERE name = 'checked_preferences'),"
1518 " 0);")
1519 == 0)
1520 /* We're in the first NVT sync after migrating preference names.
1521 *
1522 * If a preference was removed from an NVT then the preference will be in
1523 * nvt_preferences in the old format, but we will not get a new version
1524 * of the preference name from the sync. For example "Alle Dateien
1525 * Auflisten" was removed from 1.3.6.1.4.1.25623.1.0.94023.
1526 *
1527 * If a preference was not in the migrator then the new version of the
1528 * preference would be inserted alongside the old version, resulting in a
1529 * duplicate when the name of the old version was corrected.
1530 *
1531 * To solve both cases, we remove all nvt_preferences. */
1532 sql ("TRUNCATE nvt_preferences;");
1533
1534 children = vts->entities;
1535 while ((vt = first_entity (children)))
1536 {
1537 nvti_t *nvti = nvti_from_vt (vt);
1538
1539 if (nvti == NULL)
1540 continue;
1541
1542 if (nvti_creation_time (nvti) > feed_version_epoch)
1543 count_new_vts += 1;
1544 else
1545 count_modified_vts += 1;
1546
1547 insert_nvt (nvti);
1548
1549 preferences = NULL;
1550 if (update_preferences_from_vt (vt, nvti_oid (nvti), &preferences))
1551 {
1552 sql_rollback ();
1553 return -1;
1554 }
1555 sql ("DELETE FROM nvt_preferences WHERE name LIKE '%s:%%';",
1556 nvti_oid (nvti));
1557 insert_nvt_preferences_list (preferences);
1558 g_list_free_full (preferences, g_free);
1559
1560 nvti_free (nvti);
1561 children = next_entities (children);
1562 }
1563
1564 set_nvts_check_time (count_new_vts, count_modified_vts);
1565
1566 set_nvts_feed_version (scanner_feed_version);
1567
1568 if (check_config_families ())
1569 g_warning ("%s: Error updating config families."
1570 " One or more configs refer to an outdated family of an NVT.",
1571 __func__);
1572 update_all_config_caches ();
1573
1574 g_info ("Updating VTs in database ... %i new VTs, %i changed VTs",
1575 count_new_vts, count_modified_vts);
1576
1577 sql_commit ();
1578
1579 if (osp_vt_hash && strcmp (osp_vt_hash, ""))
1580 {
1581 char *db_vts_hash;
1582
1583 /*
1584 * The hashed string used for verifying the NVTs generated as follows:
1585 *
1586 * For each NVT, sorted by OID, concatenate:
1587 * - the OID
1588 * - the modification time as seconds since epoch
1589 * - the preferences sorted as strings(!) and concatenated including:
1590 * - the id
1591 * - the name
1592 * - the default value (including choices for the "radio" type)
1593 *
1594 * All values are concatenated without a separator.
1595 */
1596 db_vts_hash
1597 = sql_string ("SELECT encode ("
1598 " digest (vts_verification_str (), 'SHA256'),"
1599 " 'hex'"
1600 " );");
1601
1602 if (strcmp (osp_vt_hash, db_vts_hash ? db_vts_hash : ""))
1603 {
1604 g_warning ("%s: SHA-256 hash of the VTs in the database (%s)"
1605 " does not match the one from the scanner (%s).",
1606 __func__, db_vts_hash, osp_vt_hash);
1607
1608 g_free (db_vts_hash);
1609 return 1;
1610 }
1611
1612 g_free (db_vts_hash);
1613 }
1614 else
1615 g_warning ("%s: No SHA-256 hash received from scanner, skipping check.",
1616 __func__);
1617
1618 return 0;
1619 }
1620
1621 /**
1622 * @brief Check that preference names are in the new format.
1623 *
1624 * @param[in] table Table name.
1625 */
1626 static void
check_old_preference_names(const gchar * table)1627 check_old_preference_names (const gchar *table)
1628 {
1629 /* 1.3.6.1.4.1.25623.1.0.14259:checkbox:Log nmap output
1630 * =>
1631 * 1.3.6.1.4.1.25623.1.0.14259:21:checkbox:Log nmap output */
1632
1633 sql ("UPDATE %s"
1634 " SET name = nvt_preferences.name"
1635 " FROM nvt_preferences"
1636 " WHERE %s.name ~ '.*:.*:.*'"
1637 " AND nvt_preferences.name ~ '.*:.*:.*:.*'"
1638 " AND %s.name = regexp_replace (nvt_preferences.name,"
1639 " E'([^:]+):[^:]+:(.*)', '\\1:\\2');",
1640 table,
1641 table,
1642 table,
1643 table);
1644 }
1645
1646 /**
1647 * @brief Update config preferences where the name has changed in the NVTs.
1648 *
1649 * @param[in] trash Whether to update the trash table.
1650 * @param[in] modification_time Time NVTs considered must be modified after.
1651 */
1652 static void
check_preference_names(int trash,time_t modification_time)1653 check_preference_names (int trash, time_t modification_time)
1654 {
1655 iterator_t prefs;
1656
1657 sql_begin_immediate ();
1658
1659 init_iterator (&prefs,
1660 "WITH new_pref_matches AS"
1661 " (SELECT substring (nvt_preferences.name,"
1662 " '^([^:]*:[^:]*)') || ':%%' AS match,"
1663 " name AS new_name"
1664 " FROM nvt_preferences"
1665 " WHERE substr (name, 0, position (':' IN name))"
1666 " IN (SELECT oid FROM nvts"
1667 " WHERE modification_time > %ld))"
1668 " SELECT c_prefs.id, c_prefs.name as old_name, new_name,"
1669 " configs%s.uuid AS config_id"
1670 " FROM config_preferences%s AS c_prefs"
1671 " JOIN new_pref_matches"
1672 " ON c_prefs.name LIKE new_pref_matches.match"
1673 " JOIN configs%s ON configs%s.id = c_prefs.config"
1674 " WHERE c_prefs.name != new_name;",
1675 modification_time,
1676 trash ? "_trash" : "",
1677 trash ? "_trash" : "",
1678 trash ? "_trash" : "",
1679 trash ? "_trash" : "");
1680
1681 while (next (&prefs))
1682 {
1683 resource_t preference;
1684 const char *old_name, *new_name, *config_id;
1685 gchar *quoted_new_name;
1686
1687 preference = iterator_int64 (&prefs, 0);
1688 old_name = iterator_string (&prefs, 1);
1689 new_name = iterator_string (&prefs, 2);
1690 config_id = iterator_string (&prefs, 3);
1691
1692 g_message ("Preference '%s' of %sconfig %s changed to '%s'",
1693 old_name,
1694 trash ? "trash " : "",
1695 config_id,
1696 new_name);
1697
1698 quoted_new_name = sql_quote (new_name);
1699
1700 sql ("UPDATE config_preferences%s"
1701 " SET name = '%s'"
1702 " WHERE id = %llu",
1703 trash ? "_trash " : "",
1704 quoted_new_name,
1705 preference);
1706
1707 g_free (quoted_new_name);
1708 }
1709
1710 sql_commit ();
1711
1712 cleanup_iterator (&prefs);
1713 }
1714
1715 /**
1716 * @brief Initialise an NVT severity iterator.
1717 *
1718 * @param[in] iterator Iterator.
1719 * @param[in] oid OID of NVT.
1720 */
1721 void
init_nvt_severity_iterator(iterator_t * iterator,const char * oid)1722 init_nvt_severity_iterator (iterator_t* iterator, const char *oid)
1723 {
1724 gchar *quoted_oid;
1725 quoted_oid = sql_quote (oid ? oid : "");
1726
1727 init_iterator (iterator,
1728 "SELECT type, origin, iso_time(date), score, value"
1729 " FROM vt_severities"
1730 " WHERE vt_oid = '%s'",
1731 quoted_oid);
1732
1733 g_free (quoted_oid);
1734 }
1735
1736 /**
1737 * @brief Gets the type from an NVT severity iterator.
1738 *
1739 * @param[in] iterator Iterator.
1740 *
1741 * @return The type of the severity.
1742 */
1743 DEF_ACCESS (nvt_severity_iterator_type, 0)
1744
1745 /**
1746 * @brief Gets the origin from an NVT severity iterator.
1747 *
1748 * @param[in] iterator Iterator.
1749 *
1750 * @return The origin of the severity.
1751 */
1752 DEF_ACCESS (nvt_severity_iterator_origin, 1);
1753
1754 /**
1755 * @brief Gets the date from an NVT severity iterator.
1756 *
1757 * @param[in] iterator Iterator.
1758 *
1759 * @return The date of the severity in ISO time format.
1760 */
1761 DEF_ACCESS (nvt_severity_iterator_date, 2);
1762
1763 /**
1764 * @brief Gets the score from an NVT severity iterator.
1765 *
1766 * @param[in] iterator Iterator.
1767 *
1768 * @return The score of the severity.
1769 */
1770 double
nvt_severity_iterator_score(iterator_t * iterator)1771 nvt_severity_iterator_score (iterator_t *iterator)
1772 {
1773 return iterator_double (iterator, 3);
1774 }
1775
1776 /**
1777 * @brief Gets the value from an NVT severity iterator.
1778 *
1779 * @param[in] iterator Iterator.
1780 *
1781 * @return The value of the severity in ISO time format.
1782 */
1783 DEF_ACCESS (nvt_severity_iterator_value, 4);
1784
1785 /**
1786 * @brief Update VTs via OSP.
1787 *
1788 * @param[in] update_socket Socket to use to contact scanner.
1789 * @param[in] db_feed_version Feed version from meta table.
1790 * @param[in] scanner_feed_version Feed version from scanner.
1791 *
1792 * @return 0 success, 1 VT integrity check failed, -1 error.
1793 */
1794 static int
update_nvt_cache_osp(const gchar * update_socket,gchar * db_feed_version,gchar * scanner_feed_version)1795 update_nvt_cache_osp (const gchar *update_socket, gchar *db_feed_version,
1796 gchar *scanner_feed_version)
1797 {
1798 osp_connection_t *connection;
1799 GSList *scanner_prefs;
1800 entity_t vts;
1801 osp_get_vts_opts_t get_vts_opts;
1802 time_t old_nvts_last_modified;
1803 int ret;
1804
1805 if (db_feed_version == NULL
1806 || strcmp (db_feed_version, "") == 0
1807 || strcmp (db_feed_version, "0") == 0)
1808 old_nvts_last_modified = 0;
1809 else
1810 old_nvts_last_modified
1811 = (time_t) sql_int64_0 ("SELECT max(modification_time) FROM nvts");
1812
1813 connection = osp_connection_new (update_socket, 0, NULL, NULL, NULL);
1814 if (!connection)
1815 {
1816 g_warning ("%s: failed to connect to %s (2)", __func__,
1817 update_socket);
1818 return -1;
1819 }
1820
1821 get_vts_opts = osp_get_vts_opts_default;
1822 if (db_feed_version)
1823 get_vts_opts.filter = g_strdup_printf ("modification_time>%s", db_feed_version);
1824 else
1825 get_vts_opts.filter = NULL;
1826 if (osp_get_vts_ext (connection, get_vts_opts, &vts))
1827 {
1828 g_warning ("%s: failed to get VTs", __func__);
1829 g_free (get_vts_opts.filter);
1830 return -1;
1831 }
1832 g_free (get_vts_opts.filter);
1833
1834 osp_connection_close (connection);
1835 ret = update_nvts_from_vts (&vts, scanner_feed_version);
1836 free_entity (vts);
1837 if (ret)
1838 return ret;
1839
1840 /* Update scanner preferences */
1841 connection = osp_connection_new (update_socket, 0, NULL, NULL, NULL);
1842 if (!connection)
1843 {
1844 g_warning ("%s: failed to connect to %s (3)",
1845 __func__, update_socket);
1846 return -1;
1847 }
1848
1849 scanner_prefs = NULL;
1850 if (osp_get_scanner_details (connection, NULL, &scanner_prefs))
1851 {
1852 g_warning ("%s: failed to get scanner preferences", __func__);
1853 osp_connection_close (connection);
1854 return -1;
1855 }
1856 else
1857 {
1858 GString *prefs_sql;
1859 GSList *point;
1860 int first;
1861
1862 point = scanner_prefs;
1863 first = 1;
1864
1865 osp_connection_close (connection);
1866 prefs_sql = g_string_new ("INSERT INTO nvt_preferences (name, value)"
1867 " VALUES");
1868 while (point)
1869 {
1870 osp_param_t *param;
1871 gchar *quoted_name, *quoted_value;
1872
1873 param = point->data;
1874 quoted_name = sql_quote (osp_param_id (param));
1875 quoted_value = sql_quote (osp_param_default (param));
1876
1877 g_string_append_printf (prefs_sql,
1878 "%s ('%s', '%s')",
1879 first ? "" : ",",
1880 quoted_name,
1881 quoted_value);
1882 first = 0;
1883 point = g_slist_next (point);
1884 g_free (quoted_name);
1885 g_free (quoted_value);
1886 }
1887 g_string_append (prefs_sql,
1888 " ON CONFLICT (name)"
1889 " DO UPDATE SET value = EXCLUDED.value;");
1890
1891 if (first == 0)
1892 {
1893 sql ("%s", prefs_sql->str);
1894 }
1895
1896 g_string_free (prefs_sql, TRUE);
1897 }
1898
1899 /* Update the cache of report counts. */
1900
1901 reports_clear_count_cache_dynamic ();
1902
1903 /* Tell the main process to update its NVTi cache. */
1904 sql ("UPDATE %s.meta SET value = 1 WHERE name = 'update_nvti_cache';",
1905 sql_schema ());
1906
1907 g_info ("Updating VTs in database ... done (%i VTs).",
1908 sql_int ("SELECT count (*) FROM nvts;"));
1909
1910 if (sql_int ("SELECT coalesce ((SELECT CAST (value AS INTEGER)"
1911 " FROM meta"
1912 " WHERE name = 'checked_preferences'),"
1913 " 0);")
1914 == 0)
1915 {
1916 check_old_preference_names ("config_preferences");
1917 check_old_preference_names ("config_preferences_trash");
1918
1919 /* Force update of names in new format in case hard-coded names
1920 * used by migrators are outdated */
1921 old_nvts_last_modified = 0;
1922
1923 sql ("INSERT INTO meta (name, value)"
1924 " VALUES ('checked_preferences', 1)"
1925 " ON CONFLICT (name) DO UPDATE SET value = EXCLUDED.value;");
1926 }
1927
1928 check_preference_names (0, old_nvts_last_modified);
1929 check_preference_names (1, old_nvts_last_modified);
1930
1931 check_whole_only_in_configs ();
1932
1933 return 0;
1934 }
1935
1936 /**
1937 * @brief Get the VTs feed version from an OSP scanner.
1938 *
1939 * @param[in] update_socket Socket to use to contact ospd-openvas scanner.
1940 *
1941 * @return The feed version or NULL on error.
1942 */
1943 static char *
osp_scanner_feed_version(const gchar * update_socket)1944 osp_scanner_feed_version (const gchar *update_socket)
1945 {
1946 osp_connection_t *connection;
1947 gchar *error;
1948 gchar *scanner_feed_version;
1949
1950 scanner_feed_version = NULL;
1951
1952 connection = osp_connection_new (update_socket, 0, NULL, NULL, NULL);
1953 if (!connection)
1954 {
1955 g_debug ("%s: failed to connect to %s", __func__, update_socket);
1956 return NULL;
1957 }
1958
1959 error = NULL;
1960 if (osp_get_vts_version (connection, &scanner_feed_version, &error))
1961 {
1962 g_debug ("%s: failed to get scanner_feed_version. %s",
1963 __func__, error ? : "");
1964 g_free (error);
1965 osp_connection_close (connection);
1966 return NULL;
1967 }
1968
1969 osp_connection_close (connection);
1970
1971 return scanner_feed_version;
1972 }
1973
1974 /**
1975 * @brief Check VTs feed version status via OSP, optionally get versions.
1976 *
1977 * @param[in] update_socket Socket to use to contact ospd-openvas scanner.
1978 * @param[out] db_feed_version_out Output of database feed version.
1979 * @param[out] scanner_feed_version_out Output of scanner feed version.
1980 *
1981 * @return 0 VTs feed current, -1 error, 1 VT update needed.
1982 */
1983 static int
nvts_feed_version_status_internal(const gchar * update_socket,gchar ** db_feed_version_out,gchar ** scanner_feed_version_out)1984 nvts_feed_version_status_internal (const gchar *update_socket,
1985 gchar **db_feed_version_out,
1986 gchar **scanner_feed_version_out)
1987 {
1988 gchar *db_feed_version, *scanner_feed_version;
1989
1990 if (db_feed_version_out)
1991 *db_feed_version_out = NULL;
1992 if (scanner_feed_version_out)
1993 *scanner_feed_version_out = NULL;
1994
1995 db_feed_version = nvts_feed_version ();
1996 g_debug ("%s: db_feed_version: %s", __func__, db_feed_version);
1997 if (db_feed_version_out && db_feed_version)
1998 *db_feed_version_out = g_strdup (db_feed_version);
1999
2000 scanner_feed_version = osp_scanner_feed_version (update_socket);
2001 g_debug ("%s: scanner_feed_version: %s", __func__, scanner_feed_version);
2002 if (scanner_feed_version == NULL)
2003 return -1;
2004 if (scanner_feed_version_out && scanner_feed_version)
2005 *scanner_feed_version_out = g_strdup (scanner_feed_version);
2006
2007 if ((db_feed_version == NULL)
2008 || strcmp (scanner_feed_version, db_feed_version))
2009 {
2010 g_free (db_feed_version);
2011 g_free (scanner_feed_version);
2012 return 1;
2013 }
2014
2015 return 0;
2016 }
2017
2018 /**
2019 * @brief Check VTs feed version status
2020 *
2021 * @return 0 VTs feed current, 1 VT update needed, -1 error.
2022 */
2023 int
nvts_feed_version_status()2024 nvts_feed_version_status ()
2025 {
2026 return nvts_feed_version_status_internal (get_osp_vt_update_socket (),
2027 NULL,
2028 NULL);
2029 }
2030
2031 /**
2032 * @brief Update VTs via OSP.
2033 *
2034 * Expect to be called in the child after a fork.
2035 *
2036 * @param[in] update_socket Socket to use to contact ospd-openvas scanner.
2037 *
2038 * @return 0 success, -1 error, 1 VT integrity check failed.
2039 */
2040 int
manage_update_nvt_cache_osp(const gchar * update_socket)2041 manage_update_nvt_cache_osp (const gchar *update_socket)
2042 {
2043 gchar *db_feed_version, *scanner_feed_version;
2044 int ret;
2045
2046 /* Re-open DB after fork. */
2047
2048 reinit_manage_process ();
2049 manage_session_init (current_credentials.uuid);
2050
2051 /* Try update VTs. */
2052
2053 ret = nvts_feed_version_status_internal (update_socket,
2054 &db_feed_version,
2055 &scanner_feed_version);
2056 if (ret == 1)
2057 {
2058 g_info ("OSP service has different VT status (version %s)"
2059 " from database (version %s, %i VTs). Starting update ...",
2060 scanner_feed_version, db_feed_version,
2061 sql_int ("SELECT count (*) FROM nvts;"));
2062
2063 ret = update_nvt_cache_osp (update_socket, db_feed_version,
2064 scanner_feed_version);
2065
2066 g_free (db_feed_version);
2067 g_free (scanner_feed_version);
2068 return ret;
2069 }
2070
2071 return ret;
2072 }
2073
2074 /**
2075 * @brief Sync NVTs if newer NVTs are available.
2076 *
2077 * @param[in] fork_update_nvt_cache Function to do the update.
2078 */
2079 void
manage_sync_nvts(int (* fork_update_nvt_cache)())2080 manage_sync_nvts (int (*fork_update_nvt_cache) ())
2081 {
2082 fork_update_nvt_cache ();
2083 }
2084
2085 /**
2086 * @brief Update or rebuild NVT db.
2087 *
2088 * Caller must get the lock.
2089 *
2090 * @param[in] update 0 rebuild, else update.
2091 *
2092 * @return 0 success, -1 error, -4 no osp update socket.
2093 */
2094 int
update_or_rebuild_nvts(int update)2095 update_or_rebuild_nvts (int update)
2096 {
2097 const char *osp_update_socket;
2098 gchar *db_feed_version, *scanner_feed_version;
2099 osp_connection_t *connection;
2100 int ret;
2101 gchar *error;
2102
2103 if (check_osp_vt_update_socket ())
2104 {
2105 printf ("No OSP VT update socket found."
2106 " Use --osp-vt-update or change the 'OpenVAS Default'"
2107 " scanner to use the main ospd-openvas socket.\n");
2108 return -4;
2109 }
2110
2111 osp_update_socket = get_osp_vt_update_socket ();
2112 if (osp_update_socket == NULL)
2113 {
2114 printf ("No OSP VT update socket set.\n");
2115 return -4;
2116 }
2117
2118 db_feed_version = nvts_feed_version ();
2119 g_debug ("%s: db_feed_version: %s", __func__, db_feed_version);
2120
2121 connection = osp_connection_new (osp_update_socket, 0, NULL, NULL, NULL);
2122 if (!connection)
2123 {
2124 printf ("Failed to connect to %s.\n", osp_update_socket);
2125 return -1;
2126 }
2127
2128 error = NULL;
2129 if (osp_get_vts_version (connection, &scanner_feed_version, &error))
2130 {
2131 printf ("Failed to get scanner_version. %s\n", error ? : "");
2132 g_free (error);
2133 return -1;
2134 }
2135 g_debug ("%s: scanner_feed_version: %s", __func__, scanner_feed_version);
2136
2137 osp_connection_close (connection);
2138
2139 if (update == 0)
2140 {
2141 sql ("TRUNCATE nvts;");
2142 sql ("TRUNCATE nvt_preferences;");
2143 set_nvts_feed_version ("0");
2144 }
2145
2146 ret = update_nvt_cache_osp (osp_update_socket, NULL, scanner_feed_version);
2147 if (ret)
2148 {
2149 return -1;
2150 }
2151
2152 return 0;
2153 }
2154
2155 /**
2156 * @brief Rebuild NVT db.
2157 *
2158 * @param[in] log_config Log configuration.
2159 * @param[in] database Location of manage database.
2160 *
2161 * @return 0 success, 1 VT integrity check failed, -1 error,
2162 * -2 database is wrong version,
2163 * -3 database needs to be initialised from server, -5 sync active.
2164 */
2165 int
manage_rebuild(GSList * log_config,const db_conn_info_t * database)2166 manage_rebuild (GSList *log_config, const db_conn_info_t *database)
2167 {
2168 int ret;
2169 static lockfile_t lockfile;
2170
2171 g_info (" Rebuilding NVTs.");
2172
2173 switch (feed_lockfile_lock_timeout (&lockfile))
2174 {
2175 case 1:
2176 printf ("A feed sync is already running.\n");
2177 return -5;
2178 case -1:
2179 printf ("Error getting sync lock.\n");
2180 return -1;
2181 }
2182
2183 ret = manage_option_setup (log_config, database);
2184 if (ret)
2185 {
2186 feed_lockfile_unlock (&lockfile);
2187 return ret;
2188 }
2189
2190 sql_begin_immediate ();
2191 ret = update_or_rebuild_nvts (0);
2192 if (ret)
2193 sql_rollback ();
2194 else
2195 sql_commit ();
2196
2197 feed_lockfile_unlock (&lockfile);
2198 manage_option_cleanup ();
2199
2200 return ret;
2201 }
2202
2203 /**
2204 * @brief Dump the string used to calculate the VTs verification hash
2205 * to stdout.
2206 *
2207 * @param[in] log_config Log configuration.
2208 * @param[in] database Location of manage database.
2209 *
2210 * @return 0 success, -1 error, -2 database is wrong version,
2211 * -3 database needs to be initialised from server, -5 sync active.
2212 */
2213 int
manage_dump_vt_verification(GSList * log_config,const db_conn_info_t * database)2214 manage_dump_vt_verification (GSList *log_config,
2215 const db_conn_info_t *database)
2216 {
2217 int ret;
2218 static lockfile_t lockfile;
2219 char *verification_str;
2220
2221 switch (feed_lockfile_lock_timeout (&lockfile))
2222 {
2223 case 1:
2224 printf ("A feed sync is already running.\n");
2225 return -5;
2226 case -1:
2227 printf ("Error getting sync lock.\n");
2228 return -1;
2229 }
2230
2231 ret = manage_option_setup (log_config, database);
2232 if (ret)
2233 {
2234 feed_lockfile_unlock (&lockfile);
2235 return ret;
2236 }
2237
2238 verification_str = sql_string ("SELECT vts_verification_str ();");
2239 printf ("%s\n", verification_str);
2240
2241 feed_lockfile_unlock (&lockfile);
2242 manage_option_cleanup ();
2243
2244 return 0;
2245 }