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.c
21 * @brief The Greenbone Vulnerability Manager management layer.
22 *
23 * This file defines a management layer, for implementing
24 * Managers such as the Greenbone Vulnerability Manager daemon.
25 *
26 * This layer provides facilities for storing and manipulating user
27 * data (credentials, targets, tasks, reports, schedules, roles, etc)
28 * and general security data (NVTs, CVEs, etc).
29 * Task manipulation includes controlling external facilities such as
30 * OSP scanners.
31 *
32 * Simply put, the daemon's GMP implementation uses this layer to do the work.
33 */
34
35 /**
36 * @brief Enable extra functions.
37 *
38 * time.h in glibc2 needs this for strptime.
39 */
40 #define _XOPEN_SOURCE
41
42 /**
43 * @brief Enable extra GNU functions.
44 *
45 * pthread_sigmask () needs this with glibc < 2.19
46 */
47 #define _GNU_SOURCE
48
49 #include "gmp_base.h"
50 #include "manage.h"
51 #include "manage_acl.h"
52 #include "manage_configs.h"
53 #include "manage_port_lists.h"
54 #include "manage_report_formats.h"
55 #include "manage_sql.h"
56 #include "manage_sql_secinfo.h"
57 #include "manage_sql_nvts.h"
58 #include "manage_sql_tickets.h"
59 #include "manage_sql_tls_certificates.h"
60 #include "utils.h"
61
62 #include <assert.h>
63 #include <ctype.h>
64 #include <errno.h>
65 #include <dirent.h>
66 #include <fcntl.h>
67 #include <glib.h>
68 #include <gnutls/x509.h> /* for gnutls_x509_crt_... */
69 #include <math.h>
70 #include <locale.h>
71 #include <stdio.h>
72 #include <stdlib.h>
73 #include <string.h>
74 #include <strings.h>
75 #include <sys/file.h>
76 #include <sys/stat.h>
77 #include <sys/types.h>
78 #include <sys/socket.h>
79 #include <sys/wait.h>
80 #include <time.h>
81 #include <unistd.h>
82
83 #include <gvm/base/hosts.h>
84 #include <gvm/base/proctitle.h>
85 #include <gvm/osp/osp.h>
86 #include <gvm/util/fileutils.h>
87 #include <gvm/util/serverutils.h>
88 #include <gvm/util/uuidutils.h>
89 #include <gvm/gmp/gmp.h>
90
91 #undef G_LOG_DOMAIN
92 /**
93 * @brief GLib log domain.
94 */
95 #define G_LOG_DOMAIN "md manage"
96
97 /**
98 * @brief CPE selection stylesheet location.
99 */
100 #define CPE_GETBYNAME_XSL GVM_SCAP_RES_DIR "/cpe_getbyname.xsl"
101
102 /**
103 * @brief CVE selection stylesheet location.
104 */
105 #define CVE_GETBYNAME_XSL GVM_SCAP_RES_DIR "/cve_getbyname.xsl"
106
107 /**
108 * @brief OVALDEF selection stylesheet location.
109 */
110 #define OVALDEF_GETBYNAME_XSL GVM_SCAP_RES_DIR "/ovaldef_getbyname.xsl"
111
112 /**
113 * @brief CERT_BUND_ADV selection stylesheet location.
114 */
115 #define CERT_BUND_ADV_GETBYNAME_XSL GVM_CERT_RES_DIR "/cert_bund_getbyname.xsl"
116
117 /**
118 * @brief DFN_CERT_ADV selection stylesheet location.
119 */
120 #define DFN_CERT_ADV_GETBYNAME_XSL GVM_CERT_RES_DIR "/dfn_cert_getbyname.xsl"
121
122 /**
123 * @brief CPE dictionary location.
124 */
125 #define CPE_DICT_FILENAME GVM_SCAP_DATA_DIR "/official-cpe-dictionary_v2.2.xml"
126
127 /**
128 * @brief CVE data files location format string.
129 *
130 * %d should be the year expressed as YYYY.
131 */
132 #define CVE_FILENAME_FMT GVM_SCAP_DATA_DIR "/nvdcve-2.0-%d.xml"
133
134 /**
135 * @brief CERT-Bund data files location format string.
136 *
137 * %d should be the year without the century (expressed as YY),
138 */
139 #define CERT_BUND_ADV_FILENAME_FMT GVM_CERT_DATA_DIR "/CB-K%02d.xml"
140
141 /**
142 * @brief DFN-CERT data files location format string.
143 *
144 * First %d should be the year expressed as YYYY,
145 * second %d should be should be Month expressed as MM.
146 */
147 #define DFN_CERT_ADV_FILENAME_FMT GVM_CERT_DATA_DIR "/dfn-cert-%04d.xml"
148
149 /**
150 * @brief SCAP timestamp location.
151 */
152 #define SCAP_TIMESTAMP_FILENAME GVM_SCAP_DATA_DIR "/timestamp"
153
154 /**
155 * @brief CERT timestamp location.
156 */
157 #define CERT_TIMESTAMP_FILENAME GVM_CERT_DATA_DIR "/timestamp"
158
159 /**
160 * @brief Default for Scanner max_checks preference.
161 */
162 #define MAX_CHECKS_DEFAULT "4"
163
164 /**
165 * @brief Default for Scanner max_hosts preference.
166 */
167 #define MAX_HOSTS_DEFAULT "20"
168
169 /**
170 * @brief Path to the feed lock file
171 */
172 static gchar *feed_lock_path = NULL;
173
174 /**
175 * @brief Number of seconds to wait for the feed lock to be released.
176 */
177 static int feed_lock_timeout = 0;
178
179 /**
180 * @brief Path to the relay mapper executable, NULL to disable relays.
181 */
182 static gchar *relay_mapper_path = NULL;
183
184 /**
185 * @brief Whether to migrate sensors if relays do not match.
186 */
187 static int relay_migrate_sensors = 0;
188
189 /**
190 * @brief Number of minutes before overdue tasks timeout.
191 */
192 static int schedule_timeout = SCHEDULE_TIMEOUT_DEFAULT;
193
194 /**
195 * @brief Default number of auto retries if scanner connection is
196 * lost in a running task.
197 */
198 static int scanner_connection_retry = SCANNER_CONNECTION_RETRY_DEFAULT;
199
200
201 /* Certificate and key management. */
202
203 /**
204 * @brief Truncate a certificate, removing extra data.
205 *
206 * @param[in] certificate The certificate.
207 *
208 * @return The truncated certificate as a newly allocated string or NULL.
209 */
210 gchar *
truncate_certificate(const gchar * certificate)211 truncate_certificate (const gchar* certificate)
212 {
213 GString *cert_buffer;
214 gchar *current_pos, *cert_start, *cert_end;
215 gboolean done = FALSE;
216 cert_buffer = g_string_new ("");
217
218 current_pos = (gchar *) certificate;
219 while (done == FALSE && *current_pos != '\0')
220 {
221 cert_start = NULL;
222 cert_end = NULL;
223 if (g_str_has_prefix (current_pos,
224 "-----BEGIN CERTIFICATE-----"))
225 {
226 cert_start = current_pos;
227 cert_end = strstr (cert_start,
228 "-----END CERTIFICATE-----");
229 if (cert_end)
230 cert_end += strlen ("-----END CERTIFICATE-----");
231 else
232 done = TRUE;
233 }
234 else if (g_str_has_prefix (current_pos,
235 "-----BEGIN TRUSTED CERTIFICATE-----"))
236 {
237 cert_start = current_pos;
238 cert_end = strstr (cert_start,
239 "-----END TRUSTED CERTIFICATE-----");
240 if (cert_end)
241 cert_end += strlen ("-----END TRUSTED CERTIFICATE-----");
242 else
243 done = TRUE;
244 }
245 else if (g_str_has_prefix (current_pos,
246 "-----BEGIN PKCS7-----"))
247 {
248 cert_start = current_pos;
249 cert_end = strstr (cert_start,
250 "-----END PKCS7-----");
251 if (cert_end)
252 cert_end += strlen ("-----END PKCS7-----");
253 else
254 done = TRUE;
255 }
256
257 if (cert_start && cert_end)
258 {
259 g_string_append_len (cert_buffer, cert_start, cert_end - cert_start);
260 g_string_append_c (cert_buffer, '\n');
261 }
262 current_pos++;
263 }
264
265 return g_string_free (cert_buffer, cert_buffer->len == 0);
266 }
267
268 /**
269 * @brief Truncate a private key, removing extra data.
270 *
271 * @param[in] private_key The private key.
272 *
273 * @return The truncated private key as a newly allocated string or NULL.
274 */
275 gchar *
truncate_private_key(const gchar * private_key)276 truncate_private_key (const gchar* private_key)
277 {
278 gchar *key_start, *key_end;
279 key_end = NULL;
280 key_start = strstr (private_key, "-----BEGIN RSA PRIVATE KEY-----");
281 if (key_start)
282 {
283 key_end = strstr (key_start, "-----END RSA PRIVATE KEY-----");
284
285 if (key_end)
286 key_end += strlen ("-----END RSA PRIVATE KEY-----");
287 else
288 return NULL;
289 }
290
291 if (key_start == NULL)
292 {
293 key_start = strstr (private_key, "-----BEGIN DSA PRIVATE KEY-----");
294 if (key_start)
295 {
296 key_end = strstr (key_start, "-----END DSA PRIVATE KEY-----");
297
298 if (key_end)
299 key_end += strlen ("-----END DSA PRIVATE KEY-----");
300 else
301 return NULL;
302 }
303 }
304
305 if (key_start == NULL)
306 {
307 key_start = strstr (private_key, "-----BEGIN EC PRIVATE KEY-----");
308 if (key_start)
309 {
310 key_end = strstr (key_start, "-----END EC PRIVATE KEY-----");
311
312 if (key_end)
313 key_end += strlen ("-----END EC PRIVATE KEY-----");
314 else
315 return NULL;
316 }
317 }
318
319 if (key_end && key_end[0] == '\n')
320 key_end++;
321
322 if (key_start == NULL || key_end == NULL)
323 return NULL;
324 else
325 return g_strndup (key_start, key_end - key_start);
326 }
327
328 /**
329 * @brief Gathers info from a certificate.
330 *
331 * @param[in] certificate The certificate to get data from.
332 * @param[in] certificate_len Length of certificate, -1: null-terminated
333 * @param[out] activation_time Pointer to write activation time to.
334 * @param[out] expiration_time Pointer to write expiration time to.
335 * @param[out] md5_fingerprint Pointer for newly allocated MD5 fingerprint.
336 * @param[out] sha256_fingerprint Pointer for newly allocated SHA-256
337 * fingerprint.
338 * @param[out] subject Pointer for newly allocated subject DN.
339 * @param[out] issuer Pointer for newly allocated issuer DN.
340 * @param[out] serial Pointer for newly allocated serial.
341 * @param[out] certificate_format Pointer to certificate format.
342 *
343 * @return 0 success, -1 error.
344 */
345 int
get_certificate_info(const gchar * certificate,gssize certificate_len,time_t * activation_time,time_t * expiration_time,gchar ** md5_fingerprint,gchar ** sha256_fingerprint,gchar ** subject,gchar ** issuer,gchar ** serial,gnutls_x509_crt_fmt_t * certificate_format)346 get_certificate_info (const gchar* certificate, gssize certificate_len,
347 time_t* activation_time, time_t* expiration_time,
348 gchar** md5_fingerprint, gchar **sha256_fingerprint,
349 gchar **subject, gchar** issuer, gchar **serial,
350 gnutls_x509_crt_fmt_t *certificate_format)
351 {
352 gchar *cert_truncated;
353 gnutls_x509_crt_fmt_t certificate_format_internal;
354
355 cert_truncated = NULL;
356 if (activation_time)
357 *activation_time = -1;
358 if (expiration_time)
359 *expiration_time = -1;
360 if (md5_fingerprint)
361 *md5_fingerprint = NULL;
362 if (sha256_fingerprint)
363 *sha256_fingerprint = NULL;
364 if (subject)
365 *subject = NULL;
366 if (issuer)
367 *issuer = NULL;
368 if (serial)
369 *serial = NULL;
370 if (certificate_format)
371 *certificate_format = GNUTLS_X509_FMT_DER;
372
373 if (certificate)
374 {
375 int err;
376 gnutls_datum_t cert_datum;
377 gnutls_x509_crt_t gnutls_cert;
378 static const gchar* begin_str = "-----BEGIN ";
379
380 if (g_strstr_len (certificate, certificate_len, begin_str))
381 {
382 cert_truncated = truncate_certificate (certificate);
383 if (cert_truncated == NULL)
384 {
385 return -1;
386 }
387 certificate_format_internal = GNUTLS_X509_FMT_PEM;
388 }
389 else
390 {
391 if (certificate_len < 0)
392 {
393 g_warning ("%s: PEM encoded certificate expected if"
394 " certificate_length is negative",
395 __func__);
396 return -1;
397 }
398
399 cert_truncated = g_memdup (certificate, certificate_len);
400 certificate_format_internal = GNUTLS_X509_FMT_DER;
401 }
402
403 cert_datum.data = (unsigned char*) cert_truncated;
404 if (certificate_len < 0)
405 cert_datum.size = strlen (cert_truncated);
406 else
407 cert_datum.size = certificate_len;
408
409 gnutls_x509_crt_init (&gnutls_cert);
410 err = gnutls_x509_crt_import (gnutls_cert, &cert_datum,
411 certificate_format_internal);
412 if (err)
413 {
414 g_free (cert_truncated);
415 return -1;
416 }
417
418 if (certificate_format)
419 *certificate_format = certificate_format_internal;
420
421 if (activation_time)
422 {
423 *activation_time
424 = gnutls_x509_crt_get_activation_time (gnutls_cert);
425 }
426
427 if (expiration_time)
428 {
429 *expiration_time
430 = gnutls_x509_crt_get_expiration_time (gnutls_cert);
431 }
432
433 if (md5_fingerprint)
434 {
435 int i;
436 size_t buffer_size = 16;
437 unsigned char buffer[buffer_size];
438 GString *string;
439
440 string = g_string_new ("");
441
442 gnutls_x509_crt_get_fingerprint (gnutls_cert, GNUTLS_DIG_MD5,
443 buffer, &buffer_size);
444
445 for (i = 0; i < buffer_size; i++)
446 {
447 if (i != 0)
448 {
449 g_string_append_c (string, ':');
450 }
451 g_string_append_printf (string, "%02x", buffer[i]);
452 }
453
454 *md5_fingerprint = string->str;
455 g_string_free (string, FALSE);
456 }
457
458 if (sha256_fingerprint)
459 {
460 int i;
461 size_t buffer_size = 32;
462 unsigned char buffer[buffer_size];
463 GString *string;
464
465 string = g_string_new ("");
466
467 gnutls_x509_crt_get_fingerprint (gnutls_cert, GNUTLS_DIG_SHA256,
468 buffer, &buffer_size);
469
470 for (i = 0; i < buffer_size; i++)
471 {
472 g_string_append_printf (string, "%02X", buffer[i]);
473 }
474
475 *sha256_fingerprint = string->str;
476 g_string_free (string, FALSE);
477 }
478
479 if (subject)
480 {
481 size_t buffer_size = 0;
482 gchar *buffer;
483 gnutls_x509_crt_get_dn (gnutls_cert, NULL, &buffer_size);
484 buffer = g_malloc (buffer_size);
485 gnutls_x509_crt_get_dn (gnutls_cert, buffer, &buffer_size);
486
487 *subject = buffer;
488 }
489
490 if (issuer)
491 {
492 size_t buffer_size = 0;
493 gchar *buffer;
494 gnutls_x509_crt_get_issuer_dn (gnutls_cert, NULL, &buffer_size);
495 buffer = g_malloc (buffer_size);
496 gnutls_x509_crt_get_issuer_dn (gnutls_cert, buffer, &buffer_size);
497
498 *issuer = buffer;
499 }
500
501 if (serial)
502 {
503 int i;
504 size_t buffer_size = 0;
505 gchar* buffer;
506 GString *string;
507
508 string = g_string_new ("");
509
510 gnutls_x509_crt_get_serial (gnutls_cert, NULL, &buffer_size);
511 buffer = g_malloc (buffer_size);
512 gnutls_x509_crt_get_serial (gnutls_cert, buffer, &buffer_size);
513
514 for (i = 0; i < buffer_size; i++)
515 {
516 g_string_append_printf (string, "%02X", buffer[i]);
517 }
518
519 *serial = string->str;
520 g_string_free (string, FALSE);
521 }
522
523 gnutls_x509_crt_deinit (gnutls_cert);
524 g_free (cert_truncated);
525 }
526 return 0;
527 }
528
529 /**
530 * @brief Converts a certificate time to an ISO time string.
531 *
532 * @param[in] time The time as a time_t.
533 *
534 * @return Newly allocated string.
535 */
536 gchar *
certificate_iso_time(time_t time)537 certificate_iso_time (time_t time)
538 {
539 if (time == 0)
540 return g_strdup ("unlimited");
541 else if (time == -1)
542 return g_strdup ("unknown");
543 else
544 return g_strdup (iso_time (&time));
545 }
546
547 /**
548 * @brief Tests the activation and expiration time of a certificate.
549 *
550 * @param[in] activates Activation time.
551 * @param[in] expires Expiration time.
552 *
553 * @return Static status string.
554 */
555 const gchar *
certificate_time_status(time_t activates,time_t expires)556 certificate_time_status (time_t activates, time_t expires)
557 {
558 time_t now;
559 time (&now);
560
561 if (activates == -1 || expires == -1)
562 return "unknown";
563 else if (activates > now)
564 return "inactive";
565 else if (expires != 0 && expires < now)
566 return "expired";
567 else
568 return "valid";
569 }
570
571
572 /* Helpers. */
573
574 /**
575 * @brief Truncates text to a maximum length, optionally appends a suffix.
576 *
577 * Note: The string is modified in place instead of allocating a new one.
578 * With the xml option the function will avoid cutting the string in the middle
579 * of XML entities, but element tags will be ignored.
580 *
581 * @param[in,out] string The string to truncate.
582 * @param[in] max_len The maximum length in bytes.
583 * @param[in] xml Whether to preserve XML entities.
584 * @param[in] suffix The suffix to append when the string is shortened.
585 */
586 static void
truncate_text(gchar * string,size_t max_len,gboolean xml,const char * suffix)587 truncate_text (gchar *string, size_t max_len, gboolean xml, const char *suffix)
588 {
589 if (string == NULL)
590 return;
591
592 if (strlen (string) <= max_len)
593 return;
594 else
595 {
596 size_t offset;
597 offset = max_len;
598
599 // Move offset according according to suffix length
600 if (suffix && strlen (suffix) < max_len)
601 offset = offset - strlen (suffix);
602
603 // Go back to start of UTF-8 character
604 if (offset > 0 && (string[offset] & 0x80) == 0x80)
605 {
606 offset = g_utf8_find_prev_char (string, string + offset) - string;
607 }
608
609 if (xml)
610 {
611 // If the offset is in the middle of an XML entity,
612 // move the offset to the start of that entity.
613 ssize_t entity_start_offset = offset;
614
615 while (entity_start_offset >= 0
616 && string[entity_start_offset] != '&')
617 {
618 entity_start_offset --;
619 }
620
621 if (entity_start_offset >= 0)
622 {
623 char *entity_end = strchr(string + entity_start_offset, ';');
624 if (entity_end && (entity_end - string) >= offset)
625 offset = entity_start_offset;
626 }
627 }
628
629 // Truncate the string, inserting the suffix if applicable
630 if (suffix && strlen (suffix) < max_len)
631 sprintf (string + offset, "%s", suffix);
632 else
633 string[offset] = '\0';
634 }
635 }
636
637 /**
638 * @brief XML escapes text truncating to a maximum length with a suffix.
639 *
640 * Note: The function will avoid cutting the string in the middle of XML
641 * entities.
642 *
643 * @param[in] string The string to truncate.
644 * @param[in] max_len The maximum length in bytes.
645 * @param[in] suffix The suffix to append when the string is shortened.
646 *
647 * @return Newly allocated string with XML escaped, truncated text.
648 */
649 gchar *
xml_escape_text_truncated(const char * string,size_t max_len,const char * suffix)650 xml_escape_text_truncated (const char *string, size_t max_len,
651 const char *suffix)
652 {
653 gchar *escaped;
654 gssize orig_len;
655
656 orig_len = strlen (string);
657 if (orig_len <= max_len)
658 escaped = g_markup_escape_text (string, -1);
659 else
660 {
661 gchar *offset_next;
662 ssize_t offset;
663
664 offset_next = g_utf8_find_next_char (string + max_len,
665 string + orig_len);
666 offset = offset_next - string;
667 escaped = g_markup_escape_text (string, offset);
668 }
669
670 truncate_text (escaped, max_len, TRUE, suffix);
671 return escaped;
672 }
673
674 /**
675 * @brief Return the plural name of a resource type.
676 *
677 * @param[in] type Resource type.
678 *
679 * @return Plural name of type.
680 */
681 const char *
type_name_plural(const char * type)682 type_name_plural (const char* type)
683 {
684 if (type == NULL)
685 return "ERROR";
686
687 if (strcasecmp (type, "cpe") == 0)
688 return "CPEs";
689 if (strcasecmp (type, "cve") == 0)
690 return "CVEs";
691 if (strcasecmp (type, "cert_bund_adv") == 0)
692 return "CERT-Bund Advisories";
693 if (strcasecmp (type, "dfn_cert_adv") == 0)
694 return "DFN-CERT Advisories";
695 if (strcasecmp (type, "nvt") == 0)
696 return "NVTs";
697 if (strcasecmp (type, "ovaldef") == 0)
698 return "OVAL Definitions";
699
700 return "ERROR";
701 }
702
703 /**
704 * @brief Return the name of a resource type.
705 *
706 * @param[in] type Resource type.
707 *
708 * @return Name of type.
709 */
710 const char *
type_name(const char * type)711 type_name (const char* type)
712 {
713 if (type == NULL)
714 return "ERROR";
715
716 if (strcasecmp (type, "cpe") == 0)
717 return "CPE";
718 if (strcasecmp (type, "cve") == 0)
719 return "CVE";
720 if (strcasecmp (type, "cert_bund_adv") == 0)
721 return "CERT-Bund Advisory";
722 if (strcasecmp (type, "dfn_cert_adv") == 0)
723 return "DFN-CERT Advisory";
724 if (strcasecmp (type, "nvt") == 0)
725 return "NVT";
726 if (strcasecmp (type, "ovaldef") == 0)
727 return "OVAL Definition";
728
729 return "ERROR";
730 }
731
732 /**
733 * @brief Check if a type is a SCAP type.
734 *
735 * @param[in] type Resource type.
736 *
737 * @return Name of type.
738 */
739 int
type_is_scap(const char * type)740 type_is_scap (const char* type)
741 {
742 return (strcasecmp (type, "cpe") == 0)
743 || (strcasecmp (type, "cve") == 0)
744 || (strcasecmp (type, "ovaldef") == 0);
745 }
746
747 /**
748 * @brief Check whether a resource is available.
749 *
750 * @param[in] type Type.
751 * @param[out] resource Resource.
752 * @param[out] permission Permission required for this operation.
753 *
754 * @return 0 success, -1 error, 99 permission denied.
755 */
756 static int
check_available(const gchar * type,resource_t resource,const gchar * permission)757 check_available (const gchar *type, resource_t resource,
758 const gchar *permission)
759 {
760 if (resource)
761 {
762 gchar *uuid;
763 resource_t found;
764
765 uuid = resource_uuid (type, resource);
766 if (find_resource_with_permission (type, uuid, &found, permission, 0))
767 {
768 g_free (uuid);
769 return -1;
770 }
771 g_free (uuid);
772 if (found == 0)
773 return 99;
774
775 return 0;
776 }
777
778 return -1;
779 }
780
781 /**
782 * @brief Check if a scanner type is valid.
783 *
784 * @param[in] scanner_type Scanner type.
785 *
786 * @return 1 if valid, else 0.
787 */
788 int
scanner_type_valid(scanner_type_t scanner_type)789 scanner_type_valid (scanner_type_t scanner_type)
790 {
791 if (scanner_type > SCANNER_TYPE_NONE
792 && scanner_type < SCANNER_TYPE_MAX
793 && scanner_type != 4)
794 return 1;
795 return 0;
796 }
797
798
799 /* Severity related functions. */
800
801 /**
802 * @brief Get the message type of a threat.
803 *
804 * @param threat Threat.
805 *
806 * @return Static message type name if threat names a threat, else NULL.
807 */
808 const char *
threat_message_type(const char * threat)809 threat_message_type (const char *threat)
810 {
811 if (strcasecmp (threat, "High") == 0)
812 return "Alarm";
813 if (strcasecmp (threat, "Medium") == 0)
814 return "Alarm";
815 if (strcasecmp (threat, "Low") == 0)
816 return "Alarm";
817 if (strcasecmp (threat, "Log") == 0)
818 return "Log Message";
819 if (strcasecmp (threat, "Error") == 0)
820 return "Error Message";
821 if (strcasecmp (threat, "False Positive") == 0)
822 return "False Positive";
823 return NULL;
824 }
825
826 /**
827 * @brief Check whether a severity falls within a threat level.
828 *
829 * @param[in] severity Severity.
830 * @param[in] level Threat level.
831 *
832 * @return 1 if in level, else 0.
833 */
834 int
severity_in_level(double severity,const char * level)835 severity_in_level (double severity, const char *level)
836 {
837 if (strcmp (level, "high") == 0)
838 return severity >= 7 && severity <= 10;
839 else if (strcmp (level, "medium") == 0)
840 return severity >= 4 && severity < 7;
841 else if (strcmp (level, "low") == 0)
842 return severity > 0 && severity < 4;
843 else if (strcmp (level, "none") == 0 || strcmp (level, "log") == 0)
844 return severity == 0;
845
846 return 0;
847 }
848
849 /**
850 * @brief Get the threat level matching a severity score.
851 *
852 * @param[in] severity severity score
853 * @param[in] mode 0 for normal levels, 1 to use "Alarm" for severity > 0.0
854 *
855 * @return the level as a static string
856 */
857 const char*
severity_to_level(double severity,int mode)858 severity_to_level (double severity, int mode)
859 {
860 if (severity == SEVERITY_LOG)
861 return "Log";
862 else if (severity == SEVERITY_FP)
863 return "False Positive";
864 else if (severity == SEVERITY_ERROR)
865 return "Error";
866 else if (severity > 0.0 && severity <= 10.0)
867 {
868 if (mode == 1)
869 return "Alarm";
870 else if (severity_in_level (severity, "high"))
871 return "High";
872 else if (severity_in_level (severity, "medium"))
873 return "Medium";
874 else if (severity_in_level (severity, "low"))
875 return "Low";
876 else
877 return "Log";
878 }
879 else
880 {
881 g_warning ("%s: Invalid severity score given: %f",
882 __func__, severity);
883 return NULL;
884 }
885 }
886
887 /**
888 * @brief Get the message type matching a severity score.
889 *
890 * @param[in] severity severity score
891 *
892 * @return the message type as a static string
893 */
894 const char*
severity_to_type(double severity)895 severity_to_type (double severity)
896 {
897 if (severity == SEVERITY_LOG)
898 return "Log Message";
899 else if (severity == SEVERITY_FP)
900 return "False Positive";
901 else if (severity == SEVERITY_ERROR)
902 return "Error Message";
903 else if (severity > 0.0 && severity <= 10.0)
904 return "Alarm";
905 else
906 {
907 g_warning ("%s: Invalid severity score given: %f",
908 __func__, severity);
909 return NULL;
910 }
911 }
912
913
914 /* Credentials. */
915
916 /**
917 * @brief Current credentials during any GMP command.
918 */
919 credentials_t current_credentials;
920
921
922 /* Reports. */
923
924 /**
925 * @brief Delete all the reports for a task.
926 *
927 * It's up to the caller to ensure that this runs in a contention safe
928 * context (for example within an SQL transaction).
929 *
930 * @param[in] task A task descriptor.
931 *
932 * @return 0 on success, -1 on error.
933 */
934 int
delete_reports(task_t task)935 delete_reports (task_t task)
936 {
937 report_t report;
938 iterator_t iterator;
939 init_report_iterator_task (&iterator, task);
940 while (next_report (&iterator, &report))
941 if (delete_report_internal (report))
942 {
943 cleanup_iterator (&iterator);
944 return -1;
945 }
946 cleanup_iterator (&iterator);
947 return 0;
948 }
949
950 /**
951 * @brief Create a basic filter term to get report results.
952 *
953 * @param[in] first First row.
954 * @param[in] rows Number of rows.
955 * @param[in] apply_overrides Whether to apply overrides.
956 * @param[in] min_qod Minimum QOD.
957 *
958 * @return Filter term.
959 */
960 static gchar *
report_results_filter_term(int first,int rows,int apply_overrides,int min_qod)961 report_results_filter_term (int first, int rows,
962 int apply_overrides, int min_qod)
963 {
964 return g_strdup_printf ("first=%d rows=%d"
965 " apply_overrides=%d min_qod=%d",
966 first, rows, apply_overrides, min_qod);
967 }
968
969
970 /**
971 * @brief Create a new basic get_data_t struct to get report results.
972 *
973 * @param[in] first First row.
974 * @param[in] rows Number of rows.
975 * @param[in] apply_overrides Whether to apply overrides.
976 * @param[in] min_qod Minimum QOD.
977 *
978 * @return GET data struct.
979 */
980 get_data_t*
report_results_get_data(int first,int rows,int apply_overrides,int min_qod)981 report_results_get_data (int first, int rows,
982 int apply_overrides, int min_qod)
983 {
984 get_data_t* get = g_malloc (sizeof (get_data_t));
985 memset (get, 0, sizeof (get_data_t));
986 get->type = g_strdup ("result");
987 get->filter = report_results_filter_term (first, rows,
988 apply_overrides, min_qod);
989
990 return get;
991 }
992
993 /**
994 * @brief Array index of severity 0.0 in the severity_data_t.counts array.
995 */
996 #define ZERO_SEVERITY_INDEX 4
997
998 /**
999 * @brief Convert a severity value into an index in the counts array.
1000 *
1001 * @param[in] severity Severity value.
1002 *
1003 * @return The index, 0 for invalid severity scores.
1004 */
1005 static int
severity_data_index(double severity)1006 severity_data_index (double severity)
1007 {
1008 int ret;
1009 if (severity >= 0.0)
1010 ret = (int)(round (severity * SEVERITY_SUBDIVISIONS)) + ZERO_SEVERITY_INDEX;
1011 else if (severity == SEVERITY_FP || severity == SEVERITY_ERROR)
1012 ret = (int)(round (severity)) + ZERO_SEVERITY_INDEX;
1013 else
1014 ret = 0;
1015
1016 return ret;
1017 }
1018
1019 /**
1020 * @brief Convert an index in the counts array to a severity value.
1021 *
1022 * @param[in] index Index in the counts array.
1023 *
1024 * @return The corresponding severity value.
1025 */
1026 double
severity_data_value(int index)1027 severity_data_value (int index)
1028 {
1029 double ret;
1030 if (index <= ZERO_SEVERITY_INDEX && index > 0)
1031 ret = ((double) index) - ZERO_SEVERITY_INDEX;
1032 else if (index <= (ZERO_SEVERITY_INDEX
1033 + (SEVERITY_SUBDIVISIONS * SEVERITY_MAX)))
1034 ret = (((double) (index - ZERO_SEVERITY_INDEX)) / SEVERITY_SUBDIVISIONS);
1035 else
1036 ret = SEVERITY_MISSING;
1037
1038 return ret;
1039 }
1040
1041 /**
1042 * @brief Initialize a severity data structure.
1043 *
1044 * @param[in] data The data structure to initialize.
1045 */
1046 void
init_severity_data(severity_data_t * data)1047 init_severity_data (severity_data_t* data)
1048 {
1049 int max_i;
1050 max_i = ZERO_SEVERITY_INDEX + (SEVERITY_SUBDIVISIONS * SEVERITY_MAX);
1051
1052 data->counts = g_malloc0 (sizeof (int) * (max_i + 1));
1053
1054 data->total = 0;
1055 data->max = SEVERITY_MISSING;
1056 }
1057
1058 /**
1059 * @brief Clean up a severity data structure.
1060 *
1061 * @param[in] data The data structure to initialize.
1062 */
1063 void
cleanup_severity_data(severity_data_t * data)1064 cleanup_severity_data (severity_data_t* data)
1065 {
1066 g_free (data->counts);
1067 }
1068
1069 /**
1070 * @brief Add a severity occurrence to the counts of a severity_data_t.
1071 *
1072 * @param[in] severity_data The severity count struct to add to.
1073 * @param[in] severity The severity to add.
1074 */
1075 void
severity_data_add(severity_data_t * severity_data,double severity)1076 severity_data_add (severity_data_t* severity_data, double severity)
1077 {
1078 (severity_data->counts)[severity_data_index (severity)]++;
1079
1080 if (severity_data->total == 0 || severity_data->max <= severity)
1081 severity_data->max = severity;
1082
1083 (severity_data->total)++;
1084 }
1085
1086 /**
1087 * @brief Add a multiple severity occurrences to the counts of a severity_data_t.
1088 *
1089 * @param[in] severity_data The severity count struct to add to.
1090 * @param[in] severity The severity to add.
1091 * @param[in] count The number of occurrences to add.
1092 */
1093 void
severity_data_add_count(severity_data_t * severity_data,double severity,int count)1094 severity_data_add_count (severity_data_t* severity_data, double severity,
1095 int count)
1096 {
1097 (severity_data->counts)[severity_data_index (severity)] += count;
1098
1099 if (severity_data->total == 0 || severity_data->max <= severity)
1100 severity_data->max = severity;
1101
1102 (severity_data->total) += count;
1103 }
1104
1105 /**
1106 * @brief Calculate the total of severity counts in a range.
1107 *
1108 * @param[in] severity_data The severity data struct to get counts from.
1109 * @param[in] min_severity The minimum severity included in the range.
1110 * @param[in] max_severity The maximum severity included in the range.
1111 *
1112 * @return The total of severity counts in the specified range.
1113 */
1114 static int
severity_data_range_count(const severity_data_t * severity_data,double min_severity,double max_severity)1115 severity_data_range_count (const severity_data_t* severity_data,
1116 double min_severity, double max_severity)
1117 {
1118 int i, i_max, count;
1119
1120 i_max = severity_data_index (max_severity);
1121 count = 0;
1122
1123 for (i = severity_data_index (min_severity);
1124 i <= i_max;
1125 i++)
1126 {
1127 count += (severity_data->counts)[i];
1128 }
1129 return count;
1130 }
1131
1132 /**
1133 * @brief Count the occurrences of severities in the levels.
1134 *
1135 * @param[in] severity_data The severity counts data to evaluate.
1136 * @param[out] errors The number of error messages.
1137 * @param[out] false_positives The number of False Positives.
1138 * @param[out] logs The number of Log messages.
1139 * @param[out] lows The number of Low severity results.
1140 * @param[out] mediums The number of Medium severity results.
1141 * @param[out] highs The number of High severity results.
1142 */
1143 void
severity_data_level_counts(const severity_data_t * severity_data,int * errors,int * false_positives,int * logs,int * lows,int * mediums,int * highs)1144 severity_data_level_counts (const severity_data_t *severity_data,
1145 int *errors, int *false_positives,
1146 int *logs, int *lows, int *mediums, int *highs)
1147 {
1148 if (errors)
1149 *errors
1150 = severity_data_range_count (severity_data,
1151 level_min_severity ("Error"),
1152 level_max_severity ("Error"));
1153
1154 if (false_positives)
1155 *false_positives
1156 = severity_data_range_count (severity_data,
1157 level_min_severity ("False Positive"),
1158 level_max_severity ("False Positive"));
1159
1160 if (logs)
1161 *logs
1162 = severity_data_range_count (severity_data,
1163 level_min_severity ("Log"),
1164 level_max_severity ("Log"));
1165
1166 if (lows)
1167 *lows
1168 = severity_data_range_count (severity_data,
1169 level_min_severity ("low"),
1170 level_max_severity ("low"));
1171
1172 if (mediums)
1173 *mediums
1174 = severity_data_range_count (severity_data,
1175 level_min_severity ("medium"),
1176 level_max_severity ("medium"));
1177
1178 if (highs)
1179 *highs
1180 = severity_data_range_count (severity_data,
1181 level_min_severity ("high"),
1182 level_max_severity ("high"));
1183 }
1184
1185
1186 /* Task globals. */
1187
1188 /**
1189 * @brief The task currently running on the scanner.
1190 */
1191 task_t current_scanner_task = (task_t) 0;
1192
1193 /**
1194 * @brief The report of the current task.
1195 */
1196 report_t global_current_report = (report_t) 0;
1197
1198
1199 /* Alerts. */
1200
1201 /**
1202 * @brief Frees a alert_report_data_t struct, including contained data.
1203 *
1204 * @param[in] data The struct to free.
1205 */
1206 void
alert_report_data_free(alert_report_data_t * data)1207 alert_report_data_free (alert_report_data_t *data)
1208 {
1209 if (data == NULL)
1210 return;
1211
1212 alert_report_data_reset (data);
1213 g_free (data);
1214 }
1215
1216 /**
1217 * @brief Frees content of an alert_report_data_t, but not the struct itself.
1218 *
1219 * @param[in] data The struct to free.
1220 */
1221 void
alert_report_data_reset(alert_report_data_t * data)1222 alert_report_data_reset (alert_report_data_t *data)
1223 {
1224 if (data == NULL)
1225 return;
1226
1227 g_free (data->content_type);
1228 g_free (data->local_filename);
1229 g_free (data->remote_filename);
1230 g_free (data->report_format_name);
1231
1232 memset (data, 0, sizeof (alert_report_data_t));
1233 }
1234
1235 /**
1236 * @brief Get the name of an alert condition.
1237 *
1238 * @param[in] condition Condition.
1239 *
1240 * @return The name of the condition (for example, "Always").
1241 */
1242 const char*
alert_condition_name(alert_condition_t condition)1243 alert_condition_name (alert_condition_t condition)
1244 {
1245 switch (condition)
1246 {
1247 case ALERT_CONDITION_ALWAYS:
1248 return "Always";
1249 case ALERT_CONDITION_FILTER_COUNT_AT_LEAST:
1250 return "Filter count at least";
1251 case ALERT_CONDITION_FILTER_COUNT_CHANGED:
1252 return "Filter count changed";
1253 case ALERT_CONDITION_SEVERITY_AT_LEAST:
1254 return "Severity at least";
1255 case ALERT_CONDITION_SEVERITY_CHANGED:
1256 return "Severity changed";
1257 default:
1258 return "Internal Error";
1259 }
1260 }
1261
1262 /**
1263 * @brief Get the name of an alert event.
1264 *
1265 * @param[in] event Event.
1266 *
1267 * @return The name of the event (for example, "Run status changed").
1268 */
1269 const char*
event_name(event_t event)1270 event_name (event_t event)
1271 {
1272 switch (event)
1273 {
1274 case EVENT_TASK_RUN_STATUS_CHANGED: return "Task run status changed";
1275 case EVENT_NEW_SECINFO: return "New SecInfo arrived";
1276 case EVENT_UPDATED_SECINFO: return "Updated SecInfo arrived";
1277 case EVENT_TICKET_RECEIVED: return "Ticket received";
1278 case EVENT_ASSIGNED_TICKET_CHANGED: return "Assigned ticket changed";
1279 case EVENT_OWNED_TICKET_CHANGED: return "Owned ticket changed";
1280 default: return "Internal Error";
1281 }
1282 }
1283
1284 /**
1285 * @brief Get a description of an alert condition.
1286 *
1287 * @param[in] condition Condition.
1288 * @param[in] alert Alert.
1289 *
1290 * @return Freshly allocated description of condition.
1291 */
1292 gchar*
alert_condition_description(alert_condition_t condition,alert_t alert)1293 alert_condition_description (alert_condition_t condition,
1294 alert_t alert)
1295 {
1296 switch (condition)
1297 {
1298 case ALERT_CONDITION_ALWAYS:
1299 return g_strdup ("Always");
1300 case ALERT_CONDITION_FILTER_COUNT_AT_LEAST:
1301 {
1302 char *count;
1303 gchar *ret;
1304
1305 count = alert_data (alert, "condition", "count");
1306 ret = g_strdup_printf ("Filter count at least %s",
1307 count ? count : "0");
1308 free (count);
1309 return ret;
1310 }
1311 case ALERT_CONDITION_FILTER_COUNT_CHANGED:
1312 return g_strdup ("Filter count changed");
1313 case ALERT_CONDITION_SEVERITY_AT_LEAST:
1314 {
1315 char *level = alert_data (alert, "condition", "severity");
1316 gchar *ret = g_strdup_printf ("Task severity is at least '%s'",
1317 level);
1318 free (level);
1319 return ret;
1320 }
1321 case ALERT_CONDITION_SEVERITY_CHANGED:
1322 {
1323 char *direction;
1324 direction = alert_data (alert, "condition", "direction");
1325 gchar *ret = g_strdup_printf ("Task severity %s", direction);
1326 free (direction);
1327 return ret;
1328 }
1329 default:
1330 return g_strdup ("Internal Error");
1331 }
1332 }
1333
1334 /**
1335 * @brief Get a description of an alert event.
1336 *
1337 * @param[in] event Event.
1338 * @param[in] event_data Event data.
1339 * @param[in] task_name Name of task if required in description, else NULL.
1340 *
1341 * @return Freshly allocated description of event.
1342 */
1343 gchar*
event_description(event_t event,const void * event_data,const char * task_name)1344 event_description (event_t event, const void *event_data, const char *task_name)
1345 {
1346 switch (event)
1347 {
1348 case EVENT_TASK_RUN_STATUS_CHANGED:
1349 if (task_name)
1350 return g_strdup_printf
1351 ("The security scan task '%s' changed status to '%s'",
1352 task_name,
1353 run_status_name ((task_status_t) event_data));
1354 return g_strdup_printf ("Task status changed to '%s'",
1355 run_status_name ((task_status_t) event_data));
1356 break;
1357 case EVENT_NEW_SECINFO:
1358 return g_strdup_printf ("New SecInfo arrived");
1359 break;
1360 case EVENT_UPDATED_SECINFO:
1361 return g_strdup_printf ("Updated SecInfo arrived");
1362 break;
1363 case EVENT_TICKET_RECEIVED:
1364 return g_strdup_printf ("Ticket received");
1365 break;
1366 case EVENT_ASSIGNED_TICKET_CHANGED:
1367 return g_strdup_printf ("Assigned ticket changed");
1368 break;
1369 case EVENT_OWNED_TICKET_CHANGED:
1370 return g_strdup_printf ("Owned ticket changed");
1371 break;
1372 default:
1373 return g_strdup ("Internal Error");
1374 }
1375 }
1376
1377 /**
1378 * @brief Get the name of an alert method.
1379 *
1380 * @param[in] method Method.
1381 *
1382 * @return The name of the method (for example, "Email" or "SNMP").
1383 */
1384 const char*
alert_method_name(alert_method_t method)1385 alert_method_name (alert_method_t method)
1386 {
1387 switch (method)
1388 {
1389 case ALERT_METHOD_EMAIL: return "Email";
1390 case ALERT_METHOD_HTTP_GET: return "HTTP Get";
1391 case ALERT_METHOD_SCP: return "SCP";
1392 case ALERT_METHOD_SEND: return "Send";
1393 case ALERT_METHOD_SMB: return "SMB";
1394 case ALERT_METHOD_SNMP: return "SNMP";
1395 case ALERT_METHOD_SOURCEFIRE: return "Sourcefire Connector";
1396 case ALERT_METHOD_START_TASK: return "Start Task";
1397 case ALERT_METHOD_SYSLOG: return "Syslog";
1398 case ALERT_METHOD_TIPPINGPOINT:return "TippingPoint SMS";
1399 case ALERT_METHOD_VERINICE: return "verinice Connector";
1400 case ALERT_METHOD_VFIRE: return "Alemba vFire";
1401 default: return "Internal Error";
1402 }
1403 }
1404
1405 /**
1406 * @brief Get an alert condition from a name.
1407 *
1408 * @param[in] name Condition name.
1409 *
1410 * @return The condition.
1411 */
1412 alert_condition_t
alert_condition_from_name(const char * name)1413 alert_condition_from_name (const char* name)
1414 {
1415 if (strcasecmp (name, "Always") == 0)
1416 return ALERT_CONDITION_ALWAYS;
1417 if (strcasecmp (name, "Filter count at least") == 0)
1418 return ALERT_CONDITION_FILTER_COUNT_AT_LEAST;
1419 if (strcasecmp (name, "Filter count changed") == 0)
1420 return ALERT_CONDITION_FILTER_COUNT_CHANGED;
1421 if (strcasecmp (name, "Severity at least") == 0)
1422 return ALERT_CONDITION_SEVERITY_AT_LEAST;
1423 if (strcasecmp (name, "Severity changed") == 0)
1424 return ALERT_CONDITION_SEVERITY_CHANGED;
1425 return ALERT_CONDITION_ERROR;
1426 }
1427
1428 /**
1429 * @brief Get an event from a name.
1430 *
1431 * @param[in] name Event name.
1432 *
1433 * @return The event.
1434 */
1435 event_t
event_from_name(const char * name)1436 event_from_name (const char* name)
1437 {
1438 if (strcasecmp (name, "Task run status changed") == 0)
1439 return EVENT_TASK_RUN_STATUS_CHANGED;
1440 if (strcasecmp (name, "New SecInfo arrived") == 0)
1441 return EVENT_NEW_SECINFO;
1442 if (strcasecmp (name, "Updated SecInfo arrived") == 0)
1443 return EVENT_UPDATED_SECINFO;
1444 if (strcasecmp (name, "Ticket received") == 0)
1445 return EVENT_TICKET_RECEIVED;
1446 if (strcasecmp (name, "Assigned ticket changed") == 0)
1447 return EVENT_ASSIGNED_TICKET_CHANGED;
1448 if (strcasecmp (name, "Owned ticket changed") == 0)
1449 return EVENT_OWNED_TICKET_CHANGED;
1450 return EVENT_ERROR;
1451 }
1452
1453 /**
1454 * @brief Get an alert method from a name.
1455 *
1456 * @param[in] name Method name.
1457 *
1458 * @return The method.
1459 */
1460 alert_method_t
alert_method_from_name(const char * name)1461 alert_method_from_name (const char* name)
1462 {
1463 if (strcasecmp (name, "Email") == 0)
1464 return ALERT_METHOD_EMAIL;
1465 if (strcasecmp (name, "HTTP Get") == 0)
1466 return ALERT_METHOD_HTTP_GET;
1467 if (strcasecmp (name, "SCP") == 0)
1468 return ALERT_METHOD_SCP;
1469 if (strcasecmp (name, "Send") == 0)
1470 return ALERT_METHOD_SEND;
1471 if (strcasecmp (name, "SMB") == 0)
1472 return ALERT_METHOD_SMB;
1473 if (strcasecmp (name, "SNMP") == 0)
1474 return ALERT_METHOD_SNMP;
1475 if (strcasecmp (name, "Sourcefire Connector") == 0)
1476 return ALERT_METHOD_SOURCEFIRE;
1477 if (strcasecmp (name, "Start Task") == 0)
1478 return ALERT_METHOD_START_TASK;
1479 if (strcasecmp (name, "Syslog") == 0)
1480 return ALERT_METHOD_SYSLOG;
1481 if (strcasecmp (name, "TippingPoint SMS") == 0)
1482 return ALERT_METHOD_TIPPINGPOINT;
1483 if (strcasecmp (name, "verinice Connector") == 0)
1484 return ALERT_METHOD_VERINICE;
1485 if (strcasecmp (name, "Alemba vFire") == 0)
1486 return ALERT_METHOD_VFIRE;
1487 return ALERT_METHOD_ERROR;
1488 }
1489
1490
1491 /* General task facilities. */
1492
1493 /**
1494 * @brief Get the name of a run status.
1495 *
1496 * @param[in] status Run status.
1497 *
1498 * @return The name of the status (for example, "Done" or "Running").
1499 */
1500 const char*
run_status_name(task_status_t status)1501 run_status_name (task_status_t status)
1502 {
1503 switch (status)
1504 {
1505 case TASK_STATUS_DELETE_REQUESTED:
1506 case TASK_STATUS_DELETE_WAITING:
1507 return "Delete Requested";
1508 case TASK_STATUS_DELETE_ULTIMATE_REQUESTED:
1509 case TASK_STATUS_DELETE_ULTIMATE_WAITING:
1510 return "Ultimate Delete Requested";
1511 case TASK_STATUS_DONE: return "Done";
1512 case TASK_STATUS_NEW: return "New";
1513
1514 case TASK_STATUS_REQUESTED: return "Requested";
1515
1516 case TASK_STATUS_RUNNING: return "Running";
1517
1518 case TASK_STATUS_QUEUED: return "Queued";
1519
1520 case TASK_STATUS_STOP_REQUESTED:
1521 case TASK_STATUS_STOP_WAITING:
1522 return "Stop Requested";
1523
1524 case TASK_STATUS_STOPPED: return "Stopped";
1525 default: return "Interrupted";
1526 }
1527 }
1528
1529 /**
1530 * @brief Get the unique name of a run status.
1531 *
1532 * @param[in] status Run status.
1533 *
1534 * @return The name of the status (for example, "Done" or "Running").
1535 */
1536 const char*
run_status_name_internal(task_status_t status)1537 run_status_name_internal (task_status_t status)
1538 {
1539 switch (status)
1540 {
1541 case TASK_STATUS_DELETE_REQUESTED: return "Delete Requested";
1542 case TASK_STATUS_DELETE_ULTIMATE_REQUESTED:
1543 return "Ultimate Delete Requested";
1544 case TASK_STATUS_DELETE_ULTIMATE_WAITING:
1545 return "Ultimate Delete Waiting";
1546 case TASK_STATUS_DELETE_WAITING: return "Delete Waiting";
1547 case TASK_STATUS_DONE: return "Done";
1548 case TASK_STATUS_NEW: return "New";
1549
1550 case TASK_STATUS_REQUESTED: return "Requested";
1551
1552 case TASK_STATUS_RUNNING: return "Running";
1553
1554 case TASK_STATUS_QUEUED: return "Queued";
1555
1556 case TASK_STATUS_STOP_REQUESTED:
1557 return "Stop Requested";
1558
1559 case TASK_STATUS_STOP_WAITING:
1560 return "Stop Waiting";
1561
1562 case TASK_STATUS_STOPPED: return "Stopped";
1563 default: return "Interrupted";
1564 }
1565 }
1566
1567 /**
1568 * @brief Set a task to interrupted.
1569 *
1570 * Expects global_current_report to match the task.
1571 *
1572 * @param[in] task Task
1573 * @param[in] message Message for error result.
1574 */
1575 void
set_task_interrupted(task_t task,const gchar * message)1576 set_task_interrupted (task_t task, const gchar *message)
1577 {
1578 set_task_run_status (task, TASK_STATUS_INTERRUPTED);
1579 if (global_current_report)
1580 {
1581 result_t result;
1582 result = make_result (task, "", "", "", "", "Error Message", message,
1583 NULL);
1584 report_add_result (global_current_report, result);
1585 }
1586 }
1587
1588
1589 /* OSP tasks. */
1590
1591 /**
1592 * @brief Give a task's OSP scan options in a hash table.
1593 *
1594 * @param[in] task The task.
1595 * @param[in] target The target.
1596 *
1597 * @return Hash table with options names and their values.
1598 */
1599 static GHashTable *
task_scanner_options(task_t task,target_t target)1600 task_scanner_options (task_t task, target_t target)
1601 {
1602 GHashTable *table;
1603 config_t config;
1604 iterator_t prefs;
1605 char *allow_simultaneous_ips;
1606
1607 config = task_config (task);
1608 init_config_preference_iterator (&prefs, config);
1609 table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
1610 while (next (&prefs))
1611 {
1612 char *name, *value = NULL;
1613 const char *type;
1614
1615 name = g_strdup (config_preference_iterator_name (&prefs));
1616 type = config_preference_iterator_type (&prefs);
1617
1618 if (g_str_has_prefix (type, "credential_"))
1619 {
1620 credential_t credential = 0;
1621 iterator_t iter;
1622 const char *uuid = config_preference_iterator_value (&prefs);
1623
1624 if (!strcmp (config_preference_iterator_value (&prefs), "0"))
1625 credential = target_ssh_credential (target);
1626 else if (find_resource ("credential", uuid, &credential))
1627 {
1628 g_warning ("Error getting credential for osp parameter %s", name);
1629 g_free (name);
1630 continue;
1631 }
1632 if (credential == 0)
1633 {
1634 g_warning ("No credential for osp parameter %s", name);
1635 g_free (name);
1636 continue;
1637 }
1638
1639 init_credential_iterator_one (&iter, credential);
1640 if (!next (&iter))
1641 {
1642 g_warning ("No credential for credential_id %llu", credential);
1643 g_free (name);
1644 continue;
1645 }
1646 if (!strcmp (type, "credential_up")
1647 && !strcmp (credential_iterator_type (&iter), "up"))
1648 value = g_strdup_printf ("%s:%s", credential_iterator_login (&iter),
1649 credential_iterator_password (&iter));
1650 else if (!strcmp (type, "credential_up"))
1651 {
1652 g_warning ("OSP Parameter %s requires credentials of type"
1653 " username+password", name);
1654 g_free (name);
1655 continue;
1656 }
1657 else
1658 abort ();
1659 cleanup_iterator (&iter);
1660 if (!value)
1661 {
1662 g_warning ("No adequate %s for parameter %s", type, name);
1663 g_free (name);
1664 continue;
1665 }
1666 }
1667 else if (!strcmp (name, "definitions_file"))
1668 {
1669 char *fname;
1670
1671 if (!config_preference_iterator_value (&prefs))
1672 continue;
1673 fname = g_strdup_printf ("%s/%s", GVM_SCAP_DATA_DIR "/",
1674 config_preference_iterator_value (&prefs));
1675 value = gvm_file_as_base64 (fname);
1676 if (!value)
1677 continue;
1678 }
1679 else
1680 value = g_strdup (config_preference_iterator_value (&prefs));
1681 g_hash_table_insert (table, name, value);
1682 }
1683 cleanup_iterator (&prefs);
1684
1685 // Target options sent as scanner preferences
1686 allow_simultaneous_ips = target_allow_simultaneous_ips (target);
1687 if (allow_simultaneous_ips)
1688 {
1689 g_hash_table_replace (table,
1690 g_strdup ("allow_simultaneous_ips"),
1691 g_strdup (strcmp (allow_simultaneous_ips, "0")
1692 ? "yes"
1693 : "no"));
1694 }
1695 free (allow_simultaneous_ips);
1696
1697 return table;
1698 }
1699
1700 /**
1701 * @brief Delete an OSP scan.
1702 *
1703 * @param[in] report_id Report ID.
1704 * @param[in] host Scanner host.
1705 * @param[in] port Scanner port.
1706 * @param[in] ca_pub CA Certificate.
1707 * @param[in] key_pub Certificate.
1708 * @param[in] key_priv Private key.
1709 */
1710 static void
delete_osp_scan(const char * report_id,const char * host,int port,const char * ca_pub,const char * key_pub,const char * key_priv)1711 delete_osp_scan (const char *report_id, const char *host, int port,
1712 const char *ca_pub, const char *key_pub, const char *key_priv)
1713 {
1714 osp_connection_t *connection;
1715
1716 connection = osp_connect_with_data (host, port, ca_pub, key_pub, key_priv);
1717 if (!connection)
1718 {
1719 return;
1720 }
1721 osp_delete_scan (connection, report_id);
1722 osp_connection_close (connection);
1723 }
1724
1725 /**
1726 * @brief Get an OSP scan's report.
1727 *
1728 * @param[in] scan_id Scan ID.
1729 * @param[in] host Scanner host.
1730 * @param[in] port Scanner port.
1731 * @param[in] ca_pub CA Certificate.
1732 * @param[in] key_pub Certificate.
1733 * @param[in] key_priv Private key.
1734 * @param[in] details 1 for detailed report, 0 otherwise.
1735 * @param[in] pop_results 1 to pop results, 0 to leave results intact.
1736 * @param[out] report_xml Scan report.
1737 *
1738 * @return -1 on error, progress value between 0 and 100 on success.
1739 */
1740 static int
get_osp_scan_report(const char * scan_id,const char * host,int port,const char * ca_pub,const char * key_pub,const char * key_priv,int details,int pop_results,char ** report_xml)1741 get_osp_scan_report (const char *scan_id, const char *host, int port,
1742 const char *ca_pub, const char *key_pub, const char
1743 *key_priv, int details, int pop_results,
1744 char **report_xml)
1745 {
1746 osp_connection_t *connection;
1747 int progress;
1748 char *error = NULL;
1749
1750 connection = osp_connect_with_data (host, port, ca_pub, key_pub, key_priv);
1751 if (!connection)
1752 {
1753 return -1;
1754 }
1755 progress = osp_get_scan_pop (connection, scan_id, report_xml, details,
1756 pop_results, &error);
1757 if (progress > 100 || progress < 0)
1758 {
1759 g_warning ("OSP get_scan %s: %s", scan_id, error);
1760 g_free (error);
1761 progress = -1;
1762 }
1763
1764 osp_connection_close (connection);
1765 return progress;
1766 }
1767
1768
1769 /**
1770 * @brief Get an OSP scan's status.
1771 *
1772 * @param[in] scan_id Scan ID.
1773 * @param[in] host Scanner host.
1774 * @param[in] port Scanner port.
1775 * @param[in] ca_pub CA Certificate.
1776 * @param[in] key_pub Certificate.
1777 * @param[in] key_priv Private key.
1778 *
1779 * @return 0 in success, -1 otherwise.
1780 */
1781 static osp_scan_status_t
get_osp_scan_status(const char * scan_id,const char * host,int port,const char * ca_pub,const char * key_pub,const char * key_priv)1782 get_osp_scan_status (const char *scan_id, const char *host, int port,
1783 const char *ca_pub, const char *key_pub, const char
1784 *key_priv)
1785 {
1786 osp_connection_t *connection;
1787 char *error = NULL;
1788 osp_get_scan_status_opts_t get_scan_opts;
1789 osp_scan_status_t status = OSP_SCAN_STATUS_ERROR;
1790
1791 connection = osp_connect_with_data (host, port, ca_pub, key_pub, key_priv);
1792 if (!connection)
1793 {
1794 return status;
1795 }
1796
1797 get_scan_opts.scan_id = scan_id;
1798 status = osp_get_scan_status_ext (connection, get_scan_opts, &error);
1799 if (status == OSP_SCAN_STATUS_ERROR)
1800 {
1801 g_warning ("OSP %s %s: %s", __func__, scan_id, error);
1802 g_free (error);
1803 return status;
1804 }
1805
1806 osp_connection_close (connection);
1807 return status;
1808 }
1809
1810 /**
1811 * @brief Handle an ongoing OSP scan, until success or failure.
1812 *
1813 * @param[in] task The task.
1814 * @param[in] report The report.
1815 * @param[in] scan_id The UUID of the scan on the scanner.
1816 *
1817 * @return 0 if success, -1 if error, -2 if scan was stopped,
1818 * -3 if the scan was interrupted.
1819 */
1820 static int
handle_osp_scan(task_t task,report_t report,const char * scan_id)1821 handle_osp_scan (task_t task, report_t report, const char *scan_id)
1822 {
1823 char *host, *ca_pub, *key_pub, *key_priv;
1824 int rc, port;
1825 scanner_t scanner;
1826 gboolean started, queued_status_updated;
1827 int retry, connection_retry;
1828
1829 scanner = task_scanner (task);
1830 host = scanner_host (scanner);
1831 port = scanner_port (scanner);
1832 ca_pub = scanner_ca_pub (scanner);
1833 key_pub = scanner_key_pub (scanner);
1834 key_priv = scanner_key_priv (scanner);
1835 started = FALSE;
1836 queued_status_updated = FALSE;
1837 connection_retry = get_scanner_connection_retry ();
1838
1839 retry = connection_retry;
1840 rc = -1;
1841 while (retry >= 0)
1842 {
1843 int run_status, progress;
1844 osp_scan_status_t osp_scan_status;
1845
1846 run_status = task_run_status (task);
1847 if (run_status == TASK_STATUS_STOPPED
1848 || run_status == TASK_STATUS_STOP_REQUESTED)
1849 {
1850 rc = -2;
1851 break;
1852 }
1853
1854 /* Get only the progress, without results and details. */
1855 progress = get_osp_scan_report (scan_id, host, port, ca_pub, key_pub,
1856 key_priv, 0, 0, NULL);
1857
1858 if (progress < 0 || progress > 100)
1859 {
1860 if (retry > 0)
1861 {
1862 retry--;
1863 g_warning ("Connection lost with the scanner at %s. "
1864 "Trying again in 1 second.", host);
1865 gvm_sleep (1);
1866 continue;
1867 }
1868 result_t result = make_osp_result
1869 (task, "", "", "",
1870 threat_message_type ("Error"),
1871 "Erroneous scan progress value", "", "",
1872 QOD_DEFAULT, NULL);
1873 report_add_result (report, result);
1874 delete_osp_scan (scan_id, host, port, ca_pub, key_pub,
1875 key_priv);
1876 rc = -1;
1877 break;
1878 }
1879 else
1880 {
1881 /* Get the full OSP report. */
1882 char *report_xml = NULL;
1883 progress = get_osp_scan_report (scan_id, host, port, ca_pub, key_pub,
1884 key_priv, 1, 1, &report_xml);
1885 if (progress < 0 || progress > 100)
1886 {
1887 if (retry > 0)
1888 {
1889 retry--;
1890 g_warning ("Connection lost with the scanner at %s. "
1891 "Trying again in 1 second.", host);
1892 gvm_sleep (1);
1893 continue;
1894 }
1895
1896 g_free (report_xml);
1897 result_t result = make_osp_result
1898 (task, "", "", "",
1899 threat_message_type ("Error"),
1900 "Erroneous scan progress value", "", "",
1901 QOD_DEFAULT, NULL);
1902 report_add_result (report, result);
1903 rc = -1;
1904 break;
1905 }
1906 else
1907 {
1908 set_report_slave_progress (report, progress);
1909 parse_osp_report (task, report, report_xml);
1910 g_free (report_xml);
1911
1912 osp_scan_status = get_osp_scan_status (scan_id, host, port,
1913 ca_pub, key_pub, key_priv);
1914
1915 if (osp_scan_status == OSP_SCAN_STATUS_QUEUED)
1916 {
1917 if (queued_status_updated == FALSE)
1918 {
1919 set_task_run_status (task, TASK_STATUS_QUEUED);
1920 set_report_scan_run_status (global_current_report,
1921 TASK_STATUS_QUEUED);
1922 queued_status_updated = TRUE;
1923 }
1924 }
1925 else if (osp_scan_status == OSP_SCAN_STATUS_INTERRUPTED)
1926 {
1927 result_t result = make_osp_result
1928 (task, "", "", "",
1929 threat_message_type ("Error"),
1930 "Task interrupted unexpectedly", "", "",
1931 QOD_DEFAULT, NULL);
1932 report_add_result (report, result);
1933 delete_osp_scan (scan_id, host, port, ca_pub, key_pub,
1934 key_priv);
1935 rc = -3;
1936 break;
1937 }
1938 else if (progress >= 0 && progress < 100
1939 && osp_scan_status == OSP_SCAN_STATUS_STOPPED)
1940 {
1941 if (retry > 0)
1942 {
1943 retry--;
1944 g_warning ("Connection lost with the scanner at %s. "
1945 "Trying again in 1 second.", host);
1946 gvm_sleep (1);
1947 continue;
1948 }
1949
1950 result_t result = make_osp_result
1951 (task, "", "", "",
1952 threat_message_type ("Error"),
1953 "Scan stopped unexpectedly by the server", "", "",
1954 QOD_DEFAULT, NULL);
1955 report_add_result (report, result);
1956 delete_osp_scan (scan_id, host, port, ca_pub, key_pub,
1957 key_priv);
1958 rc = -1;
1959 break;
1960 }
1961 else if (progress == 100
1962 && osp_scan_status == OSP_SCAN_STATUS_FINISHED)
1963 {
1964 delete_osp_scan (scan_id, host, port, ca_pub, key_pub,
1965 key_priv);
1966 rc = 0;
1967 break;
1968 }
1969 else if (osp_scan_status == OSP_SCAN_STATUS_RUNNING
1970 && started == FALSE)
1971 {
1972 set_task_run_status (task, TASK_STATUS_RUNNING);
1973 set_report_scan_run_status (global_current_report,
1974 TASK_STATUS_RUNNING);
1975 started = TRUE;
1976 }
1977 }
1978 }
1979
1980 retry = connection_retry;
1981 gvm_sleep (5);
1982 }
1983
1984 g_free (host);
1985 g_free (ca_pub);
1986 g_free (key_pub);
1987 g_free (key_priv);
1988 return rc;
1989 }
1990
1991 /**
1992 * @brief Get an OSP Task's scan options.
1993 *
1994 * @param[in] task The task.
1995 * @param[in] target The target.
1996 *
1997 * @return OSP Task options, NULL if failure.
1998 */
1999 static GHashTable *
get_osp_task_options(task_t task,target_t target)2000 get_osp_task_options (task_t task, target_t target)
2001 {
2002 char *ssh_port;
2003 const char *user, *pass;
2004 iterator_t iter;
2005 credential_t cred;
2006 GHashTable *options = task_scanner_options (task, target);
2007
2008 if (!options)
2009 return NULL;
2010
2011 cred = target_ssh_credential (target);
2012 if (cred)
2013 {
2014 ssh_port = target_ssh_port (target);
2015 g_hash_table_insert (options, g_strdup ("port"), ssh_port);
2016
2017 init_credential_iterator_one (&iter, cred);
2018 if (!next (&iter))
2019 {
2020 g_warning ("%s: LSC Credential not found.", __func__);
2021 g_hash_table_destroy (options);
2022 cleanup_iterator (&iter);
2023 return NULL;
2024 }
2025 if (credential_iterator_private_key (&iter))
2026 {
2027 g_warning ("%s: LSC Credential not a user/pass pair.", __func__);
2028 g_hash_table_destroy (options);
2029 cleanup_iterator (&iter);
2030 return NULL;
2031 }
2032 user = credential_iterator_login (&iter);
2033 pass = credential_iterator_password (&iter);
2034 g_hash_table_insert (options, g_strdup ("username"), g_strdup (user));
2035 g_hash_table_insert (options, g_strdup ("password"), g_strdup (pass));
2036 cleanup_iterator (&iter);
2037 }
2038 return options;
2039 }
2040
2041 /**
2042 * @brief Launch an OSP task.
2043 *
2044 * @param[in] task The task.
2045 * @param[in] target The target.
2046 * @param[out] scan_id The new scan uuid.
2047 * @param[out] error Error return.
2048 *
2049 * @return 0 success, -1 if scanner is down.
2050 */
2051 static int
launch_osp_task(task_t task,target_t target,const char * scan_id,char ** error)2052 launch_osp_task (task_t task, target_t target, const char *scan_id,
2053 char **error)
2054 {
2055 osp_connection_t *connection;
2056 char *target_str, *ports_str;
2057 GHashTable *options;
2058 int ret;
2059
2060 options = get_osp_task_options (task, target);
2061 if (!options)
2062 return -1;
2063 connection = osp_scanner_connect (task_scanner (task));
2064 if (!connection)
2065 {
2066 g_hash_table_destroy (options);
2067 return -1;
2068 }
2069 target_str = target_hosts (target);
2070 ports_str = target_port_range (target);
2071 ret = osp_start_scan (connection, target_str, ports_str, options, scan_id,
2072 error);
2073
2074 g_hash_table_destroy (options);
2075 osp_connection_close (connection);
2076 g_free (target_str);
2077 g_free (ports_str);
2078 return ret;
2079 }
2080
2081 /**
2082 * @brief Get the SSH credential of a target as an osp_credential_t
2083 *
2084 * @param[in] target The target to get the credential from.
2085 *
2086 * @return Pointer to a newly allocated osp_credential_t
2087 */
2088 static osp_credential_t *
target_osp_ssh_credential(target_t target)2089 target_osp_ssh_credential (target_t target)
2090 {
2091 credential_t credential, ssh_elevate_credential;
2092 credential = target_ssh_credential (target);
2093 ssh_elevate_credential = target_ssh_elevate_credential (target);
2094
2095 if (credential)
2096 {
2097 iterator_t iter, ssh_elevate_iter;
2098 const char *type;
2099 char *ssh_port;
2100 osp_credential_t *osp_credential;
2101
2102 init_credential_iterator_one (&iter, credential);
2103
2104 if (!next (&iter))
2105 {
2106 g_warning ("%s: SSH Credential not found.", __func__);
2107 cleanup_iterator (&iter);
2108 return NULL;
2109 }
2110 type = credential_iterator_type (&iter);
2111 if (strcmp (type, "up") && strcmp (type, "usk"))
2112 {
2113 g_warning ("%s: SSH Credential not a user/pass pair"
2114 " or user/ssh key.", __func__);
2115 cleanup_iterator (&iter);
2116 return NULL;
2117 }
2118
2119 ssh_port = target_ssh_port (target);
2120 osp_credential = osp_credential_new (type, "ssh", ssh_port);
2121 free (ssh_port);
2122 osp_credential_set_auth_data (osp_credential,
2123 "username",
2124 credential_iterator_login (&iter));
2125 osp_credential_set_auth_data (osp_credential,
2126 "password",
2127 credential_iterator_password (&iter));
2128
2129 if (strcmp (type, "usk") == 0)
2130 {
2131 const char *private_key = credential_iterator_private_key (&iter);
2132 gchar *base64 = g_base64_encode ((guchar *) private_key,
2133 strlen (private_key));
2134 osp_credential_set_auth_data (osp_credential,
2135 "private", base64);
2136 g_free (base64);
2137 }
2138
2139 if(ssh_elevate_credential)
2140 {
2141 const char *elevate_type;
2142
2143 init_credential_iterator_one (&ssh_elevate_iter,
2144 ssh_elevate_credential);
2145 if (!next (&ssh_elevate_iter))
2146 {
2147 g_warning ("%s: SSH Elevate Credential not found.", __func__);
2148 cleanup_iterator (&ssh_elevate_iter);
2149 osp_credential_free(osp_credential);
2150 return NULL;
2151 }
2152 elevate_type = credential_iterator_type (&ssh_elevate_iter);
2153 if (strcmp (elevate_type, "up"))
2154 {
2155 g_warning ("%s: SSH Elevate Credential not of type up", __func__);
2156 cleanup_iterator (&ssh_elevate_iter);
2157 osp_credential_free(osp_credential);
2158 return NULL;
2159 }
2160 osp_credential_set_auth_data (osp_credential,
2161 "priv_username",
2162 credential_iterator_login
2163 (&ssh_elevate_iter));
2164 osp_credential_set_auth_data (osp_credential,
2165 "priv_password",
2166 credential_iterator_password
2167 (&ssh_elevate_iter));
2168 cleanup_iterator (&ssh_elevate_iter);
2169 }
2170
2171 cleanup_iterator (&iter);
2172 return osp_credential;
2173 }
2174 return NULL;
2175 }
2176
2177 /**
2178 * @brief Get the SMB credential of a target as an osp_credential_t
2179 *
2180 * @param[in] target The target to get the credential from.
2181 *
2182 * @return Pointer to a newly allocated osp_credential_t
2183 */
2184 static osp_credential_t *
target_osp_smb_credential(target_t target)2185 target_osp_smb_credential (target_t target)
2186 {
2187 credential_t credential;
2188 credential = target_smb_credential (target);
2189 if (credential)
2190 {
2191 iterator_t iter;
2192 osp_credential_t *osp_credential;
2193
2194 init_credential_iterator_one (&iter, credential);
2195 if (!next (&iter))
2196 {
2197 g_warning ("%s: SMB Credential not found.", __func__);
2198 cleanup_iterator (&iter);
2199 return NULL;
2200 }
2201 if (strcmp (credential_iterator_type (&iter), "up"))
2202 {
2203 g_warning ("%s: SMB Credential not a user/pass pair.", __func__);
2204 cleanup_iterator (&iter);
2205 return NULL;
2206 }
2207
2208 osp_credential = osp_credential_new ("up", "smb", NULL);
2209 osp_credential_set_auth_data (osp_credential,
2210 "username",
2211 credential_iterator_login (&iter));
2212 osp_credential_set_auth_data (osp_credential,
2213 "password",
2214 credential_iterator_password (&iter));
2215 cleanup_iterator (&iter);
2216 return osp_credential;
2217 }
2218 return NULL;
2219 }
2220
2221 /**
2222 * @brief Get the SMB credential of a target as an osp_credential_t
2223 *
2224 * @param[in] target The target to get the credential from.
2225 *
2226 * @return Pointer to a newly allocated osp_credential_t
2227 */
2228 static osp_credential_t *
target_osp_esxi_credential(target_t target)2229 target_osp_esxi_credential (target_t target)
2230 {
2231 credential_t credential;
2232 credential = target_esxi_credential (target);
2233 if (credential)
2234 {
2235 iterator_t iter;
2236 osp_credential_t *osp_credential;
2237
2238 init_credential_iterator_one (&iter, credential);
2239 if (!next (&iter))
2240 {
2241 g_warning ("%s: ESXi Credential not found.", __func__);
2242 cleanup_iterator (&iter);
2243 return NULL;
2244 }
2245 if (strcmp (credential_iterator_type (&iter), "up"))
2246 {
2247 g_warning ("%s: ESXi Credential not a user/pass pair.",
2248 __func__);
2249 cleanup_iterator (&iter);
2250 return NULL;
2251 }
2252
2253 osp_credential = osp_credential_new ("up", "esxi", NULL);
2254 osp_credential_set_auth_data (osp_credential,
2255 "username",
2256 credential_iterator_login (&iter));
2257 osp_credential_set_auth_data (osp_credential,
2258 "password",
2259 credential_iterator_password (&iter));
2260 cleanup_iterator (&iter);
2261 return osp_credential;
2262 }
2263 return NULL;
2264 }
2265
2266 /**
2267 * @brief Get the SMB credential of a target as an osp_credential_t
2268 *
2269 * @param[in] target The target to get the credential from.
2270 *
2271 * @return Pointer to a newly allocated osp_credential_t
2272 */
2273 static osp_credential_t *
target_osp_snmp_credential(target_t target)2274 target_osp_snmp_credential (target_t target)
2275 {
2276 credential_t credential;
2277 credential = target_credential (target, "snmp");
2278 if (credential)
2279 {
2280 iterator_t iter;
2281 osp_credential_t *osp_credential;
2282
2283 init_credential_iterator_one (&iter, credential);
2284 if (!next (&iter))
2285 {
2286 g_warning ("%s: SNMP Credential not found.", __func__);
2287 cleanup_iterator (&iter);
2288 return NULL;
2289 }
2290 if (strcmp (credential_iterator_type (&iter), "snmp"))
2291 {
2292 g_warning ("%s: SNMP Credential not of type 'snmp'.",
2293 __func__);
2294 cleanup_iterator (&iter);
2295 return NULL;
2296 }
2297
2298 osp_credential = osp_credential_new ("snmp", "snmp", NULL);
2299 osp_credential_set_auth_data (osp_credential,
2300 "username",
2301 credential_iterator_login (&iter)
2302 ?: "");
2303 osp_credential_set_auth_data (osp_credential,
2304 "password",
2305 credential_iterator_password (&iter)
2306 ?: "");
2307 osp_credential_set_auth_data (osp_credential,
2308 "community",
2309 credential_iterator_community (&iter)
2310 ?: "");
2311 osp_credential_set_auth_data (osp_credential,
2312 "auth_algorithm",
2313 credential_iterator_auth_algorithm (&iter)
2314 ?: "");
2315 osp_credential_set_auth_data (osp_credential,
2316 "privacy_algorithm",
2317 credential_iterator_privacy_algorithm
2318 (&iter) ?: "");
2319 osp_credential_set_auth_data (osp_credential,
2320 "privacy_password",
2321 credential_iterator_privacy_password
2322 (&iter) ?: "");
2323 cleanup_iterator (&iter);
2324 return osp_credential;
2325 }
2326 return NULL;
2327 }
2328
2329 /**
2330 * @brief Prepare a report for resuming an OSP scan
2331 *
2332 * @param[in] task The task of the scan.
2333 * @param[in] scan_id The scan uuid.
2334 * @param[out] error Error return.
2335 *
2336 * @return 0 scan finished or still running,
2337 * 1 scan must be started,
2338 * -1 error
2339 */
2340 static int
prepare_osp_scan_for_resume(task_t task,const char * scan_id,char ** error)2341 prepare_osp_scan_for_resume (task_t task, const char *scan_id, char **error)
2342 {
2343 osp_connection_t *connection;
2344 osp_get_scan_status_opts_t status_opts;
2345 osp_scan_status_t status;
2346
2347 assert (task);
2348 assert (scan_id);
2349 assert (global_current_report);
2350 assert (error);
2351
2352 status_opts.scan_id = scan_id;
2353
2354 connection = osp_scanner_connect (task_scanner (task));
2355 if (!connection)
2356 {
2357 *error = g_strdup ("Could not connect to Scanner");
2358 return -1;
2359 }
2360 status = osp_get_scan_status_ext (connection, status_opts, error);
2361
2362 /* Reset connection. */
2363 osp_connection_close (connection);
2364 connection = osp_scanner_connect (task_scanner (task));
2365 if (!connection)
2366 {
2367 *error = g_strdup ("Could not connect to Scanner");
2368 return -1;
2369 }
2370
2371 if (status == OSP_SCAN_STATUS_ERROR)
2372 {
2373 if (g_str_has_prefix (*error, "Failed to find scan"))
2374 {
2375 g_debug ("%s: Scan %s not found", __func__, scan_id);
2376 g_free (*error);
2377 *error = NULL;
2378 osp_connection_close (connection);
2379 trim_partial_report (global_current_report);
2380 return 1;
2381 }
2382 else
2383 {
2384 g_warning ("%s: Error getting status of scan %s: %s",
2385 __func__, scan_id, *error);
2386 osp_connection_close (connection);
2387 return -1;
2388 }
2389 }
2390 else if (status == OSP_SCAN_STATUS_RUNNING
2391 || status == OSP_SCAN_STATUS_QUEUED)
2392 {
2393 g_debug ("%s: Scan %s queued or running", __func__, scan_id);
2394 /* It would be possible to simply continue getting the results
2395 * from the scanner, but gvmd may have crashed while receiving
2396 * or storing the results, so some may be missing. */
2397 if (osp_stop_scan (connection, scan_id, error))
2398 {
2399 osp_connection_close (connection);
2400 return -1;
2401 }
2402 if (osp_delete_scan (connection, scan_id))
2403 {
2404 *error = g_strdup ("Failed to delete old report");
2405 osp_connection_close (connection);
2406 return -1;
2407 }
2408 osp_connection_close (connection);
2409 trim_partial_report (global_current_report);
2410 return 1;
2411 }
2412 else if (status == OSP_SCAN_STATUS_FINISHED)
2413 {
2414 /* OSP can't stop an already finished/interrupted scan,
2415 * but it must be delete to be resumed. */
2416 g_debug ("%s: Scan %s finished", __func__, scan_id);
2417 if (osp_delete_scan (connection, scan_id))
2418 {
2419 *error = g_strdup ("Failed to delete old report");
2420 osp_connection_close (connection);
2421 return -1;
2422 }
2423 osp_connection_close (connection);
2424 trim_partial_report (global_current_report);
2425 return 1;
2426 }
2427 else if (status == OSP_SCAN_STATUS_STOPPED
2428 || status == OSP_SCAN_STATUS_INTERRUPTED)
2429 {
2430 g_debug ("%s: Scan %s stopped or interrupted",
2431 __func__, scan_id);
2432 if (osp_delete_scan (connection, scan_id))
2433 {
2434 *error = g_strdup ("Failed to delete old report");
2435 osp_connection_close (connection);
2436 return -1;
2437 }
2438 osp_connection_close (connection);
2439 trim_partial_report (global_current_report);
2440 return 1;
2441 }
2442
2443 g_warning ("%s: Unexpected scanner status %d", __func__, status);
2444 *error = g_strdup_printf ("Unexpected scanner status %d", status);
2445 osp_connection_close (connection);
2446 return -1;
2447 }
2448
2449 /**
2450 * @brief Add OSP preferences for limiting ifaces and hosts for users.
2451 *
2452 * @param[in] scanner_options The scanner preferences table to add to.
2453 */
2454 static void
add_user_scan_preferences(GHashTable * scanner_options)2455 add_user_scan_preferences (GHashTable *scanner_options)
2456 {
2457 gchar *hosts, *ifaces, *name;
2458 int hosts_allow, ifaces_allow;
2459
2460 // Limit access to hosts
2461 hosts = user_hosts (current_credentials.uuid);
2462 hosts_allow = user_hosts_allow (current_credentials.uuid);
2463
2464 if (hosts_allow == 1)
2465 name = g_strdup ("hosts_allow");
2466 else if (hosts_allow == 0)
2467 name = g_strdup ("hosts_deny");
2468 else
2469 name = NULL;
2470
2471 if (name
2472 && (hosts_allow || (hosts && strlen (hosts))))
2473 g_hash_table_replace (scanner_options,
2474 name,
2475 hosts ? hosts : g_strdup (""));
2476 else
2477 g_free (hosts);
2478
2479 // Limit access to ifaces
2480 ifaces = user_ifaces (current_credentials.uuid);
2481 ifaces_allow = user_ifaces_allow (current_credentials.uuid);
2482
2483 if (ifaces_allow == 1)
2484 name = g_strdup ("ifaces_allow");
2485 else if (ifaces_allow == 0)
2486 name = g_strdup ("ifaces_deny");
2487 else
2488 name = NULL;
2489
2490 if (name
2491 && (ifaces_allow || (ifaces && strlen (ifaces))))
2492 g_hash_table_replace (scanner_options,
2493 name,
2494 ifaces ? ifaces : g_strdup (""));
2495 else
2496 g_free (ifaces);
2497 }
2498
2499 /**
2500 * @brief Launch an OpenVAS via OSP task.
2501 *
2502 * @param[in] task The task.
2503 * @param[in] target The target.
2504 * @param[in] scan_id The scan uuid.
2505 * @param[in] from 0 start from beginning, 1 continue from stopped,
2506 * 2 continue if stopped else start from beginning.
2507 * @param[out] error Error return.
2508 *
2509 * @return 0 success, -1 if scanner is down.
2510 */
2511 static int
launch_osp_openvas_task(task_t task,target_t target,const char * scan_id,int from,char ** error)2512 launch_osp_openvas_task (task_t task, target_t target, const char *scan_id,
2513 int from, char **error)
2514 {
2515 osp_connection_t *connection;
2516 char *hosts_str, *ports_str, *exclude_hosts_str, *finished_hosts_str;
2517 gchar *clean_hosts, *clean_exclude_hosts, *clean_finished_hosts_str;
2518 int alive_test, reverse_lookup_only, reverse_lookup_unify;
2519 osp_target_t *osp_target;
2520 GSList *osp_targets, *vts;
2521 GHashTable *vts_hash_table;
2522 osp_credential_t *ssh_credential, *smb_credential, *esxi_credential;
2523 osp_credential_t *snmp_credential;
2524 gchar *max_checks, *max_hosts, *source_iface, *hosts_ordering;
2525 GHashTable *scanner_options;
2526 int ret;
2527 config_t config;
2528 iterator_t scanner_prefs_iter, families, prefs;
2529 osp_start_scan_opts_t start_scan_opts;
2530
2531 config = task_config (task);
2532
2533 connection = NULL;
2534
2535 alive_test = 0;
2536 reverse_lookup_unify = 0;
2537 reverse_lookup_only = 0;
2538
2539 /* Prepare the report */
2540 if (from)
2541 {
2542 ret = prepare_osp_scan_for_resume (task, scan_id, error);
2543 if (ret == 0)
2544 return 0;
2545 else if (ret == -1)
2546 return -1;
2547 finished_hosts_str = report_finished_hosts_str (global_current_report);
2548 clean_finished_hosts_str = clean_hosts_string (finished_hosts_str);
2549 }
2550 else
2551 {
2552 finished_hosts_str = NULL;
2553 clean_finished_hosts_str = NULL;
2554 }
2555
2556 /* Set up target(s) */
2557 hosts_str = target_hosts (target);
2558 ports_str = target_port_range (target);
2559 exclude_hosts_str = target_exclude_hosts (target);
2560
2561 clean_hosts = clean_hosts_string (hosts_str);
2562 clean_exclude_hosts = clean_hosts_string (exclude_hosts_str);
2563
2564 if (target_alive_tests (target) > 0)
2565 alive_test = target_alive_tests (target);
2566
2567 if (target_reverse_lookup_only (target) != NULL)
2568 reverse_lookup_only = atoi (target_reverse_lookup_only (target));
2569
2570 if (target_reverse_lookup_unify (target) != NULL)
2571 reverse_lookup_unify = atoi (target_reverse_lookup_unify (target));
2572
2573 if (finished_hosts_str)
2574 {
2575 gchar *new_exclude_hosts;
2576
2577 new_exclude_hosts = g_strdup_printf ("%s,%s",
2578 clean_exclude_hosts,
2579 clean_finished_hosts_str);
2580 free (clean_exclude_hosts);
2581 clean_exclude_hosts = new_exclude_hosts;
2582 }
2583
2584 osp_target = osp_target_new (clean_hosts, ports_str, clean_exclude_hosts,
2585 alive_test, reverse_lookup_unify,
2586 reverse_lookup_only);
2587 if (finished_hosts_str)
2588 osp_target_set_finished_hosts (osp_target, finished_hosts_str);
2589
2590 free (hosts_str);
2591 free (ports_str);
2592 free (exclude_hosts_str);
2593 free (finished_hosts_str);
2594 g_free (clean_hosts);
2595 g_free (clean_exclude_hosts);
2596 g_free (clean_finished_hosts_str);
2597 osp_targets = g_slist_append (NULL, osp_target);
2598
2599 ssh_credential = target_osp_ssh_credential (target);
2600 if (ssh_credential)
2601 osp_target_add_credential (osp_target, ssh_credential);
2602
2603 smb_credential = target_osp_smb_credential (target);
2604 if (smb_credential)
2605 osp_target_add_credential (osp_target, smb_credential);
2606
2607 esxi_credential = target_osp_esxi_credential (target);
2608 if (esxi_credential)
2609 osp_target_add_credential (osp_target, esxi_credential);
2610
2611 snmp_credential = target_osp_snmp_credential (target);
2612 if (snmp_credential)
2613 osp_target_add_credential (osp_target, snmp_credential);
2614
2615 /* Setup general scanner preferences */
2616 scanner_options
2617 = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
2618 init_preference_iterator (&scanner_prefs_iter, config, "SERVER_PREFS");
2619 while (next (&scanner_prefs_iter))
2620 {
2621 const char *name, *value;
2622 name = preference_iterator_name (&scanner_prefs_iter);
2623 value = preference_iterator_value (&scanner_prefs_iter);
2624 if (name && value)
2625 {
2626 const char *osp_value;
2627
2628 // Workaround for boolean scanner preferences
2629 if (strcmp (value, "yes") == 0)
2630 osp_value = "1";
2631 else if (strcmp (value, "no") == 0)
2632 osp_value = "0";
2633 else
2634 osp_value = value;
2635 g_hash_table_replace (scanner_options,
2636 g_strdup (name),
2637 g_strdup (osp_value));
2638 }
2639 }
2640 cleanup_iterator (&scanner_prefs_iter);
2641
2642 /* Setup user-specific scanner preference */
2643 add_user_scan_preferences (scanner_options);
2644
2645 /* Setup general task preferences */
2646 max_checks = task_preference_value (task, "max_checks");
2647 g_hash_table_insert (scanner_options, g_strdup ("max_checks"),
2648 max_checks ? max_checks : g_strdup (MAX_CHECKS_DEFAULT));
2649
2650 max_hosts = task_preference_value (task, "max_hosts");
2651 g_hash_table_insert (scanner_options, g_strdup ("max_hosts"),
2652 max_hosts ? max_hosts : g_strdup (MAX_HOSTS_DEFAULT));
2653
2654 source_iface = task_preference_value (task, "source_iface");
2655 if (source_iface)
2656 g_hash_table_insert (scanner_options, g_strdup ("source_iface"),
2657 source_iface);
2658
2659 hosts_ordering = task_hosts_ordering (task);
2660 if (hosts_ordering)
2661 g_hash_table_insert (scanner_options, g_strdup ("hosts_ordering"),
2662 hosts_ordering);
2663
2664 /* Setup vulnerability tests (without preferences) */
2665 vts = NULL;
2666 vts_hash_table
2667 = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
2668 /* Value is freed in vts list. */
2669 NULL);
2670
2671 init_family_iterator (&families, 0, NULL, 1);
2672 while (next (&families))
2673 {
2674 const char *family = family_iterator_name (&families);
2675 if (family)
2676 {
2677 iterator_t nvts;
2678 init_nvt_iterator (&nvts, 0, config, family, NULL, 1, NULL);
2679 while (next (&nvts))
2680 {
2681 const char *oid;
2682 osp_vt_single_t *new_vt;
2683
2684 oid = nvt_iterator_oid (&nvts);
2685 new_vt = osp_vt_single_new (oid);
2686
2687 vts = g_slist_prepend (vts, new_vt);
2688 g_hash_table_replace (vts_hash_table, g_strdup (oid), new_vt);
2689 }
2690 cleanup_iterator (&nvts);
2691 }
2692 }
2693 cleanup_iterator (&families);
2694
2695 /* Setup VT preferences */
2696 init_preference_iterator (&prefs, config, "PLUGINS_PREFS");
2697 while (next (&prefs))
2698 {
2699 const char *full_name, *value;
2700 osp_vt_single_t *osp_vt;
2701 gchar **split_name;
2702
2703 full_name = preference_iterator_name (&prefs);
2704 value = preference_iterator_value (&prefs);
2705 split_name = g_strsplit (full_name, ":", 4);
2706
2707 osp_vt = NULL;
2708 if (split_name && split_name[0] && split_name[1] && split_name[2])
2709 {
2710 const char *oid = split_name[0];
2711 const char *pref_id = split_name[1];
2712 const char *type = split_name[2];
2713 gchar *osp_value = NULL;
2714
2715 if (strcmp (type, "checkbox") == 0)
2716 {
2717 if (strcmp (value, "yes") == 0)
2718 osp_value = g_strdup ("1");
2719 else
2720 osp_value = g_strdup ("0");
2721 }
2722 else if (strcmp (type, "radio") == 0)
2723 {
2724 gchar** split_value;
2725 split_value = g_strsplit (value, ";", 2);
2726 osp_value = g_strdup (split_value[0]);
2727 g_strfreev (split_value);
2728 }
2729 else if (strcmp (type, "file") == 0)
2730 osp_value = g_base64_encode ((guchar*) value, strlen (value));
2731
2732 osp_vt = g_hash_table_lookup (vts_hash_table, oid);
2733 if (osp_vt)
2734 osp_vt_single_add_value (osp_vt, pref_id,
2735 osp_value ? osp_value : value);
2736 g_free (osp_value);
2737 }
2738
2739 g_strfreev (split_name);
2740 }
2741 cleanup_iterator (&prefs);
2742 g_hash_table_destroy (vts_hash_table);
2743
2744 /* Start the scan */
2745 connection = osp_scanner_connect (task_scanner (task));
2746 if (!connection)
2747 {
2748 if (error)
2749 *error = g_strdup ("Could not connect to Scanner");
2750 g_slist_free_full (osp_targets, (GDestroyNotify) osp_target_free);
2751 // Credentials are freed with target
2752 g_slist_free_full (vts, (GDestroyNotify) osp_vt_single_free);
2753 g_hash_table_destroy (scanner_options);
2754 return -1;
2755 }
2756
2757 start_scan_opts.targets = osp_targets;
2758 start_scan_opts.vt_groups = NULL;
2759 start_scan_opts.vts = vts;
2760 start_scan_opts.scanner_params = scanner_options;
2761 start_scan_opts.scan_id = scan_id;
2762
2763 ret = osp_start_scan_ext (connection,
2764 start_scan_opts,
2765 error);
2766
2767 osp_connection_close (connection);
2768 g_slist_free_full (osp_targets, (GDestroyNotify) osp_target_free);
2769 // Credentials are freed with target
2770 g_slist_free_full (vts, (GDestroyNotify) osp_vt_single_free);
2771 g_hash_table_destroy (scanner_options);
2772 return ret;
2773 }
2774
2775 /**
2776 * @brief Get the last stopped report or a new one for an OSP scan.
2777 *
2778 * @param[in] task The task.
2779 * @param[in] from 0 start from beginning, 1 continue from stopped,
2780 * 2 continue if stopped else start from beginning.
2781 * @param[out] report_id UUID of the report.
2782 *
2783 * @return 0 success, -1 error
2784 */
2785 static int
run_osp_scan_get_report(task_t task,int from,char ** report_id)2786 run_osp_scan_get_report (task_t task, int from, char **report_id)
2787 {
2788 report_t resume_report;
2789
2790 resume_report = 0;
2791 *report_id = NULL;
2792
2793 if (from == 1
2794 && scanner_type (task_scanner (task)) == SCANNER_TYPE_OSP)
2795 {
2796 g_warning ("%s: Scanner type does not support resuming scans",
2797 __func__);
2798 return -1;
2799 }
2800
2801 if (from
2802 && scanner_type (task_scanner (task)) != SCANNER_TYPE_OSP
2803 && task_last_resumable_report (task, &resume_report))
2804 {
2805 g_warning ("%s: error getting report to resume", __func__);
2806 return -1;
2807 }
2808
2809 if (resume_report)
2810 {
2811 // Report to resume found
2812 if (global_current_report)
2813 {
2814 g_warning ("%s: global_current_report already set", __func__);
2815 return -1;
2816 }
2817 global_current_report = resume_report;
2818 *report_id = report_uuid (resume_report);
2819
2820 /* Ensure the report is marked as requested. */
2821 set_report_scan_run_status (resume_report, TASK_STATUS_REQUESTED);
2822
2823 /* Clear the end times of the task and partial report. */
2824 set_task_start_time_epoch (task,
2825 scan_start_time_epoch (resume_report));
2826 set_task_end_time (task, NULL);
2827 set_scan_end_time (resume_report, NULL);
2828 }
2829 else if (from == 1)
2830 // No report to resume and starting a new one is not allowed
2831 return -1;
2832
2833 // Try starting a new report
2834 if (resume_report == 0
2835 && create_current_report (task, report_id, TASK_STATUS_REQUESTED))
2836 {
2837 g_debug (" %s: failed to create report", __func__);
2838 return -1;
2839 }
2840
2841 return 0;
2842 }
2843
2844 /**
2845 * @brief Fork a child to handle an OSP scan's fetching and inserting.
2846 *
2847 * @param[in] task The task.
2848 * @param[in] target The target.
2849 * @param[in] from 0 start from beginning, 1 continue from stopped,
2850 * 2 continue if stopped else start from beginning.
2851 * @param[out] report_id_return UUID of the report.
2852 *
2853 * @return Parent returns with 0 if success, -1 if failure. Child process
2854 * doesn't return and simply exits.
2855 */
2856 static int
fork_osp_scan_handler(task_t task,target_t target,int from,char ** report_id_return)2857 fork_osp_scan_handler (task_t task, target_t target, int from,
2858 char **report_id_return)
2859 {
2860 char *report_id, title[128], *error = NULL;
2861 int rc;
2862
2863 assert (task);
2864 assert (target);
2865
2866 if (report_id_return)
2867 *report_id_return = NULL;
2868
2869 if (run_osp_scan_get_report (task, from, &report_id))
2870 return -1;
2871
2872 current_scanner_task = task;
2873 set_task_run_status (task, TASK_STATUS_REQUESTED);
2874
2875 switch (fork ())
2876 {
2877 case 0:
2878 break;
2879 case -1:
2880 /* Parent, failed to fork. */
2881 global_current_report = 0;
2882 g_warning ("%s: Failed to fork: %s",
2883 __func__,
2884 strerror (errno));
2885 set_task_interrupted (task,
2886 "Error forking scan handler."
2887 " Interrupting scan.");
2888 set_report_scan_run_status (global_current_report,
2889 TASK_STATUS_INTERRUPTED);
2890 global_current_report = (report_t) 0;
2891 current_scanner_task = 0;
2892 g_free (report_id);
2893 return -9;
2894 default:
2895 /* Parent, successfully forked. */
2896 global_current_report = 0;
2897 current_scanner_task = 0;
2898 if (report_id_return)
2899 *report_id_return = report_id;
2900 else
2901 g_free (report_id);
2902 return 0;
2903 }
2904
2905 /* Child: Re-open DB after fork and periodically check scan progress.
2906 * If progress == 100%: Parse the report results and other info then exit(0).
2907 * Else, exit(1) in error cases like connection to scanner failure.
2908 */
2909 reinit_manage_process ();
2910 manage_session_init (current_credentials.uuid);
2911
2912 if (scanner_type (task_scanner (task)) == SCANNER_TYPE_OPENVAS
2913 || scanner_type (task_scanner (task) == SCANNER_TYPE_OSP_SENSOR))
2914 {
2915 rc = launch_osp_openvas_task (task, target, report_id, from, &error);
2916 }
2917 else
2918 {
2919 rc = launch_osp_task (task, target, report_id, &error);
2920 }
2921
2922 if (rc)
2923 {
2924 result_t result;
2925
2926 g_warning ("OSP start_scan %s: %s", report_id, error);
2927 result = make_osp_result (task, "", "", "",
2928 threat_message_type ("Error"),
2929 error, "", "", QOD_DEFAULT, NULL);
2930 report_add_result (global_current_report, result);
2931 set_task_run_status (task, TASK_STATUS_DONE);
2932 set_report_scan_run_status (global_current_report, TASK_STATUS_DONE);
2933 set_task_end_time_epoch (task, time (NULL));
2934 set_scan_end_time_epoch (global_current_report, time (NULL));
2935
2936 g_free (error);
2937 g_free (report_id);
2938 exit (-1);
2939 }
2940
2941 snprintf (title, sizeof (title), "gvmd: OSP: Handling scan %s", report_id);
2942 proctitle_set (title);
2943
2944 rc = handle_osp_scan (task, global_current_report, report_id);
2945 g_free (report_id);
2946 if (rc == 0)
2947 {
2948 hosts_set_identifiers (global_current_report);
2949 hosts_set_max_severity (global_current_report, NULL, NULL);
2950 hosts_set_details (global_current_report);
2951 set_task_run_status (task, TASK_STATUS_DONE);
2952 set_report_scan_run_status (global_current_report, TASK_STATUS_DONE);
2953 }
2954 else if (rc == -1 || rc == -2)
2955 {
2956 set_task_run_status (task, TASK_STATUS_STOPPED);
2957 set_report_scan_run_status (global_current_report, TASK_STATUS_STOPPED);
2958 }
2959 else if (rc == -3)
2960 {
2961 set_task_run_status (task, TASK_STATUS_INTERRUPTED);
2962 set_report_scan_run_status (global_current_report, TASK_STATUS_INTERRUPTED);
2963 }
2964
2965 set_task_end_time_epoch (task, time (NULL));
2966 set_scan_end_time_epoch (global_current_report, time (NULL));
2967 global_current_report = 0;
2968 current_scanner_task = (task_t) 0;
2969 exit (rc);
2970 }
2971
2972 /**
2973 * @brief Start a task on an OSP or OpenVAS via OSP scanner.
2974 *
2975 * @param[in] task The task.
2976 * @param[in] from 0 start from beginning, 1 continue from stopped,
2977 * 2 continue if stopped else start from beginning.
2978 * @param[out] report_id The report ID.
2979 *
2980 * @return 0 success, 99 permission denied, -1 error.
2981 */
2982 static int
run_osp_task(task_t task,int from,char ** report_id)2983 run_osp_task (task_t task, int from, char **report_id)
2984 {
2985 target_t target;
2986
2987 target = task_target (task);
2988 if (target)
2989 {
2990 char *uuid;
2991 target_t found;
2992
2993 uuid = target_uuid (target);
2994 if (find_target_with_permission (uuid, &found, "get_targets"))
2995 {
2996 g_free (uuid);
2997 return -1;
2998 }
2999 g_free (uuid);
3000 if (found == 0)
3001 return 99;
3002 }
3003
3004 if (fork_osp_scan_handler (task, target, from, report_id))
3005 {
3006 g_warning ("Couldn't fork OSP scan handler");
3007 return -1;
3008 }
3009 return 0;
3010 }
3011
3012 /**
3013 * @brief Get the number of retries on a scanner connection lost.
3014 *
3015 * @return The number of retries on a scanner connection lost.
3016 */
3017 int
get_scanner_connection_retry()3018 get_scanner_connection_retry ()
3019 {
3020 return scanner_connection_retry;
3021 }
3022
3023 /**
3024 * @brief Set the number of retries on a scanner connection lost.
3025 *
3026 * @param new_retry The number of retries on a scanner connection lost.
3027 */
3028 void
set_scanner_connection_retry(int new_retry)3029 set_scanner_connection_retry (int new_retry)
3030 {
3031 if (new_retry >= 0)
3032 scanner_connection_retry = new_retry;
3033 }
3034
3035
3036 /* CVE tasks. */
3037
3038 /**
3039 * @brief Perform a CVE "scan" on a host.
3040 *
3041 * @param[in] task Task.
3042 * @param[in] report The report to add the host, results and details to.
3043 * @param[in] gvm_host Host.
3044 *
3045 * @return 0 success, 1 failed to get nthlast report for a host.
3046 */
3047 static int
cve_scan_host(task_t task,report_t report,gvm_host_t * gvm_host)3048 cve_scan_host (task_t task, report_t report, gvm_host_t *gvm_host)
3049 {
3050 report_host_t report_host;
3051 gchar *ip, *host;
3052
3053 assert (task);
3054 assert (report);
3055
3056 host = gvm_host_value_str (gvm_host);
3057
3058 ip = report_host_ip (host);
3059 if (ip == NULL)
3060 ip = g_strdup (host);
3061
3062 g_debug ("%s: ip: %s", __func__, ip);
3063
3064 /* Get the last report host that applies to the host IP address. */
3065
3066 if (host_nthlast_report_host (ip, &report_host, 1))
3067 {
3068 g_warning ("%s: Failed to get nthlast report", __func__);
3069 g_free (ip);
3070 return 1;
3071 }
3072
3073 g_debug ("%s: report_host: %llu", __func__, report_host);
3074
3075 if (report_host)
3076 {
3077 iterator_t report_hosts;
3078
3079 /* Get the report_host for the host. */
3080
3081 init_report_host_iterator (&report_hosts, 0, NULL, report_host);
3082 if (next (&report_hosts))
3083 {
3084 iterator_t prognosis;
3085 int prognosis_report_host, start_time;
3086 GArray *results;
3087
3088 /* Add report_host with prognosis results and host details. */
3089
3090 results = g_array_new (TRUE, TRUE, sizeof (result_t));
3091 start_time = time (NULL);
3092 prognosis_report_host = 0;
3093 init_host_prognosis_iterator (&prognosis, report_host);
3094 while (next (&prognosis))
3095 {
3096 const char *app, *cve;
3097 double severity;
3098 gchar *desc;
3099 iterator_t locations_iter;
3100 GString *locations;
3101 result_t result;
3102
3103 if (prognosis_report_host == 0)
3104 prognosis_report_host = manage_report_host_add (report,
3105 ip,
3106 start_time,
3107 0);
3108
3109 severity = prognosis_iterator_cvss_double (&prognosis);
3110
3111 app = prognosis_iterator_cpe (&prognosis);
3112 cve = prognosis_iterator_cve (&prognosis);
3113 locations = g_string_new("");
3114
3115 insert_report_host_detail (global_current_report, ip, "cve", cve,
3116 "CVE Scanner", "App", app);
3117
3118 init_app_locations_iterator (&locations_iter, report_host, app);
3119
3120 while (next (&locations_iter))
3121 {
3122 const char *location;
3123 location = app_locations_iterator_location (&locations_iter);
3124
3125 if (locations->len)
3126 g_string_append (locations, ", ");
3127 g_string_append (locations, location);
3128
3129 insert_report_host_detail (report, ip, "cve", cve,
3130 "CVE Scanner", app, location);
3131
3132 insert_report_host_detail (report, ip, "cve", cve,
3133 "CVE Scanner", "detected_at",
3134 location);
3135
3136 insert_report_host_detail (report, ip, "cve", cve,
3137 "CVE Scanner", "detected_by",
3138 /* Detected by itself. */
3139 cve);
3140 }
3141
3142 desc = g_strdup_printf ("The host carries the product: %s\n"
3143 "It is vulnerable according to: %s.\n"
3144 "%s%s%s"
3145 "\n"
3146 "%s",
3147 app,
3148 cve,
3149 locations->len
3150 ? "The product was found at: "
3151 : "",
3152 locations->len ? locations->str : "",
3153 locations->len ? ".\n" : "",
3154 prognosis_iterator_description
3155 (&prognosis));
3156
3157 g_debug ("%s: making result with severity %1.1f desc [%s]",
3158 __func__, severity, desc);
3159
3160 result = make_cve_result (task, ip, cve, severity, desc);
3161 g_free (desc);
3162
3163 g_array_append_val (results, result);
3164
3165 g_string_free (locations, TRUE);
3166 }
3167 cleanup_iterator (&prognosis);
3168
3169 report_add_results_array (report, results);
3170 g_array_free (results, TRUE);
3171
3172 if (prognosis_report_host)
3173 {
3174 /* Complete the report_host. */
3175
3176 report_host_set_end_time (prognosis_report_host, time (NULL));
3177 insert_report_host_detail (report, ip, "cve", "",
3178 "CVE Scanner", "CVE Scan", "1");
3179 }
3180 }
3181 cleanup_iterator (&report_hosts);
3182 }
3183
3184 g_free (ip);
3185 return 0;
3186 }
3187
3188 /**
3189 * @brief Fork a child to handle a CVE scan's calculating and inserting.
3190 *
3191 * A process is forked to run the task, but the forked process never returns.
3192 *
3193 * @param[in] task The task.
3194 * @param[in] target The target.
3195 *
3196 * @return 0 success, -1 error, -9 failed to fork.
3197 */
3198 static int
fork_cve_scan_handler(task_t task,target_t target)3199 fork_cve_scan_handler (task_t task, target_t target)
3200 {
3201 int pid;
3202 char *report_id, title[128], *hosts;
3203 gvm_hosts_t *gvm_hosts;
3204 gvm_host_t *gvm_host;
3205
3206 assert (task);
3207 assert (target);
3208
3209 if (create_current_report (task, &report_id, TASK_STATUS_REQUESTED))
3210 {
3211 g_debug (" %s: failed to create report", __func__);
3212 return -1;
3213 }
3214
3215 set_task_run_status (task, TASK_STATUS_REQUESTED);
3216
3217 pid = fork ();
3218 switch (pid)
3219 {
3220 case 0:
3221 break;
3222 case -1:
3223 /* Parent, failed to fork. */
3224 g_warning ("%s: Failed to fork: %s",
3225 __func__,
3226 strerror (errno));
3227 set_task_interrupted (task,
3228 "Error forking scan handler."
3229 " Interrupting scan.");
3230 set_report_scan_run_status (global_current_report,
3231 TASK_STATUS_INTERRUPTED);
3232 global_current_report = (report_t) 0;
3233 return -9;
3234 default:
3235 /* Parent, successfully forked. */
3236 g_debug ("%s: %i forked %i", __func__, getpid (), pid);
3237 return 0;
3238 }
3239
3240 /* Child.
3241 *
3242 * Re-open DB and do prognostic calculation. On success exit(0), else
3243 * exit(1). */
3244 reinit_manage_process ();
3245 manage_session_init (current_credentials.uuid);
3246
3247 /* Setup the task. */
3248
3249 set_task_run_status (task, TASK_STATUS_RUNNING);
3250
3251 snprintf (title, sizeof (title), "gvmd: CVE: Handling scan %s", report_id);
3252 g_free (report_id);
3253 proctitle_set (title);
3254
3255 hosts = target_hosts (target);
3256 if (hosts == NULL)
3257 {
3258 set_task_interrupted (task,
3259 "Error in target host list."
3260 " Interrupting scan.");
3261 set_report_scan_run_status (global_current_report, TASK_STATUS_INTERRUPTED);
3262 exit (1);
3263 }
3264
3265 reset_task (task);
3266 set_task_start_time_epoch (task, time (NULL));
3267 set_scan_start_time_epoch (global_current_report, time (NULL));
3268
3269 /* Add the results. */
3270
3271 gvm_hosts = gvm_hosts_new (hosts);
3272 free (hosts);
3273 while ((gvm_host = gvm_hosts_next (gvm_hosts)))
3274 if (cve_scan_host (task, global_current_report, gvm_host))
3275 {
3276 set_task_interrupted (task,
3277 "Failed to get nthlast report."
3278 " Interrupting scan.");
3279 set_report_scan_run_status (global_current_report, TASK_STATUS_INTERRUPTED);
3280 gvm_hosts_free (gvm_hosts);
3281 exit (1);
3282 }
3283 gvm_hosts_free (gvm_hosts);
3284
3285 /* Set the end states. */
3286
3287 set_scan_end_time_epoch (global_current_report, time (NULL));
3288 set_task_end_time_epoch (task, time (NULL));
3289 set_task_run_status (task, TASK_STATUS_DONE);
3290 set_report_scan_run_status (global_current_report, TASK_STATUS_DONE);
3291 global_current_report = 0;
3292 current_scanner_task = (task_t) 0;
3293 exit (0);
3294 }
3295
3296 /**
3297 * @brief Start a CVE task.
3298 *
3299 * @param[in] task The task.
3300 *
3301 * @return 0 success, 99 permission denied, -1 error, -9 failed to fork.
3302 */
3303 static int
run_cve_task(task_t task)3304 run_cve_task (task_t task)
3305 {
3306 target_t target;
3307
3308 target = task_target (task);
3309 if (target)
3310 {
3311 char *uuid;
3312 target_t found;
3313
3314 uuid = target_uuid (target);
3315 if (find_target_with_permission (uuid, &found, "get_targets"))
3316 {
3317 g_free (uuid);
3318 return -1;
3319 }
3320 g_free (uuid);
3321 if (found == 0)
3322 return 99;
3323 }
3324
3325 if (fork_cve_scan_handler (task, target))
3326 {
3327 g_warning ("Couldn't fork CVE scan handler");
3328 return -1;
3329 }
3330 return 0;
3331 }
3332
3333
3334 /* Tasks. */
3335
3336 /**
3337 * @brief Gets the current path of the relay mapper executable.
3338 *
3339 * @return The current relay mapper path.
3340 */
3341 const char *
get_relay_mapper_path()3342 get_relay_mapper_path ()
3343 {
3344 return relay_mapper_path;
3345 }
3346
3347 /**
3348 * @brief Gets the current path of the relay mapper executable.
3349 *
3350 * @param[in] new_path The new relay mapper path.
3351 */
3352 void
set_relay_mapper_path(const char * new_path)3353 set_relay_mapper_path (const char *new_path)
3354 {
3355 g_free (relay_mapper_path);
3356 relay_mapper_path = new_path ? g_strdup (new_path) : NULL;
3357 }
3358
3359 /**
3360 * @brief Gets whether to migrate sensors if relays do not match.
3361 *
3362 * @return Whether to migrate sensors if relays do not match.
3363 */
3364 int
get_relay_migrate_sensors()3365 get_relay_migrate_sensors ()
3366 {
3367 return relay_migrate_sensors;
3368 }
3369
3370 /**
3371 * @brief Sets whether to migrate sensors if relays do not match.
3372 *
3373 * @param[in] new_value The new value.
3374 */
3375 void
set_relay_migrate_sensors(int new_value)3376 set_relay_migrate_sensors (int new_value)
3377 {
3378 relay_migrate_sensors = new_value;
3379 }
3380
3381 /**
3382 * @brief Gets the info about a scanner relay as an XML entity_t.
3383 *
3384 * @param[in] original_host The original hostname or IP address.
3385 * @param[in] original_port The original port number.
3386 * @param[in] protocol The protocol to look for, e.g. "GMP" or "OSP".
3387 * @param[out] ret_entity Return location for the parsed XML.
3388 *
3389 * @return 0: success, -1 error.
3390 */
3391 static int
get_relay_info_entity(const char * original_host,int original_port,const char * protocol,entity_t * ret_entity)3392 get_relay_info_entity (const char *original_host, int original_port,
3393 const char *protocol, entity_t *ret_entity)
3394 {
3395 gchar **cmd, *stdout_str, *stderr_str;
3396 int ret, exit_code;
3397 GError *err;
3398 entity_t relay_entity;
3399
3400 if (ret_entity == NULL)
3401 return -1;
3402
3403 *ret_entity = NULL;
3404 stdout_str = NULL;
3405 stderr_str = NULL;
3406 ret = -1;
3407 exit_code = -1;
3408 err = NULL;
3409
3410 cmd = (gchar **) g_malloc (8 * sizeof (gchar *));
3411 cmd[0] = g_strdup (relay_mapper_path);
3412 cmd[1] = g_strdup ("--host");
3413 cmd[2] = g_strdup (original_host);
3414 cmd[3] = g_strdup ("--port");
3415 cmd[4] = g_strdup_printf ("%d", original_port);
3416 cmd[5] = g_strdup ("--protocol");
3417 cmd[6] = g_strdup (protocol);
3418 cmd[7] = NULL;
3419
3420 if (g_spawn_sync (NULL,
3421 cmd,
3422 NULL,
3423 G_SPAWN_SEARCH_PATH,
3424 NULL,
3425 NULL,
3426 &stdout_str,
3427 &stderr_str,
3428 &exit_code,
3429 &err) == FALSE)
3430 {
3431 g_warning ("%s: g_spawn_sync failed: %s",
3432 __func__, err ? err->message : "");
3433 g_strfreev (cmd);
3434 g_free (stdout_str);
3435 g_free (stderr_str);
3436 return -1;
3437 }
3438 else if (exit_code)
3439 {
3440 g_warning ("%s: mapper exited with code %d",
3441 __func__, exit_code);
3442 g_message ("%s: mapper stderr:\n%s", __func__, stderr_str);
3443 g_debug ("%s: mapper stdout:\n%s", __func__, stdout_str);
3444 g_strfreev (cmd);
3445 g_free (stdout_str);
3446 g_free (stderr_str);
3447 return -1;
3448 }
3449
3450 relay_entity = NULL;
3451 if (parse_entity (stdout_str, &relay_entity))
3452 {
3453 g_warning ("%s: failed to parse mapper output",
3454 __func__);
3455 g_message ("%s: mapper stdout:\n%s", __func__, stdout_str);
3456 g_message ("%s: mapper stderr:\n%s", __func__, stderr_str);
3457 }
3458 else
3459 {
3460 ret = 0;
3461 *ret_entity = relay_entity;
3462 }
3463
3464 g_strfreev (cmd);
3465 g_free (stdout_str);
3466 g_free (stderr_str);
3467
3468 return ret;
3469 }
3470
3471 /**
3472 * @brief Gets whether there is a relay supporting the scanner type.
3473 *
3474 * @param[in] original_host The original hostname or IP address.
3475 * @param[in] original_port The original port number.
3476 * @param[in] type The scanner type to check.
3477 *
3478 * @return Whether there is a relay supporting the scanner type.
3479 */
3480 gboolean
relay_supports_scanner_type(const char * original_host,int original_port,scanner_type_t type)3481 relay_supports_scanner_type (const char *original_host, int original_port,
3482 scanner_type_t type)
3483 {
3484 entity_t relay_entity = NULL;
3485 const char *protocol;
3486 gboolean ret = FALSE;
3487
3488 if (type == SCANNER_TYPE_OSP_SENSOR)
3489 protocol = "OSP";
3490 else
3491 return FALSE;
3492
3493 if (get_relay_info_entity (original_host, original_port,
3494 protocol, &relay_entity) == 0)
3495 {
3496 entity_t host_entity;
3497 host_entity = entity_child (relay_entity, "host");
3498
3499 if (host_entity
3500 && strcmp (entity_text (host_entity), ""))
3501 {
3502 ret = TRUE;
3503 }
3504 }
3505 free_entity (relay_entity);
3506 return ret;
3507 }
3508
3509 /**
3510 * @brief Gets a relay hostname and port for a sensor scanner.
3511 *
3512 * If no mapper is available, a copy of the original host, port and
3513 * CA certificate are returned.
3514 *
3515 * @param[in] original_host The original hostname or IP address.
3516 * @param[in] original_port The original port number.
3517 * @param[in] original_ca_cert The original CA certificate.
3518 * @param[in] protocol The protocol to look for, e.g. "GMP" or "OSP".
3519 * @param[out] new_host The hostname or IP address of the relay.
3520 * @param[out] new_port The port number of the relay.
3521 * @param[out] new_ca_cert The CA certificate of the relay.
3522 *
3523 * @return 0 success, 1 relay not found, -1 error.
3524 */
3525 int
slave_get_relay(const char * original_host,int original_port,const char * original_ca_cert,const char * protocol,gchar ** new_host,int * new_port,gchar ** new_ca_cert)3526 slave_get_relay (const char *original_host,
3527 int original_port,
3528 const char *original_ca_cert,
3529 const char *protocol,
3530 gchar **new_host,
3531 int *new_port,
3532 gchar **new_ca_cert)
3533 {
3534 int ret = -1;
3535
3536 assert (new_host);
3537 assert (new_port);
3538 assert (new_ca_cert);
3539
3540 if (relay_mapper_path == NULL)
3541 {
3542 *new_host = original_host ? g_strdup (original_host) : NULL;
3543 *new_port = original_port;
3544 *new_ca_cert = original_ca_cert ? g_strdup (original_ca_cert) : NULL;
3545
3546 return 0;
3547 }
3548 else
3549 {
3550 entity_t relay_entity = NULL;
3551
3552 if (get_relay_info_entity (original_host, original_port,
3553 protocol, &relay_entity) == 0)
3554 {
3555 entity_t host_entity, port_entity, ca_cert_entity;
3556
3557 host_entity = entity_child (relay_entity, "host");
3558 port_entity = entity_child (relay_entity, "port");
3559 ca_cert_entity = entity_child (relay_entity, "ca_cert");
3560
3561 if (host_entity && port_entity && ca_cert_entity)
3562 {
3563 if (entity_text (host_entity)
3564 && entity_text (port_entity)
3565 && strcmp (entity_text (host_entity), "")
3566 && strcmp (entity_text (port_entity), ""))
3567 {
3568 *new_host = g_strdup (entity_text (host_entity));
3569 *new_port = atoi (entity_text (port_entity));
3570
3571 if (entity_text (ca_cert_entity)
3572 && strcmp (entity_text (ca_cert_entity), ""))
3573 {
3574 *new_ca_cert = g_strdup (entity_text (ca_cert_entity));
3575 }
3576 else
3577 {
3578 *new_ca_cert = NULL;
3579 }
3580 ret = 0;
3581 }
3582 else
3583 {
3584 // Consider relay not found if host or port is empty
3585 ret = 1;
3586 }
3587 }
3588 else
3589 {
3590 g_warning ("%s: mapper output did not contain"
3591 " HOST, PORT and CA_CERT",
3592 __func__);
3593 }
3594 free_entity (relay_entity);
3595 }
3596 }
3597
3598 return ret;
3599 }
3600
3601 /**
3602 * @brief Start or resume a task.
3603 *
3604 * A process will be forked to handle the task, but the forked process will
3605 * never return.
3606 *
3607 * @param[in] task_id The task ID.
3608 * @param[out] report_id The report ID.
3609 * @param[in] from 0 start from beginning, 1 continue from stopped, 2
3610 * continue if stopped else start from beginning.
3611 *
3612 * @return 1 task is active already,
3613 * 3 failed to find task,
3614 * 4 resuming task not supported,
3615 * 99 permission denied,
3616 * -1 error,
3617 * -2 task is missing a target,
3618 * -3 creating the report failed,
3619 * -4 target missing hosts,
3620 * -6 already a task running in this process,
3621 * -9 fork failed.
3622 */
3623 static int
run_task(const char * task_id,char ** report_id,int from)3624 run_task (const char *task_id, char **report_id, int from)
3625 {
3626 task_t task;
3627 scanner_t scanner;
3628 int ret;
3629 const char *permission;
3630
3631 if (current_scanner_task)
3632 return -6;
3633
3634 if (from == 0)
3635 permission = "start_task";
3636 else if (from == 1)
3637 permission = "resume_task";
3638 else
3639 {
3640 assert (0);
3641 permission = "internal_error";
3642 }
3643
3644 task = 0;
3645 if (find_task_with_permission (task_id, &task, permission))
3646 return -1;
3647 if (task == 0)
3648 return 3;
3649
3650 scanner = task_scanner (task);
3651 assert (scanner);
3652 ret = check_available ("scanner", scanner, "get_scanners");
3653 if (ret)
3654 return ret;
3655
3656 if (scanner_type (scanner) == SCANNER_TYPE_CVE)
3657 return run_cve_task (task);
3658
3659 if (scanner_type (scanner) == SCANNER_TYPE_OPENVAS
3660 || scanner_type (scanner) == SCANNER_TYPE_OSP
3661 || scanner_type (scanner) == SCANNER_TYPE_OSP_SENSOR)
3662 return run_osp_task (task, from, report_id);
3663
3664 return -1; // Unknown scanner type
3665 }
3666
3667 /**
3668 * @brief Start a task.
3669 *
3670 * A process will be forked to handle the task, but the forked process will
3671 * never return.
3672 *
3673 * @param[in] task_id The task ID.
3674 * @param[out] report_id The report ID.
3675 *
3676 * @return 1 task is active already,
3677 * 3 failed to find task,
3678 * 4 resuming task not supported,
3679 * 99 permission denied,
3680 * -1 error,
3681 * -2 task is missing a target,
3682 * -3 creating the report failed,
3683 * -4 target missing hosts,
3684 * -6 already a task running in this process,
3685 * -9 fork failed.
3686 */
3687 int
start_task(const char * task_id,char ** report_id)3688 start_task (const char *task_id, char **report_id)
3689 {
3690 if (acl_user_may ("start_task") == 0)
3691 return 99;
3692
3693 return run_task (task_id, report_id, 0);
3694 }
3695
3696 /**
3697 * @brief Stop an OSP task.
3698 *
3699 * @param[in] task The task.
3700 *
3701 * @return 0 on success, else -1.
3702 */
3703 static int
stop_osp_task(task_t task)3704 stop_osp_task (task_t task)
3705 {
3706 osp_connection_t *connection;
3707 int ret = -1;
3708 report_t scan_report;
3709 char *scan_id;
3710 task_t previous_task;
3711 report_t previous_report;
3712
3713 previous_task = current_scanner_task;
3714 previous_report = global_current_report;
3715
3716 scan_report = task_running_report (task);
3717 scan_id = report_uuid (scan_report);
3718 if (!scan_id)
3719 goto end_stop_osp;
3720 connection = osp_scanner_connect (task_scanner (task));
3721 if (!connection)
3722 goto end_stop_osp;
3723
3724 current_scanner_task = task;
3725 global_current_report = task_running_report (task);
3726 set_task_run_status (task, TASK_STATUS_STOP_REQUESTED);
3727 ret = osp_stop_scan (connection, scan_id, NULL);
3728 osp_connection_close (connection);
3729 if (ret)
3730 {
3731 g_free (scan_id);
3732 goto end_stop_osp;
3733 }
3734
3735 connection = osp_scanner_connect (task_scanner (task));
3736 if (!connection)
3737 goto end_stop_osp;
3738 ret = osp_delete_scan (connection, scan_id);
3739 osp_connection_close (connection);
3740 g_free (scan_id);
3741
3742 end_stop_osp:
3743 set_task_end_time_epoch (task, time (NULL));
3744 set_task_run_status (task, TASK_STATUS_STOPPED);
3745 if (scan_report)
3746 {
3747 set_scan_end_time_epoch (scan_report, time (NULL));
3748 set_report_scan_run_status (scan_report, TASK_STATUS_STOPPED);
3749 }
3750 current_scanner_task = previous_task;
3751 global_current_report = previous_report;
3752 if (ret)
3753 return -1;
3754 return 0;
3755 }
3756
3757 /**
3758 * @brief Initiate stopping a task.
3759 *
3760 * @param[in] task Task.
3761 *
3762 * @return 0 on success, 1 if stop requested.
3763 */
3764 int
stop_task_internal(task_t task)3765 stop_task_internal (task_t task)
3766 {
3767 task_status_t run_status;
3768 task_t previous_task;
3769 report_t previous_report;
3770
3771 previous_task = current_scanner_task;
3772 previous_report = global_current_report;
3773
3774 run_status = task_run_status (task);
3775 if (run_status == TASK_STATUS_REQUESTED
3776 || run_status == TASK_STATUS_RUNNING
3777 || run_status == TASK_STATUS_QUEUED)
3778 {
3779 current_scanner_task = task;
3780 global_current_report = task_running_report (task);
3781 set_task_run_status (task, TASK_STATUS_STOP_REQUESTED);
3782 current_scanner_task = previous_task;
3783 global_current_report = previous_report;
3784 return 1;
3785 }
3786
3787 return 0;
3788 }
3789
3790 /**
3791 * @brief Initiate stopping a task.
3792 *
3793 * @param[in] task_id Task UUID.
3794 *
3795 * @return 0 on success, 1 if stop requested, 3 failed to find task,
3796 * 99 permission denied, -1 error.
3797 */
3798 int
stop_task(const char * task_id)3799 stop_task (const char *task_id)
3800 {
3801 task_t task;
3802
3803 if (acl_user_may ("stop_task") == 0)
3804 return 99;
3805
3806 task = 0;
3807 if (find_task_with_permission (task_id, &task, "stop_task"))
3808 return -1;
3809 if (task == 0)
3810 return 3;
3811
3812 if (scanner_type (task_scanner (task)) == SCANNER_TYPE_OPENVAS
3813 || scanner_type (task_scanner (task)) == SCANNER_TYPE_OSP
3814 || scanner_type (task_scanner (task)) == SCANNER_TYPE_OSP_SENSOR)
3815 return stop_osp_task (task);
3816
3817 return stop_task_internal (task);
3818 }
3819
3820 /**
3821 * @brief Resume a task.
3822 *
3823 * A process will be forked to handle the task, but the forked process will
3824 * never return.
3825 *
3826 * @param[in] task_id Task UUID.
3827 * @param[out] report_id If successful, ID of the resultant report.
3828 *
3829 * @return 1 task is active already,
3830 * 3 failed to find task,
3831 * 4 resuming task not supported,
3832 * 22 caller error (task must be in "stopped" or "interrupted" state),
3833 * 99 permission denied,
3834 * -1 error,
3835 * -2 task is missing a target,
3836 * -3 creating the report failed,
3837 * -4 target missing hosts,
3838 * -6 already a task running in this process,
3839 * -9 fork failed.
3840 */
3841 int
resume_task(const char * task_id,char ** report_id)3842 resume_task (const char *task_id, char **report_id)
3843 {
3844 task_t task;
3845 task_status_t run_status;
3846
3847 if (acl_user_may ("resume_task") == 0)
3848 return 99;
3849
3850 task = 0;
3851 if (find_task_with_permission (task_id, &task, "resume_task"))
3852 return -1;
3853 if (task == 0)
3854 return 3;
3855
3856 run_status = task_run_status (task);
3857 if ((run_status == TASK_STATUS_STOPPED)
3858 || (run_status == TASK_STATUS_INTERRUPTED))
3859 return run_task (task_id, report_id, 1);
3860 return 22;
3861 }
3862
3863 /**
3864 * @brief Reassign a task to another slave.
3865 *
3866 * @param[in] task_id UUID of task.
3867 * @param[in] slave_id UUID of slave.
3868 *
3869 * @return 0 success, 2 task not found,
3870 * 3 slave not found, 4 slaves not supported by scanner, 5 task cannot
3871 * be stopped currently, 6 scanner does not allow stopping, 7 new
3872 * scanner does not support slaves, 98 stop and resume permission
3873 * denied, 99 permission denied, -1 error.
3874 */
3875 int
move_task(const char * task_id,const char * slave_id)3876 move_task (const char *task_id, const char *slave_id)
3877 {
3878 task_t task;
3879 int task_scanner_type, slave_scanner_type;
3880 scanner_t slave, scanner;
3881 task_status_t status;
3882 int should_resume_task = 0;
3883
3884 if (task_id == NULL)
3885 return -1;
3886 if (slave_id == NULL)
3887 return -1;
3888
3889 if (acl_user_may ("modify_task") == 0)
3890 return 99;
3891
3892 /* Find the task. */
3893
3894 if (find_task_with_permission (task_id, &task, "get_tasks"))
3895 return -1;
3896 if (task == 0)
3897 return 2;
3898
3899 /* Make sure destination scanner supports slavery. */
3900
3901 if (strcmp (slave_id, "") == 0)
3902 slave_id = SCANNER_UUID_DEFAULT;
3903
3904 if (find_scanner_with_permission (slave_id, &slave, "get_scanners"))
3905 return -1;
3906 if (slave == 0)
3907 return 3;
3908
3909 slave_scanner_type = scanner_type (slave);
3910 if (slave_scanner_type != SCANNER_TYPE_OPENVAS)
3911 return 7;
3912
3913 /* Make sure current scanner supports slavery. */
3914
3915 scanner = task_scanner (task);
3916 if (scanner == 0)
3917 return -1;
3918
3919 task_scanner_type = scanner_type (scanner);
3920 if (task_scanner_type != SCANNER_TYPE_OPENVAS)
3921 return 4;
3922
3923 /* Stop task if required. */
3924
3925 status = task_run_status (task);
3926
3927 switch (status)
3928 {
3929 case TASK_STATUS_DELETE_REQUESTED:
3930 case TASK_STATUS_DELETE_ULTIMATE_REQUESTED:
3931 case TASK_STATUS_DELETE_WAITING:
3932 case TASK_STATUS_DELETE_ULTIMATE_WAITING:
3933 case TASK_STATUS_REQUESTED:
3934 // Task cannot be stopped now
3935 return 5;
3936 break;
3937 case TASK_STATUS_RUNNING:
3938 case TASK_STATUS_QUEUED:
3939 if (task_scanner_type == SCANNER_TYPE_CVE)
3940 return 6;
3941 // Check permissions to stop and resume task
3942 if (acl_user_has_access_uuid ("task", task_id, "stop_task", 0)
3943 && acl_user_has_access_uuid ("task", task_id, "resume_task", 0))
3944 {
3945 // Stop the task, wait and resume after changes
3946 stop_task_internal (task);
3947 should_resume_task = 1;
3948
3949 status = task_run_status (task);
3950 while (status == TASK_STATUS_STOP_REQUESTED
3951 || status == TASK_STATUS_STOP_WAITING)
3952 {
3953 sleep (5);
3954 status = task_run_status (task);
3955 }
3956 }
3957 else
3958 return 98;
3959 break;
3960 case TASK_STATUS_STOP_REQUESTED:
3961 case TASK_STATUS_STOP_WAITING:
3962 while (status == TASK_STATUS_STOP_REQUESTED
3963 || status == TASK_STATUS_STOP_WAITING)
3964 {
3965 sleep (5);
3966 status = task_run_status (task);
3967 }
3968 break;
3969 default:
3970 break;
3971 }
3972
3973 /* Update scanner. */
3974
3975 set_task_scanner (task, slave);
3976
3977 /* Resume task if required. */
3978
3979 if (should_resume_task)
3980 resume_task (task_id, NULL);
3981
3982 return 0;
3983 }
3984
3985
3986 /* Credentials. */
3987
3988 /**
3989 * @brief Get the written-out name of an LSC Credential type.
3990 *
3991 * @param[in] abbreviation The type abbreviation.
3992 *
3993 * @return The written-out type name.
3994 */
3995 const char*
credential_full_type(const char * abbreviation)3996 credential_full_type (const char* abbreviation)
3997 {
3998 if (abbreviation == NULL)
3999 return NULL;
4000 else if (strcasecmp (abbreviation, "cc") == 0)
4001 return "client certificate";
4002 else if (strcasecmp (abbreviation, "pw") == 0)
4003 return "password only";
4004 else if (strcasecmp (abbreviation, "snmp") == 0)
4005 return "SNMP";
4006 else if (strcasecmp (abbreviation, "up") == 0)
4007 return "username + password";
4008 else if (strcasecmp (abbreviation, "usk") == 0)
4009 return "username + SSH key";
4010 else
4011 return abbreviation;
4012 }
4013
4014
4015 /* System reports. */
4016
4017 /**
4018 * @brief Get a performance report from an OSP scanner.
4019 *
4020 * @param[in] scanner The scanner to get the performance report from.
4021 * @param[in] start The start time of the performance report.
4022 * @param[in] end The end time of the performance report.
4023 * @param[in] titles The end titles for the performance report.
4024 * @param[in] performance_str The performance string.
4025 * @param[in] error The error message text, if any.
4026 *
4027 * @return 0 if successful, 6 could not connect to scanner or failed to get
4028 * performance report
4029 */
4030 static int
get_osp_performance_string(scanner_t scanner,int start,int end,const char * titles,gchar ** performance_str,gchar ** error)4031 get_osp_performance_string (scanner_t scanner, int start, int end,
4032 const char *titles, gchar **performance_str,
4033 gchar **error)
4034 {
4035 char *host, *ca_pub, *key_pub, *key_priv;
4036 int port;
4037 osp_connection_t *connection = NULL;
4038 osp_get_performance_opts_t opts;
4039 int connection_retry, return_value;
4040
4041 host = scanner_host (scanner);
4042 port = scanner_port (scanner);
4043 ca_pub = scanner_ca_pub (scanner);
4044 key_pub = scanner_key_pub (scanner);
4045 key_priv = scanner_key_priv (scanner);
4046
4047 connection_retry = get_scanner_connection_retry ();
4048 connection = osp_connect_with_data (host, port, ca_pub, key_pub, key_priv);
4049 while (connection == NULL && connection_retry > 0)
4050 {
4051 sleep(1);
4052 connection = osp_connect_with_data (host, port,
4053 ca_pub, key_pub, key_priv);
4054 connection_retry--;
4055 }
4056
4057 free (host);
4058 free (ca_pub);
4059 free (key_pub);
4060 free (key_priv);
4061
4062 if (connection == NULL)
4063 {
4064 *error = g_strdup("Could not connect to scanner");
4065 return 6;
4066 }
4067
4068 opts.start = start;
4069 opts.end = end;
4070 opts.titles = g_strdup (titles);
4071
4072 return_value = osp_get_performance_ext (connection, opts,
4073 performance_str, error);
4074
4075 if (return_value)
4076 {
4077 osp_connection_close (connection);
4078 g_warning ("Error getting OSP performance report: %s", *error);
4079 g_free (opts.titles);
4080 return 6;
4081 }
4082
4083 osp_connection_close (connection);
4084 g_free (opts.titles);
4085
4086 return 0;
4087 }
4088
4089 /**
4090 * @brief Header for fallback system report.
4091 */
4092 #define FALLBACK_SYSTEM_REPORT_HEADER \
4093 "This is the most basic, fallback report. The system can be configured to\n" \
4094 "produce more powerful reports. Please contact your system administrator\n" \
4095 "for more information.\n\n"
4096
4097 /**
4098 * @brief Get the fallback report as a string.
4099 *
4100 * @param[in] fallback_report The string for the fallback report.
4101 */
4102 static void
get_fallback_report_string(GString * fallback_report)4103 get_fallback_report_string(GString *fallback_report)
4104 {
4105 int ret;
4106 double load[3];
4107 GError *get_error;
4108 gchar *output;
4109 gsize output_len;
4110
4111 g_string_append_printf (fallback_report, FALLBACK_SYSTEM_REPORT_HEADER);
4112
4113 ret = getloadavg (load, 3);
4114 if (ret == 3)
4115 {
4116 g_string_append_printf (fallback_report,
4117 "Load average for past minute: %.1f\n",
4118 load[0]);
4119 g_string_append_printf (fallback_report,
4120 "Load average for past 5 minutes: %.1f\n",
4121 load[1]);
4122 g_string_append_printf (fallback_report,
4123 "Load average for past 15 minutes: %.1f\n",
4124 load[2]);
4125 }
4126 else
4127 g_string_append (fallback_report, "Error getting load averages.\n");
4128
4129 get_error = NULL;
4130 g_file_get_contents ("/proc/meminfo",
4131 &output,
4132 &output_len,
4133 &get_error);
4134 if (get_error)
4135 g_error_free (get_error);
4136 else
4137 {
4138 gchar *safe;
4139 g_string_append (fallback_report, "\n/proc/meminfo:\n\n");
4140 safe = g_markup_escape_text (output, strlen (output));
4141 g_free (output);
4142 g_string_append (fallback_report, safe);
4143 g_free (safe);
4144 }
4145 }
4146
4147 /**
4148 * @brief Command called by get_system_report_types.
4149 * gvmcg stands for gvm-create-graphs.
4150 */
4151 #define COMMAND "gvmcg 0 titles"
4152
4153 /**
4154 * @brief Get system report types.
4155 *
4156 * @param[in] required_type Single type to limit types to.
4157 * @param[out] types Types on success.
4158 * @param[out] start Actual start of types, which caller must free.
4159 * @param[out] slave_id ID of slave.
4160 *
4161 * @return 0 if successful, 1 failed to find report type, 2 failed to find
4162 * slave, 3 serving the fallback, 4 could not connect to slave,
4163 * 5 authentication failed, 6 failed to get system report,
4164 * -1 otherwise.
4165 */
4166 static int
get_system_report_types(const char * required_type,gchar *** start,gchar *** types,const char * slave_id)4167 get_system_report_types (const char *required_type, gchar ***start,
4168 gchar ***types, const char *slave_id)
4169 {
4170 gchar *astdout = NULL;
4171 gchar *astderr = NULL;
4172 gchar *slave_error = NULL;
4173 GError *err = NULL;
4174 gint exit_status;
4175
4176 if (slave_id && strcmp (slave_id, "0"))
4177 {
4178 int ret;
4179 scanner_t slave;
4180
4181 slave = 0;
4182
4183 if (find_scanner_with_permission (slave_id, &slave, "get_scanners"))
4184 return -1;
4185 if (slave == 0)
4186 return 2;
4187
4188 // Assume OSP scanner
4189 ret = get_osp_performance_string (slave, 0, 0, "titles",
4190 &astdout, &slave_error);
4191
4192 if (ret)
4193 {
4194 g_free (slave_error);
4195 return ret;
4196 }
4197 }
4198 else
4199 {
4200 g_debug (" command: " COMMAND);
4201
4202 if ((g_spawn_command_line_sync (COMMAND,
4203 &astdout,
4204 &astderr,
4205 &exit_status,
4206 &err)
4207 == FALSE)
4208 || (WIFEXITED (exit_status) == 0)
4209 || WEXITSTATUS (exit_status))
4210 {
4211 g_debug ("%s: gvmcg failed with %d", __func__, exit_status);
4212 g_debug ("%s: stdout: %s", __func__, astdout);
4213 g_debug ("%s: stderr: %s", __func__, astderr);
4214 g_free (astdout);
4215 g_free (astderr);
4216 *start = *types = g_malloc0 (sizeof (gchar*) * 2);
4217 (*start)[0] = g_strdup ("fallback Fallback Report");
4218 (*start)[0][strlen ("fallback")] = '\0';
4219 return 3;
4220 }
4221 }
4222
4223 if (astdout)
4224 {
4225 char **type;
4226 *start = *types = type = g_strsplit (g_strchomp (astdout), "\n", 0);
4227 while (*type)
4228 {
4229 char *space;
4230 space = strchr (*type, ' ');
4231 if (space == NULL)
4232 {
4233 g_strfreev (*types);
4234 *types = NULL;
4235 g_free (astdout);
4236 g_free (astderr);
4237 g_free (slave_error);
4238 return -1;
4239 }
4240 *space = '\0';
4241 if (required_type && (strcmp (*type, required_type) == 0))
4242 {
4243 char **next;
4244 /* Found the single given type. */
4245 next = type + 1;
4246 while (*next)
4247 {
4248 free (*next);
4249 next++;
4250 }
4251 next = type + 1;
4252 *next = NULL;
4253 *types = type;
4254 g_free (astdout);
4255 g_free (astderr);
4256 g_free (slave_error);
4257 return 0;
4258 }
4259 type++;
4260 }
4261 if (required_type)
4262 {
4263 /* Failed to find the single given type. */
4264 g_free (astdout);
4265 g_free (astderr);
4266 g_free (slave_error);
4267 g_strfreev (*types);
4268 return 1;
4269 }
4270 }
4271 else
4272 *start = *types = g_malloc0 (sizeof (gchar*));
4273
4274 g_free (astdout);
4275 g_free (astderr);
4276 g_free (slave_error);
4277 return 0;
4278 }
4279
4280 #undef COMMAND
4281
4282 /**
4283 * @brief Initialise a system report type iterator.
4284 *
4285 * @param[in] iterator Iterator.
4286 * @param[in] type Single report type to iterate over, NULL for all.
4287 * @param[in] slave_id ID of slave to get reports from. 0 for local.
4288 *
4289 * @return 0 on success, 1 failed to find report type, 2 failed to find slave,
4290 * 3 used the fallback report, 4 could not connect to slave,
4291 * 5 authentication failed, 6 failed to get system report,
4292 * 99 permission denied, -1 on error.
4293 */
4294 int
init_system_report_type_iterator(report_type_iterator_t * iterator,const char * type,const char * slave_id)4295 init_system_report_type_iterator (report_type_iterator_t* iterator,
4296 const char* type,
4297 const char* slave_id)
4298 {
4299 int ret;
4300
4301 if (acl_user_may ("get_system_reports") == 0)
4302 return 99;
4303
4304 ret = get_system_report_types (type, &iterator->start, &iterator->current,
4305 slave_id);
4306 if (ret == 0 || ret == 3)
4307 {
4308 iterator->current--;
4309 return ret;
4310 }
4311 return ret;
4312 }
4313
4314 /**
4315 * @brief Cleanup a report type iterator.
4316 *
4317 * @param[in] iterator Iterator.
4318 */
4319 void
cleanup_report_type_iterator(report_type_iterator_t * iterator)4320 cleanup_report_type_iterator (report_type_iterator_t* iterator)
4321 {
4322 g_strfreev (iterator->start);
4323 }
4324
4325 /**
4326 * @brief Increment a report type iterator.
4327 *
4328 * The caller must stop using this after it returns FALSE.
4329 *
4330 * @param[in] iterator Task iterator.
4331 *
4332 * @return TRUE if there was a next item, else FALSE.
4333 */
4334 gboolean
next_report_type(report_type_iterator_t * iterator)4335 next_report_type (report_type_iterator_t* iterator)
4336 {
4337 iterator->current++;
4338 if (*iterator->current == NULL) return FALSE;
4339 return TRUE;
4340 }
4341
4342 /**
4343 * @brief Return the name from a report type iterator.
4344 *
4345 * @param[in] iterator Iterator.
4346 *
4347 * @return Name.
4348 */
4349 const char*
report_type_iterator_name(report_type_iterator_t * iterator)4350 report_type_iterator_name (report_type_iterator_t* iterator)
4351 {
4352 return (const char*) *iterator->current;
4353 }
4354
4355 /**
4356 * @brief Return the title from a report type iterator.
4357 *
4358 * @param[in] iterator Iterator.
4359 *
4360 * @return Title.
4361 */
4362 const char*
report_type_iterator_title(report_type_iterator_t * iterator)4363 report_type_iterator_title (report_type_iterator_t* iterator)
4364 {
4365 const char *name = *iterator->current;
4366 return name + strlen (name) + 1;
4367 }
4368
4369 /**
4370 * @brief Default duration for system reports.
4371 */
4372 #define DEFAULT_DURATION 86400L
4373
4374 /**
4375 * @brief Generate params for gvmcg or OSP get_performance.
4376 *
4377 * @param[in] duration The duration as a string
4378 * @param[in] start_time The start time as a string
4379 * @param[in] end_time The end time as a string
4380 * @param[out] param_1 Output of the first parameter (start or duration)
4381 * @param[out] param_2 Output of the second parameter (end time)
4382 * @param[out] params_count The number of valid parameters
4383 */
4384 void
parse_performance_params(const char * duration,const char * start_time,const char * end_time,time_t * param_1,time_t * param_2,int * params_count)4385 parse_performance_params (const char *duration,
4386 const char *start_time,
4387 const char *end_time,
4388 time_t *param_1,
4389 time_t *param_2,
4390 int *params_count)
4391 {
4392 time_t start_time_num, end_time_num, duration_num;
4393 start_time_num = 0;
4394 end_time_num = 0;
4395 duration_num = 0;
4396
4397 *param_1 = 0;
4398 *param_2 = 0;
4399 *params_count = 0;
4400
4401 if (duration && strcmp (duration, ""))
4402 {
4403 duration_num = atol (duration);
4404 if (duration_num == 0)
4405 return;
4406 }
4407 if (start_time && strcmp (start_time, ""))
4408 {
4409 start_time_num = parse_iso_time (start_time);
4410 if (start_time_num == 0)
4411 return;
4412 }
4413 if (end_time && strcmp (end_time, ""))
4414 {
4415 end_time_num = parse_iso_time (end_time);
4416 if (end_time_num == 0)
4417 return;
4418 }
4419
4420 if (start_time && strcmp (start_time, ""))
4421 {
4422 if (end_time && strcmp (end_time, ""))
4423 {
4424 *param_1 = start_time_num;
4425 *param_2 = end_time_num;
4426 *params_count = 2;
4427 }
4428 else if (duration && strcmp (duration, ""))
4429 {
4430 *param_1 = start_time_num;
4431 *param_2 = start_time_num + duration_num;
4432 *params_count = 2;
4433 }
4434 else
4435 {
4436 *param_1 = start_time_num;
4437 *param_2 = start_time_num + DEFAULT_DURATION;
4438 *params_count = 2;
4439 }
4440 }
4441 else if (end_time && strcmp (end_time, ""))
4442 {
4443 if (duration && strcmp (duration, ""))
4444 {
4445 *param_1 = end_time_num - duration_num;
4446 *param_2 = end_time_num;
4447 *params_count = 2;
4448 }
4449 else
4450 {
4451 *param_1 = end_time_num - DEFAULT_DURATION,
4452 *param_1 = end_time_num,
4453 *params_count = 2;
4454 }
4455 }
4456 else
4457 {
4458 if (duration && strcmp (duration, ""))
4459 {
4460 *param_1 = duration_num;
4461 *params_count = 1;
4462 }
4463 else
4464 {
4465 *param_1 = DEFAULT_DURATION;
4466 *params_count = 1;
4467 }
4468 }
4469 }
4470
4471 /**
4472 * @brief Get a system report.
4473 *
4474 * @param[in] name Name of report.
4475 * @param[in] duration Time range of report, in seconds.
4476 * @param[in] start_time Time of first data point in report.
4477 * @param[in] end_time Time of last data point in report.
4478 * @param[in] slave_id ID of slave to get report from. 0 for local.
4479 * @param[out] report On success, report in base64 if such a report exists
4480 * else NULL. Arbitrary on error.
4481 *
4482 * @return 0 if successful (including failure to find report), -1 on error,
4483 * 2 could not find slave scanner,
4484 * 3 if used the fallback report or got an error message to print
4485 */
4486 int
manage_system_report(const char * name,const char * duration,const char * start_time,const char * end_time,const char * slave_id,char ** report)4487 manage_system_report (const char *name, const char *duration,
4488 const char *start_time, const char *end_time,
4489 const char *slave_id, char **report)
4490 {
4491 gchar *astdout = NULL;
4492 gchar *astderr = NULL;
4493 gchar *slave_error = NULL;
4494 GError *err = NULL;
4495 GString *buffer = NULL;
4496 gint exit_status;
4497 gint return_code = 0;
4498 gchar *command = NULL;
4499 time_t cmd_param_1, cmd_param_2;
4500 int params_count;
4501
4502 assert (name);
4503
4504 parse_performance_params (duration, start_time, end_time,
4505 &cmd_param_1, &cmd_param_2, ¶ms_count);
4506
4507 *report = NULL;
4508
4509 if (params_count == 0)
4510 return manage_system_report ("blank", NULL, NULL, NULL, NULL, report);
4511
4512 if (slave_id && strcmp (slave_id, "0"))
4513 {
4514 scanner_t slave;
4515
4516 slave = 0;
4517
4518 if (find_scanner_with_permission (slave_id, &slave, "get_scanners"))
4519 return -1;
4520 if (slave == 0)
4521 return 2;
4522
4523 if (params_count == 1)
4524 {
4525 // only duration
4526 time_t now;
4527 now = time (NULL);
4528 return_code = get_osp_performance_string (slave,
4529 now - cmd_param_1,
4530 now,
4531 name,
4532 report,
4533 &slave_error);
4534 }
4535 else
4536 {
4537 // start and end time
4538 return_code = get_osp_performance_string (slave,
4539 cmd_param_1,
4540 cmd_param_2,
4541 name,
4542 report,
4543 &slave_error);
4544 }
4545 }
4546 else
4547 {
4548 if (!g_find_program_in_path ("gvmcg"))
4549 {
4550 buffer = g_string_new ("");
4551 get_fallback_report_string(buffer);
4552 *report = g_string_free (buffer, FALSE);
4553 return_code = 7;
4554 }
4555 else
4556 {
4557 /* For simplicity, it's up to the command to do the base64
4558 * encoding.
4559 */
4560 if (params_count == 1)
4561 command = g_strdup_printf ("gvmcg %ld %s",
4562 cmd_param_1,
4563 name);
4564 else
4565 command = g_strdup_printf ("gvmcg %ld %ld %s",
4566 cmd_param_1,
4567 cmd_param_2,
4568 name);
4569
4570 g_debug (" command: %s", command);
4571
4572 if ((g_spawn_command_line_sync (command,
4573 &astdout,
4574 &astderr,
4575 &exit_status,
4576 &err)
4577 == FALSE)
4578 || (WIFEXITED (exit_status) == 0)
4579 || WEXITSTATUS (exit_status))
4580 {
4581 return_code = 3;
4582
4583 g_warning ("%s: Failed to create performance graph -- %s",
4584 __func__, astderr);
4585 g_debug ("%s: gvmcg failed with %d", __func__, exit_status);
4586 g_debug ("%s: stdout: %s", __func__, astdout);
4587 g_debug ("%s: stderr: %s", __func__, astderr);
4588 }
4589 g_free (command);
4590 }
4591 }
4592
4593 if (return_code == 3 || return_code == 6)
4594 {
4595 buffer = g_string_new ("");
4596 g_string_append_printf (buffer,
4597 "Failed to create performance graph: %s",
4598 (return_code == 3 ? astderr : slave_error));
4599 *report = g_string_free (buffer, FALSE);
4600 }
4601
4602 g_free (astderr);
4603 g_free (slave_error);
4604
4605 if (return_code == 6 || return_code == 7)
4606 return_code = 3;
4607
4608 if ((astdout == NULL || strlen (astdout) == 0) &&
4609 *report == NULL)
4610 {
4611 g_free (astdout);
4612 if (strcmp (name, "blank") == 0)
4613 return -1;
4614 return manage_system_report ("blank", NULL, NULL, NULL,
4615 NULL, report);
4616 }
4617 else if (*report == NULL)
4618 *report = astdout;
4619 else
4620 g_free (astdout);
4621
4622 return return_code;
4623 }
4624
4625
4626 /* Scheduling. */
4627
4628 /**
4629 * @brief Flag for manage_auth_allow_all.
4630 *
4631 * 1 if set via scheduler, 2 if set via event, else 0.
4632 */
4633 int authenticate_allow_all = 0;
4634
4635 /**
4636 * @brief UUID of user whose scheduled task is to be started (in connection
4637 * with authenticate_allow_all).
4638 */
4639 static gchar* schedule_user_uuid = NULL;
4640
4641 /**
4642 * @brief Ensure that any subsequent authentications succeed.
4643 *
4644 * @param[in] scheduled Whether this is happening from the scheduler.
4645 */
4646 void
manage_auth_allow_all(int scheduled)4647 manage_auth_allow_all (int scheduled)
4648 {
4649 authenticate_allow_all = scheduled ? 1 : 2;
4650 }
4651
4652 /**
4653 * @brief Access UUID of user that scheduled the current task.
4654 *
4655 * @return UUID of user that scheduled the current task.
4656 */
4657 const gchar*
get_scheduled_user_uuid()4658 get_scheduled_user_uuid ()
4659 {
4660 return schedule_user_uuid;
4661 }
4662
4663 /**
4664 * @brief Set UUID of user that scheduled the current task.
4665 * The previous value is freed and a copy of the UUID is created.
4666 *
4667 * @param user_uuid UUID of user that scheduled the current task.
4668 */
4669 void
set_scheduled_user_uuid(const gchar * user_uuid)4670 set_scheduled_user_uuid (const gchar* user_uuid)
4671 {
4672 gchar *user_uuid_copy = user_uuid ? g_strdup (user_uuid) : NULL;
4673 g_free (schedule_user_uuid);
4674 schedule_user_uuid = user_uuid_copy;
4675 }
4676
4677 /**
4678 * @brief Task info, for scheduler.
4679 */
4680 typedef struct
4681 {
4682 gchar *owner_uuid; ///< UUID of owner.
4683 gchar *owner_name; ///< Name of owner.
4684 gchar *task_uuid; ///< UUID of task.
4685 } scheduled_task_t;
4686
4687 /**
4688 * @brief Create a schedule task structure.
4689 *
4690 * @param[in] task_uuid UUID of task.
4691 * @param[in] owner_uuid UUID of owner.
4692 * @param[in] owner_name Name of owner.
4693 *
4694 * @return Scheduled task structure.
4695 */
4696 static scheduled_task_t *
scheduled_task_new(const gchar * task_uuid,const gchar * owner_uuid,const gchar * owner_name)4697 scheduled_task_new (const gchar* task_uuid, const gchar* owner_uuid,
4698 const gchar* owner_name)
4699 {
4700 scheduled_task_t *scheduled_task;
4701
4702 scheduled_task = g_malloc (sizeof (*scheduled_task));
4703 scheduled_task->task_uuid = g_strdup (task_uuid);
4704 scheduled_task->owner_uuid = g_strdup (owner_uuid);
4705 scheduled_task->owner_name = g_strdup (owner_name);
4706
4707 return scheduled_task;
4708 }
4709
4710 /**
4711 * @brief Set UUID of user that scheduled the current task.
4712 *
4713 * @param[in] scheduled_task Scheduled task.
4714 */
4715 static void
scheduled_task_free(scheduled_task_t * scheduled_task)4716 scheduled_task_free (scheduled_task_t *scheduled_task)
4717 {
4718 g_free (scheduled_task->task_uuid);
4719 g_free (scheduled_task->owner_uuid);
4720 g_free (scheduled_task->owner_name);
4721 g_free (scheduled_task);
4722 }
4723
4724 /**
4725 * @brief Start a task, for the scheduler.
4726 *
4727 * @param[in] scheduled_task Scheduled task.
4728 * @param[in] fork_connection Function that forks a child which is connected
4729 * to the Manager. Must return PID in parent, 0
4730 * in child, or -1 on error.
4731 * @param[in] sigmask_current Sigmask to restore in child.
4732 *
4733 * @return 0 success, -1 error. Child does not return.
4734 */
4735 static int
scheduled_task_start(scheduled_task_t * scheduled_task,manage_connection_forker_t fork_connection,sigset_t * sigmask_current)4736 scheduled_task_start (scheduled_task_t *scheduled_task,
4737 manage_connection_forker_t fork_connection,
4738 sigset_t *sigmask_current)
4739 {
4740 char title[128];
4741 int pid;
4742 gvm_connection_t connection;
4743 gmp_authenticate_info_opts_t auth_opts;
4744
4745 /* Fork a child to start the task and wait for the response, so that the
4746 * parent can return to the main loop. Only the parent returns. */
4747
4748 pid = fork ();
4749 switch (pid)
4750 {
4751 case 0:
4752 /* Child. Carry on to start the task, reopen the database (required
4753 * after fork). */
4754
4755 /* Restore the sigmask that was blanked for pselect. */
4756 pthread_sigmask (SIG_SETMASK, sigmask_current, NULL);
4757
4758 reinit_manage_process ();
4759 manage_session_init (current_credentials.uuid);
4760 break;
4761
4762 case -1:
4763 /* Parent on error. */
4764 g_warning ("%s: fork failed", __func__);
4765 return -1;
4766
4767 default:
4768 /* Parent. Continue to next task. */
4769 g_debug ("%s: %i forked %i", __func__, getpid (), pid);
4770 return 0;
4771 }
4772
4773 /* Run the callback to fork a child connected to the Manager. */
4774
4775 pid = fork_connection (&connection, scheduled_task->owner_uuid);
4776 switch (pid)
4777 {
4778 case 0:
4779 /* Child. Break, start task, exit. */
4780 break;
4781
4782 case -1:
4783 /* Parent on error. */
4784 g_warning ("%s: fork_connection failed", __func__);
4785 reschedule_task (scheduled_task->task_uuid);
4786 scheduled_task_free (scheduled_task);
4787 exit (EXIT_FAILURE);
4788 break;
4789
4790 default:
4791 {
4792 int status;
4793
4794 /* Parent. Wait for child, to check return. */
4795
4796 snprintf (title, sizeof (title),
4797 "gvmd: scheduler: waiting for %i",
4798 pid);
4799 proctitle_set (title);
4800
4801 g_debug ("%s: %i fork_connectioned %i",
4802 __func__, getpid (), pid);
4803
4804 if (signal (SIGCHLD, SIG_DFL) == SIG_ERR)
4805 g_warning ("%s: failed to set SIGCHLD", __func__);
4806 while (waitpid (pid, &status, 0) < 0)
4807 {
4808 if (errno == ECHILD)
4809 {
4810 g_warning ("%s: Failed to get child exit,"
4811 " so task '%s' may not have been scheduled",
4812 __func__,
4813 scheduled_task->task_uuid);
4814 scheduled_task_free (scheduled_task);
4815 exit (EXIT_FAILURE);
4816 }
4817 if (errno == EINTR)
4818 continue;
4819 g_warning ("%s: waitpid: %s",
4820 __func__,
4821 strerror (errno));
4822 g_warning ("%s: As a result, task '%s' may not have been"
4823 " scheduled",
4824 __func__,
4825 scheduled_task->task_uuid);
4826 scheduled_task_free (scheduled_task);
4827 exit (EXIT_FAILURE);
4828 }
4829 if (WIFEXITED (status))
4830 switch (WEXITSTATUS (status))
4831 {
4832 case EXIT_SUCCESS:
4833 {
4834 schedule_t schedule;
4835 int periods;
4836 const gchar *task_uuid;
4837
4838 /* Child succeeded, so task successfully started. */
4839
4840 task_uuid = scheduled_task->task_uuid;
4841 schedule = task_schedule_uuid (task_uuid);
4842 if (schedule
4843 && schedule_period (schedule) == 0
4844 && schedule_duration (schedule) == 0
4845 /* Check next time too, in case the user changed
4846 * the schedule after this task was added to the
4847 * "starts" list. */
4848 && task_schedule_next_time_uuid (task_uuid) == 0)
4849 /* A once-off schedule without a duration, remove
4850 * it from the task. If it has a duration it
4851 * will be removed by manage_schedule via
4852 * clear_duration_schedules, after the duration. */
4853 set_task_schedule_uuid (task_uuid, 0, -1);
4854 else if ((periods = task_schedule_periods_uuid
4855 (task_uuid)))
4856 {
4857 /* A task restricted to a certain number of
4858 * scheduled runs. */
4859 if (periods > 1)
4860 {
4861 set_task_schedule_periods (task_uuid,
4862 periods - 1);
4863 }
4864 else if (periods == 1
4865 && schedule_duration (schedule) == 0)
4866 {
4867 /* Last run of a task restricted to a certain
4868 * number of scheduled runs. */
4869 set_task_schedule_uuid (task_uuid, 0, 1);
4870 }
4871 else if (periods == 1)
4872 /* Flag that the task has started, for
4873 * update_duration_schedule_periods. */
4874 set_task_schedule_next_time_uuid (task_uuid, 0);
4875 }
4876 }
4877 scheduled_task_free (scheduled_task);
4878 exit (EXIT_SUCCESS);
4879
4880 case EXIT_FAILURE:
4881 default:
4882 break;
4883 }
4884
4885 /* Child failed, reset task schedule time and exit. */
4886
4887 g_warning ("%s: child failed", __func__);
4888 reschedule_task (scheduled_task->task_uuid);
4889 scheduled_task_free (scheduled_task);
4890 exit (EXIT_FAILURE);
4891 }
4892 }
4893
4894 /* Start the task. */
4895
4896 snprintf (title, sizeof (title),
4897 "gvmd: scheduler: starting %s",
4898 scheduled_task->task_uuid);
4899 proctitle_set (title);
4900
4901 auth_opts = gmp_authenticate_info_opts_defaults;
4902 auth_opts.username = scheduled_task->owner_name;
4903 if (gmp_authenticate_info_ext_c (&connection, auth_opts))
4904 {
4905 g_warning ("%s: gmp_authenticate failed", __func__);
4906 scheduled_task_free (scheduled_task);
4907 gvm_connection_free (&connection);
4908 exit (EXIT_FAILURE);
4909 }
4910
4911 if (gmp_resume_task_report_c (&connection,
4912 scheduled_task->task_uuid,
4913 NULL))
4914 {
4915 gmp_start_task_opts_t opts;
4916
4917 opts = gmp_start_task_opts_defaults;
4918 opts.task_id = scheduled_task->task_uuid;
4919
4920 switch (gmp_start_task_ext_c (&connection, opts))
4921 {
4922 case 0:
4923 break;
4924
4925 case 99:
4926 g_warning ("%s: user denied permission to start task", __func__);
4927 scheduled_task_free (scheduled_task);
4928 gvm_connection_free (&connection);
4929 /* Return success, so that parent stops trying to start the task. */
4930 exit (EXIT_SUCCESS);
4931
4932 default:
4933 g_warning ("%s: gmp_start_task and gmp_resume_task failed", __func__);
4934 scheduled_task_free (scheduled_task);
4935 gvm_connection_free (&connection);
4936 exit (EXIT_FAILURE);
4937 }
4938 }
4939
4940 scheduled_task_free (scheduled_task);
4941 gvm_connection_free (&connection);
4942 exit (EXIT_SUCCESS);
4943 }
4944
4945 /**
4946 * @brief Stop a task, for the scheduler.
4947 *
4948 * @param[in] scheduled_task Scheduled task.
4949 * @param[in] fork_connection Function that forks a child which is connected
4950 * to the Manager. Must return PID in parent, 0
4951 * in child, or -1 on error.
4952 * @param[in] sigmask_current Sigmask to restore in child.
4953 *
4954 * @return 0 success, -1 error. Child does not return.
4955 */
4956 static int
scheduled_task_stop(scheduled_task_t * scheduled_task,manage_connection_forker_t fork_connection,sigset_t * sigmask_current)4957 scheduled_task_stop (scheduled_task_t *scheduled_task,
4958 manage_connection_forker_t fork_connection,
4959 sigset_t *sigmask_current)
4960 {
4961 char title[128];
4962 gvm_connection_t connection;
4963 gmp_authenticate_info_opts_t auth_opts;
4964
4965 /* TODO As with starts above, this should retry if the stop failed. */
4966
4967 /* Run the callback to fork a child connected to the Manager. */
4968
4969 switch (fork_connection (&connection, scheduled_task->owner_uuid))
4970 {
4971 case 0:
4972 /* Child. Break, stop task, exit. */
4973 break;
4974
4975 case -1:
4976 /* Parent on error. */
4977 g_warning ("%s: stop fork failed", __func__);
4978 return -1;
4979
4980 default:
4981 /* Parent. Continue to next task. */
4982 return 0;
4983 }
4984
4985 /* Stop the task. */
4986
4987 snprintf (title, sizeof (title),
4988 "gvmd: scheduler: stopping %s",
4989 scheduled_task->task_uuid);
4990 proctitle_set (title);
4991
4992 auth_opts = gmp_authenticate_info_opts_defaults;
4993 auth_opts.username = scheduled_task->owner_name;
4994 if (gmp_authenticate_info_ext_c (&connection, auth_opts))
4995 {
4996 scheduled_task_free (scheduled_task);
4997 gvm_connection_free (&connection);
4998 exit (EXIT_FAILURE);
4999 }
5000
5001 if (gmp_stop_task_c (&connection, scheduled_task->task_uuid))
5002 {
5003 scheduled_task_free (scheduled_task);
5004 gvm_connection_free (&connection);
5005 exit (EXIT_FAILURE);
5006 }
5007
5008 scheduled_task_free (scheduled_task);
5009 gvm_connection_free (&connection);
5010 exit (EXIT_SUCCESS);
5011 }
5012
5013 /**
5014 * @brief Check if a feed sync is needed without acquiring the feed lock.
5015 *
5016 * @return TRUE if a feed sync is needed, FALSE otherwise.
5017 */
5018 gboolean
feed_sync_required()5019 feed_sync_required ()
5020 {
5021 int feed_status_ret;
5022
5023 feed_status_ret = secinfo_feed_version_status ("cert");
5024 switch (feed_status_ret)
5025 {
5026 case 1:
5027 case 2:
5028 case 3:
5029 case 4:
5030 g_debug ("%s: CERT database needs to be updated (status %d)",
5031 __func__, feed_status_ret);
5032 return TRUE;
5033 default:
5034 break;
5035 }
5036
5037 feed_status_ret = secinfo_feed_version_status ("scap");
5038 switch (feed_status_ret)
5039 {
5040 case 1:
5041 case 2:
5042 case 3:
5043 case 4:
5044 g_debug ("%s: SCAP database needs to be updated (status %d)",
5045 __func__, feed_status_ret);
5046 return TRUE;
5047 default:
5048 break;
5049 }
5050
5051 if (nvts_feed_version_status () == 1)
5052 {
5053 g_debug ("%s: NVTs need to be updated", __func__);
5054 return TRUE;
5055 }
5056
5057 return FALSE;
5058 }
5059
5060
5061
5062 /**
5063 * @brief Perform any syncing that is due.
5064 *
5065 * In gvmd, periodically called from the main daemon loop.
5066 *
5067 * @param[in] sigmask_current Sigmask to restore in child.
5068 * @param[in] fork_update_nvt_cache Function that forks a child that syncs
5069 * the NVTS. Child does not return.
5070 * @param[in] try_gvmd_data_sync Whether to try to sync gvmd data objects.
5071 */
5072 void
manage_sync(sigset_t * sigmask_current,int (* fork_update_nvt_cache)(),gboolean try_gvmd_data_sync)5073 manage_sync (sigset_t *sigmask_current,
5074 int (*fork_update_nvt_cache) (),
5075 gboolean try_gvmd_data_sync)
5076 {
5077 lockfile_t lockfile;
5078
5079 reinit_manage_process ();
5080 manage_session_init (current_credentials.uuid);
5081
5082 if (feed_sync_required ())
5083 {
5084 if (feed_lockfile_lock (&lockfile) == 0)
5085 {
5086 manage_sync_nvts (fork_update_nvt_cache);
5087 manage_sync_scap (sigmask_current);
5088 manage_sync_cert (sigmask_current);
5089
5090 lockfile_unlock (&lockfile);
5091 }
5092 }
5093
5094 if (try_gvmd_data_sync
5095 && (should_sync_configs ()
5096 || should_sync_port_lists ()
5097 || should_sync_report_formats ()))
5098 {
5099 if (feed_lockfile_lock (&lockfile) == 0)
5100 {
5101 manage_sync_configs ();
5102 manage_sync_port_lists ();
5103 manage_sync_report_formats ();
5104
5105 lockfile_unlock (&lockfile);
5106 }
5107 }
5108 }
5109
5110 /**
5111 * @brief Adds a switch statement for handling the return value of a
5112 * gvmd data rebuild.
5113 * @param type The type as a description string, e.g. "port lists"
5114 */
5115 #define REBUILD_SWITCH(type) \
5116 switch (ret) \
5117 { \
5118 case 0: \
5119 g_message ("Rebuilt %s from feed.", type); \
5120 break; \
5121 case 1: \
5122 if (error_msg) \
5123 *error_msg = g_strdup_printf ("No %s feed directory.", \
5124 type); \
5125 return -1; \
5126 case 2: \
5127 if (error_msg) \
5128 *error_msg = g_strdup_printf ("Feed owner not set or invalid" \
5129 " while rebuilding %s.", \
5130 type); \
5131 return -1; \
5132 case 3: \
5133 if (error_msg) \
5134 *error_msg = g_strdup_printf ("NVTs must be available" \
5135 " while rebuilding %s.", \
5136 type); \
5137 return -1; \
5138 default: \
5139 if (error_msg) \
5140 *error_msg = g_strdup_printf ("Internal error" \
5141 " while rebuilding %s.", \
5142 type); \
5143 return -1; \
5144 }
5145
5146 /**
5147 * @brief Rebuild configs, port lists and report formats from feed.
5148 *
5149 * @param[in] types Comma-separated lists of types to rebuild or "all".
5150 * @param[in] log_config Logging configuration list.
5151 * @param[in] database Connection info for manage database.
5152 * @param[out] error_msg Error message.
5153 *
5154 * @return 0 success, -1 failed.
5155 */
5156 int
manage_rebuild_gvmd_data_from_feed(const char * types,GSList * log_config,const db_conn_info_t * database,gchar ** error_msg)5157 manage_rebuild_gvmd_data_from_feed (const char *types,
5158 GSList *log_config,
5159 const db_conn_info_t *database,
5160 gchar **error_msg)
5161 {
5162 int ret;
5163 lockfile_t lockfile;
5164 gboolean sync_configs, sync_port_lists, sync_report_formats;
5165
5166 sync_configs = sync_port_lists = sync_report_formats = FALSE;
5167
5168 if (strcasecmp (types, "all") == 0)
5169 {
5170 sync_configs = TRUE;
5171 sync_port_lists = TRUE;
5172 sync_report_formats = TRUE;
5173 }
5174 else
5175 {
5176 gchar **split, **split_iter;
5177 split = g_strsplit (types, ",", -1);
5178
5179 if (*split == NULL)
5180 {
5181 g_free (split);
5182 if (error_msg)
5183 *error_msg = g_strdup ("No types given.");
5184 return -1;
5185 }
5186
5187 split_iter = split;
5188 while (*split_iter)
5189 {
5190 gchar *type = g_strstrip (*split_iter);
5191
5192 if (strcasecmp (type, "configs") == 0)
5193 sync_configs = TRUE;
5194 else if (strcasecmp (type, "port_lists") == 0)
5195 sync_port_lists = TRUE;
5196 else if (strcasecmp (type, "report_formats") == 0)
5197 sync_report_formats = TRUE;
5198 else
5199 {
5200 if (error_msg)
5201 *error_msg = g_strdup_printf ("Invalid type \"%s\""
5202 " (must be \"configs\","
5203 " \"port_lists\","
5204 " \"report_formats\""
5205 " or \"all\")",
5206 type);
5207 g_strfreev (split);
5208 return -1;
5209 }
5210 split_iter ++;
5211 }
5212 g_strfreev (split);
5213 }
5214
5215 ret = feed_lockfile_lock_timeout (&lockfile);
5216 if (ret == 1)
5217 {
5218 if (error_msg)
5219 *error_msg = g_strdup ("Feed locked.");
5220 return -1;
5221 }
5222 else if (ret)
5223 {
5224 if (error_msg)
5225 *error_msg = g_strdup ("Error acquiring feed lock.");
5226 return -1;
5227 }
5228
5229 ret = manage_option_setup (log_config, database);
5230 if (ret)
5231 {
5232 if (error_msg)
5233 *error_msg = g_strdup ("Error setting up log config or"
5234 " database connection.");
5235 return -1;
5236 }
5237
5238 if (sync_configs)
5239 {
5240 g_message ("Rebuilding configs from feed...");
5241 ret = manage_rebuild_configs ();
5242 REBUILD_SWITCH ("configs")
5243 }
5244
5245 if (sync_port_lists)
5246 {
5247 g_message ("Rebuilding port lists from feed...");
5248 ret = manage_rebuild_port_lists ();
5249 REBUILD_SWITCH ("port lists")
5250 }
5251
5252 if (sync_report_formats)
5253 {
5254 g_message ("Rebuilding report formats from feed...");
5255 ret = manage_rebuild_report_formats ();
5256 REBUILD_SWITCH ("report formats")
5257 }
5258
5259 feed_lockfile_unlock (&lockfile);
5260 return 0;
5261 }
5262
5263 #undef REBUILD_SWITCH
5264
5265 /**
5266 * @brief Schedule any actions that are due.
5267 *
5268 * In gvmd, periodically called from the main daemon loop.
5269 *
5270 * @param[in] fork_connection Function that forks a child which is connected
5271 * to the Manager. Must return PID in parent, 0
5272 * in child, or -1 on error.
5273 * @param[in] run_tasks Whether to run scheduled tasks.
5274 * @param[in] sigmask_current Sigmask to restore in child.
5275 *
5276 * @return 0 success, 1 failed to get lock, -1 error.
5277 */
5278 int
manage_schedule(manage_connection_forker_t fork_connection,gboolean run_tasks,sigset_t * sigmask_current)5279 manage_schedule (manage_connection_forker_t fork_connection,
5280 gboolean run_tasks,
5281 sigset_t *sigmask_current)
5282 {
5283 iterator_t schedules;
5284 GSList *starts, *stops;
5285 int ret;
5286 task_t previous_start_task, previous_stop_task;
5287
5288 starts = NULL;
5289 stops = NULL;
5290 previous_start_task = 0;
5291 previous_stop_task = 0;
5292
5293 auto_delete_reports ();
5294
5295 ret = manage_update_nvti_cache ();
5296 if (ret)
5297 {
5298 if (ret == -1)
5299 {
5300 g_warning ("%s: manage_update_nvti_cache error"
5301 " (Perhaps the db went down?)",
5302 __func__);
5303 /* Just ignore, in case the db went down temporarily. */
5304 return 0;
5305 }
5306
5307 return ret;
5308 }
5309
5310 if (run_tasks == 0)
5311 return 0;
5312
5313 /* Assemble "starts" and "stops" list containing task uuid, owner name and
5314 * owner UUID for each (scheduled) task to start or stop. */
5315
5316 ret = init_task_schedule_iterator (&schedules);
5317 if (ret)
5318 {
5319 if (ret == -1)
5320 {
5321 g_warning ("%s: iterator init error"
5322 " (Perhaps the db went down?)",
5323 __func__);
5324 /* Just ignore, in case the db went down temporarily. */
5325 return 0;
5326 }
5327
5328 return ret;
5329 }
5330 /* This iterator runs in a transaction. */
5331 while (next (&schedules))
5332 if (task_schedule_iterator_start_due (&schedules))
5333 {
5334 const char *icalendar, *zone;
5335 int timed_out;
5336
5337 /* Check if task schedule is timed out before updating next due time */
5338 timed_out = task_schedule_iterator_timed_out (&schedules);
5339
5340 /* Update the task schedule info to prevent multiple schedules. */
5341
5342 icalendar = task_schedule_iterator_icalendar (&schedules);
5343 zone = task_schedule_iterator_timezone (&schedules);
5344
5345 g_debug ("%s: start due for %llu, setting next_time",
5346 __func__,
5347 task_schedule_iterator_task (&schedules));
5348 set_task_schedule_next_time
5349 (task_schedule_iterator_task (&schedules),
5350 icalendar_next_time_from_string (icalendar, zone, 0));
5351
5352 /* Skip this task if it was already added to the starts list
5353 * to avoid conflicts between multiple users with permissions. */
5354
5355 if (previous_start_task == task_schedule_iterator_task (&schedules))
5356 continue;
5357
5358 if (timed_out)
5359 {
5360 g_message (" %s: Task timed out: %s",
5361 __func__,
5362 task_schedule_iterator_task_uuid (&schedules));
5363 continue;
5364 }
5365
5366 previous_start_task = task_schedule_iterator_task (&schedules);
5367
5368 /* Add task UUID and owner name and UUID to the list. */
5369
5370 starts = g_slist_prepend
5371 (starts,
5372 scheduled_task_new
5373 (task_schedule_iterator_task_uuid (&schedules),
5374 task_schedule_iterator_owner_uuid (&schedules),
5375 task_schedule_iterator_owner_name (&schedules)));
5376 }
5377 else if (task_schedule_iterator_stop_due (&schedules))
5378 {
5379 /* Skip this task if it was already added to the stops list
5380 * to avoid conflicts between multiple users with permissions. */
5381
5382 if (previous_stop_task == task_schedule_iterator_task (&schedules))
5383 continue;
5384 previous_stop_task = task_schedule_iterator_task (&schedules);
5385
5386 /* Add task UUID and owner name and UUID to the list. */
5387
5388 stops = g_slist_prepend
5389 (stops,
5390 scheduled_task_new
5391 (task_schedule_iterator_task_uuid (&schedules),
5392 task_schedule_iterator_owner_uuid (&schedules),
5393 task_schedule_iterator_owner_name (&schedules)));
5394 }
5395 cleanup_task_schedule_iterator (&schedules);
5396
5397 /* Start tasks in forked processes, now that the SQL statement is closed. */
5398
5399 while (starts)
5400 {
5401 scheduled_task_t *scheduled_task;
5402 GSList *head;
5403
5404 scheduled_task = starts->data;
5405
5406 head = starts;
5407 starts = starts->next;
5408 g_slist_free_1 (head);
5409
5410 if (scheduled_task_start (scheduled_task,
5411 fork_connection,
5412 sigmask_current))
5413 /* Error. Reschedule and continue to next task. */
5414 reschedule_task (scheduled_task->task_uuid);
5415 scheduled_task_free (scheduled_task);
5416 }
5417
5418 /* Stop tasks in forked processes, now that the SQL statement is closed. */
5419
5420 while (stops)
5421 {
5422 scheduled_task_t *scheduled_task;
5423 GSList *head;
5424
5425 scheduled_task = stops->data;
5426 head = stops;
5427 stops = stops->next;
5428 g_slist_free_1 (head);
5429
5430 if (scheduled_task_stop (scheduled_task,
5431 fork_connection,
5432 sigmask_current))
5433 {
5434 /* Error. Exit. */
5435 scheduled_task_free (scheduled_task);
5436 while (stops)
5437 {
5438 scheduled_task_free (stops->data);
5439 stops = g_slist_delete_link (stops, stops);
5440 }
5441 return -1;
5442 }
5443 scheduled_task_free (scheduled_task);
5444 }
5445
5446 clear_duration_schedules (0);
5447 update_duration_schedule_periods (0);
5448
5449 return 0;
5450 }
5451
5452 /**
5453 * @brief Get the current schedule timeout.
5454 *
5455 * @return The schedule timeout in minutes.
5456 */
5457 int
get_schedule_timeout()5458 get_schedule_timeout ()
5459 {
5460 return schedule_timeout;
5461 }
5462
5463 /**
5464 * @brief Set the schedule timeout.
5465 *
5466 * @param new_timeout The new schedule timeout in minutes.
5467 */
5468 void
set_schedule_timeout(int new_timeout)5469 set_schedule_timeout (int new_timeout)
5470 {
5471 if (new_timeout < 0)
5472 schedule_timeout = -1;
5473 else
5474 schedule_timeout = new_timeout;
5475 }
5476
5477
5478 /* SecInfo. */
5479
5480 /* Defined in gmp.c. */
5481 void buffer_config_preference_xml (GString *, iterator_t *, config_t, int);
5482
5483 /**
5484 * @brief Return the path to the CPE dictionary.
5485 *
5486 * @return A dynamically allocated string (to be g_free'd) containing the
5487 * path to the desired file.
5488 */
5489 static char *
get_cpe_filename()5490 get_cpe_filename ()
5491 {
5492 return g_strdup (CPE_DICT_FILENAME);
5493 }
5494
5495 /**
5496 * @brief Compute the filename where a given CVE can be found.
5497 *
5498 * @param[in] item_id Full CVE identifier ("CVE-YYYY-ZZZZ").
5499 *
5500 * @return A dynamically allocated string (to be g_free'd) containing the
5501 * path to the desired file or NULL on error.
5502 */
5503 static char *
get_cve_filename(char * item_id)5504 get_cve_filename (char *item_id)
5505 {
5506 int year;
5507
5508 if (sscanf (item_id, "%*3s-%d-%*d", &year) == 1)
5509 {
5510 /* CVEs before 2002 are stored in the 2002 file. */
5511 if (year <= 2002)
5512 year = 2002;
5513 return g_strdup_printf (CVE_FILENAME_FMT, year);
5514 }
5515 return NULL;
5516 }
5517
5518 /**
5519 * @brief Get the filename where a given OVAL definition can be found.
5520 *
5521 * @param[in] item_id Full OVAL identifier with file suffix.
5522 *
5523 * @return A dynamically allocated string (to be g_free'd) containing the
5524 * path to the desired file or NULL on error.
5525 */
5526 static char *
get_ovaldef_filename(char * item_id)5527 get_ovaldef_filename (char *item_id)
5528 {
5529 char *result, *short_filename;
5530
5531 result = NULL;
5532 short_filename = get_ovaldef_short_filename (item_id);
5533
5534 if (*short_filename)
5535 {
5536 result = g_strdup_printf ("%s/%s", GVM_SCAP_DATA_DIR, short_filename);
5537 }
5538 free (short_filename);
5539
5540 return result;
5541 }
5542
5543 /**
5544 * @brief Compute the filename where a given CERT-Bund Advisory can be found.
5545 *
5546 * @param[in] item_id CERT-Bund identifier without version ("CB-K??/????").
5547 *
5548 * @return A dynamically allocated string (to be g_free'd) containing the
5549 * path to the desired file or NULL on error.
5550 */
5551 static char *
get_cert_bund_adv_filename(char * item_id)5552 get_cert_bund_adv_filename (char *item_id)
5553 {
5554 int year;
5555
5556 if (sscanf (item_id, "CB-K%d-%*s", &year) == 1)
5557 {
5558 return g_strdup_printf (CERT_BUND_ADV_FILENAME_FMT, year);
5559 }
5560 return NULL;
5561 }
5562
5563 /**
5564 * @brief Compute the filename where a given DFN-CERT Advisory can be found.
5565 *
5566 * @param[in] item_id Full DFN-CERT identifier ("DFN-CERT-YYYY-ZZZZ").
5567 *
5568 * @return A dynamically allocated string (to be g_free'd) containing the
5569 * path to the desired file or NULL on error.
5570 */
5571 static char *
get_dfn_cert_adv_filename(char * item_id)5572 get_dfn_cert_adv_filename (char *item_id)
5573 {
5574 int year;
5575
5576 if (sscanf (item_id, "DFN-CERT-%d-%*s", &year) == 1)
5577 {
5578 return g_strdup_printf (DFN_CERT_ADV_FILENAME_FMT, year);
5579 }
5580 return NULL;
5581 }
5582
5583 /**
5584 * @brief Run xsltproc in an external process.
5585 *
5586 * @param[in] stylesheet XSL stylesheet to use.
5587 * @param[in] xmlfile XML file to process.
5588 * @param[in] param_names NULL terminated array of stringparam names (can
5589 * be NULL).
5590 * @param[in] param_values NULL terminated array of stringparam values (can
5591 * be NULL).
5592 *
5593 * @return A dynamically allocated (to be g_free'd) string containing the
5594 * result of the operation of NULL on failure.
5595 */
5596 static gchar *
xsl_transform(gchar * stylesheet,gchar * xmlfile,gchar ** param_names,gchar ** param_values)5597 xsl_transform (gchar *stylesheet, gchar *xmlfile, gchar **param_names,
5598 gchar **param_values)
5599 {
5600 int i, param_idx;
5601 gchar **cmd, *cmd_full;
5602 gint exit_status;
5603 gboolean success;
5604 gchar *standard_out = NULL, *standard_err = NULL;
5605
5606 param_idx = 0;
5607 if (param_names && param_values)
5608 while (param_names[param_idx] && param_values[param_idx])
5609 param_idx++;
5610
5611 cmd = (gchar **)g_malloc ((4 + param_idx * 3) * sizeof (gchar *));
5612
5613 i = 0;
5614 cmd[i++] = "xsltproc";
5615 if (param_idx)
5616 {
5617 int j;
5618
5619 for (j = 0; j < param_idx; j++)
5620 {
5621 cmd[i++] = "--stringparam";
5622 cmd[i++] = param_names[j];
5623 cmd[i++] = param_values[j];
5624 }
5625 }
5626 cmd[i++] = stylesheet;
5627 cmd[i++] = xmlfile;
5628 cmd[i] = NULL;
5629
5630
5631 /* DEBUG: display the final command line. */
5632 cmd_full = g_strjoinv (" ", cmd);
5633 g_debug ("%s: Spawning in parent dir: %s",
5634 __func__, cmd_full);
5635 g_free (cmd_full);
5636 /* --- */
5637
5638 if ((g_spawn_sync (NULL,
5639 cmd,
5640 NULL, /* Environment. */
5641 G_SPAWN_SEARCH_PATH,
5642 NULL, /* Setup function. */
5643 NULL,
5644 &standard_out,
5645 &standard_err,
5646 &exit_status,
5647 NULL)
5648 == FALSE)
5649 || (WIFEXITED (exit_status) == 0)
5650 || WEXITSTATUS (exit_status))
5651 {
5652 g_debug ("%s: failed to transform the xml: %d (WIF %i, WEX %i)",
5653 __func__,
5654 exit_status,
5655 WIFEXITED (exit_status),
5656 WEXITSTATUS (exit_status));
5657 g_debug ("%s: stderr: %s", __func__, standard_err);
5658 g_debug ("%s: stdout: %s", __func__, standard_out);
5659 success = FALSE;
5660 }
5661 else if (strlen (standard_out) == 0)
5662 success = FALSE; /* execution succeeded but nothing was found */
5663 else
5664 success = TRUE; /* execution succeeded and we have a result */
5665
5666 /* Cleanup. */
5667 g_free (cmd);
5668 g_free (standard_err);
5669
5670 if (success)
5671 return standard_out;
5672
5673 g_free (standard_out);
5674 return NULL;
5675 }
5676
5677 /**
5678 * @brief Define a code snippet for get_nvti_xml.
5679 *
5680 * @param x Prefix for names in snippet.
5681 */
5682 #define DEF(x) \
5683 const char* x = nvt_iterator_ ## x (nvts); \
5684 gchar* x ## _text = x \
5685 ? g_markup_escape_text (x, -1) \
5686 : g_strdup ("");
5687
5688 /**
5689 * @brief Create and return XML description for an NVT.
5690 *
5691 * @param[in] nvts The NVT.
5692 * @param[in] details If true, detailed XML, else simple XML.
5693 * @param[in] pref_count Preference count. Used if details is true.
5694 * @param[in] preferences If true, included preferences.
5695 * @param[in] timeout Timeout. Used if details is true.
5696 * @param[in] config Config, used if preferences is true.
5697 * @param[in] close_tag Whether to close the NVT tag or not.
5698 *
5699 * @return A dynamically allocated string containing the XML description.
5700 */
5701 gchar *
get_nvt_xml(iterator_t * nvts,int details,int pref_count,int preferences,const char * timeout,config_t config,int close_tag)5702 get_nvt_xml (iterator_t *nvts, int details, int pref_count,
5703 int preferences, const char *timeout, config_t config,
5704 int close_tag)
5705 {
5706 const char* oid = nvt_iterator_oid (nvts);
5707 const char* name = nvt_iterator_name (nvts);
5708 gchar *msg, *name_text;
5709
5710 name_text = name
5711 ? g_markup_escape_text (name, strlen (name))
5712 : g_strdup ("");
5713 if (details)
5714 {
5715 int tag_count;
5716 GString *refs_str, *tags_str, *buffer, *nvt_tags;
5717 iterator_t cert_refs_iterator, tags, severities;
5718 gchar *tag_name_esc, *tag_value_esc, *tag_comment_esc;
5719 char *default_timeout = nvt_default_timeout (oid);
5720
5721 DEF (family);
5722 DEF (tag);
5723
5724 #undef DEF
5725
5726 nvt_tags = g_string_new (tag_text);
5727 g_free (tag_text);
5728
5729 /* Add the elements that are expected as part of the pipe-separated tag list
5730 * via API although internally already explicitly stored. Once the API is
5731 * extended to have these elements explicitly, they do not need to be
5732 * added to this tag string anymore. */
5733 if (nvt_iterator_summary (nvts) && nvt_iterator_summary (nvts)[0])
5734 {
5735 if (nvt_tags->str)
5736 xml_string_append (nvt_tags, "|summary=%s",
5737 nvt_iterator_summary (nvts));
5738 else
5739 xml_string_append (nvt_tags, "summary=%s",
5740 nvt_iterator_summary (nvts));
5741 }
5742 if (nvt_iterator_insight (nvts) && nvt_iterator_insight (nvts)[0])
5743 {
5744 if (nvt_tags->str)
5745 xml_string_append (nvt_tags, "|insight=%s",
5746 nvt_iterator_insight (nvts));
5747 else
5748 xml_string_append (nvt_tags, "insight=%s",
5749 nvt_iterator_insight (nvts));
5750 }
5751 if (nvt_iterator_affected (nvts) && nvt_iterator_affected (nvts)[0])
5752 {
5753 if (nvt_tags->str)
5754 xml_string_append (nvt_tags, "|affected=%s",
5755 nvt_iterator_affected (nvts));
5756 else
5757 xml_string_append (nvt_tags, "affected=%s",
5758 nvt_iterator_affected (nvts));
5759 }
5760 if (nvt_iterator_impact (nvts) && nvt_iterator_impact (nvts)[0])
5761 {
5762 if (nvt_tags->str)
5763 xml_string_append (nvt_tags, "|impact=%s",
5764 nvt_iterator_impact (nvts));
5765 else
5766 xml_string_append (nvt_tags, "impact=%s",
5767 nvt_iterator_impact (nvts));
5768 }
5769 if (nvt_iterator_detection (nvts) && nvt_iterator_detection (nvts)[0])
5770 {
5771 if (nvt_tags->str)
5772 xml_string_append (nvt_tags, "|vuldetect=%s",
5773 nvt_iterator_detection (nvts));
5774 else
5775 xml_string_append (nvt_tags, "vuldetect=%s",
5776 nvt_iterator_detection (nvts));
5777 }
5778
5779 refs_str = g_string_new ("");
5780
5781 if (manage_cert_loaded())
5782 {
5783 init_nvt_cert_bund_adv_iterator (&cert_refs_iterator, oid);
5784 while (next (&cert_refs_iterator))
5785 {
5786 xml_string_append (refs_str,
5787 "<ref type=\"cert-bund\" id=\"%s\"/>",
5788 nvt_cert_bund_adv_iterator_name
5789 (&cert_refs_iterator));
5790 }
5791 cleanup_iterator (&cert_refs_iterator);
5792
5793 init_nvt_dfn_cert_adv_iterator (&cert_refs_iterator, oid);
5794 while (next (&cert_refs_iterator))
5795 {
5796 xml_string_append (refs_str,
5797 "<ref type=\"dfn-cert\" id=\"%s\"/>",
5798 nvt_dfn_cert_adv_iterator_name
5799 (&cert_refs_iterator));
5800 }
5801 cleanup_iterator (&cert_refs_iterator);
5802 }
5803 else
5804 {
5805 g_string_append (refs_str,
5806 "<warning>database not available</warning>");
5807 }
5808
5809 xml_append_nvt_refs (refs_str, oid, NULL);
5810
5811 tags_str = g_string_new ("");
5812 tag_count = resource_tag_count ("nvt",
5813 get_iterator_resource (nvts),
5814 1);
5815
5816 if (tag_count)
5817 {
5818 g_string_append_printf (tags_str,
5819 "<user_tags>"
5820 "<count>%i</count>",
5821 tag_count);
5822
5823 init_resource_tag_iterator (&tags, "nvt",
5824 get_iterator_resource (nvts),
5825 1, NULL, 1);
5826 while (next (&tags))
5827 {
5828 tag_name_esc = g_markup_escape_text (resource_tag_iterator_name
5829 (&tags),
5830 -1);
5831 tag_value_esc = g_markup_escape_text (resource_tag_iterator_value
5832 (&tags),
5833 -1);
5834 tag_comment_esc = g_markup_escape_text (resource_tag_iterator_comment
5835 (&tags),
5836 -1);
5837 g_string_append_printf (tags_str,
5838 "<tag id=\"%s\">"
5839 "<name>%s</name>"
5840 "<value>%s</value>"
5841 "<comment>%s</comment>"
5842 "</tag>",
5843 resource_tag_iterator_uuid (&tags),
5844 tag_name_esc,
5845 tag_value_esc,
5846 tag_comment_esc);
5847 g_free (tag_name_esc);
5848 g_free (tag_value_esc);
5849 g_free (tag_comment_esc);
5850 }
5851 cleanup_iterator (&tags);
5852 g_string_append_printf (tags_str,
5853 "</user_tags>");
5854 }
5855
5856 buffer = g_string_new ("");
5857
5858 g_string_append_printf (buffer,
5859 "<nvt oid=\"%s\">"
5860 "<name>%s</name>"
5861 "<creation_time>%s</creation_time>"
5862 "<modification_time>%s</modification_time>"
5863 "%s" // user_tags
5864 "<category>%d</category>"
5865 "<family>%s</family>"
5866 "<cvss_base>%s</cvss_base>"
5867 "<severities score=\"%s\">",
5868 oid,
5869 name_text,
5870 get_iterator_creation_time (nvts)
5871 ? get_iterator_creation_time (nvts)
5872 : "",
5873 get_iterator_modification_time (nvts)
5874 ? get_iterator_modification_time (nvts)
5875 : "",
5876 tags_str->str,
5877 nvt_iterator_category (nvts),
5878 family_text,
5879 nvt_iterator_cvss_base (nvts)
5880 ? nvt_iterator_cvss_base (nvts)
5881 : "",
5882 nvt_iterator_cvss_base (nvts)
5883 ? nvt_iterator_cvss_base (nvts)
5884 : "");
5885
5886 init_nvt_severity_iterator (&severities, oid);
5887 while (next (&severities))
5888 {
5889 buffer_xml_append_printf
5890 (buffer,
5891 "<severity type=\"%s\">"
5892 "<origin>%s</origin>"
5893 "<date>%s</date>"
5894 "<score>%0.1f</score>"
5895 "<value>%s</value>"
5896 "</severity>",
5897 nvt_severity_iterator_type (&severities),
5898 nvt_severity_iterator_origin (&severities),
5899 nvt_severity_iterator_date (&severities),
5900 nvt_severity_iterator_score (&severities),
5901 nvt_severity_iterator_value (&severities));
5902 }
5903 cleanup_iterator (&severities);
5904
5905 g_string_append_printf (buffer,
5906 "</severities>"
5907 "<qod>"
5908 "<value>%s</value>"
5909 "<type>%s</type>"
5910 "</qod>"
5911 "<refs>%s</refs>"
5912 "<tags>%s</tags>"
5913 "<preference_count>%i</preference_count>"
5914 "<timeout>%s</timeout>"
5915 "<default_timeout>%s</default_timeout>",
5916 nvt_iterator_qod (nvts),
5917 nvt_iterator_qod_type (nvts),
5918 refs_str->str,
5919 nvt_tags->str,
5920 pref_count,
5921 timeout ? timeout : "",
5922 default_timeout ? default_timeout : "");
5923 g_free (family_text);
5924 g_string_free(nvt_tags, 1);
5925 g_string_free(refs_str, 1);
5926 g_string_free(tags_str, 1);
5927
5928 if (nvt_iterator_solution (nvts) ||
5929 nvt_iterator_solution_type (nvts) ||
5930 nvt_iterator_solution_method (nvts))
5931 {
5932 buffer_xml_append_printf (buffer, "<solution");
5933
5934 if (nvt_iterator_solution_type (nvts))
5935 buffer_xml_append_printf (buffer, " type='%s'",
5936 nvt_iterator_solution_type (nvts));
5937
5938 if (nvt_iterator_solution_method (nvts))
5939 buffer_xml_append_printf (buffer, " method='%s'",
5940 nvt_iterator_solution_method (nvts));
5941
5942 if (nvt_iterator_solution (nvts))
5943 buffer_xml_append_printf (buffer, ">%s</solution>",
5944 nvt_iterator_solution (nvts));
5945 else
5946 buffer_xml_append_printf (buffer, "/>");
5947 }
5948
5949
5950 if (preferences)
5951 {
5952 iterator_t prefs;
5953 const char *nvt_oid = nvt_iterator_oid (nvts);
5954
5955 /* Send the preferences for the NVT. */
5956
5957 xml_string_append (buffer,
5958 "<preferences>"
5959 "<timeout>%s</timeout>"
5960 "<default_timeout>%s</default_timeout>",
5961 timeout ? timeout : "",
5962 default_timeout ? default_timeout : "");
5963
5964 init_nvt_preference_iterator (&prefs, nvt_oid);
5965 while (next (&prefs))
5966 buffer_config_preference_xml (buffer, &prefs, config, 1);
5967 cleanup_iterator (&prefs);
5968
5969 xml_string_append (buffer, "</preferences>");
5970 }
5971
5972 xml_string_append (buffer, close_tag ? "</nvt>" : "");
5973 msg = g_string_free (buffer, FALSE);
5974 free (default_timeout);
5975 }
5976 else
5977 {
5978 int tag_count;
5979 tag_count = resource_tag_count ("nvt",
5980 get_iterator_resource (nvts),
5981 1);
5982
5983 if (tag_count)
5984 {
5985 msg = g_strdup_printf
5986 ("<nvt oid=\"%s\"><name>%s</name>"
5987 "<user_tags><count>%i</count></user_tags>%s",
5988 oid, name_text,
5989 tag_count,
5990 close_tag ? "</nvt>" : "");
5991 }
5992 else
5993 {
5994 msg = g_strdup_printf
5995 ("<nvt oid=\"%s\"><name>%s</name>%s",
5996 oid, name_text,
5997 close_tag ? "</nvt>" : "");
5998 }
5999 }
6000 g_free (name_text);
6001 return msg;
6002 }
6003
6004 /**
6005 * @brief GET SCAP update time, as a string.
6006 *
6007 * @return Last update time as a static string, or "" on error.
6008 */
6009 const char *
manage_scap_update_time()6010 manage_scap_update_time ()
6011 {
6012 gchar *content;
6013 GError *error;
6014 gsize content_size;
6015 struct tm update_time;
6016
6017 /* Read in the contents. */
6018
6019 error = NULL;
6020 if (g_file_get_contents (SCAP_TIMESTAMP_FILENAME,
6021 &content,
6022 &content_size,
6023 &error)
6024 == FALSE)
6025 {
6026 if (error)
6027 {
6028 g_debug ("%s: failed to read %s: %s",
6029 __func__, SCAP_TIMESTAMP_FILENAME, error->message);
6030 g_error_free (error);
6031 }
6032 return "";
6033 }
6034
6035 memset (&update_time, 0, sizeof (struct tm));
6036 if (strptime (content, "%Y%m%d%H%M", &update_time))
6037 {
6038 static char time_string[100];
6039 #if !defined(__GLIBC__)
6040 strftime (time_string, 99, "%Y-%m-%dT%T.000", &update_time);
6041 #else
6042 strftime (time_string, 99, "%FT%T.000%z", &update_time);
6043 #endif
6044 return time_string;
6045 }
6046 return "";
6047 }
6048
6049 /**
6050 * @brief Read raw information.
6051 *
6052 * @param[in] type Type of the requested information.
6053 * @param[in] uid Unique identifier of the requested information
6054 * @param[in] name Name or identifier of the requested information.
6055 * @param[out] result Pointer to the read information location. Will point
6056 * to NULL on error.
6057 *
6058 * @return 1 success, -1 error.
6059 */
6060 int
manage_read_info(gchar * type,gchar * uid,gchar * name,gchar ** result)6061 manage_read_info (gchar *type, gchar *uid, gchar *name, gchar **result)
6062 {
6063 gchar *fname;
6064 gchar *pnames[2] = { "refname", NULL };
6065 gchar *pvalues[2] = { name, NULL };
6066
6067 assert (result != NULL);
6068 *result = NULL;
6069
6070 if (g_ascii_strcasecmp ("CPE", type) == 0)
6071 {
6072 fname = get_cpe_filename ();
6073 if (fname)
6074 {
6075 gchar *cpe;
6076 cpe = xsl_transform (CPE_GETBYNAME_XSL, fname, pnames, pvalues);
6077 g_free (fname);
6078 if (cpe)
6079 *result = cpe;
6080 }
6081 }
6082 else if (g_ascii_strcasecmp ("CVE", type) == 0)
6083 {
6084 fname = get_cve_filename (uid);
6085 if (fname)
6086 {
6087 gchar *cve;
6088 cve = xsl_transform (CVE_GETBYNAME_XSL, fname, pnames, pvalues);
6089 g_free (fname);
6090 if (cve)
6091 *result = cve;
6092 }
6093 }
6094 else if (g_ascii_strcasecmp ("NVT", type) == 0)
6095 {
6096 iterator_t nvts;
6097 nvt_t nvt;
6098
6099 if (!find_nvt (uid ? uid : name, &nvt) && nvt)
6100 {
6101 init_nvt_iterator (&nvts, nvt, 0, NULL, NULL, 0, NULL);
6102
6103 if (next (&nvts))
6104 *result = get_nvt_xml (&nvts,
6105 1, /* Include details. */
6106 0, /* Preference count. */
6107 1, /* Include preferences. */
6108 NULL, /* Timeout. */
6109 0, /* Config. */
6110 1); /* Close tag. */
6111
6112 cleanup_iterator (&nvts);
6113 }
6114 }
6115 else if (g_ascii_strcasecmp ("OVALDEF", type) == 0)
6116 {
6117 fname = get_ovaldef_filename (uid);
6118 if (fname)
6119 {
6120 gchar *ovaldef;
6121 ovaldef = xsl_transform (OVALDEF_GETBYNAME_XSL, fname,
6122 pnames, pvalues);
6123 g_free (fname);
6124 if (ovaldef)
6125 *result = ovaldef;
6126 }
6127 }
6128 else if (g_ascii_strcasecmp ("CERT_BUND_ADV", type) == 0)
6129 {
6130 fname = get_cert_bund_adv_filename (uid);
6131 if (fname)
6132 {
6133 gchar *adv;
6134 adv = xsl_transform (CERT_BUND_ADV_GETBYNAME_XSL, fname,
6135 pnames, pvalues);
6136 g_free (fname);
6137 if (adv)
6138 *result = adv;
6139 }
6140 }
6141 else if (g_ascii_strcasecmp ("DFN_CERT_ADV", type) == 0)
6142 {
6143 fname = get_dfn_cert_adv_filename (uid);
6144 if (fname)
6145 {
6146 gchar *adv;
6147 adv = xsl_transform (DFN_CERT_ADV_GETBYNAME_XSL, fname,
6148 pnames, pvalues);
6149 g_free (fname);
6150 if (adv)
6151 *result = adv;
6152 }
6153 }
6154
6155 if (*result == NULL)
6156 return -1;
6157
6158 return 1;
6159 }
6160
6161
6162 /* Users. */
6163
6164 /**
6165 *
6166 * @brief Validates a username.
6167 *
6168 * @param[in] name The name.
6169 *
6170 * @return 0 if the username is valid, 1 if not.
6171 */
6172 int
validate_username(const gchar * name)6173 validate_username (const gchar * name)
6174 {
6175 if (g_regex_match_simple ("^[[:alnum:]-_.]+$", name, 0, 0))
6176 return 0;
6177 else
6178 return 1;
6179 }
6180
6181
6182 /* Resource aggregates. */
6183
6184 /**
6185 * @brief Free a sort_data_t struct and its related resources.
6186 *
6187 * @param[in] sort_data The sort_data struct to free.
6188 */
6189 void
sort_data_free(sort_data_t * sort_data)6190 sort_data_free (sort_data_t *sort_data)
6191 {
6192 g_free (sort_data->field);
6193 g_free (sort_data->stat);
6194 g_free (sort_data);
6195 }
6196
6197
6198 /* Feeds. */
6199
6200 /**
6201 * @brief Tests if the gvmd data feed directory and its subdirectories exist.
6202 *
6203 * @return TRUE if the directory exists.
6204 */
6205 gboolean
manage_gvmd_data_feed_dirs_exist()6206 manage_gvmd_data_feed_dirs_exist ()
6207 {
6208 return gvm_file_is_readable (GVMD_FEED_DIR)
6209 && configs_feed_dir_exists ()
6210 && port_lists_feed_dir_exists ()
6211 && report_formats_feed_dir_exists ();
6212 }
6213
6214 /**
6215 * @brief Get the feed lock file path.
6216 *
6217 * @return The current path to the lock file.
6218 */
6219 const gchar *
get_feed_lock_path()6220 get_feed_lock_path ()
6221 {
6222 return feed_lock_path;
6223 }
6224
6225 /**
6226 * @brief Set the feed lock file path.
6227 *
6228 * @param new_path The new path to the lock file.
6229 */
6230 void
set_feed_lock_path(const char * new_path)6231 set_feed_lock_path (const char *new_path)
6232 {
6233 g_free (feed_lock_path);
6234 if (new_path && strcmp (new_path, ""))
6235 feed_lock_path = g_strdup (new_path);
6236 else
6237 feed_lock_path = g_strdup (GVM_FEED_LOCK_PATH);
6238 }
6239
6240 /**
6241 * @brief Get the feed lock timeout.
6242 *
6243 * @return The current timeout in seconds.
6244 */
6245 int
get_feed_lock_timeout()6246 get_feed_lock_timeout ()
6247 {
6248 return feed_lock_timeout;
6249 }
6250
6251 /**
6252 * @brief Set the feed lock timeout.
6253 *
6254 * @param new_timeout The new timeout in seconds.
6255 */
6256 void
set_feed_lock_timeout(int new_timeout)6257 set_feed_lock_timeout (int new_timeout)
6258 {
6259 if (new_timeout < 0)
6260 feed_lock_timeout = 0;
6261 else
6262 feed_lock_timeout = new_timeout;
6263 }
6264
6265 /**
6266 * @brief Write start time to sync lock file.
6267 *
6268 * @param[in] lockfile_fd File descriptor of the lock file.
6269 */
6270 void
write_sync_start(int lockfile_fd)6271 write_sync_start (int lockfile_fd)
6272 {
6273 time_t now;
6274 char now_string[26];
6275 char *now_string_ptr = now_string;
6276
6277 now = time (NULL);
6278 ctime_r (&now, now_string);
6279 while (*now_string_ptr)
6280 {
6281 ssize_t count;
6282 count = write (lockfile_fd,
6283 now_string,
6284 strlen (now_string));
6285 if (count < 0)
6286 {
6287 if (errno == EAGAIN || errno == EINTR)
6288 /* Interrupted, try write again. */
6289 continue;
6290 g_warning ("%s: failed to write to lockfile: %s",
6291 __func__,
6292 strerror (errno));
6293 break;
6294 }
6295 now_string_ptr += count;
6296 }
6297 }
6298
6299 /**
6300 * @brief Acquires the feed lock and writes the current time to the lockfile.
6301 *
6302 * @param[out] lockfile Lockfile data struct.
6303 *
6304 * @return 0 success, 1 already locked, -1 error
6305 */
6306 int
feed_lockfile_lock(lockfile_t * lockfile)6307 feed_lockfile_lock (lockfile_t *lockfile)
6308 {
6309 int ret;
6310
6311 /* Try to lock the file */
6312 ret = lockfile_lock_path_nb (lockfile, get_feed_lock_path ());
6313 if (ret)
6314 {
6315 return ret;
6316 }
6317
6318 /* Write the file contents (timestamp) */
6319 write_sync_start (lockfile->fd);
6320
6321 return 0;
6322 }
6323
6324 /**
6325 * @brief Acquires the feed lock and writes the current time to the lockfile.
6326 *
6327 * @param[out] lockfile Lockfile data struct.
6328 *
6329 * @return 0 success, 1 already locked, -1 error
6330 */
6331 int
feed_lockfile_lock_timeout(lockfile_t * lockfile)6332 feed_lockfile_lock_timeout (lockfile_t *lockfile)
6333 {
6334 int lock_status;
6335 gboolean log_timeout;
6336 time_t timeout_end;
6337
6338 /* Try to lock the file */
6339
6340 log_timeout = TRUE;
6341 timeout_end = time (NULL) + feed_lock_timeout;
6342 do
6343 {
6344 lock_status = feed_lockfile_lock (lockfile);
6345 if (lock_status == 1 /* already locked, but no error */
6346 && timeout_end > time (NULL))
6347 {
6348 if (log_timeout)
6349 {
6350 log_timeout = FALSE;
6351 g_message ("%s: Feed is currently locked by another process,"
6352 " will retry until %s.",
6353 __func__, iso_time (&timeout_end));
6354 }
6355 gvm_sleep (1);
6356 }
6357 else if (lock_status) /* error */
6358 {
6359 return lock_status;
6360 }
6361 } while (lock_status); /* lock is acquired when lock_status is 0 */
6362
6363 return 0;
6364 }
6365
6366 /**
6367 * @brief Releases the feed lock and clears the contents.
6368 *
6369 * @param[in] lockfile Lockfile data struct.
6370 *
6371 * @return 0 success, -1 error
6372 */
6373 int
feed_lockfile_unlock(lockfile_t * lockfile)6374 feed_lockfile_unlock (lockfile_t *lockfile)
6375 {
6376 int ret;
6377
6378 /* Clear timestamp from lock file. */
6379 if (ftruncate (lockfile->fd, 0))
6380 g_warning ("%s: failed to ftruncate lockfile: %s",
6381 __func__,
6382 strerror (errno));
6383
6384 /* Unlock the lockfile */
6385 ret = lockfile_unlock (lockfile);
6386 if (ret)
6387 {
6388 g_critical ("%s: Error releasing checking lock", __func__);
6389 return -1;
6390 }
6391
6392 return 0;
6393 }
6394
6395 /**
6396 * @brief Request a feed synchronization script selftest.
6397 *
6398 * Ask a feed synchronization script to perform a selftest and report
6399 * the results.
6400 *
6401 * @param[in] sync_script The file name of the synchronization script.
6402 * @param[out] result Return location for selftest errors, or NULL.
6403 *
6404 * @return TRUE if the selftest was successful, or FALSE if an error occurred.
6405 */
6406 gboolean
gvm_sync_script_perform_selftest(const gchar * sync_script,gchar ** result)6407 gvm_sync_script_perform_selftest (const gchar * sync_script,
6408 gchar ** result)
6409 {
6410 g_assert (sync_script);
6411 g_assert_cmpstr (*result, ==, NULL);
6412
6413 gchar *script_working_dir = g_path_get_dirname (sync_script);
6414
6415 gchar **argv = (gchar **) g_malloc (3 * sizeof (gchar *));
6416 argv[0] = g_strdup (sync_script);
6417 argv[1] = g_strdup ("--selftest");
6418 argv[2] = NULL;
6419
6420 gchar *script_out;
6421 gchar *script_err;
6422 gint script_exit;
6423 GError *error = NULL;
6424
6425 if (!g_spawn_sync
6426 (script_working_dir, argv, NULL, 0, NULL, NULL, &script_out, &script_err,
6427 &script_exit, &error))
6428 {
6429 if (*result != NULL)
6430 {
6431 *result =
6432 g_strdup_printf ("Failed to execute synchronization " "script: %s",
6433 error->message);
6434 }
6435
6436 g_free (script_working_dir);
6437 g_strfreev (argv);
6438 g_free (script_out);
6439 g_free (script_err);
6440 g_error_free (error);
6441
6442 return FALSE;
6443 }
6444
6445 if (script_exit != 0)
6446 {
6447 if (script_err != NULL)
6448 {
6449 *result = g_strdup_printf ("%s", script_err);
6450 }
6451
6452 g_free (script_working_dir);
6453 g_strfreev (argv);
6454 g_free (script_out);
6455 g_free (script_err);
6456
6457 return FALSE;
6458 }
6459
6460 g_free (script_working_dir);
6461 g_strfreev (argv);
6462 g_free (script_out);
6463 g_free (script_err);
6464
6465 return TRUE;
6466 }
6467
6468 /**
6469 * @brief Retrieves the ID string of a feed sync script, with basic validation.
6470 *
6471 * @param[in] sync_script The file name of the synchronization script.
6472 * @param[out] identification Return location of the identification string.
6473 * @param[in] feed_type Could be NVT_FEED, SCAP_FEED or CERT_FEED.
6474 *
6475 * @return TRUE if the identification string was retrieved, or FALSE if an
6476 * error occurred.
6477 */
6478 gboolean
gvm_get_sync_script_identification(const gchar * sync_script,gchar ** identification,int feed_type)6479 gvm_get_sync_script_identification (const gchar * sync_script,
6480 gchar ** identification,
6481 int feed_type)
6482 {
6483 g_assert (sync_script);
6484 if (identification)
6485 g_assert_cmpstr (*identification, ==, NULL);
6486
6487 gchar *script_working_dir = g_path_get_dirname (sync_script);
6488
6489 gchar **argv = (gchar **) g_malloc (3 * sizeof (gchar *));
6490 argv[0] = g_strdup (sync_script);
6491 argv[1] = g_strdup ("--identify");
6492 argv[2] = NULL;
6493
6494 gchar *script_out;
6495 gchar *script_err;
6496 gint script_exit;
6497 GError *error = NULL;
6498
6499 gchar **script_identification;
6500
6501 if (!g_spawn_sync
6502 (script_working_dir, argv, NULL, 0, NULL, NULL, &script_out, &script_err,
6503 &script_exit, &error))
6504 {
6505 g_warning ("Failed to execute %s: %s", sync_script, error->message);
6506
6507 g_free (script_working_dir);
6508 g_strfreev (argv);
6509 g_free (script_out);
6510 g_free (script_err);
6511 g_error_free (error);
6512
6513 return FALSE;
6514 }
6515
6516 if (script_exit != 0)
6517 {
6518 g_warning ("%s returned a non-zero exit code.", sync_script);
6519
6520 g_free (script_working_dir);
6521 g_strfreev (argv);
6522 g_free (script_out);
6523 g_free (script_err);
6524
6525 return FALSE;
6526 }
6527
6528 script_identification = g_strsplit (script_out, "|", 6);
6529
6530 if ((script_identification[0] == NULL)
6531 || (feed_type == NVT_FEED
6532 && g_ascii_strncasecmp (script_identification[0], "NVTSYNC", 7))
6533 || (feed_type == SCAP_FEED
6534 && g_ascii_strncasecmp (script_identification[0], "SCAPSYNC", 7))
6535 || (feed_type == CERT_FEED
6536 && g_ascii_strncasecmp (script_identification[0], "CERTSYNC", 7))
6537 || g_ascii_strncasecmp (script_identification[0], script_identification[5], 7))
6538 {
6539 g_warning ("%s is not a feed synchronization script", sync_script);
6540
6541 g_free (script_working_dir);
6542 g_strfreev (argv);
6543 g_free (script_out);
6544 g_free (script_err);
6545
6546 g_strfreev (script_identification);
6547
6548 return FALSE;
6549 }
6550
6551 if (identification)
6552 *identification = g_strdup (script_out);
6553
6554 g_free (script_working_dir);
6555 g_strfreev (argv);
6556 g_free (script_out);
6557 g_free (script_err);
6558
6559 g_strfreev (script_identification);
6560
6561 return TRUE;
6562 }
6563
6564 /**
6565 * @brief Retrieves description of a feed sync script, with basic validation.
6566 *
6567 * @param[in] sync_script The file name of the synchronization script.
6568 * @param[out] description Return location of the description string.
6569 *
6570 * @return TRUE if the description was retrieved, or FALSE if an error
6571 * occurred.
6572 */
6573 gboolean
gvm_get_sync_script_description(const gchar * sync_script,gchar ** description)6574 gvm_get_sync_script_description (const gchar * sync_script,
6575 gchar ** description)
6576 {
6577 g_assert (sync_script);
6578 g_assert_cmpstr (*description, ==, NULL);
6579
6580 gchar *script_working_dir = g_path_get_dirname (sync_script);
6581
6582 gchar **argv = (gchar **) g_malloc (3 * sizeof (gchar *));
6583 argv[0] = g_strdup (sync_script);
6584 argv[1] = g_strdup ("--describe");
6585 argv[2] = NULL;
6586
6587 gchar *script_out;
6588 gchar *script_err;
6589 gint script_exit;
6590 GError *error = NULL;
6591
6592 if (!g_spawn_sync
6593 (script_working_dir, argv, NULL, 0, NULL, NULL, &script_out, &script_err,
6594 &script_exit, &error))
6595 {
6596 g_warning ("Failed to execute %s: %s", sync_script, error->message);
6597
6598 g_free (script_working_dir);
6599 g_strfreev (argv);
6600 g_free (script_out);
6601 g_free (script_err);
6602 g_error_free (error);
6603
6604 return FALSE;
6605 }
6606
6607 if (script_exit != 0)
6608 {
6609 g_warning ("%s returned a non-zero exit code.", sync_script);
6610
6611 g_free (script_working_dir);
6612 g_strfreev (argv);
6613 g_free (script_out);
6614 g_free (script_err);
6615
6616 return FALSE;
6617 }
6618
6619 *description = g_strdup (script_out);
6620
6621 g_free (script_working_dir);
6622 g_strfreev (argv);
6623 g_free (script_out);
6624 g_free (script_err);
6625
6626 return TRUE;
6627 }
6628
6629 /**
6630 * @brief Retrieves the version of a feed handled by the sync, with basic
6631 * validation.
6632 *
6633 * @param[in] sync_script The file name of the synchronization script.
6634 * @param[out] feed_version Return location of the feed version string.
6635 *
6636 * @return TRUE if the feed version was retrieved, or FALSE if an error
6637 * occurred.
6638 */
6639 gboolean
gvm_get_sync_script_feed_version(const gchar * sync_script,gchar ** feed_version)6640 gvm_get_sync_script_feed_version (const gchar * sync_script,
6641 gchar ** feed_version)
6642 {
6643 g_assert (sync_script);
6644 g_assert_cmpstr (*feed_version, ==, NULL);
6645
6646 gchar *script_working_dir = g_path_get_dirname (sync_script);
6647
6648 gchar **argv = (gchar **) g_malloc (3 * sizeof (gchar *));
6649 argv[0] = g_strdup (sync_script);
6650 argv[1] = g_strdup ("--feedversion");
6651 argv[2] = NULL;
6652
6653 gchar *script_out;
6654 gchar *script_err;
6655 gint script_exit;
6656 GError *error = NULL;
6657
6658 if (!g_spawn_sync
6659 (script_working_dir, argv, NULL, 0, NULL, NULL, &script_out, &script_err,
6660 &script_exit, &error))
6661 {
6662 g_warning ("Failed to execute %s: %s", sync_script, error->message);
6663
6664 g_free (script_working_dir);
6665 g_strfreev (argv);
6666 g_free (script_out);
6667 g_free (script_err);
6668 g_error_free (error);
6669
6670 return FALSE;
6671 }
6672
6673 if (script_exit != 0)
6674 {
6675 g_warning ("%s returned a non-zero exit code.", sync_script);
6676
6677 g_free (script_working_dir);
6678 g_strfreev (argv);
6679 g_free (script_out);
6680 g_free (script_err);
6681
6682 return FALSE;
6683 }
6684
6685 *feed_version = g_strdup (script_out);
6686
6687 g_free (script_working_dir);
6688 g_strfreev (argv);
6689 g_free (script_out);
6690 g_free (script_err);
6691
6692 return TRUE;
6693 }
6694
6695 /**
6696 * @brief Migrates SCAP or CERT database, waiting until migration terminates.
6697 *
6698 * Calls a sync script to migrate the SCAP or CERT database.
6699 *
6700 * @param[in] feed_type Could be SCAP_FEED or CERT_FEED.
6701 *
6702 * @return 0 sync complete, 1 sync already in progress, -1 error
6703 */
6704 int
gvm_migrate_secinfo(int feed_type)6705 gvm_migrate_secinfo (int feed_type)
6706 {
6707 lockfile_t lockfile;
6708 int ret;
6709
6710 if (feed_type != SCAP_FEED && feed_type != CERT_FEED)
6711 {
6712 g_warning ("%s: unsupported feed_type", __func__);
6713 return -1;
6714 }
6715
6716 ret = feed_lockfile_lock_timeout (&lockfile);
6717 if (ret == 1)
6718 return 1;
6719 else if (ret)
6720 return -1;
6721
6722 if (feed_type == SCAP_FEED)
6723 ret = check_scap_db_version ();
6724 else
6725 ret = check_cert_db_version ();
6726
6727 feed_lockfile_unlock (&lockfile);
6728
6729 return ret;
6730 }
6731
6732 /**
6733 * @brief Update NVT cache using OSP.
6734 *
6735 * @param[in] update_socket Socket to use to contact ospd-openvas scanner.
6736 *
6737 * @return 0 success, -1 error, 1 VT integrity check failed.
6738 */
6739 int
manage_update_nvts_osp(const gchar * update_socket)6740 manage_update_nvts_osp (const gchar *update_socket)
6741 {
6742 return manage_update_nvt_cache_osp (update_socket);
6743 }
6744
6745
6746 /* Wizards. */
6747
6748 /**
6749 * @brief Run a wizard.
6750 *
6751 * @param[in] wizard_name Wizard name.
6752 * @param[in] run_command Function to run GMP command.
6753 * @param[in] run_command_data Argument for run_command.
6754 * @param[in] params Wizard params. Array of name_value_t.
6755 * @param[in] read_only Whether to only allow wizards marked as
6756 * read only.
6757 * @param[in] mode Name of the mode to run the wizard in.
6758 * @param[out] command_error Either NULL or an address for an error message
6759 * when return is 0, 4 or 6.
6760 * @param[out] command_error_code Either NULL or an address for a status code
6761 * from the failed command when return is 0
6762 * or 4.
6763 * @param[out] ret_response Address for response string of last command.
6764 *
6765 * @return 0 success,
6766 * 1 name error,
6767 * 4 command in wizard failed,
6768 * 5 wizard not read only,
6769 * 6 Parameter validation failed,
6770 * -1 internal error,
6771 * 99 permission denied.
6772 */
6773 int
manage_run_wizard(const gchar * wizard_name,int (* run_command)(void *,gchar *,gchar **),void * run_command_data,array_t * params,int read_only,const char * mode,gchar ** command_error,gchar ** command_error_code,gchar ** ret_response)6774 manage_run_wizard (const gchar *wizard_name,
6775 int (*run_command) (void*, gchar*, gchar**),
6776 void *run_command_data,
6777 array_t *params,
6778 int read_only,
6779 const char *mode,
6780 gchar **command_error,
6781 gchar **command_error_code,
6782 gchar **ret_response)
6783 {
6784 GString *params_xml;
6785 gchar *file, *file_name, *response, *extra, *extra_wrapped, *wizard;
6786 gsize wizard_len;
6787 GError *get_error;
6788 entity_t entity, mode_entity, params_entity, read_only_entity;
6789 entity_t param_def, step;
6790 entities_t modes, steps, param_defs;
6791 int ret;
6792 const gchar *point;
6793
6794 if (acl_user_may ("run_wizard") == 0)
6795 return 99;
6796
6797 if (command_error)
6798 *command_error = NULL;
6799
6800 if (command_error_code)
6801 *command_error_code = NULL;
6802
6803 if (ret_response)
6804 *ret_response = NULL;
6805
6806 point = wizard_name;
6807 while (*point && (isalnum (*point) || *point == '_')) point++;
6808 if (*point)
6809 return 1;
6810
6811 /* Read wizard from file. */
6812
6813 file_name = g_strdup_printf ("%s.xml", wizard_name);
6814 file = g_build_filename (GVMD_DATA_DIR,
6815 "wizards",
6816 file_name,
6817 NULL);
6818 g_free (file_name);
6819
6820 get_error = NULL;
6821 g_file_get_contents (file,
6822 &wizard,
6823 &wizard_len,
6824 &get_error);
6825 g_free (file);
6826 if (get_error)
6827 {
6828 g_warning ("%s: Failed to read wizard: %s",
6829 __func__,
6830 get_error->message);
6831 g_error_free (get_error);
6832 return -1;
6833 }
6834
6835 /* Parse wizard. */
6836
6837 entity = NULL;
6838 if (parse_entity (wizard, &entity))
6839 {
6840 g_warning ("%s: Failed to parse wizard", __func__);
6841 g_free (wizard);
6842 return -1;
6843 }
6844 g_free (wizard);
6845
6846 /* Select mode */
6847 if (mode && strcmp (mode, ""))
6848 {
6849 modes = entity->entities;
6850 int mode_found = 0;
6851 while (mode_found == 0 && (mode_entity = first_entity (modes)))
6852 {
6853 if (strcasecmp (entity_name (mode_entity), "mode") == 0)
6854 {
6855 entity_t name_entity;
6856 name_entity = entity_child (mode_entity, "name");
6857
6858 if (strcmp (entity_text (name_entity), mode) == 0)
6859 mode_found = 1;
6860 }
6861 modes = next_entities (modes);
6862 }
6863
6864 if (mode_found == 0)
6865 {
6866 free_entity (entity);
6867 if (ret_response)
6868 *ret_response = g_strdup ("");
6869
6870 return 0;
6871 }
6872 }
6873 else
6874 {
6875 mode_entity = entity;
6876 }
6877
6878 /* If needed, check if wizard is marked as read only.
6879 * This does not check the actual commands.
6880 */
6881 if (read_only)
6882 {
6883 read_only_entity = entity_child (mode_entity, "read_only");
6884 if (read_only_entity == NULL)
6885 {
6886 free_entity (entity);
6887 return 5;
6888 }
6889 }
6890
6891 /* Check params */
6892 params_xml = g_string_new ("");
6893 params_entity = entity_child (mode_entity, "params");
6894 if (params_entity)
6895 param_defs = params_entity->entities;
6896
6897 while (params_entity && (param_def = first_entity (param_defs)))
6898 {
6899 if (strcasecmp (entity_name (param_def), "param") == 0)
6900 {
6901 entity_t name_entity, regex_entity, optional_entity;
6902 const char *name, *regex;
6903 int optional;
6904 int param_found = 0;
6905
6906 name_entity = entity_child (param_def, "name");
6907 if ((name_entity == NULL)
6908 || (strcmp (entity_text (name_entity), "") == 0))
6909 {
6910 g_warning ("%s: Wizard PARAM missing NAME",
6911 __func__);
6912 free_entity (entity);
6913 return -1;
6914 }
6915 else
6916 name = entity_text (name_entity);
6917
6918 regex_entity = entity_child (param_def, "regex");
6919 if ((regex_entity == NULL)
6920 || (strcmp (entity_text (regex_entity), "") == 0))
6921 {
6922 g_warning ("%s: Wizard PARAM missing REGEX",
6923 __func__);
6924 free_entity (entity);
6925 return -1;
6926 }
6927 else
6928 regex = entity_text (regex_entity);
6929
6930 optional_entity = entity_child (param_def, "optional");
6931 optional = (optional_entity
6932 && strcmp (entity_text (optional_entity), "")
6933 && strcmp (entity_text (optional_entity), "0"));
6934
6935 if (params)
6936 {
6937 guint index = params->len;
6938 while (index--)
6939 {
6940 name_value_t *pair;
6941
6942 pair = (name_value_t*) g_ptr_array_index (params, index);
6943
6944 if (pair == NULL)
6945 continue;
6946
6947 if ((pair->name)
6948 && (pair->value)
6949 && (strcmp (pair->name, name) == 0))
6950 {
6951 index = 0; // end loop;
6952 param_found = 1;
6953
6954 if (g_regex_match_simple (regex, pair->value, 0, 0) == 0)
6955 {
6956 if (command_error)
6957 {
6958 *command_error
6959 = g_strdup_printf ("Value '%s' is not valid for"
6960 " parameter '%s'.",
6961 pair->value, name);
6962 }
6963 free_entity (entity);
6964 g_string_free (params_xml, TRUE);
6965 return 6;
6966 }
6967 }
6968 }
6969 }
6970
6971 if (optional == 0 && param_found == 0)
6972 {
6973 if (command_error)
6974 {
6975 *command_error = g_strdup_printf ("Mandatory wizard param '%s'"
6976 " missing",
6977 name);
6978 }
6979 free_entity (entity);
6980 return 6;
6981 }
6982
6983
6984 }
6985 param_defs = next_entities (param_defs);
6986 }
6987
6988 /* Buffer params */
6989 if (params)
6990 {
6991 guint index = params->len;
6992 while (index--)
6993 {
6994 name_value_t *pair;
6995
6996 pair = (name_value_t*) g_ptr_array_index (params, index);
6997 xml_string_append (params_xml,
6998 "<param>"
6999 "<name>%s</name>"
7000 "<value>%s</value>"
7001 "</param>",
7002 pair->name ? pair->name : "",
7003 pair->value ? pair->value : "");
7004 }
7005 }
7006
7007 /* Run each step of the wizard. */
7008
7009 response = NULL;
7010 extra = NULL;
7011 steps = mode_entity->entities;
7012 while ((step = first_entity (steps)))
7013 {
7014 if (strcasecmp (entity_name (step), "step") == 0)
7015 {
7016 entity_t command, extra_xsl;
7017 gchar *gmp;
7018 int xsl_fd, xml_fd;
7019 char xsl_file_name[] = "/tmp/gvmd-xsl-XXXXXX";
7020 FILE *xsl_file, *xml_file;
7021 char xml_file_name[] = "/tmp/gvmd-xml-XXXXXX";
7022 char extra_xsl_file_name[] = "/tmp/gvmd-extra-xsl-XXXXXX";
7023 char extra_xml_file_name[] = "/tmp/gvmd-extra-xml-XXXXXX";
7024
7025 /* Get the command element. */
7026
7027 command = entity_child (step, "command");
7028 if (command == NULL)
7029 {
7030 g_warning ("%s: Wizard STEP missing COMMAND",
7031 __func__);
7032 free_entity (entity);
7033 g_free (response);
7034 g_free (extra);
7035 g_string_free (params_xml, TRUE);
7036 return -1;
7037 }
7038
7039 /* Save the command XSL from the element to a file. */
7040
7041 xsl_fd = mkstemp (xsl_file_name);
7042 if (xsl_fd == -1)
7043 {
7044 g_warning ("%s: Wizard XSL file create failed",
7045 __func__);
7046 free_entity (entity);
7047 g_free (response);
7048 g_free (extra);
7049 g_string_free (params_xml, TRUE);
7050 return -1;
7051 }
7052
7053 xsl_file = fdopen (xsl_fd, "w");
7054 if (xsl_file == NULL)
7055 {
7056 g_warning ("%s: Wizard XSL file open failed",
7057 __func__);
7058 close (xsl_fd);
7059 free_entity (entity);
7060 g_free (response);
7061 g_free (extra);
7062 g_string_free (params_xml, TRUE);
7063 return -1;
7064 }
7065
7066 if (first_entity (command->entities))
7067 print_entity (xsl_file, first_entity (command->entities));
7068
7069 /* Write the params as XML to a file. */
7070
7071 xml_fd = mkstemp (xml_file_name);
7072 if (xml_fd == -1)
7073 {
7074 g_warning ("%s: Wizard XML file create failed",
7075 __func__);
7076 fclose (xsl_file);
7077 unlink (xsl_file_name);
7078 free_entity (entity);
7079 g_free (response);
7080 g_free (extra);
7081 g_string_free (params_xml, TRUE);
7082 return -1;
7083 }
7084
7085 xml_file = fdopen (xml_fd, "w");
7086 if (xml_file == NULL)
7087 {
7088 g_warning ("%s: Wizard XML file open failed",
7089 __func__);
7090 fclose (xsl_file);
7091 unlink (xsl_file_name);
7092 close (xml_fd);
7093 free_entity (entity);
7094 g_free (response);
7095 g_free (extra);
7096 g_string_free (params_xml, TRUE);
7097 return -1;
7098 }
7099
7100 if (fprintf (xml_file,
7101 "<wizard>"
7102 "<params>%s</params>"
7103 "<previous>"
7104 "<response>%s</response>"
7105 "<extra_data>%s</extra_data>"
7106 "</previous>"
7107 "</wizard>\n",
7108 params_xml->str ? params_xml->str : "",
7109 response ? response : "",
7110 extra ? extra : "")
7111 < 0)
7112 {
7113 fclose (xsl_file);
7114 unlink (xsl_file_name);
7115 fclose (xml_file);
7116 unlink (xml_file_name);
7117 free_entity (entity);
7118 g_warning ("%s: Wizard failed to write XML",
7119 __func__);
7120 g_free (response);
7121 g_free (extra);
7122 g_string_free (params_xml, TRUE);
7123 return -1;
7124 }
7125
7126 fflush (xml_file);
7127
7128 /* Combine XSL and XML to get the GMP command. */
7129
7130 gmp = xsl_transform (xsl_file_name, xml_file_name, NULL,
7131 NULL);
7132 fclose (xsl_file);
7133 unlink (xsl_file_name);
7134 fclose (xml_file);
7135 unlink (xml_file_name);
7136 if (gmp == NULL)
7137 {
7138 g_warning ("%s: Wizard XSL transform failed",
7139 __func__);
7140 free_entity (entity);
7141 g_free (response);
7142 g_free (extra);
7143 g_string_free (params_xml, TRUE);
7144 return -1;
7145 }
7146
7147 /* Run the GMP command. */
7148
7149 g_free (response);
7150 response = NULL;
7151 ret = run_command (run_command_data, gmp, &response);
7152 if (ret == 0)
7153 {
7154 /* Command succeeded. */
7155 }
7156 else
7157 {
7158 free_entity (entity);
7159 g_free (response);
7160 g_free (extra);
7161 g_string_free (params_xml, TRUE);
7162 return -1;
7163 }
7164
7165 /* Exit if the command failed. */
7166
7167 if (response)
7168 {
7169 const char *status;
7170 entity_t response_entity;
7171
7172 response_entity = NULL;
7173 if (parse_entity (response, &response_entity))
7174 {
7175 g_warning ("%s: Wizard failed to parse response",
7176 __func__);
7177 free_entity (entity);
7178 g_free (response);
7179 g_free (extra);
7180 g_string_free (params_xml, TRUE);
7181 return -1;
7182 }
7183
7184 status = entity_attribute (response_entity, "status");
7185 if ((status == NULL)
7186 || (strlen (status) == 0)
7187 || (status[0] != '2'))
7188 {
7189 g_debug ("response was %s", response);
7190 if (command_error)
7191 {
7192 const char *text;
7193 text = entity_attribute (response_entity, "status_text");
7194 if (text)
7195 *command_error = g_strdup (text);
7196 }
7197 if (command_error_code)
7198 {
7199 *command_error_code = g_strdup (status);
7200 }
7201 free_entity (response_entity);
7202 free_entity (entity);
7203 g_free (response);
7204 g_free (extra);
7205 g_string_free (params_xml, TRUE);
7206 return 4;
7207 }
7208
7209 free_entity (response_entity);
7210 }
7211
7212 /* Get the extra_data element. */
7213
7214 extra_xsl = entity_child (step, "extra_data");
7215 if (extra_xsl)
7216 {
7217 /* Save the extra_data XSL from the element to a file. */
7218
7219 xsl_fd = mkstemp (extra_xsl_file_name);
7220 if (xsl_fd == -1)
7221 {
7222 g_warning ("%s: Wizard extra_data XSL file create failed",
7223 __func__);
7224 free_entity (entity);
7225 g_free (response);
7226 g_free (extra);
7227 g_string_free (params_xml, TRUE);
7228 return -1;
7229 }
7230
7231 xsl_file = fdopen (xsl_fd, "w");
7232 if (xsl_file == NULL)
7233 {
7234 g_warning ("%s: Wizard extra_data XSL file open failed",
7235 __func__);
7236 close (xsl_fd);
7237 free_entity (entity);
7238 g_free (response);
7239 g_free (extra);
7240 g_string_free (params_xml, TRUE);
7241 return -1;
7242 }
7243
7244 if (first_entity (extra_xsl->entities))
7245 print_entity (xsl_file, first_entity (extra_xsl->entities));
7246
7247 /* Write the params as XML to a file. */
7248
7249 xml_fd = mkstemp (extra_xml_file_name);
7250 if (xml_fd == -1)
7251 {
7252 g_warning ("%s: Wizard XML file create failed",
7253 __func__);
7254 fclose (xsl_file);
7255 unlink (xsl_file_name);
7256 free_entity (entity);
7257 g_free (response);
7258 g_free (extra);
7259 g_string_free (params_xml, TRUE);
7260 return -1;
7261 }
7262
7263 xml_file = fdopen (xml_fd, "w");
7264 if (xml_file == NULL)
7265 {
7266 g_warning ("%s: Wizard XML file open failed",
7267 __func__);
7268 fclose (xsl_file);
7269 unlink (xsl_file_name);
7270 close (xml_fd);
7271 free_entity (entity);
7272 g_free (response);
7273 g_free (extra);
7274 g_string_free (params_xml, TRUE);
7275 return -1;
7276 }
7277
7278 if (fprintf (xml_file,
7279 "<wizard>"
7280 "<params>%s</params>"
7281 "<current>"
7282 "<response>%s</response>"
7283 "</current>"
7284 "<previous>"
7285 "<extra_data>%s</extra_data>"
7286 "</previous>"
7287 "</wizard>\n",
7288 params_xml->str ? params_xml->str : "",
7289 response ? response : "",
7290 extra ? extra : "")
7291 < 0)
7292 {
7293 fclose (xsl_file);
7294 unlink (extra_xsl_file_name);
7295 fclose (xml_file);
7296 unlink (extra_xml_file_name);
7297 free_entity (entity);
7298 g_warning ("%s: Wizard failed to write XML",
7299 __func__);
7300 g_free (response);
7301 g_free (extra);
7302 g_string_free (params_xml, TRUE);
7303 return -1;
7304 }
7305
7306 fflush (xml_file);
7307
7308 g_free (extra);
7309 extra = xsl_transform (extra_xsl_file_name, extra_xml_file_name,
7310 NULL, NULL);
7311 fclose (xsl_file);
7312 unlink (extra_xsl_file_name);
7313 fclose (xml_file);
7314 unlink (extra_xml_file_name);
7315 }
7316 }
7317 steps = next_entities (steps);
7318 }
7319
7320 if (extra)
7321 extra_wrapped = g_strdup_printf ("<extra_data>%s</extra_data>",
7322 extra);
7323 else
7324 extra_wrapped = NULL;
7325 g_free (extra);
7326
7327 if (ret_response)
7328 *ret_response = response;
7329
7330 if (extra_wrapped)
7331 {
7332 entity_t extra_entity, status_entity, status_text_entity;
7333 ret = parse_entity (extra_wrapped, &extra_entity);
7334 if (ret == 0)
7335 {
7336 status_entity = entity_child (extra_entity, "status");
7337 status_text_entity = entity_child (extra_entity, "status_text");
7338
7339 if (status_text_entity && command_error)
7340 {
7341 *command_error = g_strdup (entity_text (status_text_entity));
7342 }
7343
7344 if (status_entity && command_error_code)
7345 {
7346 *command_error_code = g_strdup (entity_text (status_entity));
7347 }
7348 free_entity (extra_entity);
7349 }
7350 else
7351 {
7352 g_warning ("%s: failed to parse extra data", __func__);
7353 free_entity (entity);
7354 g_string_free (params_xml, TRUE);
7355 return -1;
7356 }
7357 }
7358
7359 free_entity (entity);
7360 g_string_free (params_xml, TRUE);
7361
7362 /* All the steps succeeded. */
7363
7364 return 0;
7365 }
7366
7367
7368 /* Resources. */
7369
7370 /**
7371 * @brief Delete a resource.
7372 *
7373 * @param[in] type Type of resource.
7374 * @param[in] resource_id UUID of resource.
7375 * @param[in] ultimate Whether to remove entirely, or to trashcan.
7376 *
7377 * @return 0 success, 1 resource in use, 2 failed to find resource,
7378 * 99 permission denied, -1 error.
7379 */
7380 int
delete_resource(const char * type,const char * resource_id,int ultimate)7381 delete_resource (const char *type, const char *resource_id, int ultimate)
7382 {
7383 if (strcasecmp (type, "ticket") == 0)
7384 return delete_ticket (resource_id, ultimate);
7385 if (strcasecmp (type, "tls_certificate") == 0)
7386 return delete_tls_certificate (resource_id, ultimate);
7387 assert (0);
7388 return -1;
7389 }
7390