Greenbone Security Assistant  7.0.3~git
gsad.c
Go to the documentation of this file.
1 /* Greenbone Security Assistant
2  * $Id$
3  * Description: Main module of Greenbone Security Assistant daemon.
4  *
5  * Authors:
6  * Chandrashekhar B <bchandra@secpod.com>
7  * Matthew Mundell <matthew.mundell@greenbone.net>
8  * Jan-Oliver Wagner <jan-oliver.wagner@greenbone.net>
9  * Michael Wiegand <michael.wiegand@greenbone.net>
10  *
11  * Copyright:
12  * Copyright (C) 2009-2016 Greenbone Networks GmbH
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27  */
28 
63 #define _GNU_SOURCE /* for strcasecmp */
64 
65 #include <arpa/inet.h>
66 #include <assert.h>
67 #include <errno.h>
68 #include <gcrypt.h>
69 #include <glib.h>
70 #include <gnutls/gnutls.h>
71 #include <langinfo.h>
72 #include <locale.h>
73 #include <netinet/in.h>
74 #include <openvas/misc/openvas_logging.h>
75 #include <openvas/base/openvas_file.h>
76 #include <openvas/base/openvas_networking.h>
77 #include <openvas/base/pidfile.h>
78 #include <openvas/omp/xml.h>
79 #include <openvas/misc/openvas_uuid.h>
80 #include <pthread.h>
81 #include <pwd.h> /* for getpwnam */
82 #include <grp.h> /* for setgroups */
83 #include <signal.h>
84 #include <stdint.h>
85 #include <stdio.h>
86 #include <stdlib.h>
87 #include <string.h>
88 #if __linux
89 #include <sys/prctl.h>
90 #endif
91 #include <sys/socket.h>
92 #include <sys/un.h>
93 #include <sys/stat.h>
94 #include <sys/types.h>
95 #include <unistd.h>
96 /* This must follow the system includes. */
97 #include <microhttpd.h>
98 
99 #include "gsad_base.h"
100 #include "gsad_omp.h"
101 #include "validator.h"
102 #include "xslt_i18n.h"
103 
104 #ifdef GIT_REV_AVAILABLE
105 #include "gitrevision.h"
106 #endif
107 
108 #undef G_LOG_DOMAIN
109 
112 #define G_LOG_DOMAIN "gsad main"
113 
114 #undef G_LOG_FATAL_MASK
115 #define G_LOG_FATAL_MASK G_LOG_LEVEL_ERROR
116 
121 #ifndef MHD_HTTP_NOT_ACCEPTABLE
122 #define MHD_HTTP_NOT_ACCEPTABLE MHD_HTTP_METHOD_NOT_ACCEPTABLE
123 #endif
124 
128 #define SID_COOKIE_NAME "GSAD_SID"
129 
133 #define DEFAULT_GSAD_HTTPS_PORT 443
134 
138 #define DEFAULT_GSAD_HTTP_PORT 80
139 
143 #define DEFAULT_GSAD_PORT 9392
144 
148 #define DEFAULT_GSAD_REDIRECT_PORT 80
149 
153 #define DEFAULT_OPENVAS_MANAGER_PORT 9390
154 
158 #define POST_BUFFER_SIZE 500000
159 
163 #define MAX_FILE_NAME_SIZE 128
164 
168 #define SESSION_TIMEOUT 15
169 
173 #define DEFAULT_CLIENT_WATCH_INTERVAL 1
174 
178 #define DEFAULT_GSAD_FACE "classic"
179 
183 #define DEFAULT_GSAD_X_FRAME_OPTIONS "SAMEORIGIN"
184 
188 #define DEFAULT_GSAD_CONTENT_SECURITY_POLICY \
189  "default-src 'self' 'unsafe-inline';" \
190  " img-src 'self' blob:;" \
191  " frame-ancestors 'self'"
192 
196 #define DEFAULT_GSAD_GUEST_CHART_X_FRAME_OPTIONS "SAMEORIGIN"
197 
201 #define DEFAULT_GSAD_GUEST_CHART_CONTENT_SECURITY_POLICY \
202  "default-src 'self' 'unsafe-inline';" \
203  " img-src 'self' blob:;" \
204  " frame-ancestors *"
205 
209 #define DEFAULT_GSAD_HSTS_MAX_AGE 31536000
210 
214 volatile int termination_signal = 0;
215 
219 #if GCRYPT_VERSION_NUMBER < 0x010600
221 #endif
222 
226 const char *NOT_FOUND_TITLE
227  = "Invalid request";
228 
232 const char *NOT_FOUND_MESSAGE
233  = "The requested page or file does not exist.";
234 
238 const char *ERROR_PAGE = "<html><body>HTTP Method not supported</body></html>";
239 
244  "<html><body>Bad request.</body></html>";
245 
250  "<html><body>An internal server error has occurred.</body></html>";
251 
252 /*
253  * UTF-8 Error page HTML.
254  */
255 #define UTF8_ERROR_PAGE(location) \
256  "<html>" \
257  "<head><title>Invalid request</title></head>" \
258  "<body>The request contained invalid UTF-8 in " location ".</body>" \
259  "</html>"
260 
261 /*
262  * Host HTTP header error page.
263  */
264 #define HOST_HEADER_ERROR_PAGE \
265  "<html>" \
266  "<head><title>Invalid request</title></head>" \
267  "<body>The request contained an unknown or invalid Host header." \
268  " If you are trying to access GSA via its hostname or a proxy," \
269  " make sure GSA is set up to allow it." \
270  "</body>" \
271  "</html>"
272 
276 struct MHD_Daemon *gsad_daemon;
277 
281 GSList *address_list = NULL;
282 
286 GHashTable *gsad_header_hosts = NULL;
287 
291 gchar *redirect_location = NULL;
292 
296 pid_t redirect_pid = 0;
297 
301 pid_t unix_pid = 0;
302 
306 int unix_socket = 0;
307 
313 GSList *log_config = NULL;
314 
321 
326 
330 gchar *guest_username = NULL;
331 
335 gchar *guest_password = NULL;
336 
340 GPtrArray *users = NULL;
341 
346 
351 
356 
361 
366 
371 
375 int chroot_state = 0;
376 
381 
385 void
386 add_security_headers (struct MHD_Response *response)
387 {
388  if (strcmp (http_x_frame_options, ""))
389  MHD_add_response_header (response, "X-Frame-Options",
391  if (strcmp (http_content_security_policy, ""))
392  MHD_add_response_header (response, "Content-Security-Policy",
395  MHD_add_response_header (response, "Strict-Transport-Security",
397 }
398 
402 void
403 add_guest_chart_content_security_headers (struct MHD_Response *response)
404 {
405  if (strcmp (http_x_frame_options, ""))
406  MHD_add_response_header (response, "X-Frame-Options",
408  if (strcmp (http_content_security_policy, ""))
409  MHD_add_response_header (response, "Content-Security-Policy",
411 }
412 
416 struct user
417 {
418  char *cookie;
419  char *token;
420  gchar *username;
421  gchar *password;
422  gchar *role;
423  gchar *timezone;
424  gchar *severity;
425  gchar *capabilities;
426  gchar *language;
427  gchar *pw_warning;
428  char *address;
429  time_t time;
430  int charts;
431  GTree *chart_prefs;
432  gchar *autorefresh;
434  int guest;
435 };
436 
440 typedef struct user user_t;
441 
445 static GMutex *mutex = NULL;
446 
468 user_t *
469 user_add (const gchar *username, const gchar *password, const gchar *timezone,
470  const gchar *severity, const gchar *role, const gchar *capabilities,
471  const gchar *language, const gchar *pw_warning, GTree *chart_prefs,
472  const gchar *autorefresh, const char *address)
473 {
474  user_t *user = NULL;
475  int index;
476  g_mutex_lock (mutex);
477  for (index = 0; index < users->len; index++)
478  {
479  user_t *item;
480  item = (user_t*) g_ptr_array_index (users, index);
481  if (strcmp (item->username, username) == 0)
482  {
483  if (time (NULL) - item->time > (session_timeout * 60))
484  g_ptr_array_remove (users, (gpointer) item);
485  }
486  }
487  user = g_malloc (sizeof (user_t));
488  user->cookie = openvas_uuid_make ();
489  user->token = openvas_uuid_make ();
490  user->username = g_strdup (username);
491  user->password = g_strdup (password);
492  user->role = g_strdup (role);
493  user->timezone = g_strdup (timezone);
494  user->severity = g_strdup (severity);
495  user->capabilities = g_strdup (capabilities);
496  user->pw_warning = pw_warning ? g_strdup (pw_warning) : NULL;
497  user->chart_prefs = chart_prefs;
498  user->autorefresh = g_strdup (autorefresh);
499  user->last_filt_ids = g_tree_new_full ((GCompareDataFunc) g_strcmp0,
500  NULL, g_free, g_free);
501  g_ptr_array_add (users, (gpointer) user);
502  set_language_code (&user->language, language);
503  user->time = time (NULL);
504  user->charts = 0;
505  if (guest_username)
506  user->guest = strcmp (username, guest_username) ? 0 : 1;
507  else
508  user->guest = 0;
509  user->address = g_strdup (address);
510  return user;
511 }
512 
513 #define USER_OK 0
514 #define USER_BAD_TOKEN 1
515 #define USER_EXPIRED_TOKEN 2
516 #define USER_BAD_MISSING_COOKIE 3
517 #define USER_BAD_MISSING_TOKEN 4
518 #define USER_GUEST_LOGIN_FAILED 5
519 #define USER_OMP_DOWN 6
520 #define USER_IP_ADDRESS_MISSMATCH 7
521 #define USER_GUEST_LOGIN_ERROR -1
522 
538 int
539 user_find (const gchar *cookie, const gchar *token, const char *address,
540  user_t **user_return)
541 {
542  int ret;
543  user_t *user = NULL;
544  int index;
545  if (token == NULL)
546  return USER_BAD_MISSING_TOKEN;
547 
548  if (guest_username && token && (strcmp (token, "guest") == 0))
549  {
550  int ret;
551  gchar *timezone, *role, *capabilities, *severity, *language;
552  gchar *pw_warning, *autorefresh;
553  GTree *chart_prefs;
554 
555  if (cookie)
556  {
557  /* Look for an existing guest user from the same browser (that is,
558  * with the same cookie). */
559 
560  g_mutex_lock (mutex);
561  for (index = 0; index < users->len; index++)
562  {
563  user_t *item;
564  item = (user_t*) g_ptr_array_index (users, index);
565  if (item->guest && (strcmp (item->cookie, cookie) == 0))
566  {
567  user = item;
568  break;
569  }
570  }
571  if (user)
572  {
573  *user_return = user;
574  user->time = time (NULL);
575  return USER_OK;
576  }
577  g_mutex_unlock (mutex);
578  }
579 
580  /* Log in as guest. */
581 
584  &role,
585  &timezone,
586  &severity,
587  &capabilities,
588  &language,
589  &pw_warning,
590  &chart_prefs,
591  &autorefresh);
592  if (ret == 1)
594  else if (ret == 2)
595  return USER_OMP_DOWN;
596  else if (ret == -1)
597  return USER_GUEST_LOGIN_ERROR;
598  else
599  {
600  user_t *user;
601  user = user_add (guest_username, guest_password, timezone, severity,
602  role, capabilities, language, pw_warning,
603  chart_prefs, autorefresh, address);
604  *user_return = user;
605  g_free (timezone);
606  g_free (severity);
607  g_free (capabilities);
608  g_free (language);
609  g_free (role);
610  g_free (pw_warning);
611  g_free (autorefresh);
612  return USER_OK;
613  }
614  }
615 
616  g_mutex_lock (mutex);
617  ret = USER_OK;
618  for (index = 0; index < users->len; index++)
619  {
620  user_t *item;
621  item = (user_t*) g_ptr_array_index (users, index);
622  if (strcmp (item->token, token) == 0)
623  {
624  if ((cookie == NULL) || strcmp (item->cookie, cookie))
625  {
626  /* Check if the session has expired. */
627  if (time (NULL) - item->time > (session_timeout * 60))
628  /* Probably the browser removed the cookie. */
629  ret = USER_EXPIRED_TOKEN;
630  else
632  break;
633  }
634  user = item;
635  break;
636  }
637  }
638  if (user)
639  {
640  /* Verify that the user address matches the client's address. */
641  if (strcmp (address, user->address))
643  else if (time (NULL) - user->time > (session_timeout * 60))
644  ret = USER_EXPIRED_TOKEN;
645  else
646  {
647  *user_return = user;
648  user->time = time (NULL);
649  /* FIXME mutex is not unlocked */
650  return USER_OK;
651  }
652  }
653  else if (ret == 0)
654  /* should it be really USER_EXPIRED_TOKEN?
655  * No user has been found therefore the token couldn't even expire */
656  ret = USER_EXPIRED_TOKEN;
657  g_mutex_unlock (mutex);
658  return ret;
659 }
660 
669 int
670 user_set_timezone (const gchar *token, const gchar *timezone)
671 {
672  int index, ret;
673  ret = 1;
674  g_mutex_lock (mutex);
675  for (index = 0; index < users->len; index++)
676  {
677  user_t *item;
678  item = (user_t*) g_ptr_array_index (users, index);
679  if (strcmp (item->token, token) == 0)
680  {
681  g_free (item->timezone);
682  item->timezone = g_strdup (timezone);
683  ret = 0;
684  break;
685  }
686  }
687  g_mutex_unlock (mutex);
688  return ret;
689 }
690 
699 int
700 user_set_password (const gchar *token, const gchar *password)
701 {
702  int index, ret;
703  ret = 1;
704  g_mutex_lock (mutex);
705  for (index = 0; index < users->len; index++)
706  {
707  user_t *item;
708  item = (user_t*) g_ptr_array_index (users, index);
709  if (strcmp (item->token, token) == 0)
710  {
711  g_free (item->password);
712  g_free (item->pw_warning);
713  item->password = g_strdup (password);
714  item->pw_warning = NULL;
715  ret = 0;
716  break;
717  }
718  }
719  g_mutex_unlock (mutex);
720  return ret;
721 }
722 
731 int
732 user_set_severity (const gchar *token, const gchar *severity)
733 {
734  int index, ret;
735  ret = 1;
736  g_mutex_lock (mutex);
737  for (index = 0; index < users->len; index++)
738  {
739  user_t *item;
740  item = (user_t*) g_ptr_array_index (users, index);
741  if (strcmp (item->token, token) == 0)
742  {
743  g_free (item->severity);
744  item->severity = g_strdup (severity);
745  ret = 0;
746  break;
747  }
748  }
749  g_mutex_unlock (mutex);
750  return ret;
751 }
752 
761 int
762 user_set_language (const gchar *token, const gchar *language)
763 {
764  int index, ret;
765  ret = 1;
766  g_mutex_lock (mutex);
767  for (index = 0; index < users->len; index++)
768  {
769  user_t *item;
770  item = (user_t*) g_ptr_array_index (users, index);
771  if (strcmp (item->token, token) == 0)
772  {
773  g_free (item->language);
774  set_language_code (&item->language, language);
775  ret = 0;
776  break;
777  }
778  }
779  g_mutex_unlock (mutex);
780  return ret;
781 }
782 
791 int
792 user_set_charts (const gchar *token, const int charts)
793 {
794  int index, ret;
795  ret = 1;
796  g_mutex_lock (mutex);
797  for (index = 0; index < users->len; index++)
798  {
799  user_t *item;
800  item = (user_t*) g_ptr_array_index (users, index);
801  if (strcmp (item->token, token) == 0)
802  {
803  item->charts = charts;
804  ret = 0;
805  break;
806  }
807  }
808  g_mutex_unlock (mutex);
809  return ret;
810 }
811 
821 int
822 user_set_chart_pref (const gchar *token, gchar* pref_id, gchar *pref_value)
823 {
824  int index, ret;
825  ret = 1;
826  g_mutex_lock (mutex);
827  for (index = 0; index < users->len; index++)
828  {
829  user_t *item;
830  item = (user_t*) g_ptr_array_index (users, index);
831  if (strcmp (item->token, token) == 0)
832  {
833  g_tree_replace (item->chart_prefs,
834  pref_id, pref_value);
835  ret = 0;
836  break;
837  }
838  }
839  g_mutex_unlock (mutex);
840  return ret;
841 }
842 
851 int
852 user_set_autorefresh (const gchar *token, const gchar *autorefresh)
853 {
854  int index, ret;
855  ret = 1;
856  g_mutex_lock (mutex);
857  for (index = 0; index < users->len; index++)
858  {
859  user_t *item;
860  item = (user_t*) g_ptr_array_index (users, index);
861  if (strcmp (item->token, token) == 0)
862  {
863  g_free (item->autorefresh);
864  item->autorefresh = g_strdup (autorefresh);
865  ret = 0;
866  break;
867  }
868  }
869  g_mutex_unlock (mutex);
870  return ret;
871 }
872 
881 int
882 user_logout_all_sessions (const gchar *username, credentials_t *credentials)
883 {
884  int index;
885  g_mutex_lock (mutex);
886  for (index = 0; index < users->len; index++)
887  {
888  user_t *item;
889  item = (user_t*) g_ptr_array_index (users, index);
890  if (strcmp (item->username, username) == 0
891  && strcmp (item->token, credentials->token))
892  {
893  g_debug ("%s: logging out user '%s', token '%s'",
894  __FUNCTION__, item->username, item->token);
895  g_ptr_array_remove (users, (gpointer) item);
896  index --;
897  }
898  }
899  g_mutex_unlock (mutex);
900 
901  return 0;
902 }
903 
909 void
911 {
912  g_mutex_unlock (mutex);
913 }
914 
920 void
922 {
923  g_ptr_array_remove (users, (gpointer) user);
924  g_mutex_unlock (mutex);
925 }
926 
937 int
938 token_user (const gchar *token, user_t **user_return)
939 {
940  int ret;
941  user_t *user = NULL;
942  int index;
943  g_mutex_lock (mutex);
944  for (index = 0; index < users->len; index++)
945  {
946  user_t *item;
947  item = (user_t*) g_ptr_array_index (users, index);
948  if (strcmp (item->token, token) == 0)
949  {
950  user = item;
951  break;
952  }
953  }
954  if (user)
955  {
956  if (time (NULL) - user->time > (session_timeout * 60))
957  ret = 2;
958  else
959  {
960  *user_return = user;
961  ret = 0;
962  user->time = time (NULL);
963  return ret;
964  }
965  }
966  else
967  ret = 1;
968  g_mutex_unlock (mutex);
969  return ret;
970 }
971 
979 int
981 {
982  user_t *user;
983  if (token_user (token, &user))
984  return -1;
985  g_ptr_array_remove (users, (gpointer) user);
986  g_mutex_unlock (mutex);
987  return 0;
988 }
989 
994 
998 void
1000 {
1002 
1004  "cmd",
1005  "^((bulk_delete)"
1006  "|(clone)"
1007  "|(create_agent)"
1008  "|(create_asset)"
1009  "|(create_config)"
1010  "|(create_container_task)"
1011  "|(create_credential)"
1012  "|(create_alert)"
1013  "|(create_filter)"
1014  "|(create_group)"
1015  "|(create_host)"
1016  "|(create_note)"
1017  "|(create_override)"
1018  "|(create_permission)"
1019  "|(create_permissions)"
1020  "|(create_port_list)"
1021  "|(create_port_range)"
1022  "|(create_report)"
1023  "|(create_role)"
1024  "|(create_scanner)"
1025  "|(create_schedule)"
1026  "|(create_tag)"
1027  "|(create_target)"
1028  "|(create_task)"
1029  "|(cvss_calculator)"
1030  "|(create_user)"
1031  "|(dashboard)"
1032  "|(delete_agent)"
1033  "|(delete_asset)"
1034  "|(delete_config)"
1035  "|(delete_credential)"
1036  "|(delete_alert)"
1037  "|(delete_filter)"
1038  "|(delete_group)"
1039  "|(delete_note)"
1040  "|(delete_override)"
1041  "|(delete_permission)"
1042  "|(delete_port_list)"
1043  "|(delete_port_range)"
1044  "|(delete_report)"
1045  "|(delete_report_format)"
1046  "|(delete_role)"
1047  "|(delete_scanner)"
1048  "|(delete_schedule)"
1049  "|(delete_tag)"
1050  "|(delete_target)"
1051  "|(delete_task)"
1052  "|(delete_trash_agent)"
1053  "|(delete_trash_config)"
1054  "|(delete_trash_alert)"
1055  "|(delete_trash_credential)"
1056  "|(delete_trash_filter)"
1057  "|(delete_trash_group)"
1058  "|(delete_trash_note)"
1059  "|(delete_trash_override)"
1060  "|(delete_trash_permission)"
1061  "|(delete_trash_port_list)"
1062  "|(delete_trash_report_format)"
1063  "|(delete_trash_role)"
1064  "|(delete_trash_scanner)"
1065  "|(delete_trash_schedule)"
1066  "|(delete_trash_tag)"
1067  "|(delete_trash_target)"
1068  "|(delete_trash_task)"
1069  "|(delete_user)"
1070  "|(delete_user_confirm)"
1071  "|(download_agent)"
1072  "|(download_credential)"
1073  "|(download_ssl_cert)"
1074  "|(download_ca_pub)"
1075  "|(download_key_pub)"
1076  "|(edit_agent)"
1077  "|(edit_alert)"
1078  "|(edit_asset)"
1079  "|(edit_config)"
1080  "|(edit_config_family)"
1081  "|(edit_config_nvt)"
1082  "|(edit_credential)"
1083  "|(edit_filter)"
1084  "|(edit_group)"
1085  "|(edit_my_settings)"
1086  "|(edit_note)"
1087  "|(edit_override)"
1088  "|(edit_permission)"
1089  "|(edit_port_list)"
1090  "|(edit_report_format)"
1091  "|(edit_role)"
1092  "|(edit_scanner)"
1093  "|(edit_schedule)"
1094  "|(edit_tag)"
1095  "|(edit_target)"
1096  "|(edit_task)"
1097  "|(edit_user)"
1098  "|(auth_settings)"
1099  "|(empty_trashcan)"
1100  "|(alert_report)"
1101  "|(export_agent)"
1102  "|(export_agents)"
1103  "|(export_alert)"
1104  "|(export_alerts)"
1105  "|(export_asset)"
1106  "|(export_assets)"
1107  "|(export_config)"
1108  "|(export_configs)"
1109  "|(export_credential)"
1110  "|(export_credentials)"
1111  "|(export_filter)"
1112  "|(export_filters)"
1113  "|(export_group)"
1114  "|(export_groups)"
1115  "|(export_note)"
1116  "|(export_notes)"
1117  "|(export_omp_doc)"
1118  "|(export_override)"
1119  "|(export_overrides)"
1120  "|(export_permission)"
1121  "|(export_permissions)"
1122  "|(export_port_list)"
1123  "|(export_port_lists)"
1124  "|(export_preference_file)"
1125  "|(export_report_format)"
1126  "|(export_report_formats)"
1127  "|(export_result)"
1128  "|(export_results)"
1129  "|(export_role)"
1130  "|(export_roles)"
1131  "|(export_scanner)"
1132  "|(export_scanners)"
1133  "|(export_schedule)"
1134  "|(export_schedules)"
1135  "|(export_tag)"
1136  "|(export_tags)"
1137  "|(export_target)"
1138  "|(export_targets)"
1139  "|(export_task)"
1140  "|(export_tasks)"
1141  "|(export_user)"
1142  "|(export_users)"
1143  "|(get_agent)"
1144  "|(get_agents)"
1145  "|(get_aggregate)"
1146  "|(get_asset)"
1147  "|(get_assets)"
1148  "|(get_assets_chart)"
1149  "|(get_config)"
1150  "|(get_config_family)"
1151  "|(get_config_nvt)"
1152  "|(get_configs)"
1153  "|(get_feeds)"
1154  "|(get_credential)"
1155  "|(get_credentials)"
1156  "|(get_filter)"
1157  "|(get_filters)"
1158  "|(get_alert)"
1159  "|(get_alerts)"
1160  "|(get_group)"
1161  "|(get_groups)"
1162  "|(get_info)"
1163  "|(get_my_settings)"
1164  "|(get_note)"
1165  "|(get_notes)"
1166  "|(get_nvts)"
1167  "|(get_override)"
1168  "|(get_overrides)"
1169  "|(get_permission)"
1170  "|(get_permissions)"
1171  "|(get_port_list)"
1172  "|(get_port_lists)"
1173  "|(get_protocol_doc)"
1174  "|(get_report)"
1175  "|(get_reports)"
1176  "|(get_report_format)"
1177  "|(get_report_formats)"
1178  "|(get_report_section)"
1179  "|(get_result)"
1180  "|(get_results)"
1181  "|(get_role)"
1182  "|(get_roles)"
1183  "|(get_scanner)"
1184  "|(get_scanners)"
1185  "|(get_schedule)"
1186  "|(get_schedules)"
1187  "|(get_system_reports)"
1188  "|(get_tag)"
1189  "|(get_tags)"
1190  "|(get_target)"
1191  "|(get_targets)"
1192  "|(get_task)"
1193  "|(get_tasks)"
1194  "|(get_tasks_chart)"
1195  "|(get_trash)"
1196  "|(get_user)"
1197  "|(get_users)"
1198  "|(import_config)"
1199  "|(import_port_list)"
1200  "|(import_report)"
1201  "|(import_report_format)"
1202  "|(login)"
1203  "|(move_task)"
1204  "|(new_agent)"
1205  "|(new_alert)"
1206  "|(new_config)"
1207  "|(new_container_task)"
1208  "|(new_credential)"
1209  "|(new_filter)"
1210  "|(new_group)"
1211  "|(new_host)"
1212  "|(new_note)"
1213  "|(new_override)"
1214  "|(new_permission)"
1215  "|(new_permissions)"
1216  "|(new_port_list)"
1217  "|(new_port_range)"
1218  "|(new_report_format)"
1219  "|(new_role)"
1220  "|(new_scanner)"
1221  "|(new_schedule)"
1222  "|(new_tag)"
1223  "|(new_target)"
1224  "|(new_task)"
1225  "|(new_user)"
1226  "|(process_bulk)"
1227  "|(restore)"
1228  "|(resume_task)"
1229  "|(run_wizard)"
1230  "|(test_alert)"
1231  "|(save_agent)"
1232  "|(save_alert)"
1233  "|(save_asset)"
1234  "|(save_auth)"
1235  "|(save_chart_preference)"
1236  "|(save_config)"
1237  "|(save_config_family)"
1238  "|(save_config_nvt)"
1239  "|(save_container_task)"
1240  "|(save_credential)"
1241  "|(save_filter)"
1242  "|(save_group)"
1243  "|(save_my_settings)"
1244  "|(save_note)"
1245  "|(save_override)"
1246  "|(save_permission)"
1247  "|(save_port_list)"
1248  "|(save_report_format)"
1249  "|(save_role)"
1250  "|(save_scanner)"
1251  "|(save_schedule)"
1252  "|(save_tag)"
1253  "|(save_target)"
1254  "|(save_task)"
1255  "|(save_user)"
1256  "|(start_task)"
1257  "|(stop_task)"
1258  "|(sync_feed)"
1259  "|(sync_scap)"
1260  "|(sync_cert)"
1261  "|(sync_config)"
1262  "|(toggle_tag)"
1263  "|(upload_config)"
1264  "|(upload_port_list)"
1265  "|(upload_report)"
1266  "|(verify_agent)"
1267  "|(verify_report_format)"
1268  "|(verify_scanner)"
1269  "|(wizard)"
1270  "|(wizard_get))$");
1271 
1272  openvas_validator_add (validator, "action_message", "(?s)^.*$");
1273  openvas_validator_add (validator, "action_status", "(?s)^.*$");
1274  openvas_validator_add (validator, "active", "^(-1|-2|[0-9]+)$");
1275  openvas_validator_add (validator, "agent_format", "^(installer)$");
1276  openvas_validator_add (validator, "agent_id", "^[a-z0-9\\-]+$");
1277  openvas_validator_add (validator, "aggregate_mode", "^[a-z0-9_]+$");
1278  openvas_validator_add (validator, "aggregate_type", "^(agent|alert|config|credential|filter|group|host|nvt|note|os|override|permission|port_list|report|report_format|result|role|scanner|schedule|tag|target|task|user|allinfo|cve|cpe|ovaldef|cert_bund_adv|dfn_cert_adv)$");
1279  openvas_validator_add (validator, "alive_tests", "^(Scan Config Default|ICMP Ping|TCP-ACK Service Ping|TCP-SYN Service Ping|ARP Ping|ICMP & TCP-ACK Service Ping|ICMP & ARP Ping|TCP-ACK Service & ARP Ping|ICMP, TCP-ACK Service & ARP Ping|Consider Alive)$");
1280  openvas_validator_add (validator, "apply_filter", "^(no|no_pagination|full)$");
1281  openvas_validator_add (validator, "asset_name", "(?s)^.*$");
1282  openvas_validator_add (validator, "asset_type", "^(host|os)$");
1283  openvas_validator_add (validator, "asset_id", "^([[:alnum:]-_.:\\/~()']|&amp;)+$");
1284  openvas_validator_add (validator, "auth_algorithm", "^(md5|sha1)$");
1285  openvas_validator_add (validator, "auth_method", "^(0|1|2)$");
1286  /* Defined in RFC 2253. */
1287  openvas_validator_add (validator, "authdn", "^.{0,200}%s.{0,200}$");
1288  openvas_validator_add (validator, "auto_delete", "^(no|keep)$");
1289  openvas_validator_add (validator, "auto_delete_data", "^(.*){0,10}$");
1290  openvas_validator_add (validator, "autofp", "^(0|1|2)$");
1291  openvas_validator_add (validator, "autofp_value", "^(1|2)$");
1292  openvas_validator_add (validator, "boolean", "^(0|1)$");
1293  openvas_validator_add (validator, "bulk_selected:name", "^(.*){0,400}$");
1294  openvas_validator_add (validator, "bulk_selected:value", "(?s)^.*$");
1295  openvas_validator_add (validator, "caller", "^.*$");
1296  openvas_validator_add (validator, "certificate", "(?s)^.*$");
1297  openvas_validator_add (validator, "chart_gen:name", "^(.*){0,400}$");
1298  openvas_validator_add (validator, "chart_gen:value", "(?s)^.*$");
1299  openvas_validator_add (validator, "chart_init:name", "^(.*){0,400}$");
1300  openvas_validator_add (validator, "chart_init:value", "(?s)^.*$");
1301  openvas_validator_add (validator, "chart_preference_id", "^(.*){0,400}$");
1302  openvas_validator_add (validator, "chart_preference_value", "^(.*){0,400}$");
1303  openvas_validator_add (validator, "comment", "^[-_;':()@[:alnum:]äüöÄÜÖß, \\./]{0,400}$");
1304  openvas_validator_add (validator, "config_id", "^[a-z0-9\\-]+$");
1305  openvas_validator_add (validator, "osp_config_id", "^[a-z0-9\\-]+$");
1306  openvas_validator_add (validator, "condition", "^[[:alnum:] ]{0,100}$");
1307  openvas_validator_add (validator, "credential_id", "^[a-z0-9\\-]+$");
1308  openvas_validator_add (validator, "create_credentials_type", "^(gen|pass|key)$");
1309  openvas_validator_add (validator, "credential_login", "^[-_[:alnum:]\\.@\\\\]{0,40}$");
1310  openvas_validator_add (validator, "condition_data:name", "^(.*){0,400}$");
1311  openvas_validator_add (validator, "condition_data:value", "(?s)^.*$");
1312  openvas_validator_add (validator, "cvss_av", "^(L|A|N)$");
1313  openvas_validator_add (validator, "cvss_ac", "^(H|M|L)$");
1314  openvas_validator_add (validator, "cvss_au", "^(M|S|N)$");
1315  openvas_validator_add (validator, "cvss_c", "^(N|P|C)$");
1316  openvas_validator_add (validator, "cvss_i", "^(N|P|C)$");
1317  openvas_validator_add (validator, "cvss_a", "^(N|P|C)$");
1318  openvas_validator_add (validator, "cvss_vector", "^AV:(L|A|N)/AC:(H|M|L)/A(u|U):(M|S|N)/C:(N|P|C)/I:(N|P|C)/A:(N|P|C)$");
1319  openvas_validator_add (validator, "min_qod", "^(|100|[1-9]?[0-9]|)$");
1320  openvas_validator_add (validator, "day_of_month", "^(0??[1-9]|[12][0-9]|30|31)$");
1321  openvas_validator_add (validator, "days", "^(-1|[0-9]+)$");
1322  openvas_validator_add (validator, "data_column", "^[_[:alnum:]]{1,80}$");
1323  openvas_validator_add (validator, "data_columns:name", "^[0123456789]{1,5}$");
1324  openvas_validator_add (validator, "data_columns:value", "^[_[:alnum:]]{1,80}$");
1325  openvas_validator_add (validator, "default_severity", "^(|10\\.0|[0-9]\\.[0-9])$");
1326  openvas_validator_add (validator, "delta_states", "^(c|g|n|s){0,4}$");
1327  openvas_validator_add (validator, "details_fname", "^([[:alnum:]_-]|%[%CcDFMmNTtUu])+$");
1328  openvas_validator_add (validator, "domain", "^[-[:alnum:]\\.]{1,80}$");
1329  openvas_validator_add (validator, "email", "^[^@ ]{1,150}@[^@ ]{1,150}$");
1330  openvas_validator_add (validator, "email_list", "^[^@ ]{1,150}@[^@ ]{1,150}(, *[^@ ]{1,150}@[^@ ]{1,150})*$");
1331  openvas_validator_add (validator, "alert_id", "^[a-z0-9\\-]+$");
1332  openvas_validator_add (validator, "alert_id_optional", "^(--|[a-z0-9\\-]+)$");
1333  openvas_validator_add (validator, "event_data:name", "^(.*){0,400}$");
1334  openvas_validator_add (validator, "event_data:value", "(?s)^.*$");
1335  openvas_validator_add (validator, "family", "^[-_[:alnum:] :.]{1,200}$");
1336  openvas_validator_add (validator, "family_page", "^[-_[:alnum:] :.]{1,200}$");
1337  openvas_validator_add (validator, "file", "(?s)^.*$");
1338  openvas_validator_add (validator, "file:name", "^.*[[0-9abcdefABCDEF\\-]{1,40}]:.*$");
1339  openvas_validator_add (validator, "file:value", "^yes$");
1340  openvas_validator_add (validator, "settings_changed:name", "^(.*){0,400}$");
1341  openvas_validator_add (validator, "settings_changed:value", "^[a-z0-9\\-]+$");
1342  openvas_validator_add (validator, "settings_default:name", "^(.*){0,400}$");
1343  openvas_validator_add (validator, "settings_default:value", "^[a-z0-9\\-]+$");
1344  openvas_validator_add (validator, "settings_filter:name", "^(.*){0,400}$");
1345  openvas_validator_add (validator, "settings_filter:value", "^[a-z0-9\\-]+$");
1346  openvas_validator_add (validator, "first", "^[0-9]+$");
1347  openvas_validator_add (validator, "first_group", "^[0-9]+$");
1348  openvas_validator_add (validator, "first_result", "^[0-9]+$");
1349  openvas_validator_add (validator, "filter", "^(.*){0,1000}$");
1350  openvas_validator_add (validator, "format_id", "^[a-z0-9\\-]+$");
1351  /* Validator for save_auth group, e.g. "method:ldap_connect". */
1352  openvas_validator_add (validator, "group", "^method:(ldap_connect|radius_connect)$");
1353  openvas_validator_add (validator, "group_column", "^[_[:alnum:]]{1,80}$");
1354  openvas_validator_add (validator, "max", "^(-?[0-9]+|)$");
1355  openvas_validator_add (validator, "max_results", "^[0-9]+$");
1356  openvas_validator_add (validator, "format", "^[-[:alnum:]]{1,15}$");
1357  openvas_validator_add (validator, "host", "^[[:alnum:]:\\.]{1,80}$");
1358  openvas_validator_add (validator, "hostport", "^[-[:alnum:]\\. :]{1,80}$");
1359  openvas_validator_add (validator, "hostpath", "^[-[:alnum:]\\. :/]{1,80}$");
1360  openvas_validator_add (validator, "hosts", "^[-[:alnum:],: \\./]+$");
1361  openvas_validator_add (validator, "hosts_allow", "^(0|1)$");
1362  openvas_validator_add (validator, "hosts_opt", "^[-[:alnum:], \\./]*$");
1363  openvas_validator_add (validator, "hosts_ordering", "^(sequential|random|reverse)$");
1364  openvas_validator_add (validator, "hour", "^([01]?[0-9]|2[0-3])$");
1365  openvas_validator_add (validator, "howto_use", "(?s)^.*$");
1366  openvas_validator_add (validator, "howto_install", "(?s)^.*$");
1367  openvas_validator_add (validator, "id", "^[a-z0-9\\-]+$");
1368  openvas_validator_add (validator, "id_optional", "^(--|[a-z0-9\\-]+)$");
1369  openvas_validator_add (validator, "id_or_empty", "^(|[a-z0-9\\-]+)$");
1370  openvas_validator_add (validator, "id_list:name", "^ *[0-9]+ *$");
1371  openvas_validator_add (validator, "id_list:value", "^[[:alnum:]\\-_ ]+:[a-z0-9\\-]+$");
1372  openvas_validator_add (validator, "ifaces_allow", "^(0|1)$");
1373  openvas_validator_add (validator, "include_id_list:name", "^[[:alnum:]\\-_ ]+$");
1374  openvas_validator_add (validator, "include_id_list:value", "^(0|1)$");
1375  openvas_validator_add (validator, "installer", "(?s)^.*$");
1376  openvas_validator_add (validator, "installer_sig", "(?s)^.*$");
1378  "^(Browser Language|"
1379  "([a-z]{2,3})(_[A-Z]{2})?(@[[:alnum:]_-]+)?"
1380  "(:([a-z]{2,3})(_[A-Z]{2})?(@[[:alnum:]_-]+)?)*)$");
1381  openvas_validator_add (validator, "levels", "^(h|m|l|g|f){0,5}$");
1382  openvas_validator_add (validator, "list_fname", "^([[:alnum:]_-]|%[%CcDFMmNTtUu])+$");
1383  /* Used for users, credentials, and scanner login name. */
1384  openvas_validator_add (validator, "login", "^[[:alnum:]-_@.]+$");
1385  openvas_validator_add (validator, "lsc_password", "^.{0,40}$");
1386  openvas_validator_add (validator, "max_result", "^[0-9]+$");
1387  openvas_validator_add (validator, "max_groups", "^-?[0-9]+$");
1388  openvas_validator_add (validator, "minute", "^[0-5]{0,1}[0-9]{1,1}$");
1389  openvas_validator_add (validator, "month", "^((0??[1-9])|1[012])$");
1390  openvas_validator_add (validator, "note_id", "^[a-z0-9\\-]+$");
1391  openvas_validator_add (validator, "note_result_id", "^[a-z0-9\\-]*$");
1392  openvas_validator_add (validator, "override_id", "^[a-z0-9\\-]+$");
1393  openvas_validator_add (validator, "override_result_id", "^[a-z0-9\\-]*$");
1394  openvas_validator_add (validator, "name", "^[#-_[:alnum:], \\./]{1,80}$");
1395  openvas_validator_add (validator, "info_name", "(?s)^.*$");
1396  openvas_validator_add (validator, "info_type", "(?s)^.*$");
1397  openvas_validator_add (validator, "info_id", "^([[:alnum:]-_.:\\/~()']|&amp;)+$");
1398  openvas_validator_add (validator, "details", "^[0-1]$");
1399  /* Number is special cased in params_mhd_validate to remove the space. */
1400  openvas_validator_add (validator, "number", "^ *[0-9]+ *$");
1401  openvas_validator_add (validator, "optional_number", "^[0-9]*$");
1402  openvas_validator_add (validator, "oid", "^([0-9.]{1,80}|CVE-[-0-9]{1,14})$");
1403  openvas_validator_add (validator, "page", "^[_[:alnum:] ]{1,40}$");
1404  openvas_validator_add (validator, "package_format", "^(pem|key|rpm|deb|exe)$");
1405  openvas_validator_add (validator, "password", "^.{0,40}$");
1406  openvas_validator_add (validator, "password:value", "(?s)^.*$");
1407  openvas_validator_add (validator, "port", "^.{1,60}$");
1408  openvas_validator_add (validator, "port_range", "^((default)|([-0-9, TU:]{1,400}))$");
1409  openvas_validator_add (validator, "port_type", "^(tcp|udp)$");
1411  openvas_validator_add (validator, "preference_name", "^(.*){0,400}$");
1412  openvas_validator_add (validator, "preference:name", "^([^[]*\\[[^]]*\\]:.*){0,400}$");
1413  openvas_validator_add (validator, "preference:value", "(?s)^.*$");
1414  openvas_validator_add (validator, "prev_action", "(?s)^.*$");
1415  openvas_validator_add (validator, "privacy_algorithm", "^(aes|des|)$");
1416  openvas_validator_add (validator, "private_key", "(?s)^.*$");
1417  openvas_validator_add (validator, "protocol_format", "^(html|rnc|xml)$");
1418  openvas_validator_add (validator, "pw", "^[[:alnum:]]{1,10}$");
1419  openvas_validator_add (validator, "xml_file", "(?s)^.*$");
1420  openvas_validator_add (validator, "definitions_file", "(?s)^.*$");
1421  openvas_validator_add (validator, "ca_pub", "(?s)^.*$");
1422  openvas_validator_add (validator, "which_cert", "^(default|existing|new)$");
1423  openvas_validator_add (validator, "key_pub", "(?s)^.*$");
1424  openvas_validator_add (validator, "key_priv", "(?s)^.*$");
1425  openvas_validator_add (validator, "radiuskey", "^.{0,40}$");
1426  openvas_validator_add (validator, "range_type", "^(duration|until_end|from_start|start_to_end)$");
1427  openvas_validator_add (validator, "related:name", "^(.*){0,400}$");
1428  openvas_validator_add (validator, "related:value", "^(.*){0,400}$");
1429  openvas_validator_add (validator, "report_id", "^[a-z0-9\\-]+$");
1430  openvas_validator_add (validator, "report_fname", "^([[:alnum:]_-]|%[%CcDFMmNTtUu])+$");
1431  openvas_validator_add (validator, "report_format_id", "^[a-z0-9\\-]+$");
1432  openvas_validator_add (validator, "report_section",
1433  "^(summary|results|hosts|ports"
1434  "|closed_cves|vulns|os|apps|errors"
1435  "|topology|ssl_certs|cves)$");
1436  openvas_validator_add (validator, "result_id", "^[a-z0-9\\-]+$");
1437  openvas_validator_add (validator, "role", "^[[:alnum:] ]{1,40}$");
1438  openvas_validator_add (validator, "optional_task_id", "^[a-z0-9\\-]*$");
1439  openvas_validator_add (validator, "permission", "^([_a-z]{1,1000}|Super)$");
1440  openvas_validator_add (validator, "port_list_id", "^[a-z0-9\\-]+$");
1441  openvas_validator_add (validator, "port_range_id", "^[a-z0-9\\-]+$");
1442  openvas_validator_add (validator, "resource_type",
1443  "^(agent|alert|asset|config|credential|filter|group|host|nvt|note|os|override|permission|port_list|report|report_format|result|role|scanner|schedule|tag|target|task|user|info|cve|cpe|ovaldef|cert_bund_adv|dfn_cert_adv|"
1444  "Agent|Alert|Asset|Config|Credential|Filter|Group|Host|Note|NVT|Operating System|Override|Permission|Port List|Report|Report Format|Result|Role|Scanner|Schedule|Tag|Target|Task|User|SecInfo|CVE|CPE|OVAL Definition|CERT-Bund Advisory|DFN-CERT Advisory)$");
1445  openvas_validator_add (validator, "resource_id", "^[[:alnum:]-_.:\\/~]*$");
1446  openvas_validator_add (validator, "optional_resource_type",
1447  "^(agent|alert|asset|config|credential|filter|group|host|note|nvt|os|override|permission|port_list|report|report_format|result|role|scanner|schedule|tag|target|task|user|info|"
1448  "Agent|Alert|Asset|Config|Credential|Filter|Group|Host|Note|NVT|Operating System|Override|Permission|Port List|Report|Report Format|Result|Role|Scanner|Schedule|Tag|Target|Task|User|SecInfo|)$");
1449  openvas_validator_add (validator, "select:value", "^(.*){0,400}$");
1450  openvas_validator_add (validator, "ssl_cert", "^(.*){0,2000}$");
1451  openvas_validator_add (validator, "method_data:name", "^(.*){0,400}$");
1452  openvas_validator_add (validator, "method_data:value", "(?s)^.*$");
1453  openvas_validator_add (validator, "nvt:name", "(?s)^.*$");
1454  openvas_validator_add (validator, "restrict_credential_type", "^[a-z0-9\\_|]+$");
1455  openvas_validator_add (validator, "subject_type", "^(group|role|user)$");
1456  openvas_validator_add (validator, "summary", "^.{0,400}$");
1457  openvas_validator_add (validator, "tag_id", "^[a-z0-9\\-]+$");
1458  openvas_validator_add (validator, "tag_name", "^[\\:-_[:alnum:], \\./]{1,80}$");
1459  openvas_validator_add (validator, "tag_value", "^[\\-_@[:alnum:], \\./]{0,200}$");
1460  openvas_validator_add (validator, "target_id", "^[a-z0-9\\-]+$");
1461  openvas_validator_add (validator, "task_id", "^[a-z0-9\\-]+$");
1462  openvas_validator_add (validator, "term", "^.{0,1000}");
1463  openvas_validator_add (validator, "text", "^.{0,1000}");
1464  openvas_validator_add (validator, "text_columns:name", "^[0123456789]{1,5}$");
1465  openvas_validator_add (validator, "text_columns:value", "^[_[:alnum:]]{1,80}$");
1466  openvas_validator_add (validator, "threat", "^(High|Medium|Low|Alarm|Log|False Positive|)$");
1467  openvas_validator_add (validator, "trend", "^(0|1)$");
1468  openvas_validator_add (validator, "trend:value", "^(0|1)$");
1469  openvas_validator_add (validator, "type", "^(assets|prognostic)$");
1470  openvas_validator_add (validator, "search_phrase", "^[[:alnum:][:punct:] äöüÄÖÜß]{0,400}$");
1471  openvas_validator_add (validator, "sort_field", "^[_[:alnum:] ]{1,40}$");
1472  openvas_validator_add (validator, "sort_order", "^(ascending|descending)$");
1473  openvas_validator_add (validator, "sort_stat", "^[_[:alnum:] ]{1,40}$");
1474  openvas_validator_add (validator, "sort_fields:name", "^[0123456789]{1,5}$");
1475  openvas_validator_add (validator, "sort_fields:value", "^[_[:alnum:] ]{1,40}$");
1476  openvas_validator_add (validator, "sort_orders:name", "^[0123456789]{1,5}$");
1477  openvas_validator_add (validator, "sort_orders:value", "^(ascending|descending)$");
1478  openvas_validator_add (validator, "sort_stats:name", "^[0123456789]{1,5}$");
1479  openvas_validator_add (validator, "sort_stats:value", "^[_[:alnum:] ]{1,40}$");
1480  openvas_validator_add (validator, "target_source", "^(asset_hosts|file|import|manual)$");
1481  openvas_validator_add (validator, "timezone", "^.{0,1000}$");
1482  openvas_validator_add (validator, "token", "^[a-z0-9\\-]+$");
1483  openvas_validator_add (validator, "scanner_id", "^[a-z0-9\\-]+$");
1484  openvas_validator_add (validator, "cve_scanner_id", "^[a-z0-9\\-]+$");
1485  openvas_validator_add (validator, "osp_scanner_id", "^[a-z0-9\\-]+$");
1486  openvas_validator_add (validator, "schedule_id", "^[a-z0-9\\-]+$");
1487  openvas_validator_add (validator, "severity", "^(-1(\\.0)?|[0-9](\\.[0-9])?|10(\\.0)?)$");
1488  openvas_validator_add (validator, "severity_class", "^(classic|nist|bsi|pci\\-dss)$");
1489  openvas_validator_add (validator, "severity_optional", "^(-1(\\.0)?|[0-9](\\.[0-9])?|10(\\.0)?)?$");
1490  openvas_validator_add (validator, "source_iface", "^(.*){1,16}$");
1491  openvas_validator_add (validator, "uuid", "^[0-9abcdefABCDEF\\-]{1,40}$");
1492  /* This must be "login" with space and comma. */
1493  openvas_validator_add (validator, "users", "^[[:alnum:]-_@., ]*$");
1494  openvas_validator_add (validator, "x_field", "^[\\[\\]_[:alnum:]]{1,80}$");
1495  openvas_validator_add (validator, "y_fields:name", "^[0-9]{1,5}$");
1496  openvas_validator_add (validator, "y_fields:value", "^[\\[\\]_[:alnum:]]{1,80}$");
1497  openvas_validator_add (validator, "year", "^[0-9]+$");
1498  openvas_validator_add (validator, "z_fields:name", "^[0-9]{1,5}$");
1499  openvas_validator_add (validator, "z_fields:value", "^[\\[\\]_[:alnum:]]{1,80}$");
1500  openvas_validator_add (validator, "calendar_unit", "^(second|minute|hour|day|week|month|year|decade)$");
1501  openvas_validator_add (validator, "chart_title", "(?s)^.*$");
1502 
1503  /* Beware, the rule must be defined before the alias. */
1504 
1505  openvas_validator_alias (validator, "add_tag", "boolean");
1506  openvas_validator_alias (validator, "alert_id_2", "alert_id");
1507  openvas_validator_alias (validator, "alert_id_optional:name", "number");
1508  openvas_validator_alias (validator, "alert_id_optional:value", "alert_id_optional");
1509  openvas_validator_alias (validator, "alerts", "optional_number");
1510  openvas_validator_alias (validator, "alert_ids:name", "number");
1511  openvas_validator_alias (validator, "alert_ids:value", "alert_id_optional");
1512  openvas_validator_alias (validator, "allow_insecure", "boolean");
1513  openvas_validator_alias (validator, "alterable", "boolean");
1514  openvas_validator_alias (validator, "apply_overrides", "boolean");
1515  openvas_validator_alias (validator, "autogenerate", "boolean");
1516  openvas_validator_alias (validator, "auto_cache_rebuild", "boolean");
1517  openvas_validator_alias (validator, "base", "name");
1518  openvas_validator_alias (validator, "build_filter", "boolean");
1519  /* the "bulk_[...].x" parameters are used to identify the image type
1520  * form element used to submit the form for process_bulk */
1521  openvas_validator_alias (validator, "bulk_create.x", "number");
1522  openvas_validator_alias (validator, "bulk_delete.x", "number");
1523  openvas_validator_alias (validator, "bulk_export.x", "number");
1524  openvas_validator_alias (validator, "bulk_trash.x", "number");
1525  openvas_validator_alias (validator, "bulk_select", "number");
1526  openvas_validator_alias (validator, "change_community", "boolean");
1527  openvas_validator_alias (validator, "change_passphrase", "boolean");
1528  openvas_validator_alias (validator, "change_password", "boolean");
1529  openvas_validator_alias (validator, "change_privacy_password", "boolean");
1530  openvas_validator_alias (validator, "charts", "boolean");
1531  openvas_validator_alias (validator, "chart_type", "name");
1532  openvas_validator_alias (validator, "chart_template", "name");
1533  openvas_validator_alias (validator, "community", "lsc_password");
1534  openvas_validator_alias (validator, "custom_severity", "boolean");
1535  openvas_validator_alias (validator, "current_user", "boolean");
1536  openvas_validator_alias (validator, "dashboard_name", "name");
1537  openvas_validator_alias (validator, "debug", "boolean");
1538  openvas_validator_alias (validator, "delta_report_id", "report_id");
1539  openvas_validator_alias (validator, "delta_state_changed", "boolean");
1540  openvas_validator_alias (validator, "delta_state_gone", "boolean");
1541  openvas_validator_alias (validator, "delta_state_new", "boolean");
1542  openvas_validator_alias (validator, "delta_state_same", "boolean");
1543  openvas_validator_alias (validator, "duration", "optional_number");
1544  openvas_validator_alias (validator, "duration_unit", "calendar_unit");
1545  openvas_validator_alias (validator, "dynamic_severity", "boolean");
1546  openvas_validator_alias (validator, "enable", "boolean");
1547  openvas_validator_alias (validator, "enable_stop", "boolean");
1548  openvas_validator_alias (validator, "end_day", "day_of_month");
1549  openvas_validator_alias (validator, "end_hour", "hour");
1550  openvas_validator_alias (validator, "end_minute", "minute");
1551  openvas_validator_alias (validator, "end_month", "month");
1552  openvas_validator_alias (validator, "end_year", "year");
1553  openvas_validator_alias (validator, "esxi_credential_id", "credential_id");
1554  openvas_validator_alias (validator, "filt_id", "id");
1555  openvas_validator_alias (validator, "filter_extra", "filter");
1556  openvas_validator_alias (validator, "filter_id", "id");
1557  openvas_validator_alias (validator, "filterbox", "boolean");
1558  openvas_validator_alias (validator, "from_file", "boolean");
1559  openvas_validator_alias (validator, "force_wizard", "boolean");
1560  openvas_validator_alias (validator, "get_name", "name");
1561  openvas_validator_alias (validator, "grant_full", "boolean");
1562  openvas_validator_alias (validator, "group_id", "id");
1563  openvas_validator_alias (validator, "group_ids:name", "number");
1564  openvas_validator_alias (validator, "group_ids:value", "id_optional");
1565  openvas_validator_alias (validator, "groups", "optional_number");
1566  openvas_validator_alias (validator, "host_search_phrase", "search_phrase");
1567  openvas_validator_alias (validator, "host_first_result", "first_result");
1568  openvas_validator_alias (validator, "host_max_results", "max_results");
1569  openvas_validator_alias (validator, "host_levels", "levels");
1570  openvas_validator_alias (validator, "host_count", "number");
1571  openvas_validator_alias (validator, "hosts_manual", "hosts");
1572  openvas_validator_alias (validator, "hosts_filter", "filter");
1573  openvas_validator_alias (validator, "exclude_hosts", "hosts");
1574  openvas_validator_alias (validator, "in_assets", "boolean");
1575  openvas_validator_alias (validator, "in_use", "boolean");
1576  openvas_validator_alias (validator, "include_related", "number");
1577  openvas_validator_alias (validator, "inheritor_id", "id");
1578  openvas_validator_alias (validator, "ignore_pagination", "boolean");
1579  openvas_validator_alias (validator, "refresh_interval", "number");
1580  openvas_validator_alias (validator, "event", "condition");
1581  openvas_validator_alias (validator, "access_hosts", "hosts_opt");
1582  openvas_validator_alias (validator, "access_ifaces", "hosts_opt");
1583  openvas_validator_alias (validator, "max_checks", "number");
1584  openvas_validator_alias (validator, "max_hosts", "number");
1585  openvas_validator_alias (validator, "method", "condition");
1586  openvas_validator_alias (validator, "modify_password", "number");
1587  openvas_validator_alias (validator, "ldaphost", "hostport");
1588  openvas_validator_alias (validator, "level_high", "boolean");
1589  openvas_validator_alias (validator, "level_medium", "boolean");
1590  openvas_validator_alias (validator, "level_low", "boolean");
1591  openvas_validator_alias (validator, "level_log", "boolean");
1592  openvas_validator_alias (validator, "level_false_positive", "boolean");
1593  openvas_validator_alias (validator, "method_data:to_address:", "email_list");
1594  openvas_validator_alias (validator, "method_data:from_address:", "email");
1595  openvas_validator_alias (validator, "new_severity", "severity_optional");
1596  openvas_validator_alias (validator, "new_severity_from_list", "severity_optional");
1597  openvas_validator_alias (validator, "new_threat", "threat");
1598  openvas_validator_alias (validator, "next", "page");
1599  openvas_validator_alias (validator, "next_next", "page");
1600  openvas_validator_alias (validator, "next_error", "page");
1601  openvas_validator_alias (validator, "next_id", "info_id");
1602  openvas_validator_alias (validator, "next_type", "resource_type");
1603  openvas_validator_alias (validator, "next_subtype", "info_type");
1604  openvas_validator_alias (validator, "next_xml", "boolean");
1605  openvas_validator_alias (validator, "notes", "boolean");
1606  openvas_validator_alias (validator, "note_task_id", "optional_task_id");
1607  openvas_validator_alias (validator, "note_task_uuid", "note_task_id");
1608  openvas_validator_alias (validator, "note_result_uuid", "note_result_id");
1609  openvas_validator_alias (validator, "no_chart_links", "boolean");
1610  openvas_validator_alias (validator, "no_filter_history", "boolean");
1611  openvas_validator_alias (validator, "no_redirect", "boolean");
1612  openvas_validator_alias (validator, "nvt:value", "uuid");
1613  openvas_validator_alias (validator, "old_login", "login");
1614  openvas_validator_alias (validator, "old_password", "password");
1615  openvas_validator_alias (validator, "original_overrides", "boolean");
1616  openvas_validator_alias (validator, "overrides", "boolean");
1617  openvas_validator_alias (validator, "override_task_id", "optional_task_id");
1618  openvas_validator_alias (validator, "override_task_uuid", "override_task_id");
1619  openvas_validator_alias (validator, "override_result_uuid", "override_result_id");
1620  openvas_validator_alias (validator, "owner", "name");
1621  openvas_validator_alias (validator, "passphrase", "lsc_password");
1622  openvas_validator_alias (validator, "password:name", "preference_name");
1623  openvas_validator_alias (validator, "permission", "name");
1624  openvas_validator_alias (validator, "permission_id", "id");
1625  openvas_validator_alias (validator, "permission_group_id", "id");
1626  openvas_validator_alias (validator, "permission_role_id", "id");
1627  openvas_validator_alias (validator, "permission_user_id", "id");
1628  openvas_validator_alias (validator, "port_manual", "port");
1629  openvas_validator_alias (validator, "port_range_end", "number");
1630  openvas_validator_alias (validator, "port_range_start", "number");
1631  openvas_validator_alias (validator, "pos", "number");
1632  openvas_validator_alias (validator, "privacy_password", "lsc_password");
1633  openvas_validator_alias (validator, "radiushost", "hostport");
1634  openvas_validator_alias (validator, "restrict_type", "resource_type");
1635  openvas_validator_alias (validator, "result_hosts_only", "boolean");
1636  openvas_validator_alias (validator, "result_task_id", "optional_task_id");
1637  openvas_validator_alias (validator, "report_result_id", "result_id");
1638  openvas_validator_alias (validator, "replace_task_id", "boolean");
1639  openvas_validator_alias (validator, "reverse_lookup_only", "boolean");
1640  openvas_validator_alias (validator, "reverse_lookup_unify", "boolean");
1641  openvas_validator_alias (validator, "role_id", "id");
1642  openvas_validator_alias (validator, "role_ids:name", "number");
1643  openvas_validator_alias (validator, "role_ids:value", "id_optional");
1644  openvas_validator_alias (validator, "roles", "optional_number");
1645  openvas_validator_alias (validator, "period", "optional_number");
1646  openvas_validator_alias (validator, "period_unit", "calendar_unit");
1647  openvas_validator_alias (validator, "scanner_host", "hostpath");
1648  openvas_validator_alias (validator, "scanner_type", "number");
1649  openvas_validator_alias (validator, "schedules_only", "boolean");
1650  openvas_validator_alias (validator, "schedule_periods", "number");
1651  openvas_validator_alias (validator, "select:name", "family");
1652  openvas_validator_alias (validator, "show_all", "boolean");
1653  openvas_validator_alias (validator, "slave_id", "id");
1654  openvas_validator_alias (validator, "smb_credential_id", "credential_id");
1655  openvas_validator_alias (validator, "snmp_credential_id", "credential_id");
1656  openvas_validator_alias (validator, "ssh_credential_id", "credential_id");
1657  openvas_validator_alias (validator, "start_day", "day_of_month");
1658  openvas_validator_alias (validator, "start_hour", "hour");
1659  openvas_validator_alias (validator, "start_minute", "minute");
1660  openvas_validator_alias (validator, "start_month", "month");
1661  openvas_validator_alias (validator, "start_year", "year");
1662  openvas_validator_alias (validator, "subgroup_column", "group_column");
1663  openvas_validator_alias (validator, "subject_id", "id");
1664  openvas_validator_alias (validator, "subject_id_optional", "id_optional");
1665  openvas_validator_alias (validator, "subject_name", "name");
1666  openvas_validator_alias (validator, "subtype", "asset_type");
1667  openvas_validator_alias (validator, "task_filter", "filter");
1668  openvas_validator_alias (validator, "task_filt_id", "filt_id");
1669  openvas_validator_alias (validator, "timeout", "boolean");
1670  openvas_validator_alias (validator, "trend:name", "family");
1671  openvas_validator_alias (validator, "user_id", "id");
1672  openvas_validator_alias (validator, "user_id_optional", "id_optional");
1673  openvas_validator_alias (validator, "xml", "boolean");
1674  openvas_validator_alias (validator, "esc_filter", "filter");
1675 }
1676 
1688 static void
1689 content_type_from_format_string (enum content_type* content_type,
1690  const char* format)
1691 {
1692  if (!format)
1694 
1695  else if (strcmp (format, "deb") == 0)
1697  else if (strcmp (format, "exe") == 0)
1699  else if (strcmp (format, "html") == 0)
1701  else if (strcmp (format, "key") == 0)
1703  else if (strcmp (format, "nbe") == 0)
1705  else if (strcmp (format, "pdf") == 0)
1707  else if (strcmp (format, "rpm") == 0)
1709  else if (strcmp (format, "xml") == 0)
1711  // Defaults to GSAD_CONTENT_TYPE_APP_HTML
1712  else
1714 }
1715 
1726 {
1727  struct MHD_PostProcessor *postprocessor;
1728  char *response;
1730  char *cookie;
1731  char *language;
1737  gchar *redirect;
1738 };
1739 
1740 #ifdef SERVE_STATIC_ASSETS
1741 
1751 static int
1752 file_reader (void *cls, uint64_t pos, char *buf, int max)
1753 {
1754  FILE *file = cls;
1755 
1756  fseek (file, pos, SEEK_SET);
1757  return fread (buf, 1, max, file);
1758 }
1759 #endif
1760 
1771 void
1772 free_resources (void *cls, struct MHD_Connection *connection,
1773  void **con_cls, enum MHD_RequestTerminationCode toe)
1774 {
1775  struct gsad_connection_info *con_info =
1776  (struct gsad_connection_info *) *con_cls;
1777 
1778  if (NULL == con_info)
1779  {
1780  g_debug ("con_info was NULL!\n");
1781  return;
1782  }
1783 
1784  g_debug ("connectiontype=%d\n", con_info->connectiontype);
1785 
1786  if (con_info->connectiontype == 1)
1787  {
1788  if (NULL != con_info->postprocessor)
1789  {
1790  MHD_destroy_post_processor (con_info->postprocessor);
1791  }
1792  }
1793 
1794  params_free (con_info->params);
1795  g_free (con_info->cookie);
1796  g_free (con_info->content_disposition);
1797  g_free (con_info->language);
1798  g_free (con_info);
1799  *con_cls = NULL;
1800 }
1801 
1814 static int
1815 params_append_mhd (params_t *params,
1816  const char *name,
1817  const char *filename,
1818  const char *chunk_data,
1819  int chunk_size,
1820  int chunk_offset)
1821 {
1822  if ((strncmp (name, "bulk_selected:", strlen ("bulk_selected:")) == 0)
1823  || (strncmp (name, "chart_gen:", strlen ("chart_gen:")) == 0)
1824  || (strncmp (name, "chart_init:", strlen ("chart_init:")) == 0)
1825  || (strncmp (name, "condition_data:", strlen ("condition_data:")) == 0)
1826  || (strncmp (name, "data_columns:", strlen ("data_columns:")) == 0)
1827  || (strncmp (name, "event_data:", strlen ("event_data:")) == 0)
1828  || (strncmp (name, "settings_changed:", strlen ("settings_changed:"))
1829  == 0)
1830  || (strncmp (name, "settings_default:", strlen ("settings_default:"))
1831  == 0)
1832  || (strncmp (name, "settings_filter:", strlen ("settings_filter:")) == 0)
1833  || (strncmp (name, "file:", strlen ("file:")) == 0)
1834  || (strncmp (name, "include_id_list:", strlen ("include_id_list:")) == 0)
1835  || (strncmp (name, "parameter:", strlen ("parameter:")) == 0)
1836  || (strncmp (name, "password:", strlen ("password:")) == 0)
1837  || (strncmp (name, "preference:", strlen ("preference:")) == 0)
1838  || (strncmp (name, "select:", strlen ("select:")) == 0)
1839  || (strncmp (name, "text_columns:", strlen ("text_columns:")) == 0)
1840  || (strncmp (name, "trend:", strlen ("trend:")) == 0)
1841  || (strncmp (name, "method_data:", strlen ("method_data:")) == 0)
1842  || (strncmp (name, "nvt:", strlen ("nvt:")) == 0)
1843  || (strncmp (name, "alert_id_optional:", strlen ("alert_id_optional:"))
1844  == 0)
1845  || (strncmp (name, "group_id_optional:", strlen ("group_id_optional:"))
1846  == 0)
1847  || (strncmp (name, "role_id_optional:", strlen ("role_id_optional:"))
1848  == 0)
1849  || (strncmp (name, "related:", strlen ("related:")) == 0)
1850  || (strncmp (name, "sort_fields:", strlen ("sort_fields:")) == 0)
1851  || (strncmp (name, "sort_orders:", strlen ("sort_orders:")) == 0)
1852  || (strncmp (name, "sort_stats:", strlen ("sort_stats:")) == 0)
1853  || (strncmp (name, "y_fields:", strlen ("y_fields:")) == 0)
1854  || (strncmp (name, "z_fields:", strlen ("z_fields:")) == 0))
1855  {
1856  param_t *param;
1857  const char *colon;
1858  gchar *prefix;
1859 
1860  colon = strchr (name, ':');
1861 
1862  /* Hashtable param, like for radios. */
1863 
1864  if ((colon - name) == (strlen (name) - 1))
1865  {
1866  /* name: "example:", value "abc". */
1867 
1868  params_append_bin (params, name, chunk_data, chunk_size, chunk_offset);
1869 
1870  return MHD_YES;
1871  }
1872 
1873  /* name: "nvt:1.3.6.1.4.1.25623.1.0.105058", value "1". */
1874 
1875  prefix = g_strndup (name, 1 + colon - name);
1876  param = params_get (params, prefix);
1877 
1878  if (param == NULL)
1879  {
1880  param = params_add (params, prefix, "");
1881  param->values = params_new ();
1882  }
1883  else if (param->values == NULL)
1884  param->values = params_new ();
1885 
1886  g_free (prefix);
1887 
1888  params_append_bin (param->values, colon + 1, chunk_data, chunk_size,
1889  chunk_offset);
1890  if (filename)
1891  param->filename = g_strdup (filename);
1892 
1893  return MHD_YES;
1894  }
1895 
1896  /*
1897  * Array param
1898  * Can be accessed like a hashtable param,with ascending numbers as the
1899  * key, which are automatically generated instead of being part of the
1900  * full name.
1901  * For example multiple instances of "x:" in the request
1902  * become "x:1", "x:2", "x:3", etc.
1903  */
1904  if ((strcmp (name, "alert_ids:") == 0)
1905  || (strcmp(name, "role_ids:") == 0)
1906  || (strcmp(name, "group_ids:") == 0)
1907  || (strcmp(name, "id_list:") == 0))
1908  {
1909  param_t *param;
1910  gchar *index_str;
1911 
1912  param = params_get (params, name);
1913 
1914  if (param == NULL)
1915  {
1916  param = params_add (params, name, "");
1917  param->values = params_new ();
1918  }
1919  else if (param->values == NULL)
1920  param->values = params_new ();
1921 
1922  if (chunk_offset == 0)
1923  param->array_len += 1;
1924 
1925  index_str = g_strdup_printf ("%d", param->array_len);
1926 
1927  params_append_bin (param->values, index_str, chunk_data, chunk_size,
1928  chunk_offset);
1929 
1930  g_free (index_str);
1931 
1932  if (filename)
1933  param->filename = g_strdup (filename);
1934 
1935  return MHD_YES;
1936  }
1937 
1938  /* Single value param. */
1939 
1940  params_append_bin (params, name, chunk_data, chunk_size, chunk_offset);
1941 
1942  return MHD_YES;
1943 }
1944 
1967 int
1968 serve_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key,
1969  const char *filename, const char *content_type,
1970  const char *transfer_encoding, const char *data, uint64_t off,
1971  size_t size)
1972 {
1973  struct gsad_connection_info *con_info =
1974  (struct gsad_connection_info *) coninfo_cls;
1975 
1976  con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
1977  con_info->response = SERVER_ERROR;
1978 
1979  if (NULL != key)
1980  {
1981  params_append_mhd (con_info->params, key, filename, data, size, off);
1982  con_info->answercode = MHD_HTTP_OK;
1983  return MHD_YES;
1984  }
1985  return MHD_NO;
1986 }
1987 
1994 void
1995 params_mhd_validate_values (const char *parent_name, void *params)
1996 {
1997  params_iterator_t iter;
1998  param_t *param;
1999  gchar *name, *name_name, *value_name;
2000 
2001  name_name = g_strdup_printf ("%sname", parent_name);
2002  value_name = g_strdup_printf ("%svalue", parent_name);
2003 
2004  params_iterator_init (&iter, params);
2005  while (params_iterator_next (&iter, &name, &param))
2006  {
2007  gchar *item_name;
2008 
2009  /* Item specific value validator like "method_data:to_adddress:". */
2010  if ((g_utf8_validate (name, -1, NULL) == FALSE)
2011  || (g_utf8_validate (param->value, -1, NULL) == FALSE))
2012  {
2013  param->original_value = param->value;
2014  param->value = NULL;
2015  param->value_size = 0;
2016  param->valid = 0;
2017  param->valid_utf8 = 0;
2018  item_name = NULL;
2019  }
2020  else switch (openvas_validate (validator,
2021  (item_name = g_strdup_printf ("%s%s:",
2022  parent_name,
2023  name)),
2024  param->value))
2025  {
2026  case 0:
2027  break;
2028  case 1:
2029  /* General name validator for collection like "method_data:name". */
2030  if (openvas_validate (validator, name_name, name))
2031  {
2032  param->original_value = param->value;
2033  param->value = NULL;
2034  param->value_size = 0;
2035  param->valid = 0;
2036  param->valid_utf8 = 0;
2037  }
2038  /* General value validator like "method_data:value". */
2039  else if (openvas_validate (validator, value_name, param->value))
2040  {
2041  param->original_value = param->value;
2042  param->value = NULL;
2043  param->value_size = 0;
2044  param->valid = 0;
2045  param->valid_utf8 = 0;
2046  }
2047  else
2048  {
2049  const gchar *alias_for;
2050 
2051  param->valid = 1;
2052  param->valid_utf8 = 1;
2053 
2054  alias_for = openvas_validator_alias_for (validator, name);
2055  if ((param->value && (strcmp ((gchar*) name, "number") == 0))
2056  || (alias_for && (strcmp ((gchar*) alias_for, "number") == 0)))
2057  /* Remove any leading or trailing space from numbers. */
2058  param->value = g_strstrip (param->value);
2059  }
2060  break;
2061  case 2:
2062  default:
2063  {
2064  param->original_value = param->value;
2065  param->value = NULL;
2066  param->value_size = 0;
2067  param->valid = 0;
2068  param->valid_utf8 = 0;
2069  }
2070  }
2071 
2072  g_free (item_name);
2073  }
2074 
2075  g_free (name_name);
2076  g_free (value_name);
2077 }
2078 
2084 static void
2085 params_mhd_validate (void *params)
2086 {
2087  GHashTableIter iter;
2088  gpointer name, value;
2089 
2090  g_hash_table_iter_init (&iter, params);
2091  while (g_hash_table_iter_next (&iter, &name, &value))
2092  {
2093  param_t *param;
2094  param = (param_t*) value;
2095 
2096  param->valid_utf8 = (g_utf8_validate (name, -1, NULL)
2097  && (param->value == NULL
2098  || g_utf8_validate (param->value, -1, NULL)));
2099 
2100  if ((!g_str_has_prefix (name, "osp_pref_")
2101  && openvas_validate (validator, name, param->value)))
2102  {
2103  param->original_value = param->value;
2104  param->value = NULL;
2105  param->valid = 0;
2106  }
2107  else
2108  {
2109  const gchar *alias_for;
2110 
2111  param->valid = 1;
2112 
2113  alias_for = openvas_validator_alias_for (validator, name);
2114  if ((param->value && (strcmp ((gchar*) name, "number") == 0))
2115  || (alias_for && (strcmp ((gchar*) alias_for, "number") == 0)))
2116  /* Remove any leading or trailing space from numbers. */
2117  param->value = g_strstrip (param->value);
2118  }
2119 
2120  if (param->values)
2121  params_mhd_validate_values (name, param->values);
2122  }
2123 }
2124 
2128 #define ELSE(name) \
2129  else if (!strcmp (cmd, G_STRINGIFY (name))) \
2130  con_info->response = name ## _omp (&connection, credentials, \
2131  con_info->params, &response_data);
2132 
2133 static credentials_t *
2134 credentials_new (user_t *user, const char *language, const char *client_address)
2135 {
2136  credentials_t *credentials;
2137 
2138  assert (user->username);
2139  assert (user->password);
2140  assert (user->role);
2141  assert (user->timezone);
2142  assert (user->capabilities);
2143  assert (user->token);
2144  credentials = g_malloc0 (sizeof (credentials_t));
2145  credentials->username = g_strdup (user->username);
2146  credentials->password = g_strdup (user->password);
2147  credentials->role = g_strdup (user->role);
2148  credentials->timezone = g_strdup (user->timezone);
2149  credentials->severity = g_strdup (user->severity);
2150  credentials->capabilities = g_strdup (user->capabilities);
2151  credentials->token = g_strdup (user->token);
2152  credentials->charts = user->charts;
2153  credentials->chart_prefs = user->chart_prefs;
2154  credentials->pw_warning = user->pw_warning ? g_strdup (user->pw_warning)
2155  : NULL;
2156  credentials->language = g_strdup (language);
2157  credentials->autorefresh = user->autorefresh
2158  ? g_strdup (user->autorefresh) : NULL;
2159  credentials->last_filt_ids = user->last_filt_ids;
2160  credentials->client_address = g_strdup (client_address);
2161  credentials->guest = user->guest;
2162 
2163  return credentials;
2164 }
2165 
2166 static void
2167 credentials_free (credentials_t *creds)
2168 {
2169  if (!creds)
2170  return;
2171 
2172  g_free (creds->username);
2173  g_free (creds->password);
2174  g_free (creds->role);
2175  g_free (creds->timezone);
2176  g_free (creds->token);
2177  g_free (creds->caller);
2178  g_free (creds->current_page);
2179  g_free (creds->capabilities);
2180  g_free (creds->language);
2181  g_free (creds->severity);
2182  g_free (creds->pw_warning);
2183  g_free (creds->client_address);
2184  g_free (creds->autorefresh);
2185  /* params, chart_prefs and last_filt_ids are not duplicated. */
2186  g_free (creds);
2187 }
2188 
2204 int
2205 exec_omp_post (struct gsad_connection_info *con_info, user_t **user_return,
2206  gchar **new_sid, const char *client_address)
2207 {
2208  int ret;
2209  user_t *user;
2210  credentials_t *credentials;
2211  const char *cmd, *caller, *language;
2212  cmd_response_data_t response_data;
2213  cmd_response_data_init (&response_data);
2214  const char *xml_flag;
2215  xml_flag = params_value (con_info->params, "xml");
2216  openvas_connection_t connection;
2217 
2218  /* Handle the login command specially. */
2219 
2220  params_mhd_validate (con_info->params);
2221 
2222  cmd = params_value (con_info->params, "cmd");
2223 
2224  if (cmd && !strcmp (cmd, "login"))
2225  {
2226  const char *password;
2227 
2228  password = params_value (con_info->params, "password");
2229  if ((password == NULL)
2230  && (params_original_value (con_info->params, "password") == NULL))
2231  password = "";
2232 
2233  if (params_value (con_info->params, "login")
2234  && password)
2235  {
2236  int ret;
2237  gchar *timezone, *role, *capabilities, *severity, *language;
2238  gchar *pw_warning, *autorefresh;
2239  GTree *chart_prefs;
2240  ret = authenticate_omp (params_value (con_info->params, "login"),
2241  password,
2242  &role,
2243  &timezone,
2244  &severity,
2245  &capabilities,
2246  &language,
2247  &pw_warning,
2248  &chart_prefs,
2249  &autorefresh);
2250  if (ret)
2251  {
2252  time_t now;
2253  gchar *xml;
2254  char *res;
2255  char ctime_now[200];
2256 
2257  if (ret == -1 || ret == 2)
2258  response_data.http_status_code = MHD_HTTP_SERVICE_UNAVAILABLE;
2259  else
2260  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
2261 
2262  now = time (NULL);
2263  ctime_r_strip_newline (&now, ctime_now);
2264 
2265  xml = login_xml
2266  (ret == 2
2267  ? "Login failed."
2268  " Waiting for OMP service to become available."
2269  : (ret == -1
2270  ? "Login failed."
2271  " Error during authentication."
2272  : "Login failed."),
2273  NULL,
2274  ctime_now,
2275  NULL,
2276  con_info->language
2277  ? con_info->language
2280 
2281  if (xml_flag && strcmp (xml_flag, "0"))
2282  res = xml;
2283  else
2284  {
2285  res = xsl_transform (xml, &response_data);
2286  g_free (xml);
2287  }
2288  con_info->response = res;
2289  con_info->answercode = response_data.http_status_code;
2290 
2291  g_warning ("Authentication failure for '%s' from %s",
2292  params_value (con_info->params, "login") ?: "",
2293  client_address);
2294  }
2295  else
2296  {
2297  user_t *user;
2298  user = user_add (params_value (con_info->params, "login"),
2299  password, timezone, severity, role, capabilities,
2300  language, pw_warning, chart_prefs, autorefresh,
2301  client_address);
2302 
2303  g_message ("Authentication success for '%s' from %s",
2304  params_value (con_info->params, "login") ?: "",
2305  client_address);
2306 
2307  /* Redirect to get_tasks. */
2308  *user_return = user;
2309  g_free (timezone);
2310  g_free (severity);
2311  g_free (capabilities);
2312  g_free (language);
2313  g_free (role);
2314  g_free (pw_warning);
2315  g_free (autorefresh);
2316  cmd_response_data_reset (&response_data);
2317  return 1;
2318  }
2319  }
2320  else
2321  {
2322  time_t now;
2323  gchar *xml;
2324  char *res;
2325  char ctime_now[200];
2326 
2327  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
2328 
2329  now = time (NULL);
2330  ctime_r_strip_newline (&now, ctime_now);
2331 
2332  xml = login_xml ("Login failed.", NULL, ctime_now, NULL,
2333  con_info->language ? con_info->language
2336  if (xml_flag && strcmp (xml_flag, "0"))
2337  res = xml;
2338  else
2339  {
2340  res = xsl_transform (xml, &response_data);
2341  g_free (xml);
2342  }
2343  con_info->response = res;
2344  con_info->answercode = response_data.http_status_code;
2345  g_warning ("Authentication failure for '%s' from %s",
2346  params_value (con_info->params, "login") ?: "",
2347  client_address);
2348  }
2349  cmd_response_data_reset (&response_data);
2350  return 3;
2351  }
2352 
2353  /* Check the session. */
2354 
2355  if (params_value (con_info->params, "token") == NULL)
2356  {
2357  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
2358  if (params_given (con_info->params, "token") == 0)
2359  con_info->response
2360  = gsad_message (NULL,
2361  "Internal error", __FUNCTION__, __LINE__,
2362  "An internal error occurred inside GSA daemon. "
2363  "Diagnostics: Token missing.",
2364  "/omp?cmd=get_tasks", &response_data);
2365  else
2366  con_info->response
2367  = gsad_message (NULL,
2368  "Internal error", __FUNCTION__, __LINE__,
2369  "An internal error occurred inside GSA daemon. "
2370  "Diagnostics: Token bad.",
2371  "/omp?cmd=get_tasks", &response_data);
2372  con_info->answercode = response_data.http_status_code;
2373  cmd_response_data_reset (&response_data);
2374  return 3;
2375  }
2376 
2377  ret = user_find (con_info->cookie, params_value (con_info->params, "token"),
2378  client_address, &user);
2379  if (ret == USER_BAD_TOKEN)
2380  {
2381  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
2382  con_info->response
2383  = gsad_message (NULL,
2384  "Internal error", __FUNCTION__, __LINE__,
2385  "An internal error occurred inside GSA daemon. "
2386  "Diagnostics: Bad token.",
2387  "/omp?cmd=get_tasks", &response_data);
2388  con_info->answercode = response_data.http_status_code;
2389  cmd_response_data_reset (&response_data);
2390  return 3;
2391  }
2392 
2393  if (ret == USER_EXPIRED_TOKEN)
2394  {
2395  time_t now;
2396  gchar *xml;
2397  char ctime_now[200];
2398 
2399  now = time (NULL);
2400  ctime_r_strip_newline (&now, ctime_now);
2401 
2402  caller = params_value (con_info->params, "caller");
2403 
2404  if (caller && g_utf8_validate (caller, -1, NULL) == FALSE)
2405  {
2406  caller = NULL;
2407  g_warning ("%s - caller is not valid UTF-8", __FUNCTION__);
2408  }
2409 
2410  /* @todo Validate caller. */
2411 
2412  xml = login_xml ("Session has expired. Please login again.",
2413  NULL,
2414  ctime_now,
2415  caller
2416  ? caller
2417  : "",
2418  con_info->language
2419  ? con_info->language
2422  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
2423  if (xml_flag && strcmp (xml_flag, "0"))
2424  con_info->response = xml;
2425  else
2426  {
2427  con_info->response = xsl_transform (xml, &response_data);
2428  g_free (xml);
2429  }
2430  con_info->answercode = response_data.http_status_code;
2431  cmd_response_data_reset (&response_data);
2432  return 2;
2433  }
2434 
2436  {
2437  time_t now;
2438  gchar *xml;
2439  char ctime_now[200];
2440 
2441  now = time (NULL);
2442  ctime_r_strip_newline (&now, ctime_now);
2443 
2444  xml = login_xml ("Cookie missing or bad. Please login again.",
2445  NULL,
2446  ctime_now,
2447  NULL,
2448  con_info->language
2449  ? con_info->language
2452  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
2453  if (xml_flag && strcmp (xml_flag, "0"))
2454  con_info->response = xml;
2455  else
2456  {
2457  con_info->response = xsl_transform (xml, &response_data);
2458  g_free (xml);
2459  }
2460  con_info->answercode = response_data.http_status_code;
2461  cmd_response_data_reset (&response_data);
2462  return 2;
2463  }
2464 
2465  if (ret == USER_GUEST_LOGIN_FAILED || ret == USER_OMP_DOWN ||
2466  ret == USER_GUEST_LOGIN_ERROR)
2467  {
2468  time_t now;
2469  gchar *xml;
2470  char ctime_now[200];
2471 
2472  now = time (NULL);
2473  ctime_r_strip_newline (&now, ctime_now);
2474 
2475  response_data.http_status_code = MHD_HTTP_SERVICE_UNAVAILABLE;
2476  xml = login_xml (ret == USER_OMP_DOWN
2477  ? "Login failed. OMP service is down."
2478  : (ret == USER_GUEST_LOGIN_ERROR
2479  ? "Login failed. Error during authentication."
2480  : "Login failed."),
2481  NULL,
2482  ctime_now,
2483  NULL,
2484  con_info->language
2485  ? con_info->language
2488  if (xml_flag && strcmp (xml_flag, "0"))
2489  con_info->response = xml;
2490  else
2491  {
2492  con_info->response = xsl_transform (xml, &response_data);
2493  g_free (xml);
2494  }
2495  con_info->answercode = response_data.http_status_code;
2496  cmd_response_data_reset (&response_data);
2497  return 2;
2498  }
2499 
2500  if (ret)
2501  abort ();
2502 
2503  /* From here, the user is authenticated. */
2504 
2505 
2506  language = user->language ?: con_info->language ?: DEFAULT_GSAD_LANGUAGE;
2507  credentials = credentials_new (user, language, client_address);
2508  credentials->params = con_info->params; // FIXME remove params from credentials
2509  gettimeofday (&credentials->cmd_start, NULL);
2510 
2511  /* The caller of a POST is usually the caller of the page that the POST form
2512  * was on. */
2513  caller = params_value (con_info->params, "caller");
2514  if (caller && g_utf8_validate (caller, -1, NULL) == FALSE)
2515  {
2516  g_warning ("%s - caller is not valid UTF-8", __FUNCTION__);
2517  caller = NULL;
2518  }
2519  credentials->caller = g_strdup (caller ?: "");
2520 
2521  if (new_sid) *new_sid = g_strdup (user->cookie);
2522 
2523  user_release (user);
2524 
2525  /* Set the timezone. */
2526 
2527  if (credentials->timezone)
2528  {
2529  if (setenv ("TZ", credentials->timezone, 1) == -1)
2530  {
2531  g_critical ("%s: failed to set TZ\n", __FUNCTION__);
2532  exit (EXIT_FAILURE);
2533  }
2534  tzset ();
2535  }
2536 
2537  /* Connect to manager */
2538  switch (manager_connect (credentials, &connection, &response_data))
2539  {
2540  case 0:
2541  break;
2542  case -1:
2543  con_info->answercode = MHD_HTTP_SERVICE_UNAVAILABLE;
2544  con_info->response = logout (credentials,
2545  "Logged out. OMP service is down.",
2546  &response_data);
2547  return 2;
2548  break;
2549  case -2:
2550  con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
2551  con_info->response
2552  = gsad_message (credentials,
2553  "Internal error", __FUNCTION__, __LINE__,
2554  "An internal error occurred. "
2555  "Diagnostics: Could not authenticate to manager "
2556  "daemon.",
2557  "/omp?cmd=get_tasks",
2558  &response_data);
2559  return 2;
2560  default:
2561  con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
2562  con_info->response
2563  = gsad_message (credentials,
2564  "Internal error", __FUNCTION__, __LINE__,
2565  "An internal error occurred. "
2566  "Diagnostics: Failure to connect to manager "
2567  "daemon.",
2568  "/omp?cmd=get_tasks",
2569  &response_data);
2570  return 2;
2571  }
2572 
2573 
2574  /* Handle the usual commands. */
2575 
2576  if (!cmd)
2577  {
2578  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
2579  con_info->response = gsad_message (credentials,
2580  "Internal error",
2581  __FUNCTION__,
2582  __LINE__,
2583  "An internal error occurred inside GSA daemon. "
2584  "Diagnostics: Empty command.",
2585  "/omp?cmd=get_tasks", &response_data);
2586  }
2587  ELSE (bulk_delete)
2588  ELSE (clone)
2589  ELSE (create_agent)
2590  ELSE (create_alert)
2591  ELSE (create_asset)
2592  ELSE (create_container_task)
2593  ELSE (create_credential)
2594  ELSE (create_filter)
2595  ELSE (create_group)
2596  ELSE (create_host)
2597  ELSE (create_permission)
2598  ELSE (create_permissions)
2599  ELSE (create_port_list)
2600  ELSE (create_port_range)
2601  ELSE (create_report)
2602  ELSE (create_task)
2603  ELSE (create_user)
2604  ELSE (create_role)
2605  ELSE (create_scanner)
2606  ELSE (create_schedule)
2607  ELSE (create_tag)
2608  ELSE (create_target)
2609  ELSE (create_config)
2610  ELSE (create_note)
2611  ELSE (create_override)
2612  ELSE (delete_agent)
2613  ELSE (delete_asset)
2614  ELSE (delete_task)
2615  ELSE (delete_alert)
2616  ELSE (delete_credential)
2617  ELSE (delete_filter)
2618  ELSE (delete_group)
2619  ELSE (delete_note)
2620  ELSE (delete_override)
2621  ELSE (delete_permission)
2622  ELSE (delete_port_list)
2623  ELSE (delete_port_range)
2624  ELSE (delete_report)
2625  ELSE (delete_report_format)
2626  ELSE (delete_role)
2627  ELSE (delete_scanner)
2628  ELSE (delete_schedule)
2629  ELSE (delete_user)
2630  ELSE (delete_tag)
2631  ELSE (delete_target)
2632  ELSE (delete_trash_agent)
2633  ELSE (delete_trash_config)
2634  ELSE (delete_trash_alert)
2635  ELSE (delete_trash_credential)
2636  ELSE (delete_trash_filter)
2637  ELSE (delete_trash_group)
2638  ELSE (delete_trash_note)
2639  ELSE (delete_trash_override)
2640  ELSE (delete_trash_permission)
2641  ELSE (delete_trash_port_list)
2642  ELSE (delete_trash_report_format)
2643  ELSE (delete_trash_role)
2644  ELSE (delete_trash_scanner)
2645  ELSE (delete_trash_schedule)
2646  ELSE (delete_trash_tag)
2647  ELSE (delete_trash_target)
2648  ELSE (delete_trash_task)
2649  ELSE (delete_config)
2650  ELSE (empty_trashcan)
2651  else if (!strcmp (cmd, "alert_report"))
2652  {
2653  con_info->response = get_report_section_omp
2654  (&connection, credentials, con_info->params,
2655  &response_data);
2656  }
2657  ELSE (import_config)
2658  ELSE (import_port_list)
2659  ELSE (import_report)
2660  ELSE (import_report_format)
2661  else if (!strcmp (cmd, "process_bulk"))
2662  {
2663  con_info->response = process_bulk_omp (&connection,
2664  credentials,
2665  con_info->params,
2666  &con_info->content_type,
2667  &con_info->content_disposition,
2668  &con_info->content_length,
2669  &response_data);
2670  }
2671  ELSE (move_task)
2672  ELSE (restore)
2673  ELSE (resume_task)
2674  ELSE (run_wizard)
2675  ELSE (save_agent)
2676  ELSE (save_alert)
2677  ELSE (save_asset)
2678  ELSE (save_auth)
2679  else if (!strcmp (cmd, "save_chart_preference"))
2680  {
2681  gchar *pref_id, *pref_value;
2682 
2683  con_info->response = save_chart_preference_omp (&connection,
2684  credentials,
2685  con_info->params,
2686  &pref_id, &pref_value,
2687  &response_data);
2688  if (pref_id && pref_value)
2689  user_set_chart_pref (credentials->token, pref_id, pref_value);
2690  }
2691  ELSE (save_config)
2692  ELSE (save_config_family)
2693  ELSE (save_config_nvt)
2694  ELSE (save_credential)
2695  ELSE (save_filter)
2696  ELSE (save_group)
2697  else if (!strcmp (cmd, "save_my_settings"))
2698  {
2699  char *timezone, *password, *severity, *language;
2700  con_info->response = save_my_settings_omp (&connection,
2701  credentials, con_info->params,
2702  con_info->language,
2703  &timezone, &password,
2704  &severity, &language,
2705  &response_data);
2706  if (timezone)
2707  /* credentials->timezone set in save_my_settings_omp before XSLT. */
2708  user_set_timezone (credentials->token, timezone);
2709  if (password)
2710  {
2711  /* credentials->password set in save_my_settings_omp before XSLT. */
2712  user_set_password (credentials->token, password);
2713 
2714  user_logout_all_sessions (credentials->username, credentials);
2715  }
2716  if (severity)
2717  /* credentials->severity set in save_my_settings_omp before XSLT. */
2718  user_set_severity (credentials->token, severity);
2719  if (language)
2720  /* credentials->language is set in save_my_settings_omp before XSLT. */
2721  user_set_language (credentials->token, language);
2722 
2723  g_free (timezone);
2724  g_free (password);
2725  g_free (severity);
2726  g_free (language);
2727  }
2728  ELSE (save_note)
2729  ELSE (save_override)
2730  ELSE (save_permission)
2731  ELSE (save_port_list)
2732  ELSE (save_report_format)
2733  ELSE (save_role)
2734  ELSE (save_scanner)
2735  ELSE (save_schedule)
2736  ELSE (save_tag)
2737  ELSE (save_target)
2738  ELSE (save_task)
2739  ELSE (save_container_task)
2740  else if (!strcmp (cmd, "save_user"))
2741  {
2742  char *password, *modified_user;
2743  int logout;
2744  con_info->response = save_user_omp (&connection, credentials,
2745  con_info->params,
2746  &password, &modified_user, &logout,
2747  &response_data);
2748  if (modified_user && logout)
2749  user_logout_all_sessions (modified_user, credentials);
2750 
2751  if (password)
2752  /* credentials->password set in save_user_omp before XSLT. */
2753  user_set_password (credentials->token, password);
2754 
2755  g_free (password);
2756  }
2757  ELSE (start_task)
2758  ELSE (stop_task)
2759  ELSE (sync_feed)
2760  ELSE (sync_scap)
2761  ELSE (sync_cert)
2762  ELSE (test_alert)
2763  ELSE (toggle_tag)
2764  ELSE (verify_agent)
2765  ELSE (verify_report_format)
2766  ELSE (verify_scanner)
2767  else
2768  {
2769  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
2770  con_info->response = gsad_message (credentials,
2771  "Internal error",
2772  __FUNCTION__,
2773  __LINE__,
2774  "An internal error occurred inside GSA daemon. "
2775  "Diagnostics: Unknown command.",
2776  "/omp?cmd=get_tasks", &response_data);
2777  }
2778 
2779  if (response_data.redirect)
2780  {
2781  con_info->answercode = MHD_HTTP_SEE_OTHER;
2782  con_info->redirect = response_data.redirect;
2783  }
2784  else
2785  con_info->answercode = response_data.http_status_code;
2786 
2787  cmd_response_data_reset (&response_data);
2788  credentials_free (credentials);
2789  openvas_connection_close (&connection);
2790  return 0;
2791 }
2792 
2801 static int
2802 params_mhd_add (void *params, enum MHD_ValueKind kind, const char *name,
2803  const char *value)
2804 {
2805  if ((strncmp (name, "bulk_selected:", strlen ("bulk_selected:")) == 0)
2806  || (strncmp (name, "chart_gen:", strlen ("chart_gen:")) == 0)
2807  || (strncmp (name, "chart_init:", strlen ("chart_init:")) == 0)
2808  || (strncmp (name, "condition_data:", strlen ("condition_data:")) == 0)
2809  || (strncmp (name, "data_columns:", strlen ("data_columns:")) == 0)
2810  || (strncmp (name, "event_data:", strlen ("event_data:")) == 0)
2811  || (strncmp (name, "settings_changed:", strlen ("settings_changed:"))
2812  == 0)
2813  || (strncmp (name, "settings_default:", strlen ("settings_default:"))
2814  == 0)
2815  || (strncmp (name, "settings_filter:", strlen ("settings_filter:")) == 0)
2816  || (strncmp (name, "file:", strlen ("file:")) == 0)
2817  || (strncmp (name, "include_id_list:", strlen ("include_id_list:")) == 0)
2818  || (strncmp (name, "parameter:", strlen ("parameter:")) == 0)
2819  || (strncmp (name, "password:", strlen ("password:")) == 0)
2820  || (strncmp (name, "preference:", strlen ("preference:")) == 0)
2821  || (strncmp (name, "select:", strlen ("select:")) == 0)
2822  || (strncmp (name, "text_columns:", strlen ("text_columns:")) == 0)
2823  || (strncmp (name, "trend:", strlen ("trend:")) == 0)
2824  || (strncmp (name, "method_data:", strlen ("method_data:")) == 0)
2825  || (strncmp (name, "nvt:", strlen ("nvt:")) == 0)
2826  || (strncmp (name, "alert_id_optional:", strlen ("alert_id_optional:"))
2827  == 0)
2828  || (strncmp (name, "group_id_optional:", strlen ("group_id_optional:"))
2829  == 0)
2830  || (strncmp (name, "role_id_optional:", strlen ("role_id_optional:"))
2831  == 0)
2832  || (strncmp (name, "related:", strlen ("related:")) == 0)
2833  || (strncmp (name, "sort_fields:", strlen ("sort_fields:")) == 0)
2834  || (strncmp (name, "sort_orders:", strlen ("sort_orders:")) == 0)
2835  || (strncmp (name, "sort_stats:", strlen ("sort_stats:")) == 0)
2836  || (strncmp (name, "y_fields:", strlen ("y_fields:")) == 0)
2837  || (strncmp (name, "z_fields:", strlen ("z_fields:")) == 0))
2838  {
2839  param_t *param;
2840  const char *colon;
2841  gchar *prefix;
2842 
2843  /* Hashtable param, like for radios. */
2844 
2845  colon = strchr (name, ':');
2846 
2847  if ((colon - name) == (strlen (name) - 1))
2848  {
2849  params_append_bin (params, name, value, strlen (value), 0);
2850 
2851  return MHD_YES;
2852  }
2853 
2854  prefix = g_strndup (name, 1 + colon - name);
2855  param = params_get (params, prefix);
2856 
2857  if (param == NULL)
2858  {
2859  param = params_add (params, prefix, "");
2860  param->values = params_new ();
2861  }
2862  else if (param->values == NULL)
2863  param->values = params_new ();
2864 
2865  g_free (prefix);
2866 
2867  params_append_bin (param->values, colon + 1, value, strlen (value), 0);
2868 
2869  return MHD_YES;
2870  }
2871 
2872  /*
2873  * Array param (See params_append_mhd for a description)
2874  */
2875  if ((strcmp (name, "alert_ids:") == 0)
2876  || (strcmp(name, "role_ids:") == 0)
2877  || (strcmp(name, "group_ids:") == 0)
2878  || (strcmp(name, "id_list:") == 0))
2879  {
2880  param_t *param;
2881  gchar *index_str;
2882 
2883  param = params_get (params, name);
2884 
2885  if (param == NULL)
2886  {
2887  param = params_add (params, name, "");
2888  param->values = params_new ();
2889  }
2890  else if (param->values == NULL)
2891  param->values = params_new ();
2892 
2893  param->array_len += 1;
2894 
2895  index_str = g_strdup_printf ("%d", param->array_len);
2896 
2897  params_append_bin (param->values, index_str, value, strlen (value), 0);
2898 
2899  g_free (index_str);
2900 
2901  return MHD_YES;
2902  }
2903 
2904  /* Single value param. */
2905 
2906  params_add ((params_t *) params, name, value);
2907  return MHD_YES;
2908 }
2909 
2910 /*
2911  * Connection watcher thread data
2912  */
2913 typedef struct {
2915  openvas_connection_t *openvas_connection;
2917  pthread_mutex_t mutex;
2919 
2930 connection_watcher_data_new (openvas_connection_t *openvas_connection,
2931  int client_socket_fd)
2932 {
2933  connection_watcher_data_t *watcher_data;
2934  watcher_data = g_malloc (sizeof (connection_watcher_data_t));
2935 
2936  watcher_data->openvas_connection = openvas_connection;
2937  watcher_data->client_socket_fd = client_socket_fd;
2938  watcher_data->connection_closed = 0;
2939  pthread_mutex_init (&(watcher_data->mutex), NULL);
2940 
2941  return watcher_data;
2942 }
2943 
2951 static void*
2952 watch_client_connection (void* data)
2953 {
2954  int active;
2955  connection_watcher_data_t *watcher_data;
2956 
2957  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
2958  watcher_data = (connection_watcher_data_t*) data;
2959 
2960  pthread_mutex_lock (&(watcher_data->mutex));
2961  active = 1;
2962  pthread_mutex_unlock (&(watcher_data->mutex));
2963 
2964  while (active)
2965  {
2966  pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
2967  sleep (client_watch_interval);
2968  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
2969 
2970  pthread_mutex_lock (&(watcher_data->mutex));
2971 
2972  if (watcher_data->connection_closed)
2973  {
2974  active = 0;
2975  pthread_mutex_unlock (&(watcher_data->mutex));
2976  break;
2977  }
2978  int ret;
2979  char buf[1];
2980  errno = 0;
2981  ret = recv (watcher_data->client_socket_fd, buf, 1, MSG_PEEK);
2982 
2983  if (ret >= 0)
2984  {
2985  if (watcher_data->connection_closed == 0)
2986  {
2987  watcher_data->connection_closed = 1;
2988  active = 0;
2989  g_debug ("%s: Client connection closed", __FUNCTION__);
2990 
2991  if (watcher_data->openvas_connection->tls)
2992  {
2993  openvas_connection_t *gvm_conn;
2994  gvm_conn = watcher_data->openvas_connection;
2995  gnutls_bye (gvm_conn->session, GNUTLS_SHUT_RDWR);
2996  }
2997  else
2998  {
2999  openvas_connection_close (watcher_data->openvas_connection);
3000  }
3001  }
3002  }
3003 
3004  pthread_mutex_unlock (&(watcher_data->mutex));
3005  }
3006 
3007  return NULL;
3008 }
3009 
3010 
3011 #undef ELSE
3012 
3016 #define ELSE(name) \
3017  else if (!strcmp (cmd, G_STRINGIFY (name))) \
3018  ret = name ## _omp (&connection, credentials, params, response_data);
3019 
3039 char *
3040 exec_omp_get (struct MHD_Connection *con,
3041  credentials_t *credentials,
3042  enum content_type* content_type,
3043  gchar **content_type_string,
3044  char** content_disposition,
3045  gsize* response_size,
3046  cmd_response_data_t *response_data)
3047 {
3048  openvas_connection_t connection;
3049  char *cmd = NULL;
3050  const int CMD_MAX_SIZE = 27; /* delete_trash_lsc_credential */
3051  params_t *params;
3052  char *ret;
3053  pthread_t watch_thread;
3054  connection_watcher_data_t *watcher_data;
3055 
3056  cmd =
3057  (char *) MHD_lookup_connection_value (con, MHD_GET_ARGUMENT_KIND,
3058  "cmd");
3059  if (cmd == NULL)
3060  {
3061  cmd = "dashboard"; // TODO: Allow settings for face + users(?)
3062  }
3063 
3064  if (openvas_validate (validator, "cmd", cmd))
3065  cmd = NULL;
3066 
3067  if ((cmd != NULL) && (strlen (cmd) <= CMD_MAX_SIZE))
3068  {
3069  g_debug ("cmd: [%s]\n", cmd);
3070 
3071  params = params_new ();
3072 
3073  MHD_get_connection_values (con, MHD_GET_ARGUMENT_KIND,
3074  params_mhd_add, params);
3075 
3076  params_mhd_validate (params);
3077  credentials->params = params;
3078  }
3079  else
3080  {
3081  response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
3082  return gsad_message (credentials,
3083  "Internal error", __FUNCTION__, __LINE__,
3084  "An internal error occurred inside GSA daemon. "
3085  "Diagnostics: No valid command for omp.",
3086  "/omp?cmd=get_tasks", response_data);
3087  }
3088 
3089 
3090  /* Set the timezone. */
3091 
3092  if (credentials->timezone)
3093  {
3094  if (setenv ("TZ", credentials->timezone, 1) == -1)
3095  {
3096  g_critical ("%s: failed to set TZ\n", __FUNCTION__);
3097  exit (EXIT_FAILURE);
3098  }
3099  tzset ();
3100  }
3101 
3102  /* Connect to manager */
3103  switch (manager_connect (credentials, &connection, response_data))
3104  {
3105  case 0:
3106  break;
3107  case -1:
3108  return logout (credentials,
3109  "Logged out. OMP service is down.",
3110  response_data);
3111  case -2:
3112  return gsad_message (credentials,
3113  "Internal error", __FUNCTION__, __LINE__,
3114  "An internal error occurred. "
3115  "Diagnostics: Could not authenticate to manager "
3116  "daemon.",
3117  "/omp?cmd=get_tasks",
3118  response_data);
3119  default:
3120  return gsad_message (credentials,
3121  "Internal error", __FUNCTION__, __LINE__,
3122  "An internal error occurred. "
3123  "Diagnostics: Failure to connect to manager "
3124  "daemon.",
3125  "/omp?cmd=get_tasks",
3126  response_data);
3127  }
3128 
3129  /* Set page display settings */
3130 
3131  /* Show / hide charts */
3132  if (params_given (params, "charts"))
3133  {
3134  const char* charts;
3135  charts = params_value (params, "charts");
3136  credentials->charts = atoi (charts);
3137  user_set_charts (credentials->token, credentials->charts);
3138  }
3139 
3140  gettimeofday (&credentials->cmd_start, NULL);
3141 
3143  {
3144  const union MHD_ConnectionInfo *mhd_con_info;
3145  mhd_con_info
3146  = MHD_get_connection_info (con,
3147  MHD_CONNECTION_INFO_CONNECTION_FD);
3148 
3149  watcher_data = connection_watcher_data_new (&connection,
3150  mhd_con_info->connect_fd);
3151 
3152  pthread_create (&watch_thread, NULL,
3153  watch_client_connection, watcher_data);
3154  }
3155  else
3156  {
3157  watcher_data = NULL;
3158  }
3159 
3162  /* Check cmd and precondition, start respective OMP command(s). */
3163 
3164  if (!strcmp (cmd, "cvss_calculator"))
3165  ret = cvss_calculator (&connection, credentials, params, response_data);
3166 
3167  else if (!strcmp (cmd, "dashboard"))
3168  ret = dashboard (&connection, credentials, params, response_data);
3169 
3170  else if (!strcmp (cmd, "new_filter"))
3171  ret = new_filter_omp (&connection, credentials, params, response_data);
3172 
3173  ELSE (new_container_task)
3174  ELSE (new_target)
3175  ELSE (new_tag)
3176  ELSE (new_task)
3177  ELSE (new_user)
3178  ELSE (new_alert)
3179  ELSE (new_group)
3180  ELSE (new_role)
3181  ELSE (get_assets_chart)
3182  ELSE (get_task)
3183  ELSE (get_tasks)
3184  ELSE (get_tasks_chart)
3185  ELSE (delete_user_confirm)
3186  ELSE (edit_agent)
3187  ELSE (edit_alert)
3188  ELSE (edit_asset)
3189  ELSE (edit_config)
3190  ELSE (edit_config_family)
3191  ELSE (edit_config_nvt)
3192  ELSE (edit_credential)
3193  ELSE (edit_filter)
3194  ELSE (edit_group)
3195  ELSE (edit_my_settings)
3196  ELSE (edit_note)
3199  ELSE (edit_port_list)
3200  ELSE (edit_report_format)
3201  ELSE (edit_role)
3202  ELSE (edit_scanner)
3204  ELSE (edit_tag)
3205  ELSE (edit_target)
3206  ELSE (edit_task)
3207  ELSE (edit_user)
3208  ELSE (auth_settings)
3209 
3210  else if (!strcmp (cmd, "export_agent"))
3211  ret = export_agent_omp (&connection, credentials, params, content_type,
3212  content_disposition, response_size,
3213  response_data);
3214 
3215  else if (!strcmp (cmd, "export_agents"))
3216  ret = export_agents_omp (&connection, credentials, params, content_type,
3217  content_disposition, response_size,
3218  response_data);
3219 
3220  else if (!strcmp (cmd, "export_alert"))
3221  ret = export_alert_omp (&connection, credentials, params, content_type,
3222  content_disposition, response_size,
3223  response_data);
3224 
3225  else if (!strcmp (cmd, "export_alerts"))
3226  ret = export_alerts_omp (&connection, credentials, params, content_type,
3227  content_disposition, response_size,
3228  response_data);
3229 
3230  else if (!strcmp (cmd, "export_asset"))
3231  ret = export_asset_omp (&connection, credentials, params, content_type,
3232  content_disposition, response_size,
3233  response_data);
3234 
3235  else if (!strcmp (cmd, "export_assets"))
3236  ret = export_assets_omp (&connection, credentials, params, content_type,
3237  content_disposition, response_size,
3238  response_data);
3239 
3240  else if (!strcmp (cmd, "export_config"))
3241  ret = export_config_omp (&connection, credentials, params, content_type,
3242  content_disposition, response_size,
3243  response_data);
3244 
3245  else if (!strcmp (cmd, "export_configs"))
3246  ret = export_configs_omp (&connection, credentials, params, content_type,
3247  content_disposition, response_size,
3248  response_data);
3249 
3250  else if (!strcmp (cmd, "download_credential"))
3251  {
3252  char *html;
3253  gchar *credential_login;
3254  const char *credential_id;
3255  const char *package_format;
3256 
3257  package_format = params_value (params, "package_format");
3258  credential_login = NULL;
3259  credential_id = params_value (params, "credential_id");
3260 
3261  if (download_credential_omp (&connection,
3262  credentials,
3263  params,
3264  response_size,
3265  &html,
3266  &credential_login,
3267  response_data))
3268  ret = html;
3269 
3270  /* Returned above if package_format was NULL. */
3271  content_type_from_format_string (content_type, package_format);
3272  g_free (*content_disposition);
3273  *content_disposition = g_strdup_printf
3274  ("attachment; filename=credential-%s.%s",
3275  (credential_login
3276  && strcmp (credential_login, ""))
3277  ? credential_login
3278  : credential_id,
3279  (strcmp (package_format, "key") == 0
3280  ? "pub"
3281  : package_format));
3282  g_free (credential_login);
3283 
3284  ret = html;
3285  }
3286 
3287  else if (!strcmp (cmd, "export_credential"))
3288  ret = export_credential_omp (&connection, credentials, params, content_type,
3289  content_disposition, response_size,
3290  response_data);
3291 
3292  else if (!strcmp (cmd, "export_credentials"))
3293  ret = export_credentials_omp (&connection, credentials, params,
3294  content_type, content_disposition,
3295  response_size, response_data);
3296 
3297  else if (!strcmp (cmd, "export_filter"))
3298  ret = export_filter_omp (&connection, credentials, params, content_type,
3299  content_disposition, response_size,
3300  response_data);
3301 
3302  else if (!strcmp (cmd, "export_filters"))
3303  ret = export_filters_omp (&connection, credentials, params, content_type,
3304  content_disposition, response_size,
3305  response_data);
3306 
3307  else if (!strcmp (cmd, "export_group"))
3308  ret = export_group_omp (&connection, credentials, params, content_type,
3309  content_disposition, response_size,
3310  response_data);
3311 
3312  else if (!strcmp (cmd, "export_groups"))
3313  ret = export_groups_omp (&connection, credentials, params, content_type,
3314  content_disposition, response_size,
3315  response_data);
3316 
3317  else if (!strcmp (cmd, "export_note"))
3318  ret = export_note_omp (&connection, credentials, params, content_type,
3319  content_disposition, response_size,
3320  response_data);
3321 
3322  else if (!strcmp (cmd, "export_notes"))
3323  ret = export_notes_omp (&connection, credentials, params, content_type,
3324  content_disposition, response_size,
3325  response_data);
3326 
3327  else if (!strcmp (cmd, "export_omp_doc"))
3328  ret = export_omp_doc_omp (&connection, credentials, params, content_type,
3329  content_disposition, response_size,
3330  response_data);
3331 
3332  else if (!strcmp (cmd, "export_override"))
3333  ret = export_override_omp (&connection, credentials, params, content_type,
3334  content_disposition, response_size,
3335  response_data);
3336 
3337  else if (!strcmp (cmd, "export_overrides"))
3338  ret = export_overrides_omp (&connection, credentials, params, content_type,
3339  content_disposition, response_size,
3340  response_data);
3341 
3342  else if (!strcmp (cmd, "export_permission"))
3343  ret = export_permission_omp (&connection, credentials, params, content_type,
3344  content_disposition, response_size,
3345  response_data);
3346 
3347  else if (!strcmp (cmd, "export_permissions"))
3348  ret = export_permissions_omp (&connection, credentials, params, content_type,
3349  content_disposition, response_size,
3350  response_data);
3351 
3352  else if (!strcmp (cmd, "export_port_list"))
3353  ret = export_port_list_omp (&connection, credentials, params, content_type,
3354  content_disposition, response_size,
3355  response_data);
3356 
3357  else if (!strcmp (cmd, "export_port_lists"))
3358  ret = export_port_lists_omp (&connection, credentials, params, content_type,
3359  content_disposition, response_size,
3360  response_data);
3361 
3362  else if (!strcmp (cmd, "export_preference_file"))
3363  ret = export_preference_file_omp (&connection, credentials, params,
3364  content_type, content_disposition,
3365  response_size, response_data);
3366 
3367  else if (!strcmp (cmd, "export_report_format"))
3368  ret = export_report_format_omp (&connection, credentials, params,
3369  content_type, content_disposition,
3370  response_size, response_data);
3371 
3372  else if (!strcmp (cmd, "export_report_formats"))
3373  ret = export_report_formats_omp (&connection, credentials, params,
3374  content_type, content_disposition,
3375  response_size, response_data);
3376 
3377  else if (!strcmp (cmd, "export_result"))
3378  ret = export_result_omp (&connection, credentials, params, content_type,
3379  content_disposition, response_size, response_data);
3380 
3381  else if (!strcmp (cmd, "export_results"))
3382  ret = export_results_omp (&connection, credentials, params, content_type,
3383  content_disposition, response_size,
3384  response_data);
3385 
3386  else if (!strcmp (cmd, "export_role"))
3387  ret = export_role_omp (&connection, credentials, params, content_type,
3388  content_disposition, response_size,
3389  response_data);
3390 
3391  else if (!strcmp (cmd, "export_roles"))
3392  ret = export_roles_omp (&connection, credentials, params, content_type,
3393  content_disposition, response_size,
3394  response_data);
3395 
3396  else if (!strcmp (cmd, "export_scanner"))
3397  ret = export_scanner_omp (&connection, credentials, params, content_type,
3398  content_disposition, response_size,
3399  response_data);
3400 
3401  else if (!strcmp (cmd, "export_scanners"))
3402  ret = export_scanners_omp (&connection, credentials, params, content_type,
3403  content_disposition, response_size,
3404  response_data);
3405 
3406  else if (!strcmp (cmd, "export_schedule"))
3407  ret = export_schedule_omp (&connection, credentials, params, content_type,
3408  content_disposition, response_size,
3409  response_data);
3410 
3411  else if (!strcmp (cmd, "export_schedules"))
3412  ret = export_schedules_omp (&connection, credentials, params, content_type,
3413  content_disposition, response_size,
3414  response_data);
3415 
3416  else if (!strcmp (cmd, "export_tag"))
3417  ret = export_tag_omp (&connection, credentials, params, content_type,
3418  content_disposition, response_size,
3419  response_data);
3420 
3421  else if (!strcmp (cmd, "export_tags"))
3422  ret = export_tags_omp (&connection, credentials, params, content_type,
3423  content_disposition, response_size,
3424  response_data);
3425 
3426  else if (!strcmp (cmd, "export_target"))
3427  ret = export_target_omp (&connection, credentials, params, content_type,
3428  content_disposition, response_size,
3429  response_data);
3430 
3431  else if (!strcmp (cmd, "export_targets"))
3432  ret = export_targets_omp (&connection, credentials, params, content_type,
3433  content_disposition, response_size,
3434  response_data);
3435 
3436  else if (!strcmp (cmd, "export_task"))
3437  ret = export_task_omp (&connection, credentials, params, content_type,
3438  content_disposition, response_size,
3439  response_data);
3440 
3441  else if (!strcmp (cmd, "export_tasks"))
3442  ret = export_tasks_omp (&connection, credentials, params, content_type,
3443  content_disposition, response_size,
3444  response_data);
3445 
3446  else if (!strcmp (cmd, "export_user"))
3447  ret = export_user_omp (&connection, credentials, params, content_type,
3448  content_disposition, response_size,
3449  response_data);
3450 
3451  else if (!strcmp (cmd, "export_users"))
3452  ret = export_users_omp (&connection, credentials, params, content_type,
3453  content_disposition, response_size,
3454  response_data);
3455 
3456  ELSE (get_agent)
3457  ELSE (get_agents)
3458  ELSE (get_asset)
3459  ELSE (get_assets)
3460 
3461  else if (!strcmp (cmd, "download_agent"))
3462  {
3463  char *html, *filename;
3464 
3465  if (download_agent_omp (&connection, credentials,
3466  params,
3467  response_size,
3468  &html,
3469  &filename,
3470  response_data))
3471  ret = html;
3472 
3473  *content_type = GSAD_CONTENT_TYPE_OCTET_STREAM;
3474  g_free (*content_disposition);
3475  *content_disposition = g_strdup_printf ("attachment; filename=%s",
3476  filename);
3477  g_free (filename);
3478 
3479  ret = html;
3480  }
3481 
3482  else if (!strcmp (cmd, "download_ssl_cert"))
3483  {
3484  *content_type = GSAD_CONTENT_TYPE_APP_KEY;
3485  g_free (*content_disposition);
3486  *content_disposition = g_strdup_printf
3487  ("attachment; filename=ssl-cert-%s.pem",
3488  params_value (params, "name"));
3489 
3490  ret = download_ssl_cert (&connection, credentials, params, response_size,
3491  response_data);
3492  }
3493 
3494  else if (!strcmp (cmd, "download_ca_pub"))
3495  {
3496  *content_type = GSAD_CONTENT_TYPE_APP_KEY;
3497  g_free (*content_disposition);
3498  *content_disposition = g_strdup_printf
3499  ("attachment; filename=scanner-ca-pub-%s.pem",
3500  params_value (params, "scanner_id"));
3501  ret = download_ca_pub (&connection, credentials, params, response_size,
3502  response_data);
3503  }
3504 
3505  else if (!strcmp (cmd, "download_key_pub"))
3506  {
3507  *content_type = GSAD_CONTENT_TYPE_APP_KEY;
3508  g_free (*content_disposition);
3509  *content_disposition = g_strdup_printf
3510  ("attachment; filename=scanner-key-pub-%s.pem",
3511  params_value (params, "scanner_id"));
3512  ret = download_key_pub (&connection, credentials, params, response_size,
3513  response_data);
3514  }
3515 
3516  ELSE (get_aggregate)
3517  ELSE (get_alert)
3518  ELSE (get_alerts)
3519  ELSE (get_credential)
3520  ELSE (get_credentials)
3521  ELSE (get_filter)
3522  ELSE (get_filters)
3523  ELSE (get_group)
3524  ELSE (get_groups)
3525  ELSE (get_info)
3526  ELSE (get_my_settings)
3527  ELSE (get_note)
3528  ELSE (get_notes)
3529  ELSE (get_override)
3530  ELSE (get_overrides)
3531  ELSE (get_permission)
3532  ELSE (get_permissions)
3533  ELSE (get_port_list)
3534  ELSE (get_port_lists)
3535 
3536  else if (!strcmp (cmd, "get_report"))
3537  {
3538  gchar *content_type_omp;
3539  ret = get_report_omp (&connection, credentials,
3540  params,
3541  response_size,
3542  &content_type_omp,
3543  content_disposition,
3544  response_data);
3545 
3546  if (content_type_omp)
3547  {
3548  *content_type = GSAD_CONTENT_TYPE_DONE;
3549  *content_type_string = content_type_omp;
3550  }
3551  }
3552 
3553  ELSE (get_reports)
3554  ELSE (get_result)
3555  ELSE (get_results)
3556  ELSE (get_report_format)
3557  ELSE (get_report_formats)
3558  ELSE (get_report_section)
3559  ELSE (get_role)
3560  ELSE (get_roles)
3561  ELSE (get_scanner)
3562  ELSE (get_scanners)
3563  ELSE (get_schedule)
3564  ELSE (get_schedules)
3565  ELSE (get_system_reports)
3566  ELSE (get_tag)
3567  ELSE (get_tags)
3568  ELSE (get_target)
3569  ELSE (get_targets)
3570  ELSE (get_trash)
3571  ELSE (get_user)
3572  ELSE (get_users)
3573  ELSE (get_feeds)
3574  ELSE (get_config)
3575  ELSE (get_configs)
3576  ELSE (get_config_family)
3577  ELSE (get_config_nvt)
3578  ELSE (get_nvts)
3579  ELSE (get_protocol_doc)
3580  ELSE (new_agent)
3581  ELSE (new_host)
3582  ELSE (new_config)
3583  ELSE (new_credential)
3584  ELSE (new_note)
3585  ELSE (new_override)
3588  ELSE (new_port_list)
3589  ELSE (new_port_range)
3590  ELSE (new_report_format)
3591  ELSE (new_scanner)
3592  ELSE (new_schedule)
3593  ELSE (upload_config)
3594  ELSE (upload_port_list)
3595  ELSE (upload_report)
3596  ELSE (sync_config)
3597  ELSE (wizard)
3598  ELSE (wizard_get)
3599 
3600  else
3601  {
3602  response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
3603  ret = gsad_message (credentials,
3604  "Internal error", __FUNCTION__, __LINE__,
3605  "An internal error occurred inside GSA daemon. "
3606  "Diagnostics: Unknown command.",
3607  "/omp?cmd=get_tasks",
3608  response_data);
3609  }
3610 
3611  if (watcher_data)
3612  {
3613  pthread_mutex_lock (&(watcher_data->mutex));
3614  if (watcher_data->connection_closed == 0
3615  || watcher_data->openvas_connection->tls)
3616  {
3617  openvas_connection_close (watcher_data->openvas_connection);
3618  }
3619  watcher_data->connection_closed = 1;
3620  pthread_mutex_unlock (&(watcher_data->mutex));
3621  pthread_cancel (watch_thread);
3622  pthread_join (watch_thread, NULL);
3623  g_free (watcher_data);
3624  }
3625  else
3626  {
3627  openvas_connection_close (&connection);
3628  }
3629 
3630  return ret;
3631 }
3632 
3636 #define EXPIRES_LENGTH 100
3637 
3646 static int
3647 attach_sid (struct MHD_Response *response, const char *sid)
3648 {
3649  int ret, timeout;
3650  gchar *value;
3651  gchar *locale;
3652  char expires[EXPIRES_LENGTH + 1];
3653  struct tm expire_time_broken;
3654  time_t now, expire_time;
3655  gchar *tz;
3656 
3657  /* Set up the expires param. */
3658 
3659  /* Store current TZ, switch to GMT. */
3660  tz = getenv ("TZ") ? g_strdup (getenv ("TZ")) : NULL;
3661  if (setenv ("TZ", "GMT", 1) == -1)
3662  {
3663  g_critical ("%s: failed to set TZ\n", __FUNCTION__);
3664  g_free (tz);
3665  exit (EXIT_FAILURE);
3666  }
3667  tzset ();
3668 
3669  locale = g_strdup (setlocale (LC_ALL, NULL));
3670  setlocale (LC_ALL, "C");
3671 
3672  timeout = session_timeout * 60 + 30;
3673 
3674  now = time (NULL);
3675  expire_time = now + timeout;
3676  if (localtime_r (&expire_time, &expire_time_broken) == NULL)
3677  abort ();
3678  ret = strftime (expires, EXPIRES_LENGTH, "%a, %d %b %Y %T GMT",
3679  &expire_time_broken);
3680  if (ret == 0)
3681  abort ();
3682 
3683  setlocale (LC_ALL, locale);
3684  g_free (locale);
3685 
3686  /* Revert to stored TZ. */
3687  if (tz)
3688  {
3689  if (setenv ("TZ", tz, 1) == -1)
3690  {
3691  g_warning ("%s: Failed to switch to original TZ", __FUNCTION__);
3692  g_free (tz);
3693  exit (EXIT_FAILURE);
3694  }
3695  }
3696  else
3697  unsetenv ("TZ");
3698  g_free (tz);
3699 
3700  /* Add the cookie.
3701  *
3702  * Tim Brown's suggested cookie included a domain attribute. How would
3703  * we get the domain in here? Maybe a --domain option. */
3704 
3705  value = g_strdup_printf (SID_COOKIE_NAME
3706  "=%s; expires=%s; max-age=%d; path=/; %sHTTPonly",
3707  sid,
3708  expires,
3709  timeout,
3710  (use_secure_cookie ? "secure; " : ""));
3711  ret = MHD_add_response_header (response, "Set-Cookie", value);
3712  g_free (value);
3713  return ret;
3714 }
3715 
3723 static int
3724 remove_sid (struct MHD_Response *response)
3725 {
3726  int ret;
3727  gchar *value;
3728  gchar *locale;
3729  char expires[EXPIRES_LENGTH + 1];
3730  struct tm expire_time_broken;
3731  time_t expire_time;
3732 
3733  /* Set up the expires param. */
3734  locale = g_strdup (setlocale (LC_ALL, NULL));
3735  setlocale (LC_ALL, "C");
3736 
3737  expire_time = time (NULL);
3738  if (localtime_r (&expire_time, &expire_time_broken) == NULL)
3739  abort ();
3740  ret = strftime (expires, EXPIRES_LENGTH, "%a, %d %b %Y %T GMT",
3741  &expire_time_broken);
3742  if (ret == 0)
3743  abort ();
3744 
3745  setlocale (LC_ALL, locale);
3746  g_free (locale);
3747 
3748  /* Add the cookie.
3749  *
3750  * Tim Brown's suggested cookie included a domain attribute. How would
3751  * we get the domain in here? Maybe a --domain option. */
3752 
3753  value = g_strdup_printf (SID_COOKIE_NAME "=0; expires=%s; path=/; %sHTTPonly",
3754  expires,
3755  (use_secure_cookie ? "secure; " : ""));
3756  ret = MHD_add_response_header (response, "Set-Cookie", value);
3757  g_free (value);
3758  return ret;
3759 }
3760 
3770 static void
3771 gsad_add_content_type_header (struct MHD_Response *response,
3772  enum content_type* ct)
3773 {
3774  if (!response)
3775  return;
3776 
3777  switch (*ct)
3778  {
3780  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3781  "application/deb");
3782  break;
3784  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3785  "application/exe");
3786  break;
3788  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3789  "application/html");
3790  break;
3792  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3793  "application/key");
3794  break;
3796  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3797  "application/nbe");
3798  break;
3800  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3801  "application/pdf");
3802  break;
3804  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3805  "application/rpm");
3806  break;
3808  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3809  "application/xml; charset=utf-8");
3810  break;
3812  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3813  "image/png");
3814  break;
3816  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3817  "image/svg+xml");
3818  break;
3820  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3821  "application/octet-stream");
3822  break;
3824  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3825  "text/css");
3826  break;
3828  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3829  "text/html; charset=utf-8");
3830  break;
3832  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3833  "text/javascript");
3834  break;
3836  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3837  "text/plain; charset=utf-8");
3838  break;
3840  break;
3841  default:
3842  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3843  "text/plain; charset=utf-8");
3844  break;
3845  }
3846 }
3847 
3855 void
3856 add_local_addresses (GHashTable *hashtable, int include_ipv6,
3857  int localhost_only)
3858 {
3859  struct ifaddrs *ifaddr, *ifa;
3860  int family, ret;
3861  char host[NI_MAXHOST];
3862 
3863  // Basic loopback addresses
3864  g_hash_table_add (gsad_header_hosts, g_strdup ("localhost"));
3865  g_hash_table_add (gsad_header_hosts, g_strdup ("127.0.0.1"));
3866  if (include_ipv6)
3867  g_hash_table_add (gsad_header_hosts, g_strdup ("::1"));
3868 
3869  // Other interface addresses
3870  if (localhost_only == 0 && getifaddrs(&ifaddr) != -1)
3871  {
3872  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
3873  {
3874  if (ifa->ifa_addr == NULL)
3875  continue;
3876 
3877  family = ifa->ifa_addr->sa_family;
3878 
3879  if (family == AF_INET || (include_ipv6 && family == AF_INET6))
3880  {
3881  ret = getnameinfo(ifa->ifa_addr,
3882  (family == AF_INET)
3883  ? sizeof(struct sockaddr_in)
3884  : sizeof(struct sockaddr_in6),
3885  host, NI_MAXHOST,
3886  NULL, 0, NI_NUMERICHOST);
3887  if (ret != 0) {
3888  g_warning ("%s: getnameinfo() failed: %s\n",
3889  __FUNCTION__, gai_strerror(ret));
3890  return;
3891  }
3892 
3893  g_hash_table_insert (hashtable, g_strdup (host), NULL);
3894  }
3895  }
3896  freeifaddrs(ifaddr);
3897  }
3898 }
3899 
3907 static int
3908 host_is_gsad (const char *host)
3909 {
3910  if (host == NULL)
3911  return 0;
3912 
3913  return host ? g_hash_table_contains (gsad_header_hosts, host) : 0;
3914 }
3915 
3923 static int
3924 validate_host_header (const char *host_header)
3925 {
3926  int ret;
3927  int char_index, colon_index, bracket_index;
3928  gchar *host;
3929 
3930  if (host_header == NULL || strlen (host_header) == 0)
3931  return 2;
3932  else if (g_utf8_validate (host_header, -1, NULL) == FALSE)
3933  return 1;
3934 
3935  /*
3936  * Find brackets and colons for detecting IPv6 addresses and port.
3937  */
3938  bracket_index = -1;
3939  colon_index = -1;
3940  for (char_index = strlen (host_header) - 1;
3941  char_index >= 0;
3942  char_index --)
3943  {
3944  if (host_header[char_index] == ']' && bracket_index == -1)
3945  bracket_index = char_index;
3946  if (host_header[char_index] == ':' && colon_index == -1)
3947  colon_index = char_index;
3948  }
3949 
3950  if (bracket_index != -1 && host_header[0] == '['
3951  && (colon_index == bracket_index + 1 || colon_index < bracket_index))
3952  {
3953  /*
3954  * IPv6 address which starts with a square bracket and
3955  * where the last colon is right after a closing bracket,
3956  * e.g. "[::1]:9392" -> "::1" or inside brackets, e.g. "[::1]" -> "::1".
3957  */
3958  host = g_strndup (host_header + 1, bracket_index - 1);
3959  }
3960  else if (colon_index > 0 && bracket_index == -1)
3961  {
3962  /*
3963  * Hostname or IPv4 address (no brackets) with a port after the colon,
3964  * e.g. "127.0.0.1:9393" -> "127.0.0.1".
3965  */
3966  host = g_strndup (host_header, colon_index);
3967  }
3968  else if (colon_index == -1 && bracket_index == -1)
3969  {
3970  /*
3971  * Hostname or IPv4 address (no brackets) without any colon for a port,
3972  * e.g. "127.0.0.1".
3973  */
3974  host = g_strdup (host_header);
3975  }
3976  else
3977  {
3978  /*
3979  * Invalid because colon or brackets are in unexpected places.
3980  */
3981  host = NULL;
3982  }
3983 
3984  g_debug ("%s: header: '%s' -> host: '%s'", __FUNCTION__, host_header, host);
3985 
3986  ret = host_is_gsad (host) ? 0 : 2;
3987  g_free (host);
3988 
3989  return ret;
3990 }
3991 
4005 int
4006 send_response (struct MHD_Connection *connection, const char *content,
4007  int status_code, const gchar *sid,
4009  const char *content_disposition,
4010  size_t content_length)
4011 {
4012  struct MHD_Response *response;
4013  size_t size = (content_length ? content_length : strlen (content));
4014  int ret;
4015 
4016  response = MHD_create_response_from_buffer (size, (void *) content,
4017  MHD_RESPMEM_MUST_COPY);
4018  gsad_add_content_type_header (response, &content_type);
4019 
4020  if (content_disposition)
4021  MHD_add_response_header (response, "Content-Disposition",
4022  content_disposition);
4023 
4024  if (sid)
4025  {
4026  if (strcmp (sid, "0"))
4027  {
4028  if (attach_sid (response, sid) == MHD_NO)
4029  {
4030  MHD_destroy_response (response);
4031  return MHD_NO;
4032  }
4033  }
4034  else
4035  {
4036  if (remove_sid (response) == MHD_NO)
4037  {
4038  MHD_destroy_response (response);
4039  return MHD_NO;
4040  }
4041  }
4042  }
4043  add_security_headers (response);
4044  ret = MHD_queue_response (connection, status_code, response);
4045  MHD_destroy_response (response);
4046  return ret;
4047 }
4048 
4058 int
4059 send_redirect_to_uri (struct MHD_Connection *connection, const char *uri,
4060  user_t *user)
4061 {
4062  int ret;
4063  struct MHD_Response *response;
4064  char *body;
4065 
4066  /* Some libmicrohttp versions get into an endless loop in https mode
4067  if an empty body is passed. As a workaround and because it is
4068  anyway suggested by the HTTP specs, we provide a short body. We
4069  assume that uri does not need to be quoted. */
4070  body = g_strdup_printf ("<html><body>Code 303 - Redirecting to"
4071  " <a href=\"%s\">%s<a/></body></html>\n",
4072  uri, uri);
4073  response = MHD_create_response_from_buffer (strlen (body), body,
4074  MHD_RESPMEM_MUST_FREE);
4075 
4076  if (!response)
4077  {
4078  g_warning ("%s: failed to create response, dropping request",
4079  __FUNCTION__);
4080  return MHD_NO;
4081  }
4082  ret = MHD_add_response_header (response, MHD_HTTP_HEADER_LOCATION, uri);
4083  if (!ret)
4084  {
4085  MHD_destroy_response (response);
4086  g_warning ("%s: failed to add location header, dropping request",
4087  __FUNCTION__);
4088  return MHD_NO;
4089  }
4090 
4091  if (user)
4092  {
4093  if (attach_sid (response, user->cookie) == MHD_NO)
4094  {
4095  MHD_destroy_response (response);
4096  g_warning ("%s: failed to attach SID, dropping request",
4097  __FUNCTION__);
4098  return MHD_NO;
4099  }
4100  }
4101 
4102  MHD_add_response_header (response, MHD_HTTP_HEADER_EXPIRES, "-1");
4103  MHD_add_response_header (response, MHD_HTTP_HEADER_CACHE_CONTROL, "no-cache");
4104 
4105  add_security_headers (response);
4106  ret = MHD_queue_response (connection, MHD_HTTP_SEE_OTHER, response);
4107  MHD_destroy_response (response);
4108  return ret;
4109 }
4110 
4111 #undef MAX_HOST_LEN
4112 
4116 #define MAX_HOST_LEN 1000
4117 
4127 int
4128 send_redirect_to_urn (struct MHD_Connection *connection, const char *urn,
4129  user_t *user)
4130 {
4131  const char *host, *protocol;
4132  char uri[MAX_HOST_LEN];
4133 
4134  host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
4135  MHD_HTTP_HEADER_HOST);
4136 
4137  switch (validate_host_header (host))
4138  {
4139  case 0:
4140  // Header is valid
4141  break;
4142  case 1:
4143  // Invalid UTF-8
4144  send_response (connection,
4145  UTF8_ERROR_PAGE ("'Host' header"),
4146  MHD_HTTP_BAD_REQUEST, NULL,
4147  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4148  return MHD_YES;
4149  case 2:
4150  default:
4151  // Otherwise invalid
4152  send_response (connection,
4154  MHD_HTTP_BAD_REQUEST, NULL,
4155  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4156  return MHD_YES;
4157  }
4158 
4159  protocol = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
4160  "X-Forwarded-Protocol");
4161  if (protocol && g_utf8_validate (protocol, -1, NULL) == FALSE)
4162  {
4163  send_response (connection,
4164  UTF8_ERROR_PAGE ("'X-Forwarded-Protocol' header"),
4165  MHD_HTTP_BAD_REQUEST, NULL,
4166  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4167  return MHD_YES;
4168  }
4169  else if ((protocol == NULL)
4170  || (strcmp(protocol, "http") && strcmp(protocol, "https")))
4171  {
4172  if (use_secure_cookie)
4173  protocol = "https";
4174  else
4175  protocol = "http";
4176  }
4177 
4178  snprintf (uri, sizeof (uri), "%s://%s%s", protocol, host, urn);
4179  return send_redirect_to_uri (connection, uri, user);
4180 }
4181 
4200 int
4201 redirect_handler (void *cls, struct MHD_Connection *connection,
4202  const char *url, const char *method,
4203  const char *version, const char *upload_data,
4204  size_t *upload_data_size, void **con_cls)
4205 {
4206  gchar *location;
4207  const char *host;
4208  char name[MAX_HOST_LEN + 1];
4209 
4210  /* Never respond on first call of a GET. */
4211  if ((!strcmp (method, "GET")) && *con_cls == NULL)
4212  {
4213  struct gsad_connection_info *con_info;
4214 
4215  /* Freed by MHD_OPTION_NOTIFY_COMPLETED callback, free_resources. */
4216  con_info = g_malloc0 (sizeof (struct gsad_connection_info));
4217  con_info->params = params_new ();
4218  con_info->connectiontype = 2;
4219 
4220  *con_cls = (void *) con_info;
4221  return MHD_YES;
4222  }
4223 
4224  /* If called with undefined URL, abort request handler. */
4225  if (&url[0] == NULL)
4226  return MHD_NO;
4227 
4228  /* Only accept GET and POST methods and send ERROR_PAGE in other cases. */
4229  if (strcmp (method, "GET") && strcmp (method, "POST"))
4230  {
4232  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4233  return MHD_YES;
4234  }
4235 
4236  /* Redirect every URL to the default file on the HTTPS port. */
4237  host = MHD_lookup_connection_value (connection,
4238  MHD_HEADER_KIND,
4239  "Host");
4240  switch (validate_host_header (host))
4241  {
4242  case 0:
4243  // Header is valid
4244  break;
4245  case 1:
4246  // Invalid UTF-8
4247  send_response (connection,
4248  UTF8_ERROR_PAGE ("'Host' header"),
4249  MHD_HTTP_BAD_REQUEST, NULL,
4250  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4251  return MHD_YES;
4252  case 2:
4253  default:
4254  // Otherwise invalid
4255  send_response (connection,
4257  MHD_HTTP_BAD_REQUEST, NULL,
4258  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4259  return MHD_YES;
4260  }
4261  /* [IPv6 or IPv4-mapped IPv6]:port */
4262  if (sscanf (host, "[%" G_STRINGIFY(MAX_HOST_LEN) "[0-9a-f:.]]:%*i", name)
4263  == 1)
4264  {
4265  char *name6 = g_strdup_printf ("[%s]", name);
4266  location = g_strdup_printf (redirect_location, name6);
4267  g_free (name6);
4268  }
4269  /* IPv4:port */
4270  else if (sscanf (host, "%" G_STRINGIFY(MAX_HOST_LEN) "[^:]:%*i", name) == 1)
4271  location = g_strdup_printf (redirect_location, name);
4272  else
4273  location = g_strdup_printf (redirect_location, host);
4274  if (send_redirect_to_uri (connection, location, NULL) == MHD_NO)
4275  {
4276  g_free (location);
4277  return MHD_NO;
4278  }
4279  g_free (location);
4280  return MHD_YES;
4281 }
4282 
4286 #define DATE_2822_LEN 100
4287 
4288 #ifdef SERVE_STATIC_ASSETS
4289 
4305 static struct MHD_Response*
4306 file_content_response (credentials_t *credentials,
4307  struct MHD_Connection *connection, const char* url,
4308  int* http_response_code, enum content_type* content_type,
4309  char** content_disposition)
4310 {
4311  FILE* file;
4312  gchar* path;
4313  char *default_file = "login/login.html";
4314  struct MHD_Response* response;
4315  char date_2822[DATE_2822_LEN];
4316  struct tm *mtime;
4317  time_t next_week;
4318  cmd_response_data_t response_data;
4319 
4320  cmd_response_data_init (&response_data);
4321 
4325  /* Attempt to prevent disclosing non-gsa content. */
4326  if (strstr (url, ".."))
4327  path = g_strconcat (default_file, NULL);
4328  else
4329  {
4330  /* Ensure that url is relative. */
4331  const char* relative_url = url;
4332  if (*url == '/') relative_url = url + 1;
4333  path = g_strconcat (relative_url, NULL);
4334  }
4335 
4336  file = fopen (path, "r"); /* this file is just read and sent */
4337 
4338  if (file == NULL)
4339  {
4340  g_debug ("File %s failed, ", path);
4341  g_free (path);
4342  struct MHD_Response *response;
4343 
4344  *http_response_code = MHD_HTTP_NOT_FOUND;
4345  cmd_response_data_reset (&response_data);
4346  gchar *msg = gsad_message (NULL,
4347  NOT_FOUND_TITLE, NULL, 0,
4349  "/login/login.html", NULL);
4350  response = MHD_create_response_from_buffer (strlen (msg),
4351  (void *) msg,
4352  MHD_RESPMEM_MUST_COPY);
4353  g_free (msg);
4354  return response;
4355  }
4356 
4357  /* Guess content type. */
4358  if (strstr (path, ".png"))
4359  *content_type = GSAD_CONTENT_TYPE_IMAGE_PNG;
4360  else if (strstr (path, ".svg"))
4361  *content_type = GSAD_CONTENT_TYPE_IMAGE_SVG;
4362  else if (strstr (path, ".html"))
4363  *content_type = GSAD_CONTENT_TYPE_TEXT_HTML;
4364  else if (strstr (path, ".css"))
4365  *content_type = GSAD_CONTENT_TYPE_TEXT_CSS;
4366  else if (strstr (path, ".js"))
4367  *content_type = GSAD_CONTENT_TYPE_TEXT_JS;
4368  else if (strstr (path, ".txt"))
4369  *content_type = GSAD_CONTENT_TYPE_TEXT_PLAIN;
4372  struct stat buf;
4373  g_debug ("Default file successful.\n");
4374  if (stat (path, &buf))
4375  {
4376  /* File information could not be retrieved. */
4377  g_critical ("%s: file <%s> can not be stat'ed.\n",
4378  __FUNCTION__,
4379  path);
4380  g_free (path);
4381  fclose (file);
4382  return NULL;
4383  }
4384 
4385  /* Make sure the requested path really is a file. */
4386  if ((buf.st_mode & S_IFMT) != S_IFREG)
4387  {
4388  struct MHD_Response *ret;
4389  response_data.http_status_code = MHD_HTTP_NOT_FOUND;
4390  char *res = gsad_message (NULL,
4391  NOT_FOUND_TITLE, NULL, 0,
4393  NULL, &response_data);
4394  *http_response_code = response_data.http_status_code;
4395  g_free (path);
4396  fclose (file);
4397  cmd_response_data_reset (&response_data);
4398  ret = MHD_create_response_from_buffer (strlen (res), (void *) res,
4399  MHD_RESPMEM_MUST_FREE);
4400  return ret;
4401  }
4402 
4403  response = MHD_create_response_from_callback (buf.st_size, 32 * 1024,
4404  (MHD_ContentReaderCallback) &file_reader,
4405  file,
4406  (MHD_ContentReaderFreeCallback)
4407  &fclose);
4408 
4409  mtime = localtime (&buf.st_mtime);
4410  if (mtime
4411  && strftime (date_2822, DATE_2822_LEN, "%a, %d %b %Y %H:%M:%S %Z", mtime))
4412  {
4413  MHD_add_response_header (response, "Last-Modified", date_2822);
4414  }
4415 
4416  next_week = time (NULL) + 7 * 24 * 60 * 60;
4417  mtime = localtime (&next_week);
4418  if (mtime
4419  && strftime (date_2822, DATE_2822_LEN, "%a, %d %b %Y %H:%M:%S %Z", mtime))
4420  {
4421  MHD_add_response_header (response, "Expires", date_2822);
4422  }
4423 
4424  g_free (path);
4425  *http_response_code = response_data.http_status_code;
4426  cmd_response_data_reset (&response_data);
4427  return response;
4428 }
4429 #endif
4430 
4443 static int
4444 handler_send_response (struct MHD_Connection *connection,
4445  struct MHD_Response *response,
4446  enum content_type *content_type,
4447  char *content_disposition,
4448  int http_response_code,
4449  int remove_cookie)
4450 {
4451  int ret;
4452 
4453  if (remove_cookie)
4454  if (remove_sid (response) == MHD_NO)
4455  {
4456  MHD_destroy_response (response);
4457  g_warning ("%s: failed to remove SID, dropping request",
4458  __FUNCTION__);
4459  return MHD_NO;
4460  }
4461  gsad_add_content_type_header (response, content_type);
4462  if (content_disposition != NULL)
4463  {
4464  MHD_add_response_header (response, "Content-Disposition",
4465  content_disposition);
4466  g_free (content_disposition);
4467  }
4468  ret = MHD_queue_response (connection, http_response_code, response);
4469  if (ret == MHD_NO)
4470  {
4471  /* Assume this was due to a bad request, to keep the MHD "Internal
4472  * application error" out of the log. */
4474  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4475  return MHD_YES;
4476  }
4477  MHD_destroy_response (response);
4478  return ret;
4479 }
4480 
4491 static int
4492 append_param (void *string, enum MHD_ValueKind kind, const char *key,
4493  const char *value)
4494 {
4495  if (value == NULL)
4496  /* http://foo/bar?key */
4497  return MHD_YES;
4498  if (key == NULL)
4499  {
4500  assert (0);
4501  return MHD_YES;
4502  }
4503  /* http://foo/bar?key=value */
4504  if (strcmp (key, "token") && strcmp (key, "r"))
4505  {
4506  g_string_append ((GString*) string, key);
4507  g_string_append ((GString*) string, "=");
4508  g_string_append ((GString*) string, value);
4509  g_string_append ((GString*) string, "&");
4510  }
4511  return MHD_YES;
4512 }
4513 
4522 static gchar *
4523 reconstruct_url (struct MHD_Connection *connection, const char *url)
4524 {
4525  GString *full_url;
4526 
4527  full_url = g_string_new (url);
4528  /* To simplify appending the token later, ensure there is at least
4529  * one param. */
4530  g_string_append (full_url, "?r=1&");
4531 
4532  MHD_get_connection_values (connection, MHD_GET_ARGUMENT_KIND,
4533  append_param, full_url);
4534 
4535  if (full_url->str[strlen (full_url->str) - 1] == '&')
4536  full_url->str[strlen (full_url->str) - 1] = '\0';
4537 
4538  return g_string_free (full_url, FALSE);
4539 }
4540 
4550 static int
4551 get_client_address (struct MHD_Connection *conn, char *client_address)
4552 {
4553  const char* x_real_ip;
4554 
4555  /* First try X-Real-IP header (unless told to ignore), then MHD connection. */
4556 
4557  x_real_ip = MHD_lookup_connection_value (conn,
4558  MHD_HEADER_KIND,
4559  "X-Real-IP");
4560 
4562  && x_real_ip && g_utf8_validate (x_real_ip, -1, NULL) == FALSE)
4563  return 1;
4564  else if (!ignore_http_x_real_ip && x_real_ip != NULL)
4565  strncpy (client_address, x_real_ip, INET6_ADDRSTRLEN);
4566  else if (unix_socket)
4567  strncpy (client_address, "unix_socket", INET6_ADDRSTRLEN);
4568  else
4569  {
4570  const union MHD_ConnectionInfo* info;
4571 
4572  info = MHD_get_connection_info (conn, MHD_CONNECTION_INFO_CLIENT_ADDRESS);
4573  sockaddr_as_str ((struct sockaddr_storage *) info->client_addr,
4574  client_address);
4575  }
4576  return 0;
4577 }
4578 
4597 int
4598 handle_request (void *cls, struct MHD_Connection *connection,
4599  const char *url, const char *method,
4600  const char *version, const char *upload_data,
4601  size_t * upload_data_size, void **con_cls)
4602 {
4603  const char *url_base = "/";
4604  char *default_file = "/login/login.html", client_address[INET6_ADDRSTRLEN];
4606  char *content_disposition = NULL;
4607  gsize response_size = 0;
4608  int http_response_code = MHD_HTTP_OK;
4609  const char *xml_flag = NULL;
4610  int ret;
4611  openvas_connection_t con;
4612 
4613  /* Never respond on first call of a GET. */
4614  if ((!strcmp (method, "GET")) && *con_cls == NULL)
4615  {
4616  struct gsad_connection_info *con_info;
4617 
4618  /* First call for this request, a GET. */
4619 
4620  /* Freed by MHD_OPTION_NOTIFY_COMPLETED callback, free_resources. */
4621  con_info = g_malloc0 (sizeof (struct gsad_connection_info));
4622  con_info->params = params_new ();
4623  con_info->connectiontype = 2;
4624 
4625  *con_cls = (void *) con_info;
4626  return MHD_YES;
4627  }
4628 
4629  /* If called with undefined URL, abort request handler. */
4630  if (&url[0] == NULL)
4631  {
4633  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4634  return MHD_YES;
4635  }
4636 
4637  /* Prevent guest link from leading to URL redirection. */
4638  if (url && (url[0] == '/') && (url[1] == '/'))
4639  {
4640  gchar *msg = gsad_message (NULL,
4641  NOT_FOUND_TITLE, NULL, 0,
4643  "/login/login.html", NULL);
4644  send_response (connection, msg, MHD_HTTP_NOT_FOUND,
4645  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4646  g_free (msg);
4647  return MHD_YES;
4648  }
4649 
4650  /* Many Glib functions require valid UTF-8. */
4651  if (url && (g_utf8_validate (url, -1, NULL) == FALSE))
4652  {
4653  send_response (connection,
4654  UTF8_ERROR_PAGE ("URL"),
4655  MHD_HTTP_BAD_REQUEST, NULL,
4656  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4657  return MHD_YES;
4658  }
4659 
4660  /* Only accept GET and POST methods and send ERROR_PAGE in other cases. */
4661  if (strcmp (method, "GET") && strcmp (method, "POST"))
4662  {
4663  send_response (connection, ERROR_PAGE, MHD_HTTP_METHOD_NOT_ALLOWED,
4664  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4665  return MHD_YES;
4666  }
4667 
4668  /* Redirect the base URL to the login page. Serve the login page
4669  * even if the user is already logged in.
4670  *
4671  * This might make users think that they have been logged out. The only
4672  * way to logout, however, is with a token. I guess this is where a cookie
4673  * would be useful. */
4674 
4675  g_debug ("============= url: %s\n", reconstruct_url (connection, url));
4676 
4677  if (!strcmp (&url[0], url_base))
4678  {
4679  return send_redirect_to_urn (connection, default_file, NULL);
4680  }
4681 
4682  if ((!strcmp (method, "GET"))
4683  && (!strncmp (&url[0], "/login/", strlen ("/login/")))
4684  && !url[strlen ("/login/")])
4685  {
4686  return send_redirect_to_urn (connection, default_file, NULL);
4687  }
4688 
4689  /* Set HTTP Header values. */
4690 
4691  if (!strcmp (method, "GET"))
4692  {
4693  const char *token, *cookie, *accept_language, *xml_flag;
4694  const char *omp_cgi_base = "/omp";
4695  gchar *language;
4696  struct MHD_Response *response;
4697  credentials_t *credentials;
4698  user_t *user;
4699  gchar *sid;
4700  char *res;
4701 
4702  token = NULL;
4703  cookie = NULL;
4704 
4705  xml_flag = MHD_lookup_connection_value (connection,
4706  MHD_GET_ARGUMENT_KIND,
4707  "xml");
4708 
4709  /* Second or later call for this request, a GET. */
4710 
4711  content_type = GSAD_CONTENT_TYPE_TEXT_HTML;
4712 
4713  /* Special case the login page, stylesheet and icon. */
4714 
4715  if (!strcmp (url, default_file))
4716  {
4717  time_t now;
4718  gchar *xml;
4719  char *res;
4720  char ctime_now[200];
4721  const char* accept_language;
4722  gchar *language;
4723  cmd_response_data_t response_data;
4724  cmd_response_data_init (&response_data);
4725 
4726  now = time (NULL);
4727  ctime_r_strip_newline (&now, ctime_now);
4728 
4729  accept_language = MHD_lookup_connection_value (connection,
4730  MHD_HEADER_KIND,
4731  "Accept-Language");
4732  if (accept_language
4733  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
4734  {
4735  send_response (connection,
4736  UTF8_ERROR_PAGE ("'Accept-Language' header"),
4737  MHD_HTTP_BAD_REQUEST, NULL,
4738  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4739  return MHD_YES;
4740  }
4741  language = accept_language_to_env_fmt (accept_language);
4742  xml = login_xml (NULL,
4743  NULL,
4744  ctime_now,
4745  NULL,
4746  language,
4748  g_free (language);
4749  if (xml_flag && strcmp (xml_flag, "0"))
4750  res = xml;
4751  else
4752  {
4753  res = xsl_transform (xml, &response_data);
4754  g_free (xml);
4755  }
4756  response = MHD_create_response_from_buffer (strlen (res), res,
4757  MHD_RESPMEM_MUST_FREE);
4758  add_security_headers (response);
4759  cmd_response_data_reset (&response_data);
4760  return handler_send_response (connection,
4761  response,
4762  &content_type,
4763  content_disposition,
4764  http_response_code,
4765  1);
4766  }
4767 
4768 #ifdef SERVE_STATIC_ASSETS
4769 
4770  if (!strcmp (url, "/favicon.ico")
4771  || !strcmp (url, "/favicon.gif")
4772  || !strcmp (url, "/robots.txt"))
4773  {
4774  response = file_content_response (NULL,
4775  connection, url,
4776  &http_response_code,
4777  &content_type,
4778  &content_disposition);
4779  add_security_headers (response);
4780  return handler_send_response (connection,
4781  response,
4782  &content_type,
4783  content_disposition,
4784  http_response_code,
4785  0);
4786  }
4787 
4788  /* Allow the decorative images and scripts to anyone. */
4789 
4790  if (strncmp (url, "/img/", strlen ("/img/")) == 0
4791  || strncmp (url, "/js/", strlen ("/js/")) == 0
4792  || strncmp (url, "/css/", strlen ("/css/")) == 0)
4793  {
4794  response = file_content_response (NULL,
4795  connection, url,
4796  &http_response_code,
4797  &content_type,
4798  &content_disposition);
4799  add_security_headers (response);
4800  return handler_send_response (connection,
4801  response,
4802  &content_type,
4803  content_disposition,
4804  http_response_code,
4805  0);
4806  }
4807 #endif
4808 
4809  /* Setup credentials from token. */
4810 
4811  token = MHD_lookup_connection_value (connection,
4812  MHD_GET_ARGUMENT_KIND,
4813  "token");
4814  if (token == NULL)
4815  {
4816  g_debug ("%s: Missing token in arguments", __FUNCTION__);
4817  cookie = NULL;
4818  ret = USER_BAD_MISSING_TOKEN;
4819  }
4820  else
4821  {
4822  if (openvas_validate (validator, "token", token))
4823  token = NULL;
4824 
4825  cookie = MHD_lookup_connection_value (connection,
4826  MHD_COOKIE_KIND,
4827  SID_COOKIE_NAME);
4828  if (openvas_validate (validator, "token", cookie))
4829  cookie = NULL;
4830 
4831  get_client_address (connection, client_address);
4832  ret = get_client_address (connection, client_address);
4833  if (ret == 1)
4834  {
4835  send_response (connection,
4836  UTF8_ERROR_PAGE ("'X-Real-IP' header"),
4837  MHD_HTTP_BAD_REQUEST, NULL,
4838  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4839  return MHD_YES;
4840  }
4841 
4842  ret = user_find (cookie, token, client_address, &user);
4843  }
4844 
4845  if (ret == USER_BAD_TOKEN || ret == USER_GUEST_LOGIN_FAILED
4846  || ret == USER_OMP_DOWN || ret == USER_GUEST_LOGIN_ERROR)
4847  {
4848  cmd_response_data_t response_data;
4849  cmd_response_data_init (&response_data);
4850  if (ret == 1)
4851  {
4852  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
4853  res = gsad_message (NULL,
4854  "Internal error", __FUNCTION__, __LINE__,
4855  "An internal error occurred inside GSA daemon. "
4856  "Diagnostics: Bad token.",
4857  "/omp?cmd=get_tasks", &response_data);
4858  }
4859  else
4860  {
4861  time_t now;
4862  gchar *xml;
4863  char ctime_now[200];
4864 
4865  now = time (NULL);
4866  ctime_r_strip_newline (&now, ctime_now);
4867 
4868  accept_language = MHD_lookup_connection_value (connection,
4869  MHD_HEADER_KIND,
4870  "Accept-Language");
4871  if (accept_language
4872  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
4873  {
4874  send_response (connection,
4875  UTF8_ERROR_PAGE ("'Accept-Language' header"),
4876  MHD_HTTP_BAD_REQUEST, NULL,
4877  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4878  return MHD_YES;
4879  }
4880  language = accept_language_to_env_fmt (accept_language);
4881  xml = login_xml (ret == 6
4882  ? "Login failed. OMP service is down."
4883  : (ret == -1
4884  ? "Login failed. Error during authentication."
4885  : "Login failed."),
4886  NULL,
4887  ctime_now,
4888  NULL,
4889  language,
4891  response_data.http_status_code = MHD_HTTP_SERVICE_UNAVAILABLE;
4892  g_free (language);
4893  if (xml_flag && strcmp (xml_flag, "0"))
4894  res = xml;
4895  else
4896  {
4897  res = xsl_transform (xml, &response_data);
4898  g_free (xml);
4899  }
4900  }
4901  response = MHD_create_response_from_buffer (strlen (res), res,
4902  MHD_RESPMEM_MUST_FREE);
4903  http_response_code = response_data.http_status_code;
4904  add_security_headers (response);
4905  cmd_response_data_reset (&response_data);
4906  return handler_send_response (connection,
4907  response,
4908  &content_type,
4909  content_disposition,
4910  http_response_code,
4911  1);
4912  }
4913 
4914  if ((ret == USER_EXPIRED_TOKEN) || (ret == USER_BAD_MISSING_COOKIE)
4915  || (ret == USER_BAD_MISSING_TOKEN)
4916  || (ret == USER_IP_ADDRESS_MISSMATCH))
4917  {
4918  time_t now;
4919  gchar *xml;
4920  char *res;
4921  gchar *full_url;
4922  char ctime_now[200];
4923  const char *cmd;
4924  int export;
4925  cmd_response_data_t response_data;
4926  cmd_response_data_init (&response_data);
4927 
4928  now = time (NULL);
4929  ctime_r_strip_newline (&now, ctime_now);
4930 
4931  cmd = MHD_lookup_connection_value (connection,
4932  MHD_GET_ARGUMENT_KIND,
4933  "cmd");
4934 
4935  export = 0;
4936  if (cmd && g_utf8_validate (cmd, -1, NULL))
4937  {
4938  if (strncmp (cmd, "export", strlen ("export")) == 0)
4939  export = 1;
4940  else if (strcmp (cmd, "get_report") == 0)
4941  {
4942  const char *report_format_id;
4943 
4944  report_format_id = MHD_lookup_connection_value
4945  (connection,
4946  MHD_GET_ARGUMENT_KIND,
4947  "report_format_id");
4948  if (report_format_id
4949  && g_utf8_validate (report_format_id, -1, NULL))
4950  export = 1;
4951  }
4952  }
4953 
4954  accept_language = MHD_lookup_connection_value (connection,
4955  MHD_HEADER_KIND,
4956  "Accept-Language");
4957  if (accept_language
4958  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
4959  {
4960  send_response (connection,
4961  UTF8_ERROR_PAGE ("'Accept-Language' header"),
4962  MHD_HTTP_BAD_REQUEST, NULL,
4963  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4964  return MHD_YES;
4965  }
4966  language = accept_language_to_env_fmt (accept_language);
4967 
4968  if ((export == 0) && strncmp (url, "/logout", strlen ("/logout")))
4969  {
4970  full_url = reconstruct_url (connection, url);
4971  if (full_url && g_utf8_validate (full_url, -1, NULL) == FALSE)
4972  {
4973  g_free (full_url);
4974  full_url = NULL;
4975  }
4976  }
4977  else
4978  full_url = NULL;
4979 
4980  if (ret == USER_EXPIRED_TOKEN)
4981  {
4982  if (strncmp (url, "/logout", strlen ("/logout")))
4983  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
4984  else
4985  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
4986  }
4987  else
4988  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
4989 
4990  xml = login_xml
4991  ((ret == USER_EXPIRED_TOKEN)
4992  ? (strncmp (url, "/logout", strlen ("/logout"))
4993  ? "Session has expired. Please login again."
4994  : "Already logged out.")
4995  : ((ret == USER_BAD_MISSING_COOKIE)
4996  ? "Cookie missing or bad. Please login again."
4997  : "Token missing or bad. Please login again."),
4998  NULL,
4999  ctime_now,
5000  full_url ? full_url : "",
5001  language,
5003 
5004  g_free (language);
5005  g_free (full_url);
5006  if (xml_flag && strcmp (xml_flag, "0"))
5007  res = xml;
5008  else
5009  {
5010  res = xsl_transform (xml, &response_data);
5011  g_free (xml);
5012  }
5013 
5014  http_response_code = response_data.http_status_code;
5015  response = MHD_create_response_from_buffer (strlen (res), res,
5016  MHD_RESPMEM_MUST_FREE);
5017  add_security_headers (response);
5018  cmd_response_data_reset (&response_data);
5019  return handler_send_response (connection,
5020  response,
5021  &content_type,
5022  content_disposition,
5023  http_response_code,
5024  1);
5025  }
5026 
5027  if (ret)
5028  abort ();
5029 
5030  /* From here on, the user is authenticated. */
5031 
5032  if (!strncmp (url, "/logout", strlen ("/logout")))
5033  {
5034  time_t now;
5035  gchar *xml;
5036  char ctime_now[200];
5037  cmd_response_data_t response_data;
5038  cmd_response_data_init (&response_data);
5039 
5040  now = time (NULL);
5041  ctime_r_strip_newline (&now, ctime_now);
5042 
5043  user_remove (user);
5044 
5045  accept_language = MHD_lookup_connection_value (connection,
5046  MHD_HEADER_KIND,
5047  "Accept-Language");
5048  if (accept_language
5049  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
5050  {
5051  send_response (connection,
5052  UTF8_ERROR_PAGE ("'Accept-Language' header"),
5053  MHD_HTTP_BAD_REQUEST, NULL,
5054  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
5055  return MHD_YES;
5056  }
5057  language = accept_language_to_env_fmt (accept_language);
5058  xml = login_xml ("Successfully logged out.",
5059  NULL,
5060  ctime_now,
5061  NULL,
5062  language,
5064  g_free (language);
5065  http_response_code = response_data.http_status_code;
5066  if (xml_flag && strcmp (xml_flag, "0"))
5067  res = xml;
5068  else
5069  {
5070  res = xsl_transform (xml, &response_data);
5071  g_free (xml);
5072  }
5073  response = MHD_create_response_from_buffer (strlen (res), res,
5074  MHD_RESPMEM_MUST_FREE);
5075  cmd_response_data_reset (&response_data);
5076  add_security_headers (response);
5077  return handler_send_response (connection,
5078  response,
5079  &content_type,
5080  content_disposition,
5081  http_response_code,
5082  1);
5083  }
5084 
5085  language = g_strdup (user->language);
5086  if (!language)
5087  /* Accept-Language: de; q=1.0, en; q=0.5 */
5088  {
5089  accept_language = MHD_lookup_connection_value
5090  (connection, MHD_HEADER_KIND, "Accept-Language");
5091  if (accept_language
5092  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
5093  {
5094  send_response (connection,
5095  UTF8_ERROR_PAGE ("'Accept-Language' header"),
5096  MHD_HTTP_BAD_REQUEST, NULL,
5097  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
5098  return MHD_YES;
5099  }
5100  language = accept_language_to_env_fmt (accept_language);
5101  credentials = credentials_new (user, language, client_address);
5102  g_free (language);
5103  }
5104  else
5105  credentials = credentials_new (user, language, client_address);
5106 
5107  credentials->caller = reconstruct_url (connection, url);
5108  if (credentials->caller
5109  && g_utf8_validate (credentials->caller, -1, NULL) == FALSE)
5110  {
5111  g_free (credentials->caller);
5112  credentials->caller = NULL;
5113  }
5114 
5115  sid = g_strdup (user->cookie);
5116 
5117  user_release (user);
5118 
5119  /* Serve the request. */
5120 
5121  if (!strncmp (&url[0], omp_cgi_base, strlen (omp_cgi_base)))
5122  {
5123  /* URL requests to run OMP command. */
5124 
5125  unsigned int res_len = 0;
5126  gchar *content_type_string = NULL;
5127 
5128  cmd_response_data_t response_data;
5129  cmd_response_data_init (&response_data);
5130 
5131  res = exec_omp_get (connection, credentials, &content_type,
5132  &content_type_string, &content_disposition,
5133  &response_size, &response_data);
5134  if (response_size > 0)
5135  {
5136  res_len = response_size;
5137  response_size = 0;
5138  }
5139  else
5140  {
5141  res_len = strlen (res);
5142 
5143  xml_flag = credentials->params
5144  ? params_value (credentials->params, "xml")
5145  : NULL;
5146  if (xml_flag && strcmp (xml_flag, "0"))
5147  content_type = GSAD_CONTENT_TYPE_APP_XML;
5148  }
5149 
5150  response = MHD_create_response_from_buffer (res_len, (void *) res,
5151  MHD_RESPMEM_MUST_FREE);
5152  if (content_type_string)
5153  {
5154  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
5155  content_type_string);
5156  g_free (content_type_string);
5157  }
5158 
5159  if (response_data.redirect)
5160  {
5161  MHD_add_response_header (response, MHD_HTTP_HEADER_LOCATION,
5162  response_data.redirect);
5163  http_response_code = MHD_HTTP_SEE_OTHER;
5164  }
5165  else
5166  {
5167  http_response_code = response_data.http_status_code;
5168  }
5169 
5170  cmd_response_data_reset (&response_data);
5171  }
5172  /* URL does not request OMP command but perhaps a special GSAD command? */
5173  else if (!strncmp (&url[0], "/system_report/",
5174  strlen ("/system_report/")))
5175  {
5176  params_t *params;
5177  gsize res_len = 0;
5178  const char *slave_id;
5179 
5180  params = params_new ();
5181 
5182  MHD_get_connection_values (connection, MHD_GET_ARGUMENT_KIND,
5183  params_mhd_add, params);
5184 
5185  params_mhd_validate (params);
5186 
5187  slave_id = MHD_lookup_connection_value (connection,
5188  MHD_GET_ARGUMENT_KIND,
5189  "slave_id");
5190  if (slave_id && openvas_validate (validator, "slave_id", slave_id))
5191  {
5192  g_free (sid);
5193  credentials_free (credentials);
5194  g_warning ("%s: failed to validate slave_id, dropping request",
5195  __FUNCTION__);
5196  return MHD_NO;
5197  }
5198 
5199  cmd_response_data_t response_data;
5200  cmd_response_data_init (&response_data);
5201 
5202  /* Connect to manager */
5203  switch (manager_connect (credentials, &con, &response_data))
5204  {
5205  case 0:
5206  res = get_system_report_omp (&con,
5207  credentials,
5208  &url[0] + strlen ("/system_report/"),
5209  params,
5210  &content_type,
5211  &response_size,
5212  &response_data);
5213  break;
5214  case -1:
5215  res = logout (credentials,
5216  "Logged out. OMP service is down.",
5217  &response_data);
5218  break;
5219  case -2:
5220  res = gsad_message (credentials,
5221  "Internal error", __FUNCTION__, __LINE__,
5222  "An internal error occurred. "
5223  "Diagnostics: Could not authenticate to manager "
5224  "daemon.",
5225  "/omp?cmd=get_tasks",
5226  &response_data);
5227  break;
5228  default:
5229  res = gsad_message (credentials,
5230  "Internal error", __FUNCTION__, __LINE__,
5231  "An internal error occurred. "
5232  "Diagnostics: Failure to connect to manager daemon.",
5233  "/omp?cmd=get_tasks",
5234  &response_data);
5235  break;
5236  }
5237  openvas_connection_close (&con);
5238 
5239  if (response_size > 0)
5240  {
5241  res_len = response_size;
5242  }
5243  else
5244  {
5245  res_len = strlen (res);
5246  }
5247 
5248  if (res == NULL)
5249  {
5250  g_free (sid);
5251  credentials_free (credentials);
5252  g_warning ("%s: failed to get system reports, dropping request",
5253  __FUNCTION__);
5254  return MHD_NO;
5255  }
5256  response = MHD_create_response_from_buffer ((unsigned int) res_len,
5257  res, MHD_RESPMEM_MUST_FREE);
5258 
5259  http_response_code = response_data.http_status_code;
5260  cmd_response_data_reset (&response_data);
5261  }
5262  else if (!strncmp (&url[0], "/help/",
5263  strlen ("/help/")))
5264  {
5265  cmd_response_data_t response_data;
5266  cmd_response_data_init (&response_data);
5267 
5268  if (!g_ascii_isalpha (url[6]))
5269  {
5270  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
5271  res = gsad_message (credentials,
5272  "Invalid request", __FUNCTION__, __LINE__,
5273  "The requested help page does not exist.",
5274  "/help/contents.html", &response_data);
5275  }
5276  else
5277  {
5278  gchar **preferred_languages;
5279  gchar *xsl_filename = NULL;
5280  gchar *page = g_strndup ((gchar *) &url[6], MAX_FILE_NAME_SIZE);
5281  GHashTable *template_attributes;
5282  int template_found = 0;
5283 
5284  // Disallow names that would be invalid for XML elements
5285  if (g_regex_match_simple ("^(?!xml)[[:alpha:]_][[:alnum:]-_.]*$",
5286  page, G_REGEX_CASELESS, 0) == 0)
5287  {
5288  g_free (page);
5289  page = g_strdup ("_invalid_");
5290  }
5291  // XXX: url subsearch could be nicer and xsl transform could
5292  // be generalized with the other transforms.
5293  time_t now;
5294  char ctime_now[200];
5295  gchar *xml, *pre;
5296  int index;
5297 
5298  assert (credentials->token);
5299 
5300  now = time (NULL);
5301  ctime_r_strip_newline (&now, ctime_now);
5302 
5303  pre = g_markup_printf_escaped
5304  ("<envelope>"
5305  "<version>%s</version>"
5306  "<vendor_version>%s</vendor_version>"
5307  "<token>%s</token>"
5308  "<time>%s</time>"
5309  "<login>%s</login>"
5310  "<role>%s</role>"
5311  "<i18n>%s</i18n>"
5312  "<charts>%i</charts>"
5313  "<guest>%d</guest>"
5314  "<client_address>%s</client_address>"
5315  "<help><%s/></help>",
5316  GSAD_VERSION,
5317  vendor_version_get (),
5318  credentials->token,
5319  ctime_now,
5320  credentials->username,
5321  credentials->role,
5322  credentials->language,
5323  credentials->charts,
5324  credentials->guest,
5325  credentials->client_address,
5326  page);
5327  xml = g_strdup_printf ("%s"
5328  "<capabilities>%s</capabilities>"
5329  "</envelope>",
5330  pre,
5331  credentials->capabilities);
5332  g_free (pre);
5333 
5334  preferred_languages = g_strsplit (credentials->language, ":", 0);
5335 
5336  index = 0;
5337  while (preferred_languages [index] && xsl_filename == NULL)
5338  {
5339  gchar *help_language;
5340  help_language = g_strdup (preferred_languages [index]);
5341  xsl_filename = g_strdup_printf ("help_%s.xsl",
5342  help_language);
5343  if (access (xsl_filename, R_OK) != 0)
5344  {
5345  g_free (xsl_filename);
5346  xsl_filename = NULL;
5347  if (strchr (help_language, '_'))
5348  {
5349  *strchr (help_language, '_') = '\0';
5350  xsl_filename = g_strdup_printf ("help_%s.xsl",
5351  help_language);
5352  if (access (xsl_filename, R_OK) != 0)
5353  {
5354  g_free (xsl_filename);
5355  xsl_filename = NULL;
5356  }
5357  }
5358  }
5359  g_free (help_language);
5360  index ++;
5361  }
5362 
5363  template_attributes
5364  = g_hash_table_new (g_str_hash, g_str_equal);
5365 
5366  g_hash_table_insert (template_attributes, "match", page);
5367  g_hash_table_insert (template_attributes, "mode", "help");
5368 
5369  // Try to find the requested page template
5370  if (xsl_filename)
5371  {
5372  template_found
5373  = find_element_in_xml_file (xsl_filename, "xsl:template",
5374  template_attributes);
5375  }
5376 
5377  if (template_found == 0)
5378  {
5379  // Try finding page template again in default help
5380  template_found
5381  = find_element_in_xml_file ("help.xsl", "xsl:template",
5382  template_attributes);
5383  }
5384 
5385  if (template_found == 0)
5386  {
5387  response_data.http_status_code = MHD_HTTP_NOT_FOUND;
5388  res = gsad_message (credentials,
5389  NOT_FOUND_TITLE, NULL, 0,
5391  "/help/contents.html", &response_data);
5392  }
5393  else if (xsl_filename)
5394  {
5395  res = xsl_transform_with_stylesheet (xml, xsl_filename,
5396  &response_data);
5397 
5398  }
5399  else
5400  {
5401  res = xsl_transform_with_stylesheet (xml, "help.xsl",
5402  &response_data);
5403  }
5404 
5405  g_strfreev (preferred_languages);
5406  g_free (xsl_filename);
5407  g_free (page);
5408  }
5409  if (res == NULL)
5410  {
5411  response_data.http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
5412  res = gsad_message (credentials,
5413  "Invalid request", __FUNCTION__, __LINE__,
5414  "Error generating help page.",
5415  "/help/contents.html", &response_data);
5416  }
5417  http_response_code = response_data.http_status_code;
5418  response = MHD_create_response_from_buffer (strlen (res), res,
5419  MHD_RESPMEM_MUST_FREE);
5420  cmd_response_data_reset (&response_data);
5421  }
5422  else
5423  {
5424  /* URL requests neither an OMP command nor a special GSAD command,
5425  * so it is a simple file. */
5426  /* Serve a file. */
5427 #ifdef SERVE_STATIC_ASSETS
5428  response = file_content_response (credentials,
5429  connection, url,
5430  &http_response_code,
5431  &content_type,
5432  &content_disposition);
5433 #else
5434  gchar *msg = gsad_message (NULL,
5435  NOT_FOUND_TITLE, NULL, 0,
5437  "/login/login.html", NULL);
5438  response = MHD_create_response_from_buffer (strlen (msg),
5439  (void *) msg,
5440  MHD_RESPMEM_MUST_COPY);
5441  g_free (msg);
5442 #endif
5443  }
5444 
5445  if (response)
5446  {
5447  const char* cmd;
5448 
5449  if (credentials->params)
5450  cmd = params_value (credentials->params, "cmd");
5451  else
5452  cmd = NULL;
5453 
5454  if (attach_sid (response, sid) == MHD_NO)
5455  {
5456  g_free (sid);
5457  MHD_destroy_response (response);
5458  g_warning ("%s: failed to attach SID, dropping request",
5459  __FUNCTION__);
5460  return MHD_NO;
5461  }
5462  g_free (sid);
5463 
5464  if (guest_password
5465  && strcmp (credentials->username, guest_username) == 0
5466  && cmd
5467  && (strcmp (cmd, "get_aggregate") == 0
5468  || strcmp (cmd, "get_assets_chart") == 0
5469  || strcmp (cmd, "get_tasks_chart") == 0))
5470  {
5472  }
5473  else
5474  {
5475  add_security_headers (response);
5476  }
5477 
5478  credentials_free (credentials);
5479  return handler_send_response (connection,
5480  response,
5481  &content_type,
5482  content_disposition,
5483  http_response_code,
5484  0);
5485  }
5486  else
5487  {
5488  /* Severe memory or file access problem. */
5489  g_free (sid);
5490  credentials_free (credentials);
5491  g_warning ("%s: memory or file access problem, dropping request",
5492  __FUNCTION__);
5493  return MHD_NO;
5494  }
5495  }
5496 
5497  if (!strcmp (method, "POST"))
5498  {
5499  user_t *user;
5500  const char *sid, *accept_language;
5501  gchar *new_sid;
5502  int ret;
5503 
5504  if (NULL == *con_cls)
5505  {
5506  /* First call for this request, a POST. */
5507 
5508  struct gsad_connection_info *con_info;
5509 
5510  /* Freed by MHD_OPTION_NOTIFY_COMPLETED callback, free_resources. */
5511  con_info = g_malloc0 (sizeof (struct gsad_connection_info));
5512 
5513  con_info->postprocessor =
5514  MHD_create_post_processor (connection, POST_BUFFER_SIZE,
5515  serve_post, (void *) con_info);
5516  if (NULL == con_info->postprocessor)
5517  {
5518  g_free (con_info);
5519  /* Both bad request or running out of memory will lead here, but
5520  * we return the Bad Request page always, to prevent bad requests
5521  * from leading to "Internal application error" in the log. */
5522  send_response (connection, BAD_REQUEST_PAGE,
5524  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
5525  return MHD_YES;
5526  }
5527  con_info->params = params_new ();
5528  con_info->connectiontype = 1;
5529  con_info->answercode = MHD_HTTP_OK;
5531  con_info->content_disposition = NULL;
5532  con_info->content_length = 0;
5533  con_info->redirect = NULL;
5534 
5535  *con_cls = (void *) con_info;
5536  return MHD_YES;
5537  }
5538 
5539  /* Second or later call for this request, a POST. */
5540 
5541  struct gsad_connection_info *con_info = *con_cls;
5542  if (0 != *upload_data_size)
5543  {
5544  MHD_post_process (con_info->postprocessor, upload_data,
5545  *upload_data_size);
5546  *upload_data_size = 0;
5547  return MHD_YES;
5548  }
5549 
5550  sid = MHD_lookup_connection_value (connection,
5551  MHD_COOKIE_KIND,
5552  SID_COOKIE_NAME);
5553  if (openvas_validate (validator, "token", sid))
5554  con_info->cookie = NULL;
5555  else
5556  con_info->cookie = g_strdup (sid);
5557 
5558  accept_language = MHD_lookup_connection_value (connection,
5559  MHD_HEADER_KIND,
5560  "Accept-Language");
5561  if (accept_language
5562  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
5563  {
5564  send_response (connection,
5565  UTF8_ERROR_PAGE ("'Accept-Language' header"),
5566  MHD_HTTP_BAD_REQUEST, NULL,
5567  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
5568  return MHD_YES;
5569  }
5570  con_info->language = accept_language_to_env_fmt (accept_language);
5571 
5572  get_client_address (connection, client_address);
5573  ret = get_client_address (connection, client_address);
5574  if (ret == 1)
5575  {
5576  send_response (connection,
5577  UTF8_ERROR_PAGE ("'X-Real-IP' header"),
5578  MHD_HTTP_BAD_REQUEST, NULL,
5579  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
5580  return MHD_YES;
5581  }
5582 
5583  user = NULL;
5584  new_sid = NULL;
5585  ret = exec_omp_post (con_info, &user, &new_sid, client_address);
5586 
5587  if (ret == 1)
5588  {
5589  gchar *url;
5590  url = g_strdup_printf ("%s&token=%s",
5591  params_value (con_info->params, "text"),
5592  user->token);
5593  user_release (user);
5594  ret = send_redirect_to_urn (connection, url, user);
5595  g_free (url);
5596  return ret;
5597  }
5598 
5599  if (con_info->redirect)
5600  {
5601  ret = send_redirect_to_uri (connection, con_info->redirect, user);
5602  g_free (con_info->redirect);
5603  con_info->redirect = NULL;
5604  }
5605  else
5606  {
5607  xml_flag = con_info->params
5608  ? params_value (con_info->params, "xml")
5609  : NULL;
5610 
5611  if (xml_flag && strcmp (xml_flag, "0"))
5612  {
5613  content_type = GSAD_CONTENT_TYPE_APP_XML;
5614  }
5615  else
5616  {
5617  content_type = con_info->content_type;
5618  }
5619 
5620  ret = send_response (connection, con_info->response,
5621  con_info->answercode,
5622  new_sid ? new_sid : "0",
5623  content_type,
5624  con_info->content_disposition,
5625  con_info->content_length);
5626  }
5627 
5628  g_free (new_sid);
5629  return ret;
5630  }
5631 
5632  assert (0);
5633  g_warning ("%s: something went wrong, dropping request",
5634  __FUNCTION__);
5635  return MHD_NO;
5636 }
5637 
5638 
5646 static gboolean
5647 drop_privileges (struct passwd * user_pw)
5648 {
5649  if (setgroups (0, NULL))
5650  {
5651  g_critical ("%s: failed to set groups: %s\n", __FUNCTION__,
5652  strerror (errno));
5653  return FALSE;
5654  }
5655  if (setgid (user_pw->pw_gid))
5656  {
5657  g_critical ("%s: failed to drop group privileges: %s\n", __FUNCTION__,
5658  strerror (errno));
5659  return FALSE;
5660  }
5661  if (setuid (user_pw->pw_uid))
5662  {
5663  g_critical ("%s: failed to drop user privileges: %s\n", __FUNCTION__,
5664  strerror (errno));
5665  return FALSE;
5666  }
5667 
5668  return TRUE;
5669 }
5670 
5680 static int
5681 chroot_drop_privileges (gboolean do_chroot, gchar *drop,
5682  const gchar *subdir)
5683 {
5684  struct passwd *user_pw;
5685 
5686  if (drop)
5687  {
5688  user_pw = getpwnam (drop);
5689  if (user_pw == NULL)
5690  {
5691  g_critical ("%s: Failed to drop privileges."
5692  " Could not determine UID and GID for user \"%s\"!\n",
5693  __FUNCTION__,
5694  drop);
5695  return 1;
5696  }
5697  }
5698  else
5699  user_pw = NULL;
5700 
5701  if (do_chroot)
5702  {
5703  /* Chroot into state dir. */
5704 
5705  if (chroot (GSA_DATA_DIR))
5706  {
5707  g_critical ("%s: Failed to chroot to \"%s\": %s\n",
5708  __FUNCTION__,
5709  GSA_DATA_DIR,
5710  strerror (errno));
5711  return 1;
5712  }
5713  set_chroot_state (1);
5714  }
5715 
5716  if (user_pw && (drop_privileges (user_pw) == FALSE))
5717  {
5718  g_critical ("%s: Failed to drop privileges\n",
5719  __FUNCTION__);
5720  return 1;
5721  }
5722 
5723  if (do_chroot)
5724  {
5725  gchar* root_face_dir = g_build_filename ("/", subdir, NULL);
5726  if (chdir (root_face_dir))
5727  {
5728  g_critical ("%s: failed change to chroot root directory (%s): %s\n",
5729  __FUNCTION__,
5730  root_face_dir,
5731  strerror (errno));
5732  g_free (root_face_dir);
5733  return 1;
5734  }
5735  g_free (root_face_dir);
5736  }
5737  else
5738  {
5739  gchar* data_dir = g_build_filename (GSA_DATA_DIR, subdir, NULL);
5740  if (chdir (data_dir))
5741  {
5742  g_critical ("%s: failed to change to \"%s\": %s\n",
5743  __FUNCTION__,
5744  data_dir,
5745  strerror (errno));
5746  g_free (data_dir);
5747  return 1;
5748  }
5749  g_free (data_dir);
5750  }
5751 
5752  return 0;
5753 }
5754 
5763 static void
5764 my_gnutls_log_func (int level, const char *text)
5765 {
5766  fprintf (stderr, "[%d] (%d) %s", getpid (), level, text);
5767  if (*text && text[strlen (text) -1] != '\n')
5768  putc ('\n', stderr);
5769 }
5770 
5771 
5780 int
5782 {
5783  g_debug ("Initializing the Greenbone Security Assistant...\n");
5784 
5785  /* Init Glib. */
5786  mutex = g_malloc (sizeof (GMutex));
5787  g_mutex_init (mutex);
5788  users = g_ptr_array_new ();
5789 
5790  /* Check for required files. */
5791  if (openvas_file_check_is_dir (GSA_DATA_DIR) < 1)
5792  {
5793  g_critical ("%s: Could not access %s!\n", __FUNCTION__, GSA_DATA_DIR);
5794  return MHD_NO;
5795  }
5796 
5797  /* Init GCRYPT. */
5798  /* Register thread callback structure for libgcrypt < 1.6.0. */
5799 #if GCRYPT_VERSION_NUMBER < 0x010600
5800  gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
5801 #endif
5802 
5803  /* Version check should be the very first call because it makes sure that
5804  * important subsystems are intialized.
5805  * We pass NULL to gcry_check_version to disable the internal version mismatch
5806  * test. */
5807  if (!gcry_check_version (NULL))
5808  {
5809  g_critical ("%s: libgcrypt version check failed\n", __FUNCTION__);
5810  return MHD_NO;
5811  }
5812 
5813  /* We don't want to see any warnings, e.g. because we have not yet parsed
5814  * program options which might be used to suppress such warnings. */
5815  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
5816 
5817  /* ... If required, other initialization goes here. Note that the process
5818  * might still be running with increased privileges and that the secure
5819  * memory has not been intialized. */
5820 
5821  /* Allocate a pool of 16k secure memory. This make the secure memory
5822  * available and also drops privileges where needed. */
5823  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
5824 
5825  /* It is now okay to let Libgcrypt complain when there was/is a problem with
5826  * the secure memory. */
5827  gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
5828 
5829  /* ... If required, other initialization goes here. */
5830 
5831  /* Tell Libgcrypt that initialization has completed. */
5832  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
5833 
5834  /* Init GNUTLS. */
5835  int ret = gnutls_global_init ();
5836  if (ret < 0)
5837  {
5838  g_critical ("%s: Failed to initialize GNUTLS.\n", __FUNCTION__);
5839  return MHD_NO;
5840  }
5841 
5842  /* Init the validator. */
5843  init_validator ();
5844 
5845  g_debug ("Initialization of GSA successful.\n");
5846  return MHD_YES;
5847 }
5848 
5855 void
5857 {
5858  if (redirect_pid) kill (redirect_pid, SIGTERM);
5859  if (unix_pid) kill (unix_pid, SIGTERM);
5860 
5861  MHD_stop_daemon (gsad_daemon);
5862 
5863  if (log_config) free_log_configuration (log_config);
5864 
5865  gsad_base_cleanup ();
5866 
5867  pidfile_remove ("gsad");
5868 }
5869 
5875 void
5877 {
5878  termination_signal = signal;
5879 }
5880 
5888 static int
5889 register_signal_handlers ()
5890 {
5891  if (signal (SIGTERM, handle_signal_exit) == SIG_ERR
5892  || signal (SIGINT, handle_signal_exit) == SIG_ERR
5893  || signal (SIGHUP, SIG_IGN) == SIG_ERR
5894  || signal (SIGPIPE, SIG_IGN) == SIG_ERR
5895 #ifdef USE_LIBXSLT
5896  || signal (SIGCHLD, SIG_IGN) == SIG_ERR)
5897 #else
5898  || signal (SIGCHLD, SIG_DFL) == SIG_ERR)
5899 #endif
5900  return -1;
5901  return 0;
5902 }
5903 
5904 static void
5905 mhd_logger (void *arg, const char *fmt, va_list ap)
5906 {
5907  char buf[1024];
5908 
5909  vsnprintf (buf, sizeof (buf), fmt, ap);
5910  va_end (ap);
5911  g_warning ("MHD: %s", buf);
5912 }
5913 
5914 static struct MHD_Daemon *
5915 start_unix_http_daemon (const char *unix_socket_path,
5916  int handler (void *, struct MHD_Connection *,
5917  const char *, const char *, const char *,
5918  const char *, size_t *, void **))
5919 {
5920  struct sockaddr_un addr;
5921  struct stat ustat;
5922  mode_t oldmask = 0;
5923 
5924  unix_socket = socket (AF_UNIX, SOCK_STREAM, 0);
5925  if (unix_socket == -1)
5926  {
5927  g_warning ("%s: Couldn't create UNIX socket", __FUNCTION__);
5928  return NULL;
5929  }
5930  addr.sun_family = AF_UNIX;
5931  strncpy (addr.sun_path, unix_socket_path, sizeof (addr.sun_path));
5932  if (!stat (addr.sun_path, &ustat))
5933  {
5934  /* Remove socket so we can bind(). Keep same permissions when recreating
5935  * it. */
5936  unlink (addr.sun_path);
5937  oldmask = umask (~ustat.st_mode);
5938  }
5939  if (bind (unix_socket, (struct sockaddr *) &addr, sizeof (struct sockaddr_un))
5940  == -1)
5941  {
5942  g_warning ("%s: Error on bind(%s): %s", __FUNCTION__,
5943  unix_socket_path, strerror (errno));
5944  return NULL;
5945  }
5946  if (oldmask)
5947  umask (oldmask);
5948  if (listen (unix_socket, 128) == -1)
5949  {
5950  g_warning ("%s: Error on listen(): %s", __FUNCTION__, strerror (errno));
5951  return NULL;
5952  }
5953 
5954  return MHD_start_daemon
5955  (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, 0,
5956  NULL, NULL, handler, NULL, MHD_OPTION_NOTIFY_COMPLETED,
5957  free_resources, NULL, MHD_OPTION_LISTEN_SOCKET, unix_socket,
5958  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 30,
5959  MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, NULL, MHD_OPTION_END);
5960 }
5961 
5962 static struct MHD_Daemon *
5963 start_http_daemon (int port,
5964  int handler (void *, struct MHD_Connection *, const char *,
5965  const char *, const char *, const char *,
5966  size_t *, void **),
5967  struct sockaddr_storage *address)
5968 {
5969  int ipv6_flag;
5970 
5971  if (address->ss_family == AF_INET6)
5972 /* LibmicroHTTPD 0.9.28 and higher. */
5973 #if MHD_VERSION >= 0x00092800
5974  ipv6_flag = MHD_USE_DUAL_STACK;
5975 #else
5976  ipv6_flag = MHD_USE_IPv6;
5977 #endif
5978  else
5979  ipv6_flag = MHD_NO_FLAG;
5980  return MHD_start_daemon
5981  (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | ipv6_flag, port,
5982  NULL, NULL, handler, NULL, MHD_OPTION_NOTIFY_COMPLETED,
5983  free_resources, NULL, MHD_OPTION_SOCK_ADDR, address,
5984  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 30,
5985  MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, NULL, MHD_OPTION_END);
5986 }
5987 
5988 static struct MHD_Daemon *
5989 start_https_daemon (int port, const char *key, const char *cert,
5990  const char *priorities, const char *dh_params,
5991  struct sockaddr_storage *address)
5992 {
5993  int ipv6_flag;
5994 
5995  if (address->ss_family == AF_INET6)
5996 /* LibmicroHTTPD 0.9.28 and higher. */
5997 #if MHD_VERSION >= 0x00092800
5998  ipv6_flag = MHD_USE_DUAL_STACK;
5999 #else
6000  ipv6_flag = MHD_USE_IPv6;
6001 #endif
6002  else
6003  ipv6_flag = MHD_NO_FLAG;
6004  return MHD_start_daemon
6005  (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | MHD_USE_SSL
6006  | ipv6_flag, port, NULL, NULL, &handle_request, NULL,
6007  MHD_OPTION_HTTPS_MEM_KEY, key,
6008  MHD_OPTION_HTTPS_MEM_CERT, cert,
6009  MHD_OPTION_NOTIFY_COMPLETED, free_resources, NULL,
6010  MHD_OPTION_SOCK_ADDR, address,
6011  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 30,
6012  MHD_OPTION_HTTPS_PRIORITIES, priorities,
6013  MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, NULL,
6014 /* LibmicroHTTPD 0.9.35 and higher. */
6015 #if MHD_VERSION >= 0x00093500
6016  dh_params ? MHD_OPTION_HTTPS_MEM_DHPARAMS : MHD_OPTION_END,
6017  dh_params,
6018 #endif
6019  MHD_OPTION_END);
6020 }
6021 
6028 static void
6029 gsad_address_set_port (struct sockaddr_storage *address, int port)
6030 {
6031  struct sockaddr_in *gsad_address = (struct sockaddr_in *) address;
6032  struct sockaddr_in6 *gsad_address6 = (struct sockaddr_in6 *) address;
6033 
6034  gsad_address->sin_port = htons (port);
6035  gsad_address6->sin6_port = htons (port);
6036 }
6037 
6048 static int
6049 gsad_address_init (const char *address_str, int port)
6050 {
6051  struct sockaddr_storage *address = g_malloc0 (sizeof (*address));
6052  struct sockaddr_in *gsad_address = (struct sockaddr_in *) address;
6053  struct sockaddr_in6 *gsad_address6 = (struct sockaddr_in6 *) address;
6054 
6055  gsad_address_set_port (address, port);
6056  if (address_str)
6057  {
6058  if (inet_pton (AF_INET6, address_str, &gsad_address6->sin6_addr) > 0)
6059  address->ss_family = AF_INET6;
6060  else if (inet_pton (AF_INET, address_str, &gsad_address->sin_addr) > 0)
6061  address->ss_family = AF_INET;
6062  else
6063  {
6064  g_warning ("Failed to create GSAD address %s", address_str);
6065  g_free (address);
6066  return 1;
6067  }
6068  g_hash_table_add (gsad_header_hosts, g_strdup (address_str));
6069  }
6070  else
6071  {
6072  gsad_address->sin_addr.s_addr = INADDR_ANY;
6073  gsad_address6->sin6_addr = in6addr_any;
6074  if (ipv6_is_enabled ())
6075  address->ss_family = AF_INET6;
6076  else
6077  address->ss_family = AF_INET;
6078  }
6079  address_list = g_slist_append (address_list, address);
6080  return 0;
6081 }
6082 
6091 int
6092 main (int argc, char **argv)
6093 {
6094  gchar *rc_name;
6095  gchar *old_locale;
6096  char *locale;
6097  int gsad_port;
6098  int gsad_redirect_port = DEFAULT_GSAD_REDIRECT_PORT;
6099  int gsad_manager_port = DEFAULT_OPENVAS_MANAGER_PORT;
6100  sigset_t sigmask_all, sigmask_current;
6101 
6102  /* Initialise. */
6103 
6104  if (gsad_init () == MHD_NO)
6105  {
6106  g_critical ("%s: Initialization failed!\nExiting...\n", __FUNCTION__);
6107  exit (EXIT_FAILURE);
6108  }
6109 
6110  /* Process command line options. */
6111 
6112  static gboolean do_chroot = FALSE;
6113  static gchar *drop = NULL;
6114  static gboolean foreground = FALSE;
6115  static gboolean http_only = FALSE;
6116  static gboolean print_version = FALSE;
6117  static gboolean no_redirect = FALSE;
6118  static gboolean secure_cookie = FALSE;
6119  static int timeout = SESSION_TIMEOUT;
6120  static gchar **gsad_address_string = NULL;
6121  static gchar **gsad_header_host_strings = NULL;
6122  static gchar *gsad_manager_address_string = NULL;
6123  static gchar *gsad_manager_unix_socket_path = NULL;
6124  static gchar *gsad_port_string = NULL;
6125  static gchar *gsad_redirect_port_string = NULL;
6126  static gchar *gsad_manager_port_string = NULL;
6127  static gchar *gsad_vendor_version_string = NULL;
6128  static gchar *gsad_login_label_name = NULL;
6129  static gchar *ssl_private_key_filename = OPENVAS_SERVER_KEY;
6130  static gchar *ssl_certificate_filename = OPENVAS_SERVER_CERTIFICATE;
6131  static gchar *dh_params_filename = NULL;
6132  static gchar *unix_socket_path = NULL;
6133  static gchar *gnutls_priorities = "NORMAL";
6134  static int debug_tls = 0;
6135  static gchar *face_name = NULL;
6136  static gchar *guest_user = NULL;
6137  static gchar *guest_pass = NULL;
6138  static gchar *http_frame_opts = DEFAULT_GSAD_X_FRAME_OPTIONS;
6139  static gchar *http_csp = DEFAULT_GSAD_CONTENT_SECURITY_POLICY;
6140  static gchar *http_guest_chart_frame_opts
6142  static gchar *http_guest_chart_csp
6144  static int hsts_enabled = FALSE;
6145  static int hsts_max_age = DEFAULT_GSAD_HSTS_MAX_AGE;
6146  static gboolean ignore_x_real_ip = FALSE;
6147  static int verbose = 0;
6148  GError *error = NULL;
6149  GOptionContext *option_context;
6150  static GOptionEntry option_entries[] = {
6151  {"allow-header-host", '\0',
6152  0, G_OPTION_ARG_STRING_ARRAY, &gsad_header_host_strings,
6153  "Allow <host> as hostname/address part of a Host header."
6154  "<host>" },
6155  {"drop-privileges", '\0',
6156  0, G_OPTION_ARG_STRING, &drop,
6157  "Drop privileges to <user>.", "<user>" },
6158  {"foreground", 'f',
6159  0, G_OPTION_ARG_NONE, &foreground,
6160  "Run in foreground.", NULL},
6161  {"http-only", '\0',
6162  0, G_OPTION_ARG_NONE, &http_only,
6163  "Serve HTTP only, without SSL.", NULL},
6165  {"listen", '\0',
6166  0, G_OPTION_ARG_STRING_ARRAY, &gsad_address_string,
6167  "Listen on <address>.", "<address>" },
6168  {"mlisten", '\0',
6169  0, G_OPTION_ARG_STRING, &gsad_manager_address_string,
6170  "Manager address.", "<address>" },
6171  {"port", 'p',
6172  0, G_OPTION_ARG_STRING, &gsad_port_string,
6173  "Use port number <number>.", "<number>"},
6174  {"mport", 'm',
6175  0, G_OPTION_ARG_STRING, &gsad_manager_port_string,
6176  "Use manager port number <number>.", "<number>"},
6177  {"rport", 'r',
6178  0, G_OPTION_ARG_STRING, &gsad_redirect_port_string,
6179  "Redirect HTTP from this port number <number>.", "<number>"},
6180  {"no-redirect", '\0',
6181  0, G_OPTION_ARG_NONE, &no_redirect,
6182  "Don't redirect HTTP to HTTPS.", NULL },
6183  {"verbose", 'v',
6184  0, G_OPTION_ARG_NONE, &verbose,
6185  "Has no effect. See INSTALL for logging config.", NULL },
6186  {"version", 'V',
6187  0, G_OPTION_ARG_NONE, &print_version,
6188  "Print version and exit.", NULL},
6189  {"vendor-version", '\0',
6190  0, G_OPTION_ARG_STRING, &gsad_vendor_version_string,
6191  "Use <string> as version in interface.", "<string>"},
6192  {"login-label", '\0',
6193  0, G_OPTION_ARG_STRING, &gsad_login_label_name,
6194  "Use <string> as login label.", "<string>"},
6195  {"ssl-private-key", 'k',
6196  0, G_OPTION_ARG_FILENAME, &ssl_private_key_filename,
6197  "Use <file> as the private key for HTTPS", "<file>"},
6198  {"ssl-certificate", 'c',
6199  0, G_OPTION_ARG_FILENAME, &ssl_certificate_filename,
6200  "Use <file> as the certificate for HTTPS", "<file>"},
6201  {"dh-params", '\0',
6202  0, G_OPTION_ARG_FILENAME, &dh_params_filename,
6203  "Diffie-Hellman parameters file", "<file>"},
6204  {"do-chroot", '\0',
6205  0, G_OPTION_ARG_NONE, &do_chroot,
6206  "Do chroot.", NULL},
6207  {"secure-cookie", '\0',
6208  0, G_OPTION_ARG_NONE, &secure_cookie,
6209  "Use a secure cookie (implied when using HTTPS).", NULL},
6210  {"timeout", '\0',
6211  0, G_OPTION_ARG_INT, &timeout,
6212  "Minutes of user idle time before session expires.", "<number>"},
6213  {"client-watch-interval", '\0',
6214  0, G_OPTION_ARG_INT, &client_watch_interval,
6215  "Check if client connection was closed every <number> seconds."
6216  " 0 to disable. Defaults to " G_STRINGIFY (DEFAULT_CLIENT_WATCH_INTERVAL)
6217  " seconds.",
6218  "<number>"},
6219  {"debug-tls", 0,
6220  0, G_OPTION_ARG_INT, &debug_tls,
6221  "Enable TLS debugging at <level>", "<level>"},
6222  {"gnutls-priorities", '\0',
6223  0, G_OPTION_ARG_STRING, &gnutls_priorities,
6224  "GnuTLS priorities string.", "<string>"},
6225  {"face", 0,
6226  0, G_OPTION_ARG_STRING, &face_name,
6227  "Use interface files from subdirectory <dir>", "<dir>"},
6228  {"guest-username", 0,
6229  0, G_OPTION_ARG_STRING, &guest_user,
6230  "Username for guest user. Enables guest logins.", "<name>"},
6231  {"guest-password", 0,
6232  0, G_OPTION_ARG_STRING, &guest_pass,
6233  "Password for guest user. Defaults to guest username.", "<password>"},
6234  {"http-frame-opts", 0,
6235  0, G_OPTION_ARG_STRING, &http_frame_opts,
6236  "X-Frame-Options HTTP header. Defaults to \""
6237  DEFAULT_GSAD_X_FRAME_OPTIONS "\".", "<frame-opts>"},
6238  {"http-csp", 0,
6239  0, G_OPTION_ARG_STRING, &http_csp,
6240  "Content-Security-Policy HTTP header. Defaults to \""
6241  DEFAULT_GSAD_CONTENT_SECURITY_POLICY"\".", "<csp>"},
6242  {"http-guest-chart-frame-opts", 0,
6243  0, G_OPTION_ARG_STRING, &http_guest_chart_frame_opts,
6244  "X-Frame-Options HTTP header for guest charts. Defaults to \""
6245  DEFAULT_GSAD_GUEST_CHART_X_FRAME_OPTIONS "\".", "<frame-opts>"},
6246  {"http-guest-chart-csp", 0,
6247  0, G_OPTION_ARG_STRING, &http_guest_chart_csp,
6248  "Content-Security-Policy HTTP header. Defaults to \""
6250  {"http-sts", 0,
6251  0, G_OPTION_ARG_NONE, &hsts_enabled,
6252  "Enable HTTP Strict-Tranport-Security header.", NULL},
6253  {"http-sts-max-age", 0,
6254  0, G_OPTION_ARG_INT, &hsts_max_age,
6255  "max-age in seconds for HTTP Strict-Tranport-Security header."
6256  " Defaults to \"" G_STRINGIFY (DEFAULT_GSAD_HSTS_MAX_AGE) "\".",
6257  "<max-age>"},
6258  {"ignore-x-real-ip", '\0',
6259  0, G_OPTION_ARG_NONE, &ignore_x_real_ip,
6260  "Do not use X-Real-IP to determine the client address.", NULL},
6261  {"unix-socket", '\0',
6262  0, G_OPTION_ARG_FILENAME, &unix_socket_path,
6263  "Path to unix socket to listen on", "<file>"},
6264  {"munix-socket", '\0',
6265  0, G_OPTION_ARG_FILENAME, &gsad_manager_unix_socket_path,
6266  "Path to Manager unix socket", "<file>"},
6267  {NULL}
6268  };
6269 
6270  option_context =
6271  g_option_context_new ("- Greenbone Security Assistant Daemon");
6272  g_option_context_add_main_entries (option_context, option_entries, NULL);
6273  if (!g_option_context_parse (option_context, &argc, &argv, &error))
6274  {
6275  g_critical ("%s: %s\n\n", __FUNCTION__, error->message);
6276  exit (EXIT_FAILURE);
6277  }
6278  g_option_context_free (option_context);
6279 
6280  http_x_frame_options = http_frame_opts;
6281  http_content_security_policy = http_csp;
6282  http_guest_chart_x_frame_options = http_guest_chart_frame_opts;
6283  http_guest_chart_content_security_policy = http_guest_chart_csp;
6284 
6285  set_http_only (!!http_only);
6286 
6287  if (http_only == FALSE && hsts_enabled)
6288  {
6290  = g_strdup_printf ("max-age=%d",
6291  hsts_max_age >= 0 ? hsts_max_age
6293  }
6294  else
6296 
6297  ignore_http_x_real_ip = ignore_x_real_ip;
6298 
6299  if (register_signal_handlers ())
6300  {
6301  g_critical ("Failed to register signal handlers!\n");
6302  exit (EXIT_FAILURE);
6303  }
6304 
6305  if (print_version)
6306  {
6307  printf ("Greenbone Security Assistant %s\n", GSAD_VERSION);
6308 #ifdef GSAD_GIT_REVISION
6309  printf ("GIT revision %s\n", GSAD_GIT_REVISION);
6310 #endif
6311  if (debug_tls)
6312  {
6313  printf ("gnutls %s\n", gnutls_check_version (NULL));
6314  printf ("libmicrohttpd %s\n", MHD_get_version ());
6315  }
6316  printf ("Copyright (C) 2010-2016 Greenbone Networks GmbH\n");
6317  printf ("License GPLv2+: GNU GPL version 2 or later\n");
6318  printf
6319  ("This is free software: you are free to change and redistribute it.\n"
6320  "There is NO WARRANTY, to the extent permitted by law.\n\n");
6321  exit (EXIT_SUCCESS);
6322  }
6323 
6324  if (debug_tls)
6325  {
6326  gnutls_global_set_log_function (my_gnutls_log_func);
6327  gnutls_global_set_log_level (debug_tls);
6328  }
6329 
6330  switch (gsad_base_init ())
6331  {
6332  case 1:
6333  g_critical ("%s: libxml must be compiled with thread support\n",
6334  __FUNCTION__);
6335  exit (EXIT_FAILURE);
6336  }
6337 
6338  if (gsad_vendor_version_string)
6339  vendor_version_set (gsad_vendor_version_string);
6340 
6341  if (gsad_login_label_name)
6342  {
6343  if (label_name_set (gsad_login_label_name))
6344  {
6345  g_critical ("Invalid character in login label name\n");
6346  exit (EXIT_FAILURE);
6347  }
6348  }
6349 
6350  if (no_redirect && gsad_redirect_port_string)
6351  {
6352  g_warning ("--no-redirect option given with --rport");
6353  return 1;
6354  }
6355 
6356  /* Switch to UTC for scheduling. */
6357 
6358  if (setenv ("TZ", "utc 0", 1) == -1)
6359  {
6360  g_critical ("%s: failed to set timezone\n", __FUNCTION__);
6361  exit (EXIT_FAILURE);
6362  }
6363  tzset ();
6364 
6365  /* Setup logging. */
6366 
6367  rc_name = g_build_filename (GSA_CONFIG_DIR, "gsad_log.conf", NULL);
6368  if (g_file_test (rc_name, G_FILE_TEST_EXISTS))
6369  log_config = load_log_configuration (rc_name);
6370  g_free (rc_name);
6371  setup_log_handlers (log_config);
6372  /* Set to ensure that recursion is left out, in case two threads log
6373  * concurrently. */
6374  g_log_set_always_fatal (G_LOG_FATAL_MASK);
6375 
6376 #ifdef GSAD_GIT_REVISION
6377  g_message ("Starting GSAD version %s (GIT revision %s)\n",
6378  GSAD_VERSION,
6379  GSAD_GIT_REVISION);
6380 #else
6381  g_message ("Starting GSAD version %s\n",
6382  GSAD_VERSION);
6383 #endif
6384 
6385  /* Finish processing the command line options. */
6386 
6387  use_secure_cookie = secure_cookie;
6388 
6389  if ((timeout < 1) || (timeout > 1440))
6390  {
6391  g_critical ("%s: Timeout must be a number from 1 to 1440\n",
6392  __FUNCTION__);
6393  exit (EXIT_FAILURE);
6394  }
6395  session_timeout = timeout;
6396 
6397  if (client_watch_interval < 0)
6398  {
6400  }
6401 
6402  if (guest_user)
6403  {
6404  guest_username = guest_user;
6405  guest_password = guest_pass ? guest_pass : guest_user;
6406  }
6407 
6408  gsad_port = http_only ? DEFAULT_GSAD_HTTP_PORT : DEFAULT_GSAD_HTTPS_PORT;
6409 
6410  if (gsad_port_string)
6411  {
6412  gsad_port = atoi (gsad_port_string);
6413  if (gsad_port <= 0 || gsad_port >= 65536)
6414  {
6415  g_critical ("%s: Port must be a number between 0 and 65536\n",
6416  __FUNCTION__);
6417  exit (EXIT_FAILURE);
6418  }
6419  }
6420 
6421  if (gsad_manager_port_string)
6422  {
6423  gsad_manager_port = atoi (gsad_manager_port_string);
6424  if (gsad_manager_port <= 0 || gsad_manager_port >= 65536)
6425  {
6426  g_critical ("%s: Manager port must be a number between 0 and 65536\n",
6427  __FUNCTION__);
6428  exit (EXIT_FAILURE);
6429  }
6430  }
6431 
6432  /* Set and test the base locale for XSLt gettext */
6433  old_locale = g_strdup (setlocale (LC_ALL, NULL));
6434 
6435  locale = setlocale (LC_ALL, "");
6436  if (locale == NULL)
6437  {
6438  g_warning ("%s: "
6439  "Failed to set locale according to environment variables,"
6440  " gettext translations are disabled.",
6441  __FUNCTION__);
6443  }
6444  else if (strcmp (locale, "C") == 0)
6445  {
6446  g_message ("%s: Locale for gettext extensions set to \"C\","
6447  " gettext translations are disabled.",
6448  __FUNCTION__);
6450  }
6451  else
6452  {
6453  if (strcasestr (locale, "en_") != locale)
6454  {
6455  g_warning ("%s: Locale defined by environment variables"
6456  " is not an \"en_...\" one.",
6457  __FUNCTION__);
6459  }
6460 
6461  if (strcasecmp (nl_langinfo (CODESET), "UTF-8"))
6462  g_warning ("%s: Locale defined by environment variables"
6463  " does not use UTF-8 encoding.",
6464  __FUNCTION__);
6465 
6466  g_debug ("%s: gettext translation extensions are enabled"
6467  " (using locale \"%s\").",
6468  __FUNCTION__, locale);
6470  }
6471 
6472  setlocale (LC_ALL, old_locale);
6473  g_free (old_locale);
6474 
6476 
6477  if (gsad_redirect_port_string)
6478  {
6479  gsad_redirect_port = atoi (gsad_redirect_port_string);
6480  if (gsad_redirect_port <= 0 || gsad_redirect_port >= 65536)
6481  {
6482  g_critical ("%s: Redirect port must be a number between 0 and 65536\n",
6483  __FUNCTION__);
6484  exit (EXIT_FAILURE);
6485  }
6486  }
6487 
6488  if (foreground == FALSE)
6489  {
6490  /* Fork into the background. */
6491  g_debug ("Forking...\n");
6492  pid_t pid = fork ();
6493  switch (pid)
6494  {
6495  case 0:
6496  /* Child. */
6497  break;
6498  case -1:
6499  /* Parent when error. */
6500  g_critical ("%s: Failed to fork!\n", __FUNCTION__);
6501  exit (EXIT_FAILURE);
6502  break;
6503  default:
6504  /* Parent. */
6505  exit (EXIT_SUCCESS);
6506  break;
6507  }
6508  }
6509 
6510  if (http_only)
6511  no_redirect = TRUE;
6512 
6513  if (unix_socket_path)
6514  {
6515  /* Fork for the unix socket server. */
6516  g_debug ("Forking for unix socket...\n");
6517  pid_t pid = fork ();
6518  switch (pid)
6519  {
6520  case 0:
6521  /* Child. */
6522 #if __linux
6523  if (prctl (PR_SET_PDEATHSIG, SIGKILL))
6524  g_warning ("%s: Failed to change parent death signal;"
6525  " unix socket process will remain if parent is killed:"
6526  " %s\n",
6527  __FUNCTION__,
6528  strerror (errno));
6529 #endif
6530  break;
6531  case -1:
6532  /* Parent when error. */
6533  g_warning ("%s: Failed to fork for unix socket!\n", __FUNCTION__);
6534  exit (EXIT_FAILURE);
6535  break;
6536  default:
6537  /* Parent. */
6538  unix_pid = pid;
6539  no_redirect = TRUE;
6540  break;
6541  }
6542  }
6543 
6544  if (!no_redirect)
6545  {
6546  /* Fork for the redirect server. */
6547  g_debug ("Forking for redirect...\n");
6548  pid_t pid = fork ();
6549  switch (pid)
6550  {
6551  case 0:
6552  /* Child. */
6553 #if __linux
6554  if (prctl (PR_SET_PDEATHSIG, SIGKILL))
6555  g_warning ("%s: Failed to change parent death signal;"
6556  " redirect process will remain if parent is killed:"
6557  " %s\n",
6558  __FUNCTION__,
6559  strerror (errno));
6560 #endif
6561  redirect_location = g_strdup_printf ("https://%%s:%i/login/login.html",
6562  gsad_port);
6563  break;
6564  case -1:
6565  /* Parent when error. */
6566  g_critical ("%s: Failed to fork for redirect!\n", __FUNCTION__);
6567  exit (EXIT_FAILURE);
6568  break;
6569  default:
6570  /* Parent. */
6571  redirect_pid = pid;
6572  no_redirect = TRUE;
6573  break;
6574  }
6575  }
6576 
6577  /* Register the cleanup function. */
6578 
6579  if (atexit (&gsad_cleanup))
6580  {
6581  g_critical ("%s: Failed to register cleanup function!\n", __FUNCTION__);
6582  exit (EXIT_FAILURE);
6583  }
6584 
6585  /* Write pidfile. */
6586 
6587  if (pidfile_create ("gsad"))
6588  {
6589  g_critical ("%s: Could not write PID file.\n", __FUNCTION__);
6590  exit (EXIT_FAILURE);
6591  }
6592 
6593  /* Initialize addresses and accepted host headers for HTTP header */
6594  gsad_header_hosts = g_hash_table_new_full (g_str_hash, g_str_equal,
6595  g_free, NULL);
6596 
6597  if (gsad_address_string)
6598  {
6599  // Allow basic loopback addresses in Host header
6600  add_local_addresses (gsad_header_hosts, ipv6_is_enabled (), 1);
6601  // Listen to given addresses and allow them in Host header
6602  while (*gsad_address_string)
6603  {
6604  if (gsad_address_init (*gsad_address_string, gsad_port))
6605  return 1;
6606  gsad_address_string++;
6607  }
6608  }
6609  else
6610  {
6611  // Allow all local interface addresses in Host Header
6612  add_local_addresses (gsad_header_hosts, ipv6_is_enabled (), 0);
6613  // Listen on all addresses
6614  if (gsad_address_init (NULL, gsad_port))
6615  return 1;
6616  }
6617 
6618  if (gsad_header_host_strings)
6619  while (*gsad_header_host_strings)
6620  {
6621  g_hash_table_add (gsad_header_hosts,
6622  g_strdup (*gsad_header_host_strings));
6623  gsad_header_host_strings ++;
6624  }
6625 
6626  g_debug ("Accepting %d host addresses in Host headers",
6627  g_hash_table_size (gsad_header_hosts));
6628  if (verbose)
6629  {
6630  GHashTableIter iter;
6631  char *hostname;
6632  g_hash_table_iter_init (&iter, gsad_header_hosts);
6633  while (g_hash_table_iter_next (&iter, (void**)(&hostname), NULL))
6634  {
6635  g_debug ("- %s\n", hostname);
6636  }
6637  }
6638 
6639  if (!no_redirect)
6640  {
6641  /* Start the HTTP to HTTPS redirect server. */
6642  GSList *list = address_list;
6643 
6644  while (list)
6645  {
6646  gsad_address_set_port (list->data, gsad_redirect_port);
6647  gsad_daemon = start_http_daemon (gsad_redirect_port, redirect_handler,
6648  list->data);
6649  list = list->next;
6650  }
6651 
6652  if (gsad_daemon == NULL)
6653  {
6654  g_warning ("%s: start_http_daemon redirect failed !", __FUNCTION__);
6655  return EXIT_FAILURE;
6656  }
6657  else
6658  {
6659  g_debug ("GSAD started successfully and is redirecting on port %d.\n",
6660  gsad_redirect_port);
6661  }
6662  }
6663  else if (unix_socket_path && !unix_pid)
6664  {
6665  /* Start the unix socket server. */
6666 
6667  omp_init (gsad_manager_unix_socket_path,
6668  gsad_manager_address_string,
6669  gsad_manager_port);
6670 
6671  gsad_daemon = start_unix_http_daemon (unix_socket_path, handle_request);
6672 
6673  if (gsad_daemon == NULL)
6674  {
6675  g_warning ("%s: start_unix_http_daemon failed !", __FUNCTION__);
6676  return EXIT_FAILURE;
6677  }
6678  else
6679  {
6680  g_debug ("GSAD started successfully and is listening on unix"
6681  " socket %s.\n",
6682  unix_socket_path);
6683  }
6684  }
6685  else
6686  {
6687  /* Start the real server. */
6688 
6689  omp_init (gsad_manager_unix_socket_path,
6690  gsad_manager_address_string,
6691  gsad_manager_port);
6692 
6693  if (http_only)
6694  {
6695  GSList *list = address_list;
6696 
6697  while (list)
6698  {
6699  gsad_daemon = start_http_daemon (gsad_port, handle_request,
6700  list->data);
6701  if (gsad_daemon == NULL && gsad_port_string == NULL)
6702  {
6703  g_warning ("Binding to port %d failed, trying default port"
6704  " %d next.", gsad_port, DEFAULT_GSAD_PORT);
6705  gsad_port = DEFAULT_GSAD_PORT;
6706  gsad_address_set_port (list->data, gsad_port);
6707  gsad_daemon = start_http_daemon (gsad_port, handle_request,
6708  list->data);
6709  }
6710  list = list->next;
6711  }
6712  }
6713  else
6714  {
6715  gchar *ssl_private_key = NULL;
6716  gchar *ssl_certificate = NULL;
6717  gchar *dh_params = NULL;
6718  GSList *list = address_list;
6719 
6720  use_secure_cookie = 1;
6721 
6722  if (!g_file_get_contents (ssl_private_key_filename, &ssl_private_key,
6723  NULL, &error))
6724  {
6725  g_critical ("%s: Could not load private SSL key from %s: %s\n",
6726  __FUNCTION__,
6727  ssl_private_key_filename,
6728  error->message);
6729  g_error_free (error);
6730  exit (EXIT_FAILURE);
6731  }
6732 
6733  if (!g_file_get_contents (ssl_certificate_filename, &ssl_certificate,
6734  NULL, &error))
6735  {
6736  g_critical ("%s: Could not load SSL certificate from %s: %s\n",
6737  __FUNCTION__,
6738  ssl_certificate_filename,
6739  error->message);
6740  g_error_free (error);
6741  exit (EXIT_FAILURE);
6742  }
6743 
6744  if (dh_params_filename &&
6745  !g_file_get_contents (dh_params_filename, &dh_params, NULL,
6746  &error))
6747  {
6748  g_critical ("%s: Could not load SSL certificate from %s: %s\n",
6749  __FUNCTION__, dh_params_filename, error->message);
6750  g_error_free (error);
6751  exit (EXIT_FAILURE);
6752  }
6753 
6754  while (list)
6755  {
6756  gsad_daemon = start_https_daemon
6757  (gsad_port, ssl_private_key, ssl_certificate,
6758  gnutls_priorities, dh_params, list->data);
6759  if (gsad_daemon == NULL && gsad_port_string == NULL)
6760  {
6761  g_warning ("Binding to port %d failed, trying default port"
6762  " %d next.", gsad_port, DEFAULT_GSAD_PORT);
6763  gsad_port = DEFAULT_GSAD_PORT;
6764  gsad_address_set_port (list->data, gsad_port);
6765  gsad_daemon = start_https_daemon
6766  (gsad_port, ssl_private_key, ssl_certificate,
6767  gnutls_priorities, dh_params, list->data);
6768  }
6769  list = list->next;
6770  }
6771  }
6772 
6773  if (gsad_daemon == NULL)
6774  {
6775  g_critical ("%s: start_https_daemon failed!\n", __FUNCTION__);
6776  return EXIT_FAILURE;
6777  }
6778  else
6779  {
6780  g_debug ("GSAD started successfully and is listening on port %d.\n",
6781  gsad_port);
6782  }
6783  }
6784 
6785  /* Chroot and drop privileges, if requested. */
6786 
6787  if (chroot_drop_privileges (do_chroot, drop,
6788  face_name ? face_name : DEFAULT_GSAD_FACE))
6789  {
6790  if (face_name && strcmp (face_name, DEFAULT_GSAD_FACE))
6791  {
6792  g_critical ("%s: Cannot use custom face \"%s\".\n",
6793  __FUNCTION__, face_name);
6794  exit (EXIT_FAILURE);
6795  }
6796  else
6797  {
6798  g_critical ("%s: Cannot use default face \"%s\"!\n",
6799  __FUNCTION__, DEFAULT_GSAD_FACE);
6800  exit (EXIT_FAILURE);
6801  }
6802  }
6803 
6804  /* Wait forever for input or interrupts. */
6805 
6806 
6807  if (sigfillset (&sigmask_all))
6808  {
6809  g_critical ("%s: Error filling signal set\n", __FUNCTION__);
6810  exit (EXIT_FAILURE);
6811  }
6812  if (pthread_sigmask (SIG_BLOCK, &sigmask_all, &sigmask_current))
6813  {
6814  g_critical ("%s: Error setting signal mask\n", __FUNCTION__);
6815  exit (EXIT_FAILURE);
6816  }
6817  while (1)
6818  {
6819  if (termination_signal)
6820  {
6821  g_debug ("Received %s signal.\n", sys_siglist[termination_signal]);
6822  gsad_cleanup ();
6823  /* Raise signal again, to exit with the correct return value. */
6824  signal (termination_signal, SIG_DFL);
6825  raise (termination_signal);
6826  }
6827 
6828  if (pselect (0, NULL, NULL, NULL, NULL, &sigmask_current) == -1)
6829  {
6830  if (errno == EINTR)
6831  continue;
6832  g_critical ("%s: pselect: %s\n", __FUNCTION__, strerror (errno));
6833  exit (EXIT_FAILURE);
6834  }
6835  }
6836  return EXIT_SUCCESS;
6837 }
int openvas_validator_alias(validator_t validator, const char *alias, const char *name)
Make an alias for a rule name.
Definition: validator.c:125
int download_credential_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, gsize *result_len, char **html, char **login, cmd_response_data_t *response_data)
Export a Credential in a defined format.
Definition: gsad_omp.c:6328
char * export_filter_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a filter.
Definition: gsad_omp.c:24049
char * exec_omp_get(struct MHD_Connection *con, credentials_t *credentials, enum content_type *content_type, gchar **content_type_string, char **content_disposition, gsize *response_size, cmd_response_data_t *response_data)
Handle a complete GET request.
Definition: gsad.c:3040
char * export_user_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a user.
Definition: gsad_omp.c:25556
char * edit_agent(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit_agent XML, XSL transform the result.
Definition: gsad_omp.c:7259
#define HOST_HEADER_ERROR_PAGE
Definition: gsad.c:264
#define DEFAULT_GSAD_HTTP_PORT
Fallback GSAD port for HTTP.
Definition: gsad.c:138
size_t content_length
Content length.
Definition: gsad.c:1736
int answercode
HTTP response code.
Definition: gsad.c:1733
int gsad_init()
Initialization routine for GSAD.
Definition: gsad.c:5781
char * export_agents_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of agents.
Definition: gsad_omp.c:7579
struct MHD_Daemon * gsad_daemon
The handle on the embedded HTTP daemon.
Definition: gsad.c:276
char * address
Client&#39;s IP address.
Definition: gsad.c:428
gchar * pw_warning
Password policy warning.
Definition: gsad.c:427
int authenticate_omp(const gchar *username, const gchar *password, gchar **role, gchar **timezone, gchar **severity, gchar **capabilities, gchar **language, gchar **pw_warning, GTree **chart_prefs, gchar **autorefresh)
Check authentication credentials.
Definition: gsad_omp.c:27622
char * export_report_formats_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of Report Formats.
Definition: gsad_omp.c:13224
char * download_ssl_cert(openvas_connection_t *connection, credentials_t *credentials, params_t *params, gsize *response_size, cmd_response_data_t *response_data)
Get an SSL Certificate.
Definition: gsad_omp.c:14798
#define ELSE(name)
Add else branch for an OMP operation.
Definition: gsad.c:3016
void set_ext_gettext_enabled(int enabled)
Enable or disable gettext functions for extensions.
Definition: xslt_i18n.c:569
gchar * value
Definition: gsad_base.h:148
int gsad_base_cleanup()
Base init.
Definition: gsad_base.c:104
char * export_permissions_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of permissions.
Definition: gsad_omp.c:22236
char * edit_filter(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit_filter XML, XSL transform the result.
Definition: gsad_omp.c:24010
char * export_asset_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export an asset.
Definition: gsad_omp.c:27269
char * export_permission_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a permission.
Definition: gsad_omp.c:22210
user_t * user_add(const gchar *username, const gchar *password, const gchar *timezone, const gchar *severity, const gchar *role, const gchar *capabilities, const gchar *language, const gchar *pw_warning, GTree *chart_prefs, const gchar *autorefresh, const char *address)
Add a user.
Definition: gsad.c:469
char * save_my_settings_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *accept_language, char **timezone, char **password, char **severity, char **language, cmd_response_data_t *response_data)
Returns page with user&#39;s settings, for editing.
Definition: gsad_omp.c:19221
void cmd_response_data_init(cmd_response_data_t *data)
Initializes a cmd_response_data_t struct.
Definition: gsad_omp.c:348
int user_set_chart_pref(const gchar *token, gchar *pref_id, gchar *pref_value)
Set a chart preference of a user.
Definition: gsad.c:822
time_t time
Login time.
Definition: gsad.c:429
#define G_LOG_FATAL_MASK
Definition: gsad.c:115
char * capabilities
Capabilites of manager.
Definition: gsad_base.h:76
#define USER_GUEST_LOGIN_ERROR
Definition: gsad.c:521
#define DEFAULT_GSAD_FACE
Default face name.
Definition: gsad.c:178
param_t * params_get(params_t *params, const char *name)
Get param.
Definition: gsad_base.c:679
char * timezone
User&#39;s timezone.
Definition: gsad_base.h:72
content_type
Content types.
Definition: gsad_base.h:120
gchar * language
User Interface Language, in short form like "en".
Definition: gsad.c:426
char * export_users_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of users.
Definition: gsad_omp.c:25580
char * gsad_message(credentials_t *credentials, const char *title, const char *function, int line, const char *msg, const char *backurl, cmd_response_data_t *response_data)
Handles fatal errors.
Definition: gsad_base.c:467
char * edit_scanner(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit_scanner XML, XSL transform the result.
Definition: gsad_omp.c:17026
char * export_agent_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a agent.
Definition: gsad_omp.c:7554
char * SERVER_ERROR
Server error HTML.
Definition: gsad.c:249
params_t * params
Request parameters.
Definition: gsad.c:1729
#define DEFAULT_GSAD_LANGUAGE
Default language code, used when Accept-Language header is missing.
Definition: xslt_i18n.h:35
char * edit_asset(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit XML, XSL transform the result.
Definition: gsad_omp.c:27315
int params_given(params_t *params, const char *name)
Get whether a param was given at all.
Definition: gsad_base.c:695
#define USER_BAD_MISSING_COOKIE
Definition: gsad.c:516
gchar * guest_username
Guest username.
Definition: gsad.c:330
int user_set_language(const gchar *token, const gchar *language)
Set language of user.
Definition: gsad.c:762
char * save_user_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, char **password_return, char **modified_user, int *logout_user, cmd_response_data_t *response_data)
Modify a user, get all users, XSL transform the result.
Definition: gsad_omp.c:25325
gchar * http_guest_chart_x_frame_options
Current guest chart specific value for HTTP header "X-Frame-Options".
Definition: gsad.c:355
int unix_socket
Unix socket to listen on.
Definition: gsad.c:306
char * export_roles_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of roles.
Definition: gsad_omp.c:23424
char * export_preference_file_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a file preference.
Definition: gsad_omp.c:13097
char * caller
Caller URL, for POST relogin.
Definition: gsad_base.h:74
char * export_tags_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of tags.
Definition: gsad_omp.c:10506
char * export_results_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of results.
Definition: gsad_omp.c:14940
int send_response(struct MHD_Connection *connection, const char *content, int status_code, const gchar *sid, enum content_type content_type, const char *content_disposition, size_t content_length)
Sends a HTTP response.
Definition: gsad.c:4006
int charts
Whether to show charts for this user.
Definition: gsad.c:430
Response information for commands.
Definition: gsad_base.h:92
GHashTable * gsad_header_hosts
Host names and IP accepted in the "Host" HTTP header.
Definition: gsad.c:286
#define EXPIRES_LENGTH
Max length of cookie expires param.
Definition: gsad.c:3636
void omp_init(const gchar *manager_address_unix, const gchar *manager_address_tls, int port_manager)
Init the GSA OMP library.
Definition: gsad_omp.c:319
#define DEFAULT_GSAD_X_FRAME_OPTIONS
Default value for HTTP header "X-Frame-Options".
Definition: gsad.c:183
int main(int argc, char **argv)
Main routine of Greenbone Security Assistant daemon.
Definition: gsad.c:6092
int valid_utf8
Definition: gsad_base.h:153
void params_mhd_validate_values(const char *parent_name, void *params)
Validate param values.
Definition: gsad.c:1995
char * logout(credentials_t *credentials, const gchar *message, cmd_response_data_t *response_data)
Setup edit_user XML, XSL transform the result.
Definition: gsad_omp.c:25280
gchar * filename
Definition: gsad_base.h:150
validator_t openvas_validator_new()
Create a new validator.
Definition: validator.c:90
void user_remove(user_t *user)
Remove a user from the session "database", releasing the user_t too.
Definition: gsad.c:921
char * download_key_pub(openvas_connection_t *connection, credentials_t *credentials, params_t *params, gsize *response_size, cmd_response_data_t *response_data)
Get a Scanner&#39;s Certificate.
Definition: gsad_omp.c:14876
char * dashboard(openvas_connection_t *connection, credentials_t *credentials, params_t *params, cmd_response_data_t *response_data)
Show a dashboard.
Definition: gsad_omp.c:25685
char * new_permissions(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup new_permissions XML, XSL transform the result.
Definition: gsad_omp.c:21202
char * cvss_calculator(openvas_connection_t *connection, credentials_t *credentials, params_t *params, cmd_response_data_t *response_data)
Definition: gsad_omp.c:25590
void params_free(params_t *params)
Make a params.
Definition: gsad_base.c:664
void set_chroot_state(int state)
Sets the chroot state.
Definition: gsad_base.c:130
char * new_override(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Return the new overrides page.
Definition: gsad_omp.c:15950
int session_timeout
Maximum number of minutes of user idle time.
Definition: gsad.c:325
#define DEFAULT_GSAD_GUEST_CHART_X_FRAME_OPTIONS
Default value for HTTP header "X-Frame-Options" for guest charts.
Definition: gsad.c:196
void set_language_code(gchar **lang, const gchar *language)
Set language code of user.
Definition: gsad_base.c:218
void set_http_only(int state)
Sets the http_only state.
Definition: gsad_base.c:152
#define DATE_2822_LEN
At least maximum length of rfc2822 format date.
Definition: gsad.c:4286
#define USER_GUEST_LOGIN_FAILED
Definition: gsad.c:518
#define SESSION_TIMEOUT
Max number of minutes between activity in a session.
Definition: gsad.c:168
#define MHD_HTTP_NOT_ACCEPTABLE
The symbol is deprecated, but older versions (0.9.37 - Debian jessie) don&#39;t define it yet...
Definition: gsad.c:122
gchar * capabilities
Capabilities.
Definition: gsad.c:425
void openvas_validator_add(validator_t validator, const char *name, const char *regex)
Add or overwrite a validation rule.
Definition: validator.c:106
int connectiontype
1=POST, 2=GET.
Definition: gsad.c:1732
void cmd_response_data_reset(cmd_response_data_t *data)
Clears a cmd_response_data_t struct.
Definition: gsad_omp.c:360
#define USER_IP_ADDRESS_MISSMATCH
Definition: gsad.c:520
gchar * guest_password
Guest password.
Definition: gsad.c:335
int serve_post(void *coninfo_cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size)
Serves part of a POST request.
Definition: gsad.c:1968
char * edit_schedule(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit_schedule XML, XSL transform the result.
Definition: gsad_omp.c:24202
char * export_task_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a task.
Definition: gsad_omp.c:4993
Structure of credential related information.
Definition: gsad_base.h:66
char * export_configs_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of scan configs.
Definition: gsad_omp.c:12925
const char * params_original_value(params_t *params, const char *name)
Get original value of param, before validation.
Definition: gsad_base.c:745
GTree * chart_prefs
Chart preferences.
Definition: gsad.c:431
gchar * severity
Severity class.
Definition: gsad.c:424
#define DEFAULT_GSAD_PORT
Fallback unprivileged GSAD port.
Definition: gsad.c:143
gchar * original_value
Definition: gsad_base.h:149
char * edit_tag(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit_tag XML, XSL transform the result.
Definition: gsad_omp.c:10280
gchar * accept_language_to_env_fmt(const char *accept_language)
Convert an Accept-Language string to the LANGUAGE env variable form.
Definition: xslt_i18n.c:769
int user_set_password(const gchar *token, const gchar *password)
Set password of user.
Definition: gsad.c:700
char * username
Name of user.
Definition: gsad_base.h:69
const char * NOT_FOUND_TITLE
Title for "Page not found" messages.
Definition: gsad.c:227
char * get_system_report_omp(openvas_connection_t *connection, credentials_t *credentials, const char *url, params_t *params, enum content_type *content_type, gsize *content_length, cmd_response_data_t *response_data)
Return system report image.
Definition: gsad_omp.c:17777
int exec_omp_post(struct gsad_connection_info *con_info, user_t **user_return, gchar **new_sid, const char *client_address)
Handle a complete POST request.
Definition: gsad.c:2205
char * export_port_list_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a Port List.
Definition: gsad_omp.c:13046
gchar * openvas_validator_alias_for(validator_t validator, const char *alias)
Get the name of the rule for which a rule is an alias.
Definition: validator.c:157
char * edit_user(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit_user XML, XSL transform the result.
Definition: gsad_omp.c:25044
char * content_disposition
Content disposition of reponse.
Definition: gsad.c:1735
char * export_config_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a config.
Definition: gsad_omp.c:12900
char * process_bulk_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Returns a process_bulk page.
Definition: gsad_omp.c:26347
GSList * address_list
The IP addresses of this program, "the GSAD".
Definition: gsad.c:281
char * export_report_format_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a report format.
Definition: gsad_omp.c:13198
int user_set_autorefresh(const gchar *token, const gchar *autorefresh)
Set default autorefresh interval of user.
Definition: gsad.c:852
char * edit_alert(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit_alert XML, XSL transform the result.
Definition: gsad_omp.c:8723
char * edit_note(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Edit note, get next page, XSL transform the result.
Definition: gsad_omp.c:15664
GSList * log_config
Logging parameters, as passed to setup_log_handlers.
Definition: gsad.c:313
Headers/structs for a string validator.
char * autorefresh
Auto-refresh interval.
Definition: gsad_base.h:82
GTree * last_filt_ids
Last filter ids.
Definition: gsad_base.h:83
char * client_address
Client&#39;s address.
Definition: gsad_base.h:80
Special marker.
Definition: gsad_base.h:130
int openvas_validate(validator_t validator, const char *name, const char *value)
Validate a string for a given rule.
Definition: validator.c:182
void add_local_addresses(GHashTable *hashtable, int include_ipv6, int localhost_only)
Add all local IP addresses to a GHashTable.
Definition: gsad.c:3856
char * get_report_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, gsize *report_len, gchar **content_type, char **content_disposition, cmd_response_data_t *response_data)
Get a report and XSL transform the result.
Definition: gsad_omp.c:14595
char * edit_override(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Edit override, get next page, XSL transform the result.
Definition: gsad_omp.c:16377
gchar * redirect
Redirect URL.
Definition: gsad.c:1737
Connection information.
Definition: gsad.c:1725
char * token
Request session token.
Definition: gsad.c:419
gchar * timezone
Timezone.
Definition: gsad.c:423
char * export_alerts_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of alerts.
Definition: gsad_omp.c:9210
#define DEFAULT_GSAD_HSTS_MAX_AGE
Default "max-age" for HTTP header "Strict-Transport-Security".
Definition: gsad.c:209
char * export_credential_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a Credential.
Definition: gsad_omp.c:6517
Headers/structs used generally in GSA.
int value_size
Definition: gsad_base.h:154
char * export_schedules_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of schedules.
Definition: gsad_omp.c:24267
#define MAX_FILE_NAME_SIZE
Maximum length of "file name" for /help/ URLs.
Definition: gsad.c:163
void vendor_version_set(const gchar *version)
Set the vendor version.
Definition: gsad_base.c:163
pid_t unix_pid
PID of unix socket child in parent, 0 in child.
Definition: gsad.c:301
validator_t validator
Parameter validator.
Definition: gsad.c:993
struct timeval cmd_start
Seconds since command page handler started.
Definition: gsad_base.h:68
gchar * login_xml(const gchar *message, const gchar *token, const gchar *time, const gchar *url, const gchar *i18n, const gchar *guest)
Generate XML for login page.
Definition: gsad_base.c:584
pid_t redirect_pid
PID of redirect child in parent, 0 in child.
Definition: gsad.c:296
int guest
Whether the user is a guest.
Definition: gsad.c:434
int download_agent_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, gsize *result_len, char **html, char **filename, cmd_response_data_t *response_data)
Get an agent, XSL transform the result.
Definition: gsad_omp.c:7095
char * export_tasks_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of tasks.
Definition: gsad_omp.c:5017
char * response
HTTP response text.
Definition: gsad.c:1728
openvas_connection_t * openvas_connection
Definition: gsad.c:2915
char * BAD_REQUEST_PAGE
Bad request error HTML.
Definition: gsad.c:243
char * export_credentials_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of Credentials.
Definition: gsad_omp.c:6543
#define SID_COOKIE_NAME
Name of the cookie used to store the SID.
Definition: gsad.c:128
int array_len
Definition: gsad_base.h:155
char * xsl_transform_with_stylesheet(const char *xml_text, const char *xsl_stylesheet, cmd_response_data_t *response_data)
XSL Transformation.
Definition: gsad_base.c:281
char * save_chart_preference_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, gchar **pref_id, gchar **pref_value, cmd_response_data_t *response_data)
Save chart preferences.
Definition: gsad_omp.c:26000
params_t * params_new()
Make a params.
Definition: gsad_base.c:653
#define USER_BAD_MISSING_TOKEN
Definition: gsad.c:517
char * export_note_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a note.
Definition: gsad_omp.c:12948
#define params_t
Definition: gsad_base.h:61
void user_release(user_t *user)
Release a user_t returned by user_add or user_find.
Definition: gsad.c:910
char * export_port_lists_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of Port Lists.
Definition: gsad_omp.c:13072
#define DEFAULT_GSAD_HTTPS_PORT
Fallback GSAD port for HTTPS.
Definition: gsad.c:133
int user_logout_all_sessions(const gchar *username, credentials_t *credentials)
Logs out all sessions of a given user, except the current one.
Definition: gsad.c:882
char * get_info(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Requests SecInfo.
Definition: gsad_omp.c:5282
struct MHD_PostProcessor * postprocessor
POST processor.
Definition: gsad.c:1727
char * export_groups_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of groups.
Definition: gsad_omp.c:20448
int chroot_state
Whether chroot is used.
Definition: gsad.c:375
int user_set_severity(const gchar *token, const gchar *severity)
Set severity class of user.
Definition: gsad.c:732
int send_redirect_to_uri(struct MHD_Connection *connection, const char *uri, user_t *user)
Sends a HTTP redirection to an uri.
Definition: gsad.c:4059
char * export_targets_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of targets.
Definition: gsad_omp.c:11230
Request parameter.
Definition: gsad_base.h:146
gchar * http_x_frame_options
Current value for HTTP header "X-Frame-Options".
Definition: gsad.c:345
int send_redirect_to_urn(struct MHD_Connection *connection, const char *urn, user_t *user)
Sends an HTTP redirection response to an urn.
Definition: gsad.c:4128
void free_resources(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Free resources.
Definition: gsad.c:1772
int gsad_base_init()
Base init.
Definition: gsad_base.c:87
GPtrArray * users
User session data.
Definition: gsad.c:340
#define USER_EXPIRED_TOKEN
Definition: gsad.c:515
pthread_mutex_t mutex
Definition: gsad.c:2917
void gsad_cleanup()
Cleanup routine for GSAD.
Definition: gsad.c:5856
int guest
Whether the user is a guest user.
Definition: gsad_base.h:86
param_t * params_append_bin(params_t *params, const char *name, const char *chunk_data, int chunk_size, int chunk_offset)
Append binary data to a param.
Definition: gsad_base.c:841
gchar * username
Login name.
Definition: gsad.c:420
char * export_assets_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of assets.
Definition: gsad_omp.c:27294
char * token
Session token.
Definition: gsad_base.h:73
char * export_override_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export an override.
Definition: gsad_omp.c:12995
const char * params_value(params_t *params, const char *name)
Get value of param.
Definition: gsad_base.c:711
char * new_filter_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, cmd_response_data_t *response_data)
Returns page to create a new filter.
Definition: gsad_omp.c:24094
char * export_scanners_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of scanners.
Definition: gsad_omp.c:16703
char * export_alert_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export an alert.
Definition: gsad_omp.c:9185
char * download_ca_pub(openvas_connection_t *connection, credentials_t *credentials, params_t *params, gsize *response_size, cmd_response_data_t *response_data)
Get a Scanner&#39;s CA Certificate.
Definition: gsad_omp.c:14841
void handle_signal_exit(int signal)
Handle a SIGINT signal.
Definition: gsad.c:5876
gboolean params_iterator_next(params_iterator_t *iterator, char **name, param_t **param)
Increment a params iterator.
Definition: gsad_base.c:887
GTree * last_filt_ids
Last used filter ids.
Definition: gsad.c:433
char * language
Language code e.g. en.
Definition: gsad.c:1731
int init_language_lists()
Initialize the list of available languages.
Definition: xslt_i18n.c:580
char * role
User&#39;s role.
Definition: gsad_base.h:71
char * edit_target(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit_target XML, XSL transform the result.
Definition: gsad_omp.c:10692
const gchar * vendor_version_get()
Get the vendor version.
Definition: gsad_base.c:175
int charts
Whether to show charts for this user.
Definition: gsad_base.h:85
char * export_scanner_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a scanner.
Definition: gsad_omp.c:16678
char * pw_warning
Password policy warning message.
Definition: gsad_base.h:79
User information structure, for sessions.
Definition: gsad.c:416
int user_find(const gchar *cookie, const gchar *token, const char *address, user_t **user_return)
Find a user, given a token and cookie.
Definition: gsad.c:539
gchar * redirect
HTTP status code.
Definition: gsad_base.h:94
char * export_schedule_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a schedule.
Definition: gsad_omp.c:24242
char * export_omp_doc_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Download the OMP doc.
Definition: gsad_omp.c:20023
void add_guest_chart_content_security_headers(struct MHD_Response *response)
Add guest chart content security headers to a MHD response.
Definition: gsad.c:403
gchar * http_content_security_policy
Current value for HTTP header "Content-Security-Policy".
Definition: gsad.c:350
char * export_group_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a group.
Definition: gsad_omp.c:20423
char * xsl_transform(const char *xml_text, cmd_response_data_t *response_data)
XSL Transformation.
Definition: gsad_base.c:445
#define UTF8_ERROR_PAGE(location)
Definition: gsad.c:255
void init_validator()
Initialise the parameter validator.
Definition: gsad.c:999
GHashTable * validator_t
A set of name rule pairs.
Definition: validator.h:40
GTree * chart_prefs
Chart preferences.
Definition: gsad_base.h:81
#define USER_OMP_DOWN
Definition: gsad.c:519
#define DEFAULT_CLIENT_WATCH_INTERVAL
Default value for client_watch_interval.
Definition: gsad.c:173
volatile int termination_signal
Flag for signal handler.
Definition: gsad.c:214
#define USER_BAD_TOKEN
Definition: gsad.c:514
char * new_note(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Return the new notes page.
Definition: gsad_omp.c:15269
char * get_report_section_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, cmd_response_data_t *response_data)
Get a report section, XSL transform the result.
Definition: gsad_omp.c:14779
const char * ERROR_PAGE
Error page HTML.
Definition: gsad.c:238
char * severity
Severity class.
Definition: gsad_base.h:78
gchar * http_guest_chart_content_security_policy
Current guest chart value for HTTP header "Content-Security-Policy".
Definition: gsad.c:360
char * export_target_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a target.
Definition: gsad_omp.c:11205
#define MAX_HOST_LEN
Maximum length of the host portion of the redirect address.
Definition: gsad.c:4116
#define DEFAULT_GSAD_REDIRECT_PORT
Fallback GSAD port.
Definition: gsad.c:148
gboolean ignore_http_x_real_ip
Current preference for using X_Real_IP from HTTP header.
Definition: gsad.c:370
gchar * password
Password.
Definition: gsad.c:421
void add_security_headers(struct MHD_Response *response)
Add security headers to a MHD response.
Definition: gsad.c:386
#define params_iterator_init
Definition: gsad_base.h:189
char * current_page
Current page URL, for refresh.
Definition: gsad_base.h:75
gchar * role
Role.
Definition: gsad.c:422
char * cookie
Value of SID cookie param.
Definition: gsad.c:1730
const char * NOT_FOUND_MESSAGE
Main message for "Page not found" messages.
Definition: gsad.c:233
char * language
Accept-Language browser header.
Definition: gsad_base.h:77
gchar * redirect_location
Location for redirection server.
Definition: gsad.c:291
int user_set_timezone(const gchar *token, const gchar *timezone)
Set timezone of user.
Definition: gsad.c:670
char * cookie
Cookie token.
Definition: gsad.c:418
char * new_permission(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup new_permission XML, XSL transform the result.
Definition: gsad_omp.c:20675
char * export_filters_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of filters.
Definition: gsad_omp.c:24074
int use_secure_cookie
Whether to use a secure cookie.
Definition: gsad.c:320
int manager_connect(credentials_t *credentials, openvas_connection_t *connection, cmd_response_data_t *response_data)
Connect to OpenVAS Manager daemon.
Definition: gsad_omp.c:27835
#define DEFAULT_OPENVAS_MANAGER_PORT
Fallback Manager port.
Definition: gsad.c:153
int valid
Definition: gsad_base.h:152
int redirect_handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
HTTP request handler for GSAD.
Definition: gsad.c:4201
params_t * params
Request parameters.
Definition: gsad_base.h:84
char * ctime_r_strip_newline(time_t *time, char *string)
Return string from ctime_r with newline replaces with terminator.
Definition: gsad_base.c:241
gchar * autorefresh
Auto-Refresh interval.
Definition: gsad.c:432
char * export_role_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a role.
Definition: gsad_omp.c:23400
#define params_iterator_t
Definition: gsad_base.h:187
#define USER_OK
Definition: gsad.c:513
GCRY_THREAD_OPTION_PTHREAD_IMPL
Libgcrypt thread callback definition for libgcrypt < 1.6.0.
Definition: gsad.c:220
Headers for GSA&#39;s OMP communication module.
char * export_result_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a result.
Definition: gsad_omp.c:14915
char * edit_group(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit_group XML, XSL transform the result.
Definition: gsad_omp.c:20384
char * edit_permission(openvas_connection_t *connection, credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Setup edit_permission XML, XSL transform the result.
Definition: gsad_omp.c:22026
#define POST_BUFFER_SIZE
Buffer size for POST processor.
Definition: gsad.c:158
int client_watch_interval
Interval in seconds to check whether client connection was closed.
Definition: gsad.c:380
int user_set_charts(const gchar *token, const int charts)
Set charts setting of user.
Definition: gsad.c:792
int label_name_set(const gchar *name)
Set the login label.
Definition: gsad_base.c:199
gchar * http_strict_transport_security
Current value of for HTTP header "Strict-Transport-Security".
Definition: gsad.c:365
params_t * values
Definition: gsad_base.h:151
int token_user_remove(const char *token)
Remove a user from the session "database", releasing the user_t too.
Definition: gsad.c:980
char * password
User&#39;s password.
Definition: gsad_base.h:70
char * export_notes_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of notes.
Definition: gsad_omp.c:12972
param_t * params_add(params_t *params, const char *name, const char *value)
Add a param.
Definition: gsad_base.c:808
#define DEFAULT_GSAD_GUEST_CHART_CONTENT_SECURITY_POLICY
Default guest charts value for HTTP header "Content-Security-Policy".
Definition: gsad.c:201
char * export_tag_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a tag.
Definition: gsad_omp.c:10482
int handle_request(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
HTTP request handler for GSAD.
Definition: gsad.c:4598
char * export_overrides_omp(openvas_connection_t *connection, credentials_t *credentials, params_t *params, enum content_type *content_type, char **content_disposition, gsize *content_length, cmd_response_data_t *response_data)
Export a list of overrides.
Definition: gsad_omp.c:13021
#define DEFAULT_GSAD_CONTENT_SECURITY_POLICY
Default value for HTTP header "Content-Security-Policy".
Definition: gsad.c:188
enum content_type content_type
Content type of response.
Definition: gsad.c:1734
int token_user(const gchar *token, user_t **user_return)
Find a user, given a token.
Definition: gsad.c:938