OpenVAS Manager  7.0.3~git
otp.c
Go to the documentation of this file.
1 /* OpenVAS Manager
2  * $Id$
3  * Description: Module for OpenVAS Manager: the OTP library.
4  *
5  * Authors:
6  * Matthew Mundell <matthew.mundell@greenbone.net>
7  *
8  * Copyright:
9  * Copyright (C) 2009 Greenbone Networks GmbH
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
45 #include "otp.h"
46 #include "manage.h"
47 #include "scanner.h"
48 #include "types.h"
49 
50 #include <assert.h>
51 #include <ctype.h>
52 #include <errno.h>
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 #include <unistd.h>
57 
58 #include <openvas/base/openvas_string.h>
59 #include <openvas/misc/nvt_categories.h>
60 
61 #undef G_LOG_DOMAIN
62 
65 #define G_LOG_DOMAIN "md otp"
66 
70 
71 
72 /* Helper functions. */
73 
81 static int
82 category_number (const char *category)
83 {
84  static const char *categories[] = { ACT_STRING_LIST_ALL };
85  int index;
86  for (index = ACT_FIRST; index <= ACT_END; index++)
87  if (strcmp (category, categories[index]) == 0)
88  return index;
89  return ACT_UNKNOWN;
90 }
91 
96 static void
97 blank_control_chars (char *string)
98 {
99  for (; *string; string++)
100  if (iscntrl (*string) && *string != '\n') *string = ' ';
101 }
102 
103 
104 /* Messages. */
105 
109 static message_t* current_message = NULL;
110 
114 static gchar* current_host = NULL;
115 
116 static char *plugins_feed_version = NULL;
117 
125 static message_t*
126 make_message (const char* host)
127 {
128  message_t* message;
129 
130  message = (message_t*) g_malloc (sizeof (message_t));
131 
132  message->host = g_strdup (host);
133  message->description = NULL;
134  message->oid = NULL;
135  message->port.number = 0;
136  message->port.protocol = PORT_PROTOCOL_OTHER;
137  message->port.string = NULL;
138 
139  return message;
140 }
141 
147 static void
148 free_message (message_t* message)
149 {
150  if (message->host) free (message->host);
151  if (message->description) free (message->description);
152  if (message->oid) free (message->oid);
153  if (message->port.string) free (message->port.string);
154  free (message);
155 }
156 
164 static void
165 set_message_port_number (message_t* message, int number)
166 {
167  message->port.number = number;
168 }
169 
177 static void
178 set_message_port_protocol (message_t* message, const char* protocol)
179 {
180  if (strcasecmp ("udp", protocol) == 0)
181  message->port.protocol = PORT_PROTOCOL_UDP;
182  else if (strcasecmp ("tcp", protocol) == 0)
183  message->port.protocol = PORT_PROTOCOL_TCP;
184  else
185  message->port.protocol = PORT_PROTOCOL_OTHER;
186 }
187 
194 static void
195 set_message_port_string (message_t* message, char* string)
196 {
197  if (message->port.string) free (message->port.string);
198  message->port.string = string;
199 }
200 
208 static void
209 set_message_description (message_t* message, char* description)
210 {
211  if (message->description) free (message->description);
212  message->description = description;
213 }
214 
222 static void
223 set_message_oid (message_t* message, char* oid)
224 {
225  if (message->oid) free (message->oid);
226  message->oid = oid;
227 }
228 
236 static void
237 write_message (task_t task, message_t* message, char* type)
238 {
239  result_t result;
240 
241  assert (current_report);
242 
244  result = make_result (task, message->host, message->port.string, message->oid,
245  type, message->description);
247 }
248 
255 static void
256 append_error_message (task_t task, message_t* message)
257 {
258  write_message (task, message, "Error Message");
259 }
260 
267 static void
268 append_alarm_message (task_t task, message_t* message)
269 {
270  write_message (task, message, "Alarm");
271 }
272 
279 static void
280 append_log_message (task_t task, message_t* message)
281 {
282  assert (current_report);
283 
284  if (message->port.string
285  && (strcmp (message->port.string, "general/Host_Details") == 0))
286  {
287  int len;
288  /* Strip trailing \n. */
289  len = strlen (message->description);
290  if ((len > 2)
291  && (message->description[len - 1] == 'n')
292  && (message->description[len - 2] == '\\'))
293  message->description[len - 2] = '\0';
294  /* Add detail to report. */
296  message->host,
297  message->description))
298  g_warning ("%s: Failed to add report detail for host '%s': %s\n",
299  __FUNCTION__,
300  message->host,
301  message->description);
302  }
303  else
304  write_message (task, message, "Log Message");
305 }
306 
307 
308 /* Scanner preferences. */
309 
313 static char* current_scanner_preference = NULL;
314 
315 
316 /* Scanner plugins. */
317 
321 static nvti_t* current_plugin = NULL;
322 
326 GList* scanner_plugins_list = NULL;
327 
332 
333 
334 /* Scanner state. */
335 
341 void
343 {
344  plugins_feed_version = NULL;
345 }
346 
350 typedef enum
351 {
392 
396 static scanner_state_t scanner_state = SCANNER_TOP;
397 
401 static void
402 set_scanner_state (scanner_state_t state)
403 {
404  scanner_state = state;
405  g_debug (" scanner state set: %i\n", scanner_state);
406 }
407 
412 
417 
422 
427 
431 void
433 {
434  scanner_init_state = state;
435  g_debug (" scanner init state set: %i\n", scanner_init_state);
436 }
437 
441 void
443 {
444  set_scanner_state (SCANNER_TOP);
449 }
450 
451 
452 /* OTP input processor. */
453 
456 extern char *from_scanner;
459 
467 static int
468 sync_buffer ()
469 {
471  {
473  g_debug (" scanner start caught end\n");
474  }
475  else if (from_scanner_start == 0)
476  {
478  {
479  g_warning ("From scanner buffer treshold.");
480  return -1;
481  }
482  }
483  else
484  {
485  /* Move the remaining partial line to the front of the buffer. This
486  * ensures that there is space after the partial line into which
487  * serve_omp can read the rest of the line. */
488  char* start = from_scanner + from_scanner_start;
490  memmove (from_scanner, start, from_scanner_end);
491  from_scanner_start = 0;
493  g_debug (" new from_scanner_start: %" BUFFER_SIZE_T_FORMAT "\n",
494  from_scanner_start);
495  g_debug (" new from_scanner_end: %" BUFFER_SIZE_T_FORMAT "\n",
497  }
498  return 0;
499 }
500 
508 static int
509 parse_scanner_done (char** messages)
510 {
511  char *end = *messages + from_scanner_end - from_scanner_start;
512  while (*messages < end && ((*messages)[0] == ' ' || (*messages)[0] == '\n'))
513  { (*messages)++; from_scanner_start++; }
514  if ((int) (end - *messages) < 6)
515  /* Too few characters to be the end marker, return to select to
516  * wait for more input. */
517  return -2;
518  if (strncasecmp ("SERVER", *messages, 6))
519  {
520  g_debug (" scanner fail: expected final \"SERVER\"\n");
521  return -1;
522  }
523  set_scanner_state (SCANNER_TOP);
524  from_scanner_start += 6;
525  (*messages) += 6;
526  return 0;
527 }
528 
536 static int
537 parse_scanner_bad_login (char** messages)
538 {
539  char *end, *match;
540  end = *messages + from_scanner_end - from_scanner_start;
541  while (*messages < end && ((*messages)[0] == ' '))
542  { (*messages)++; from_scanner_start++; }
543  if ((match = memchr (*messages,
544  (int) '\n',
545  from_scanner_end - from_scanner_start)))
546  {
548  if (strncasecmp ("Bad login attempt !", *messages, 19) == 0)
549  {
550  g_debug ("match bad login\n");
551  from_scanner_start += match + 1 - *messages;
552  *messages = match + 1;
554  return 0;
555  }
556  }
557  return 1;
558 }
559 
568 static int
569 parse_scanner_preference_value (char** messages, void (*progress) ())
570 {
571  char *value, *end, *match;
572  end = *messages + from_scanner_end - from_scanner_start;
573  while (*messages < end && ((*messages)[0] == ' '))
574  { (*messages)++; from_scanner_start++; }
575  if ((match = memchr (*messages,
576  (int) '\n',
577  from_scanner_end - from_scanner_start)))
578  {
579  match[0] = '\0';
580  if (current_scanner_preference)
581  {
582  preference_t *preference;
583 
584  value = g_strdup (*messages);
585  blank_control_chars (value);
586  if (progress)
587  progress ();
588  preference = g_malloc0 (sizeof (preference_t));
589  preference->name = g_strdup (current_scanner_preference);
590  preference->value = value;
591  /* Add the preference to the_list which will be bulk-inserted
592  * in DB later in manage_complete_nvt_cache_update. */
594  preference);
595  }
596  set_scanner_state (SCANNER_PREFERENCE_NAME);
597  from_scanner_start += match + 1 - *messages;
598  *messages = match + 1;
599  return 0;
600  }
601  return -2;
602 }
603 
611 static int
612 parse_scanner_plugin_list_tags (char** messages)
613 {
614  char *value, *end, *match;
615  assert (current_plugin != NULL);
616  end = *messages + from_scanner_end - from_scanner_start;
617  while (*messages < end && ((*messages)[0] == ' '))
618  { (*messages)++; from_scanner_start++; }
619  if ((match = memchr (*messages,
620  (int) '\n',
621  from_scanner_end - from_scanner_start)))
622  {
623  match[0] = '\0';
624  value = g_strdup (*messages);
625  blank_control_chars (value);
626  if (value != NULL)
627  {
628  char* pos = value;
629  while (*pos)
630  {
631  if (*pos == ';')
632  *pos = '\n';
633  pos++;
634  }
635  }
636  if (current_plugin)
637  {
638  gchar *tags, *cvss_base;
639  parse_tags (value, &tags, &cvss_base);
640  nvti_set_tag (current_plugin, tags);
641  nvti_set_cvss_base (current_plugin, cvss_base);
642  g_free (tags);
643  g_free (cvss_base);
644 
645  /* Add the plugin to scanner_plugins_list which will be bulk-inserted
646  * in DB later in manage_complete_nvt_cache_update. */
647  scanner_plugins_list = g_list_prepend (scanner_plugins_list,
648  current_plugin);
649  current_plugin = NULL;
650  }
651  set_scanner_state (SCANNER_PLUGIN_LIST_OID);
652  from_scanner_start += match + 1 - *messages;
653  *messages = match + 1;
654  g_free (value);
655  return 0;
656  }
657  return -2;
658 }
659 
669 static int
670 parse_scanner_server (char** messages)
671 {
672  char *end, *match;
673  end = *messages + from_scanner_end - from_scanner_start;
674  while (*messages < end && ((*messages)[0] == ' '))
675  { (*messages)++; from_scanner_start++; }
676  if ((match = memchr (*messages,
677  (int) '\n',
678  from_scanner_end - from_scanner_start)))
679  {
680  char* newline;
681  char* input;
682  buffer_size_t from_start, from_end;
683  match[0] = '\0';
685  while (*messages < end && ((*messages)[0] == ' '))
686  { (*messages)++; from_scanner_start++; }
689  newline = match;
690  newline[0] = '\n';
691  /* Check for a <|>. */
692  input = *messages;
693  from_start = from_scanner_start;
694  from_end = from_scanner_end;
695  while (from_start < from_end
696  && ((match = memchr (input,
697  (int) '<',
698  from_end - from_start))
699  != NULL))
700  {
701  assert (match >= input);
702  if ((((match - input) + from_start + 1) < from_end)
703  && (match[1] == '|')
704  && (match[2] == '>'))
705  {
706  if (match > newline)
707  /* The next <|> is after the newline, which is an error. */
708  return -1;
709  /* The next <|> is before the newline, which may be correct. */
710  return -3;
711  }
712  from_start += match + 1 - input;
713  input = match + 1;
714  }
715  /* Need more input for a newline or <|>. */
716  return -2;
717  }
718  return -4;
719 }
720 
721 static int
722 scanner_is_loading (char *messages)
723 {
724  if (!strncasecmp ("SCANNER_LOADING ", messages, strlen ("SCANNER_LOADING ")))
725  return 1;
726  return 0;
727 }
728 
733 static void
734 parse_scanner_loading (char *messages)
735 {
736  char *str;
737 
738  str = strstr (messages, " <|> ");
739  if (str == NULL)
740  return;
741  str += 5;
742  scanner_current_loading = atoi (str);
744  return;
745 
746  str = strstr (str, " <|> ");
747  if (str == NULL)
748  return;
749  str += 5;
750  scanner_total_loading = atoi (str);
751  str = strchr (str, '\n');
752  if (str)
753  from_scanner_start += str - messages;
754 }
755 
780 int
782 {
783  char* match = NULL;
784  char* messages = from_scanner + from_scanner_start;
785  char* input;
786  const char *ver_str = "< OTP/2.0 >\n";
787  size_t ver_len = strlen (ver_str);
788  buffer_size_t from_start, from_end;
789  //g_debug (" consider %.*s\n", from_scanner_end - from_scanner_start, messages);
790 
791  /* Before processing the input, check if another manager process has stopped
792  * the current task. If so, send the stop request to the scanner. This is
793  * the only place in this file that writes to the to_scanner buffer, and hence
794  * the only place that requires that the writes to to_scanner in the OMP XML
795  * handlers must be whole OTP commands. */
796 
797  if (manage_check_current_task () == -1)
798  {
799  /* Out of space in to_scanner. Just treat it as an error for now. */
800  return -1;
801  }
802 
803  /* First, handle special scanner states where the input from the scanner
804  * ends in something other than <|> (usually a newline). */
805 
806  switch (scanner_init_state)
807  {
809  /* Read over any whitespace left by the previous session. */
810  while (from_scanner_start < from_scanner_end
811  && (messages[0] == ' ' || messages[0] == '\n'))
812  from_scanner_start++, messages++;
813 
814  if (scanner_is_loading (messages))
815  {
816  parse_scanner_loading (messages);
818  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE,
819  "Waiting for scanner to load NVTs: %d / %d.\n",
821  else
822  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE,
823  "Waiting for scanner to load: No information provided. (Message: %s)\n", messages);
824  return 3;
825  }
826  /* If message is empty we assume the scanner is still loading. */
827  if (!*messages)
828  {
829  return 5;
830  }
831  if (from_scanner_end - from_scanner_start < ver_len)
832  {
833  /* Need more input. */
834  if (sync_buffer ()) return -1;
835  return 0;
836  }
837  if (strncasecmp (ver_str, messages, ver_len))
838  {
839  g_debug (" scanner fail: expected \"%s\""
840  " got \"%.12s\"\n\n", ver_str, messages);
841  return -1;
842  }
843  from_scanner_start += ver_len;
844  messages += ver_len;
846  return 0;
848  /* Nothing to parse. */
849  return 0;
851  /* Nothing to parse. */
852  return 0;
854  /* Input from scanner before version string sent. */
855  return -1;
858  case SCANNER_INIT_DONE:
861  case SCANNER_INIT_TOP:
862  if (scanner_state == SCANNER_TOP)
863  switch (parse_scanner_bad_login (&messages))
864  {
865  case 0: return 2; /* Found bad login response. */
866  case 1: break;
867  }
868  else if (scanner_state == SCANNER_DONE)
869  switch (parse_scanner_done (&messages))
870  {
871  case -1: return -1;
872  case -2:
873  /* Need more input. */
874  if (sync_buffer ()) return -1;
875  return 0;
876  }
877  else if (scanner_state == SCANNER_PLUGIN_LIST_TAGS)
878  switch (parse_scanner_plugin_list_tags (&messages))
879  {
880  case -2:
881  /* Need more input. */
882  if (sync_buffer ()) return -1;
883  return 0;
884  }
885  else if (scanner_state == SCANNER_PREFERENCE_VALUE)
886  {
887  switch (parse_scanner_preference_value (&messages, progress))
888  {
889  case -2:
890  /* Need more input. */
891  if (sync_buffer ()) return -1;
892  return 0;
893  }
894  g_free (current_scanner_preference);
895  current_scanner_preference = NULL;
896  }
897  else if (scanner_state == SCANNER_SERVER)
898  /* Look for any newline delimited scanner commands. */
899  switch (parse_scanner_server (&messages))
900  {
901  case 0: break; /* Found newline delimited command. */
902  case -1: return -1; /* Error. */
903  case -2:
904  /* Need more input. */
905  if (sync_buffer ()) return -1;
906  return 0;
907  case -3: break; /* Next <|> is before next \n. */
908  case -4: break; /* Failed to find \n, try for <|>. */
909  }
910  break;
911  } /* switch (scanner_init_state) */
912 
913  /* Parse and handle any fields ending in <|>. */
914 
915  input = messages;
916  from_start = from_scanner_start;
917  from_end = from_scanner_end;
918  while (from_start < from_end
919  && ((match = memchr (input,
920  (int) '<',
921  from_end - from_start))
922  != NULL))
923  {
924  assert (match >= input);
925 
926  /* Check whether we've had a transaction open too long, because
927  * it may take some time until we get out of this loop and do a
928  * process_omp_change, and we don't want to hold up other writer
929  * processes. Note that in GSA even tabular pages like Tasks now
930  * write (settings) to the db. */
931  manage_transaction_stop (FALSE);
932 
933  if ((((match - input) + from_start + 1) < from_end)
934  && (match[1] == '|')
935  && (match[2] == '>'))
936  {
937  char* message;
938  char* field;
939  /* Found a full field, process the field. */
940  message = messages;
941  *match = '\0';
942  from_scanner_start += match + 3 - messages;
943  from_start = from_scanner_start;
944  messages = match + 3;
945  input = messages;
946 
947  /* Strip leading and trailing whitespace. */
948  field = openvas_strip_space (message, match);
949  blank_control_chars (field);
950 
951  g_debug (" scanner old state %i\n", scanner_state);
952  g_debug (" scanner field: %s\n", field);
953  switch (scanner_state)
954  {
955  case SCANNER_BYE:
956  if (strcasecmp ("BYE", field))
957  goto return_error;
958  /* It's up to the caller to set the init state, as the
959  * caller must flush the ACK. */
960  set_scanner_state (SCANNER_DONE);
961  switch (parse_scanner_done (&messages))
962  {
963  case 0:
964  if (sync_buffer ()) goto return_error;
965  if (acknowledge_bye ()) goto return_error;
966  goto return_bye;
967  case -1: goto return_error;
968  case -2:
969  /* Need more input. */
970  if (sync_buffer ()) goto return_error;
971  goto return_need_more;
972  }
973  break;
975  {
976  if (current_message)
977  {
979  char* description = g_strdup (field);
980  set_message_description (current_message, description);
981  }
982  set_scanner_state (SCANNER_ERRMSG_OID);
983  break;
984  }
985  case SCANNER_ERRMSG_HOST:
986  {
987  assert (current_message == NULL);
988  current_message = make_message (field);
989  set_scanner_state (SCANNER_ERRMSG_NUMBER);
990  break;
991  }
993  {
995  int number;
996  char *protocol, *formatted;
997 
998  assert (current_message);
999 
1000  protocol = g_newa (char, strlen (field));
1001 
1002  if (sscanf (field, "%i/%s",
1003  &number, protocol)
1004  != 2)
1005  {
1006  number = atoi (field);
1007  protocol[0] = '\0';
1008  }
1009  g_debug (" scanner got debug port, number: %i, protocol: %s\n",
1010  number, protocol);
1011 
1012  set_message_port_number (current_message, number);
1013  set_message_port_protocol (current_message, protocol);
1014 
1015  formatted = port_name_formatted (field);
1016  if (formatted == NULL)
1017  formatted = g_strdup (field);
1018  set_message_port_string (current_message, formatted);
1019 
1020  set_scanner_state (SCANNER_ERRMSG_DESCRIPTION);
1021  break;
1022  }
1023  case SCANNER_ERRMSG_OID:
1024  {
1025  if (current_message != NULL
1026  && current_scanner_task != (task_t) 0)
1027  {
1028  char* oid = g_strdup (field);
1029  set_message_oid (current_message, oid);
1030 
1031  append_error_message (current_scanner_task, current_message);
1032  free_message (current_message);
1033  current_message = NULL;
1034  }
1035  set_scanner_state (SCANNER_DONE);
1036  switch (parse_scanner_done (&messages))
1037  {
1038  case -1: goto return_error;
1039  case -2:
1040  /* Need more input. */
1041  if (sync_buffer ()) goto return_error;
1042  goto return_need_more;
1043  }
1044  break;
1045  }
1047  {
1048  if (current_message)
1049  {
1051  char* description = g_strdup (field);
1052  set_message_description (current_message, description);
1053  }
1054  set_scanner_state (SCANNER_ALARM_OID);
1055  break;
1056  }
1057  case SCANNER_ALARM_HOST:
1058  {
1059  assert (current_message == NULL);
1060  current_message = make_message (field);
1061  set_scanner_state (SCANNER_ALARM_NUMBER);
1062  break;
1063  }
1064  case SCANNER_ALARM_NUMBER:
1065  {
1067  int number;
1068  char *protocol, *formatted;
1069 
1070  assert (current_message);
1071 
1072  protocol = g_newa (char, strlen (field));
1073 
1074  if (sscanf (field, "%i/%s",
1075  &number, protocol)
1076  != 2)
1077  {
1078  number = atoi (field);
1079  protocol[0] = '\0';
1080  }
1081  g_debug (" scanner got alarm port, number: %i, protocol: %s\n",
1082  number, protocol);
1083 
1084  set_message_port_number (current_message, number);
1085  set_message_port_protocol (current_message, protocol);
1086 
1087  formatted = port_name_formatted (field);
1088  if (formatted == NULL)
1089  formatted = g_strdup (field);
1090  set_message_port_string (current_message, formatted);
1091 
1092  set_scanner_state (SCANNER_ALARM_DESCRIPTION);
1093  break;
1094  }
1095  case SCANNER_ALARM_OID:
1096  {
1097  if (current_message != NULL
1098  && current_scanner_task != (task_t) 0)
1099  {
1100  char* oid = g_strdup (field);
1101  set_message_oid (current_message, oid);
1102 
1103  append_alarm_message (current_scanner_task, current_message);
1104  free_message (current_message);
1105  current_message = NULL;
1106  }
1107  set_scanner_state (SCANNER_DONE);
1108  switch (parse_scanner_done (&messages))
1109  {
1110  case -1: goto return_error;
1111  case -2:
1112  /* Need more input. */
1113  if (sync_buffer ()) goto return_error;
1114  goto return_need_more;
1115  }
1116  break;
1117  }
1119  {
1120  if (current_message)
1121  {
1123  char* description = g_strdup (field);
1124  set_message_description (current_message, description);
1125  }
1126  set_scanner_state (SCANNER_LOG_OID);
1127  break;
1128  }
1129  case SCANNER_LOG_HOST:
1130  {
1131  assert (current_message == NULL);
1132  current_message = make_message (field);
1133  set_scanner_state (SCANNER_LOG_NUMBER);
1134  break;
1135  }
1136  case SCANNER_LOG_NUMBER:
1137  {
1139  int number;
1140  char *protocol, *formatted;
1141 
1142  assert (current_message);
1143 
1144  protocol = g_newa (char, strlen (field));
1145 
1146  if (sscanf (field, "%i/%s",
1147  &number, protocol)
1148  != 2)
1149  {
1150  number = atoi (field);
1151  protocol[0] = '\0';
1152  }
1153  g_debug (" scanner got log port, number: %i, protocol: %s\n",
1154  number, protocol);
1155 
1156  set_message_port_number (current_message, number);
1157  set_message_port_protocol (current_message, protocol);
1158 
1159  formatted = port_name_formatted (field);
1160  if (formatted == NULL)
1161  formatted = g_strdup (field);
1162  set_message_port_string (current_message, formatted);
1163 
1164  set_scanner_state (SCANNER_LOG_DESCRIPTION);
1165  break;
1166  }
1167  case SCANNER_LOG_OID:
1168  {
1169  if (current_message != NULL
1170  && current_scanner_task != (task_t) 0)
1171  {
1172  char* oid = g_strdup (field);
1173  set_message_oid (current_message, oid);
1174 
1175  append_log_message (current_scanner_task, current_message);
1176  free_message (current_message);
1177  current_message = NULL;
1178  }
1179  set_scanner_state (SCANNER_DONE);
1180  switch (parse_scanner_done (&messages))
1181  {
1182  case -1: goto return_error;
1183  case -2:
1184  /* Need more input. */
1185  if (sync_buffer ()) goto return_error;
1186  goto return_need_more;
1187  }
1188  break;
1189  }
1191  {
1192  /* Use match[1] instead of field[1] for UTF-8 hack. */
1193  if (strlen (field) == 0 && match[1] == '|')
1194  {
1195  set_scanner_state (SCANNER_DONE);
1196  switch (parse_scanner_done (&messages))
1197  {
1198  case 0:
1199  if (scanner_init_state
1203  {
1205  set_nvts_feed_version (plugins_feed_version);
1206  }
1207  break;
1208  case -1: goto return_error;
1209  case -2:
1210  /* Need more input. */
1211  if (sync_buffer ()) goto return_error;
1212  goto return_need_more;
1213  }
1214  break;
1215  }
1216  assert (current_plugin == NULL);
1217  current_plugin = nvti_new ();
1218  if (progress)
1219  progress ();
1220  if (current_plugin == NULL) abort ();
1221  nvti_set_oid (current_plugin, field);
1222  set_scanner_state (SCANNER_PLUGIN_LIST_NAME);
1223  break;
1224  }
1226  {
1227  nvti_set_name (current_plugin, field);
1228  set_scanner_state (SCANNER_PLUGIN_LIST_CATEGORY);
1229  break;
1230  }
1232  {
1233  nvti_set_category (current_plugin, category_number (field));
1234  set_scanner_state (SCANNER_PLUGIN_LIST_COPYRIGHT);
1235  break;
1236  }
1238  {
1239  nvti_set_copyright (current_plugin, field);
1240  set_scanner_state (SCANNER_PLUGIN_LIST_FAMILY);
1241  break;
1242  }
1244  {
1245  nvti_set_family (current_plugin, field);
1246  set_scanner_state (SCANNER_PLUGIN_LIST_PLUGIN_VERSION);
1247  break;
1248  }
1250  {
1251  nvti_set_version (current_plugin, field);
1252  set_scanner_state (SCANNER_PLUGIN_LIST_CVE_ID);
1253  break;
1254  }
1256  {
1257  nvti_set_cve (current_plugin, field);
1258  set_scanner_state (SCANNER_PLUGIN_LIST_BUGTRAQ_ID);
1259  break;
1260  }
1262  {
1263  nvti_set_bid (current_plugin, field);
1264  set_scanner_state (SCANNER_PLUGIN_LIST_XREFS);
1265  break;
1266  }
1268  {
1269  nvti_set_xref (current_plugin, field);
1270  set_scanner_state (SCANNER_PLUGIN_LIST_TAGS);
1271  switch (parse_scanner_plugin_list_tags (&messages))
1272  {
1273  case -2:
1274  /* Need more input. */
1275  if (sync_buffer ()) goto return_error;
1276  goto return_need_more;
1277  }
1278  break;
1279  }
1280  case SCANNER_NVT_INFO:
1281  {
1282  char* feed_version = g_strdup (field);
1283  g_debug (" scanner got nvti_info: %s\n", feed_version);
1284  if (plugins_feed_version)
1285  g_free (plugins_feed_version);
1286  plugins_feed_version = feed_version;
1287  set_scanner_state (SCANNER_DONE);
1288  switch (parse_scanner_done (&messages))
1289  {
1290  case 0:
1293  else if (acknowledge_feed_version_info ())
1294  goto return_error;
1295  break;
1296  case -1: goto return_error;
1297  case -2:
1298  /* Need more input. */
1299  if (sync_buffer ()) goto return_error;
1300  goto return_need_more;
1301  }
1302  break;
1303  }
1305  {
1306  /* Use match[1] instead of field[1] for UTF-8 hack. */
1307  if (strlen (field) == 0 && match[1] == '|')
1308  {
1309  set_scanner_state (SCANNER_DONE);
1310  switch (parse_scanner_done (&messages))
1311  {
1312  case -1: goto return_error;
1313  case -2:
1314  /* Need more input. */
1315  if (sync_buffer ()) goto return_error;
1316  goto return_need_more;
1317  }
1321  {
1326  ? -2 : -1);
1329  /* Return 1, as though the scanner sent BYE. */
1331  goto return_bye;
1332  }
1333  break;
1334  }
1335 
1336  {
1337  int value_start = -1, value_end = -1, count;
1338  char name[21];
1339  /* LDAPsearch[entry]:Timeout value */
1340  count = sscanf (field, "%20[^[][%*[^]]]:%n%*[ -~]%n",
1341  name, &value_start, &value_end);
1342  if (count == 1 && value_start > 0 && value_end > 0
1343  && ((strcmp (name, "SSH Authorization") == 0)
1344  || (strcmp (name, "SMB Authorization") == 0)))
1345  current_scanner_preference = NULL;
1346  else
1347  current_scanner_preference = g_strdup (field);
1348  set_scanner_state (SCANNER_PREFERENCE_VALUE);
1349  switch (parse_scanner_preference_value (&messages,
1350  progress))
1351  {
1352  case -2:
1353  /* Need more input. */
1354  if (sync_buffer ()) goto return_error;
1355  goto return_need_more;
1356  }
1357  g_free (current_scanner_preference);
1358  current_scanner_preference = NULL;
1359  }
1360  break;
1361  }
1362  case SCANNER_SERVER:
1363  if (strcasecmp ("BYE", field) == 0)
1364  set_scanner_state (SCANNER_BYE);
1365  else if (strcasecmp ("ERRMSG", field) == 0)
1366  set_scanner_state (SCANNER_ERRMSG_HOST);
1367  else if (strcasecmp ("FILE_ACCEPTED", field) == 0)
1368  {
1369  set_scanner_state (SCANNER_DONE);
1370  switch (parse_scanner_done (&messages))
1371  {
1372  case -1: goto return_error;
1373  case -2:
1374  /* Need more input. */
1375  if (sync_buffer ()) goto return_error;
1376  goto return_need_more;
1377  }
1378  }
1379  else if (strcasecmp ("ALARM", field) == 0)
1380  set_scanner_state (SCANNER_ALARM_HOST);
1381  else if (strcasecmp ("LOG", field) == 0)
1382  set_scanner_state (SCANNER_LOG_HOST);
1383  else if (strcasecmp ("NVT_INFO", field) == 0)
1384  set_scanner_state (SCANNER_NVT_INFO);
1385  else if (strcasecmp ("PLUGIN_LIST", field) == 0)
1386  {
1387  set_scanner_state (SCANNER_PLUGIN_LIST_OID);
1388  }
1389  else if (strcasecmp ("PREFERENCES", field) == 0)
1390  {
1391  assert (current_scanner_preference == NULL);
1392  set_scanner_state (SCANNER_PREFERENCE_NAME);
1393  }
1394  else if (strcasecmp ("TIME", field) == 0)
1395  {
1396  set_scanner_state (SCANNER_TIME);
1397  }
1398  else if (strcasecmp ("STATUS", field) == 0)
1399  {
1400  set_scanner_state (SCANNER_STATUS_HOST);
1401  }
1402  else
1403  {
1404  g_debug ("New scanner command to implement: %s\n",
1405  field);
1406  goto return_error;
1407  }
1408  break;
1409  case SCANNER_STATUS_HOST:
1410  {
1411  assert (current_host == NULL);
1412  current_host = g_strdup (field);
1413  set_scanner_state (SCANNER_STATUS_PROGRESS);
1414  break;
1415  }
1417  {
1418  /* Store the progress in the ports slots in the db. */
1419  assert (current_report);
1420  if (current_report && current_host)
1421  {
1422  unsigned int current, max;
1423  g_debug (" scanner got ports: %s\n", field);
1424  if (sscanf (field, "%u/%u", &current, &max) == 2)
1426  current_host,
1427  current,
1428  max);
1429  }
1430  if (current_host)
1431  {
1432  g_free (current_host);
1433  current_host = NULL;
1434  }
1435  set_scanner_state (SCANNER_DONE);
1436  switch (parse_scanner_done (&messages))
1437  {
1438  case -1: goto return_error;
1439  case -2:
1440  /* Need more input. */
1441  if (sync_buffer ()) goto return_error;
1442  goto return_need_more;
1443  }
1444  break;
1445  }
1446  case SCANNER_TIME:
1447  {
1448  if (strcasecmp ("HOST_START", field) == 0)
1449  set_scanner_state (SCANNER_TIME_HOST_START_HOST);
1450  else if (strcasecmp ("HOST_END", field) == 0)
1451  set_scanner_state (SCANNER_TIME_HOST_END_HOST);
1452  else if (strcasecmp ("SCAN_START", field) == 0)
1453  set_scanner_state (SCANNER_TIME_SCAN_START);
1454  else if (strcasecmp ("SCAN_END", field) == 0)
1455  set_scanner_state (SCANNER_TIME_SCAN_END);
1456  else
1458  abort ();
1459  break;
1460  }
1462  {
1463  assert (current_host == NULL);
1464  current_host = g_strdup (field);
1465  set_scanner_state (SCANNER_TIME_HOST_START_TIME);
1466  break;
1467  }
1469  {
1471  {
1472  assert (current_host);
1473  assert (current_report);
1474 
1476  current_host,
1477  field);
1478  g_free (current_host);
1479  current_host = NULL;
1480  }
1481  set_scanner_state (SCANNER_DONE);
1482  switch (parse_scanner_done (&messages))
1483  {
1484  case -1: goto return_error;
1485  case -2:
1486  /* Need more input. */
1487  if (sync_buffer ()) goto return_error;
1488  goto return_need_more;
1489  }
1490  break;
1491  }
1493  {
1494  assert (current_host == NULL);
1495  current_host = g_strdup (field);
1496  set_scanner_state (SCANNER_TIME_HOST_END_TIME);
1497  break;
1498  }
1500  {
1501  assert (current_host);
1502  assert (current_report);
1503 
1504  if (report_host_noticeable (current_report, current_host))
1505  {
1506  char *uuid;
1507  uuid = report_uuid (current_report);
1508  host_notice (current_host, "ip", current_host,
1509  "Report Host", uuid, 1, 0);
1510  free (uuid);
1511  }
1512 
1514  {
1515  assert (current_host);
1517  current_host,
1518  field);
1519  g_free (current_host);
1520  current_host = NULL;
1521  }
1522  set_scanner_state (SCANNER_DONE);
1523  switch (parse_scanner_done (&messages))
1524  {
1525  case -1: goto return_error;
1526  case -2:
1527  /* Need more input. */
1528  if (sync_buffer ()) goto return_error;
1529  goto return_need_more;
1530  }
1531  break;
1532  }
1534  {
1536  {
1539  {
1542  /* If the scan has been started before, then leave
1543  * the start time alone. */
1545  {
1547  g_strdup (field));
1549  }
1550  }
1551  }
1552  set_scanner_state (SCANNER_DONE);
1553  switch (parse_scanner_done (&messages))
1554  {
1555  case -1: goto return_error;
1556  case -2:
1557  /* Need more input. */
1558  if (sync_buffer ()) goto return_error;
1559  goto return_need_more;
1560  }
1561  break;
1562  }
1563  case SCANNER_TIME_SCAN_END:
1564  {
1566  {
1567  /* Stop transaction now, because delete_task_lock and
1568  * set_scan_end_time_otp run transactions themselves. */
1569  manage_transaction_stop (TRUE);
1571  if (current_report)
1572  {
1573  hosts_set_max_severity (current_report, NULL, NULL);
1576  }
1578  {
1580  break;
1585  break;
1591  current_report = (report_t) 0;
1592  break;
1598  current_report = (report_t) 0;
1599  break;
1600  default:
1602  g_strdup (field));
1605  }
1608  current_report = (report_t) 0;
1610  }
1611  set_scanner_state (SCANNER_DONE);
1612  switch (parse_scanner_done (&messages))
1613  {
1614  case -1: goto return_error;
1615  case -2:
1616  /* Need more input. */
1617  if (sync_buffer ()) goto return_error;
1618  goto return_need_more;
1619  }
1620  break;
1621  }
1622  case SCANNER_TOP:
1623  default:
1624  g_debug (" switch t\n");
1625  g_debug (" cmp %i\n", strcasecmp ("SERVER", field));
1626  if (strcasecmp ("SERVER", field))
1627  goto return_error;
1628  set_scanner_state (SCANNER_SERVER);
1629  /* Look for any newline delimited scanner commands. */
1630  switch (parse_scanner_server (&messages))
1631  {
1632  case 0: break; /* Found newline delimited command. */
1633  case -1: goto return_error; /* Error. */
1634  case -2:
1635  /* Need more input. */
1636  if (sync_buffer ()) goto return_error;
1637  goto return_need_more;
1638  case -3: break; /* Next <|> is before next \n. */
1639  case -4: break; /* Failed to find \n, try for <|>. */
1640  }
1641  break;
1642  }
1643 
1644  g_debug (" scanner new state: %i\n", scanner_state);
1645 
1646  continue;
1647 
1648  return_error:
1649  return -1;
1650 
1651  return_need_more:
1652  return 0;
1653 
1654  return_bye:
1655  return 1;
1656  }
1657  else
1658  {
1659  from_start += match + 1 - input;
1660  input = match + 1;
1661  }
1662  }
1663 
1664  if (sync_buffer ()) return -1;
1665  return 0;
1666 }
int report_host_noticeable(report_t, const gchar *)
Check if a report host is alive and has at least one result.
Definition: manage_sql.c:31510
void report_add_result(report_t, result_t)
Add a result to a report.
Definition: manage_sql.c:21590
char * string
Original string describing port.
Definition: manage.h:196
void set_scan_host_start_time_otp(report_t, const char *, const char *)
Set the start time of a scanned host.
Definition: manage_sql.c:24446
char * name
Name of preference.
Definition: manage.h:1739
int scanner_total_loading
Scanner total number of plugins to be loaded, when still loading.
Definition: otp.c:426
void manage_complete_nvt_cache_update(GList *, GList *, int)
Complete an update of the NVT cache.
Definition: manage_sql.c:39190
void parse_tags(const char *scanner_tags, gchar **tags, gchar **cvss_base)
Split up the tags received from the scanner.
Definition: manage.c:7241
port_protocol_t protocol
Port protocol (TCP, UDP, ...).
Definition: manage.h:195
scanner_init_state_t scanner_init_state
The initialisation state of the scanner.
Definition: otp.c:411
void reset_scanner_states()
Set the scanner initialisation state, scanner_init_state.
Definition: otp.c:442
GList * scanner_plugins_list
The full plugins list, during reading of scanner plugin list.
Definition: otp.c:326
scanner_state_t
Possible states of the scanner.
Definition: otp.c:350
void set_task_run_status(task_t, task_status_t)
Set the run state of a task.
Definition: manage_sql.c:18307
int scan_start_time_epoch(report_t)
Get the start time of a scan, in seconds since the epoch.
Definition: manage_sql.c:24198
host_t host_notice(const char *, const char *, const char *, const char *, const char *, int, int)
Notice a host.
Definition: manage_sql.c:19765
task_t current_scanner_task
The task currently running on the scanner.
Definition: manage.c:998
void hosts_set_max_severity(report_t, int *, int *)
Set the maximum severity of each host in a scan.
Definition: manage_sql.c:60390
char * description
Description of the message.
Definition: manage.h:207
int openvas_scanner_full()
Check whether the buffer for data from Scanner is full.
Definition: scanner.c:310
long long int result_t
Definition: manage.h:287
task_status_t task_run_status(task_t)
Return the run state of a task.
Definition: manage_sql.c:18238
void set_scan_start_time_otp(report_t, const char *)
Set the start time of a scan.
Definition: manage_sql.c:24256
buffer_size_t from_scanner_start
The start of the data in the from_scanner buffer.
Definition: scanner.c:67
void set_scan_host_end_time_otp(report_t, const char *, const char *)
Set the end time of a scanned host.
Definition: manage_sql.c:24398
void(* progress)()
Function to mark progress.
Definition: manage_sql.c:352
char * value
Value of preference.
Definition: manage.h:1741
int openvas_scanner_realloc()
Reallocates the from_scanner buffer to a higher size.
Definition: scanner.c:321
void clear_duration_schedules(task_t)
Clear once-off schedules from tasks where the duration has passed.
Definition: manage_sql.c:19289
scanner_init_state_t
Possible initialisation states of the scanner.
Definition: otp.h:42
void hosts_set_identifiers()
Setup hosts and their identifiers after a scan, from host details.
Definition: manage_sql.c:60125
result_t make_result(task_t, const char *, const char *, const char *, const char *, const char *)
Make a result.
Definition: manage_sql.c:19892
long long int report_t
Definition: manage.h:288
void set_scan_ports(report_t, const char *, unsigned int, unsigned int)
Set the ports for a particular host in a scan.
Definition: manage_sql.c:32533
void hosts_set_details(report_t report)
Store certain host details in the assets after a scan.
Definition: manage_sql.c:60474
void init_otp_data()
Initialise OTP library data.
Definition: otp.c:342
#define G_LOG_DOMAIN
GLib log domain.
Definition: otp.c:65
void set_task_start_time_otp(task_t, char *)
Set the start time of a task.
Definition: manage_sql.c:18524
buffer_size_t from_scanner_end
The end of the data in the from_scanner buffer.
Definition: scanner.c:72
void set_scanner_init_state(scanner_init_state_t state)
Set the scanner initialisation state, scanner_init_state.
Definition: otp.c:432
void update_duration_schedule_periods(task_t)
Update tasks with limited run schedules which have durations.
Definition: manage_sql.c:19334
int scanner_init_offset
Offset into initialisation string being sent to scanner.
Definition: otp.c:416
report_t current_report
The report of the current task.
Definition: manage.c:1003
char * oid
NVT identifier.
Definition: manage.h:208
int manage_check_current_task()
Handle state changes to current task made by other processes.
Definition: manage.c:5733
void set_scan_end_time_otp(report_t, const char *)
Set the end time of a scan.
Definition: manage_sql.c:24336
char * host
Host message describes.
Definition: manage.h:205
An NVT preference.
Definition: manage.h:1737
unsigned int number
Port number.
Definition: manage.h:194
void set_task_end_time(task_t task, char *time)
Set the end time of a task.
Definition: manage_sql.c:24145
char * report_uuid(report_t)
Return the UUID of a report.
Definition: manage_sql.c:21382
void manage_transaction_stop(gboolean)
Commit the current transaction, if any.
Definition: manage_sql.c:32976
int acknowledge_bye()
Acknowledge a scanner BYE.
Definition: manage.c:5705
void set_nvts_feed_version(const char *)
Set the feed version of the plugins in the plugin cache.
Definition: manage_sql.c:37416
char * port_name_formatted(const char *)
Returns formatted port number, protocol and iana name from.
Definition: manage_sql.c:6378
buffer_size_t from_buffer_size
Size of from_client data buffer, in bytes.
Definition: ompd.c:79
port_t port
The port.
Definition: manage.h:206
The record of a message.
Definition: manage.h:203
void manage_nvt_preferences_enable()
Enable the NVT preferences.
Definition: manage_sql.c:40973
int manage_report_host_detail(report_t, const char *, const char *)
Add a host detail to a report host.
Definition: manage_sql.c:60792
#define BUFFER_SIZE_T_FORMAT
Definition: types.h:29
GList * scanner_preferences_list
The full preferences list, during reading of scanner plugin list.
Definition: otp.c:331
void manage_transaction_start()
Start a new IMMEDIATE transaction.
Definition: manage_sql.c:32956
int process_otp_scanner_input(void(*progress)())
Process any lines available in from_scanner.
Definition: otp.c:781
int acknowledge_feed_version_info()
Acknowledge scanner PLUGINS_FEED_VERSION message,.
Definition: manage.c:5719
unsigned int buffer_size_t
Definition: types.h:31
char * from_scanner
Buffer of input from the scanner.
Definition: scanner.c:62
long long int task_t
Definition: manage.h:286
int scanner_current_loading
Scanner current number of loaded plugins, when still loading.
Definition: otp.c:421
int delete_task_lock(task_t, int)
Complete deletion of a task.
Definition: manage_sql.c:32399