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;
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);
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;
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);
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 
1725 struct gsad_connection_info
1726 {
1727  struct MHD_PostProcessor *postprocessor;
1728  char *response;
1729  params_t *params;
1730  char *cookie;
1731  char *language;
1732  int connectiontype;
1733  int answercode;
1734  enum content_type content_type;
1735  char *content_disposition;
1736  size_t content_length;
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  {
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  {
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  {
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  {
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  {
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 {
2914  int client_socket_fd;
2915  openvas_connection_t *openvas_connection;
2916  int connection_closed;
2917  pthread_mutex_t mutex;
2918 } connection_watcher_data_t;
2919 
2929 static connection_watcher_data_t*
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 
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  {
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  {
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  {
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  {
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  {
4231  send_response (connection, ERROR_PAGE, MHD_HTTP_NOT_ACCEPTABLE,
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"))
4360  else if (strstr (path, ".svg"))
4362  else if (strstr (path, ".html"))
4364  else if (strstr (path, ".css"))
4366  else if (strstr (path, ".js"))
4368  else if (strstr (path, ".txt"))
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. */
4473  send_response (connection, BAD_REQUEST_PAGE, MHD_HTTP_NOT_ACCEPTABLE,
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  {
4632  send_response (connection, BAD_REQUEST_PAGE, MHD_HTTP_NOT_ACCEPTABLE,
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 
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"))
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;
5530  con_info->content_type = GSAD_CONTENT_TYPE_TEXT_HTML;
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  {
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
5781 gsad_init ()
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
5856 gsad_cleanup ()
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
5876 handle_signal_exit (int signal)
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 
5931  memset (&addr, 0, sizeof (struct sockaddr_un));
5932 
5933  addr.sun_family = AF_UNIX;
5934  strncpy (addr.sun_path, unix_socket_path, sizeof (addr.sun_path) - 1);
5935  if (!stat (addr.sun_path, &ustat))
5936  {
5937  /* Remove socket so we can bind(). Keep same permissions when recreating
5938  * it. */
5939  unlink (addr.sun_path);
5940  oldmask = umask (~ustat.st_mode);
5941  }
5942  if (bind (unix_socket, (struct sockaddr *) &addr, sizeof (struct sockaddr_un))
5943  == -1)
5944  {
5945  g_warning ("%s: Error on bind(%s): %s", __FUNCTION__,
5946  unix_socket_path, strerror (errno));
5947  return NULL;
5948  }
5949  if (oldmask)
5950  umask (oldmask);
5951  if (listen (unix_socket, 128) == -1)
5952  {
5953  g_warning ("%s: Error on listen(): %s", __FUNCTION__, strerror (errno));
5954  return NULL;
5955  }
5956 
5957  return MHD_start_daemon
5958  (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, 0,
5959  NULL, NULL, handler, NULL, MHD_OPTION_NOTIFY_COMPLETED,
5960  free_resources, NULL, MHD_OPTION_LISTEN_SOCKET, unix_socket,
5961  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 30,
5962  MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, NULL, MHD_OPTION_END);
5963 }
5964 
5965 static struct MHD_Daemon *
5966 start_http_daemon (int port,
5967  int handler (void *, struct MHD_Connection *, const char *,
5968  const char *, const char *, const char *,
5969  size_t *, void **),
5970  struct sockaddr_storage *address)
5971 {
5972  int ipv6_flag;
5973 
5974  if (address->ss_family == AF_INET6)
5975 /* LibmicroHTTPD 0.9.28 and higher. */
5976 #if MHD_VERSION >= 0x00092800
5977  ipv6_flag = MHD_USE_DUAL_STACK;
5978 #else
5979  ipv6_flag = MHD_USE_IPv6;
5980 #endif
5981  else
5982  ipv6_flag = MHD_NO_FLAG;
5983  return MHD_start_daemon
5984  (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | ipv6_flag, port,
5985  NULL, NULL, handler, NULL, MHD_OPTION_NOTIFY_COMPLETED,
5986  free_resources, NULL, MHD_OPTION_SOCK_ADDR, address,
5987  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 30,
5988  MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, NULL, MHD_OPTION_END);
5989 }
5990 
5991 static struct MHD_Daemon *
5992 start_https_daemon (int port, const char *key, const char *cert,
5993  const char *priorities, const char *dh_params,
5994  struct sockaddr_storage *address)
5995 {
5996  int ipv6_flag;
5997 
5998  if (address->ss_family == AF_INET6)
5999 /* LibmicroHTTPD 0.9.28 and higher. */
6000 #if MHD_VERSION >= 0x00092800
6001  ipv6_flag = MHD_USE_DUAL_STACK;
6002 #else
6003  ipv6_flag = MHD_USE_IPv6;
6004 #endif
6005  else
6006  ipv6_flag = MHD_NO_FLAG;
6007  return MHD_start_daemon
6008  (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | MHD_USE_SSL
6009  | ipv6_flag, port, NULL, NULL, &handle_request, NULL,
6010  MHD_OPTION_HTTPS_MEM_KEY, key,
6011  MHD_OPTION_HTTPS_MEM_CERT, cert,
6012  MHD_OPTION_NOTIFY_COMPLETED, free_resources, NULL,
6013  MHD_OPTION_SOCK_ADDR, address,
6014  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 30,
6015  MHD_OPTION_HTTPS_PRIORITIES, priorities,
6016  MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, NULL,
6017 /* LibmicroHTTPD 0.9.35 and higher. */
6018 #if MHD_VERSION >= 0x00093500
6019  dh_params ? MHD_OPTION_HTTPS_MEM_DHPARAMS : MHD_OPTION_END,
6020  dh_params,
6021 #endif
6022  MHD_OPTION_END);
6023 }
6024 
6031 static void
6032 gsad_address_set_port (struct sockaddr_storage *address, int port)
6033 {
6034  struct sockaddr_in *gsad_address = (struct sockaddr_in *) address;
6035  struct sockaddr_in6 *gsad_address6 = (struct sockaddr_in6 *) address;
6036 
6037  gsad_address->sin_port = htons (port);
6038  gsad_address6->sin6_port = htons (port);
6039 }
6040 
6051 static int
6052 gsad_address_init (const char *address_str, int port)
6053 {
6054  struct sockaddr_storage *address = g_malloc0 (sizeof (*address));
6055  struct sockaddr_in *gsad_address = (struct sockaddr_in *) address;
6056  struct sockaddr_in6 *gsad_address6 = (struct sockaddr_in6 *) address;
6057 
6058  gsad_address_set_port (address, port);
6059  if (address_str)
6060  {
6061  if (inet_pton (AF_INET6, address_str, &gsad_address6->sin6_addr) > 0)
6062  address->ss_family = AF_INET6;
6063  else if (inet_pton (AF_INET, address_str, &gsad_address->sin_addr) > 0)
6064  address->ss_family = AF_INET;
6065  else
6066  {
6067  g_warning ("Failed to create GSAD address %s", address_str);
6068  g_free (address);
6069  return 1;
6070  }
6071  g_hash_table_add (gsad_header_hosts, g_strdup (address_str));
6072  }
6073  else
6074  {
6075  gsad_address->sin_addr.s_addr = INADDR_ANY;
6076  gsad_address6->sin6_addr = in6addr_any;
6077  if (ipv6_is_enabled ())
6078  address->ss_family = AF_INET6;
6079  else
6080  address->ss_family = AF_INET;
6081  }
6082  address_list = g_slist_append (address_list, address);
6083  return 0;
6084 }
6085 
6094 int
6095 main (int argc, char **argv)
6096 {
6097  gchar *rc_name;
6098  gchar *old_locale;
6099  char *locale;
6100  int gsad_port;
6101  int gsad_redirect_port = DEFAULT_GSAD_REDIRECT_PORT;
6102  int gsad_manager_port = DEFAULT_OPENVAS_MANAGER_PORT;
6103  sigset_t sigmask_all, sigmask_current;
6104 
6105  /* Initialise. */
6106 
6107  if (gsad_init () == MHD_NO)
6108  {
6109  g_critical ("%s: Initialization failed!\nExiting...\n", __FUNCTION__);
6110  exit (EXIT_FAILURE);
6111  }
6112 
6113  /* Process command line options. */
6114 
6115  static gboolean do_chroot = FALSE;
6116  static gchar *drop = NULL;
6117  static gboolean foreground = FALSE;
6118  static gboolean http_only = FALSE;
6119  static gboolean print_version = FALSE;
6120  static gboolean no_redirect = FALSE;
6121  static gboolean secure_cookie = FALSE;
6122  static int timeout = SESSION_TIMEOUT;
6123  static gchar **gsad_address_string = NULL;
6124  static gchar **gsad_header_host_strings = NULL;
6125  static gchar *gsad_manager_address_string = NULL;
6126  static gchar *gsad_manager_unix_socket_path = NULL;
6127  static gchar *gsad_port_string = NULL;
6128  static gchar *gsad_redirect_port_string = NULL;
6129  static gchar *gsad_manager_port_string = NULL;
6130  static gchar *gsad_vendor_version_string = NULL;
6131  static gchar *gsad_login_label_name = NULL;
6132  static gchar *ssl_private_key_filename = OPENVAS_SERVER_KEY;
6133  static gchar *ssl_certificate_filename = OPENVAS_SERVER_CERTIFICATE;
6134  static gchar *dh_params_filename = NULL;
6135  static gchar *unix_socket_path = NULL;
6136  static gchar *gnutls_priorities = "NORMAL";
6137  static int debug_tls = 0;
6138  static gchar *face_name = NULL;
6139  static gchar *guest_user = NULL;
6140  static gchar *guest_pass = NULL;
6141  static gchar *http_frame_opts = DEFAULT_GSAD_X_FRAME_OPTIONS;
6142  static gchar *http_csp = DEFAULT_GSAD_CONTENT_SECURITY_POLICY;
6143  static gchar *http_guest_chart_frame_opts
6145  static gchar *http_guest_chart_csp
6147  static int hsts_enabled = FALSE;
6148  static int hsts_max_age = DEFAULT_GSAD_HSTS_MAX_AGE;
6149  static gboolean ignore_x_real_ip = FALSE;
6150  static int verbose = 0;
6151  GError *error = NULL;
6152  GOptionContext *option_context;
6153  static GOptionEntry option_entries[] = {
6154  {"allow-header-host", '\0',
6155  0, G_OPTION_ARG_STRING_ARRAY, &gsad_header_host_strings,
6156  "Allow <host> as hostname/address part of a Host header."
6157  "<host>" },
6158  {"drop-privileges", '\0',
6159  0, G_OPTION_ARG_STRING, &drop,
6160  "Drop privileges to <user>.", "<user>" },
6161  {"foreground", 'f',
6162  0, G_OPTION_ARG_NONE, &foreground,
6163  "Run in foreground.", NULL},
6164  {"http-only", '\0',
6165  0, G_OPTION_ARG_NONE, &http_only,
6166  "Serve HTTP only, without SSL.", NULL},
6168  {"listen", '\0',
6169  0, G_OPTION_ARG_STRING_ARRAY, &gsad_address_string,
6170  "Listen on <address>.", "<address>" },
6171  {"mlisten", '\0',
6172  0, G_OPTION_ARG_STRING, &gsad_manager_address_string,
6173  "Manager address.", "<address>" },
6174  {"port", 'p',
6175  0, G_OPTION_ARG_STRING, &gsad_port_string,
6176  "Use port number <number>.", "<number>"},
6177  {"mport", 'm',
6178  0, G_OPTION_ARG_STRING, &gsad_manager_port_string,
6179  "Use manager port number <number>.", "<number>"},
6180  {"rport", 'r',
6181  0, G_OPTION_ARG_STRING, &gsad_redirect_port_string,
6182  "Redirect HTTP from this port number <number>.", "<number>"},
6183  {"no-redirect", '\0',
6184  0, G_OPTION_ARG_NONE, &no_redirect,
6185  "Don't redirect HTTP to HTTPS.", NULL },
6186  {"verbose", 'v',
6187  0, G_OPTION_ARG_NONE, &verbose,
6188  "Has no effect. See INSTALL for logging config.", NULL },
6189  {"version", 'V',
6190  0, G_OPTION_ARG_NONE, &print_version,
6191  "Print version and exit.", NULL},
6192  {"vendor-version", '\0',
6193  0, G_OPTION_ARG_STRING, &gsad_vendor_version_string,
6194  "Use <string> as version in interface.", "<string>"},
6195  {"login-label", '\0',
6196  0, G_OPTION_ARG_STRING, &gsad_login_label_name,
6197  "Use <string> as login label.", "<string>"},
6198  {"ssl-private-key", 'k',
6199  0, G_OPTION_ARG_FILENAME, &ssl_private_key_filename,
6200  "Use <file> as the private key for HTTPS", "<file>"},
6201  {"ssl-certificate", 'c',
6202  0, G_OPTION_ARG_FILENAME, &ssl_certificate_filename,
6203  "Use <file> as the certificate for HTTPS", "<file>"},
6204  {"dh-params", '\0',
6205  0, G_OPTION_ARG_FILENAME, &dh_params_filename,
6206  "Diffie-Hellman parameters file", "<file>"},
6207  {"do-chroot", '\0',
6208  0, G_OPTION_ARG_NONE, &do_chroot,
6209  "Do chroot.", NULL},
6210  {"secure-cookie", '\0',
6211  0, G_OPTION_ARG_NONE, &secure_cookie,
6212  "Use a secure cookie (implied when using HTTPS).", NULL},
6213  {"timeout", '\0',
6214  0, G_OPTION_ARG_INT, &timeout,
6215  "Minutes of user idle time before session expires.", "<number>"},
6216  {"client-watch-interval", '\0',
6217  0, G_OPTION_ARG_INT, &client_watch_interval,
6218  "Check if client connection was closed every <number> seconds."
6219  " 0 to disable. Defaults to " G_STRINGIFY (DEFAULT_CLIENT_WATCH_INTERVAL)
6220  " seconds.",
6221  "<number>"},
6222  {"debug-tls", 0,
6223  0, G_OPTION_ARG_INT, &debug_tls,
6224  "Enable TLS debugging at <level>", "<level>"},
6225  {"gnutls-priorities", '\0',
6226  0, G_OPTION_ARG_STRING, &gnutls_priorities,
6227  "GnuTLS priorities string.", "<string>"},
6228  {"face", 0,
6229  0, G_OPTION_ARG_STRING, &face_name,
6230  "Use interface files from subdirectory <dir>", "<dir>"},
6231  {"guest-username", 0,
6232  0, G_OPTION_ARG_STRING, &guest_user,
6233  "Username for guest user. Enables guest logins.", "<name>"},
6234  {"guest-password", 0,
6235  0, G_OPTION_ARG_STRING, &guest_pass,
6236  "Password for guest user. Defaults to guest username.", "<password>"},
6237  {"http-frame-opts", 0,
6238  0, G_OPTION_ARG_STRING, &http_frame_opts,
6239  "X-Frame-Options HTTP header. Defaults to \""
6240  DEFAULT_GSAD_X_FRAME_OPTIONS "\".", "<frame-opts>"},
6241  {"http-csp", 0,
6242  0, G_OPTION_ARG_STRING, &http_csp,
6243  "Content-Security-Policy HTTP header. Defaults to \""
6244  DEFAULT_GSAD_CONTENT_SECURITY_POLICY"\".", "<csp>"},
6245  {"http-guest-chart-frame-opts", 0,
6246  0, G_OPTION_ARG_STRING, &http_guest_chart_frame_opts,
6247  "X-Frame-Options HTTP header for guest charts. Defaults to \""
6248  DEFAULT_GSAD_GUEST_CHART_X_FRAME_OPTIONS "\".", "<frame-opts>"},
6249  {"http-guest-chart-csp", 0,
6250  0, G_OPTION_ARG_STRING, &http_guest_chart_csp,
6251  "Content-Security-Policy HTTP header. Defaults to \""
6253  {"http-sts", 0,
6254  0, G_OPTION_ARG_NONE, &hsts_enabled,
6255  "Enable HTTP Strict-Tranport-Security header.", NULL},
6256  {"http-sts-max-age", 0,
6257  0, G_OPTION_ARG_INT, &hsts_max_age,
6258  "max-age in seconds for HTTP Strict-Tranport-Security header."
6259  " Defaults to \"" G_STRINGIFY (DEFAULT_GSAD_HSTS_MAX_AGE) "\".",
6260  "<max-age>"},
6261  {"ignore-x-real-ip", '\0',
6262  0, G_OPTION_ARG_NONE, &ignore_x_real_ip,
6263  "Do not use X-Real-IP to determine the client address.", NULL},
6264  {"unix-socket", '\0',
6265  0, G_OPTION_ARG_FILENAME, &unix_socket_path,
6266  "Path to unix socket to listen on", "<file>"},
6267  {"munix-socket", '\0',
6268  0, G_OPTION_ARG_FILENAME, &gsad_manager_unix_socket_path,
6269  "Path to Manager unix socket", "<file>"},
6270  {NULL}
6271  };
6272 
6273  option_context =
6274  g_option_context_new ("- Greenbone Security Assistant Daemon");
6275  g_option_context_add_main_entries (option_context, option_entries, NULL);
6276  if (!g_option_context_parse (option_context, &argc, &argv, &error))
6277  {
6278  g_critical ("%s: %s\n\n", __FUNCTION__, error->message);
6279  exit (EXIT_FAILURE);
6280  }
6281  g_option_context_free (option_context);
6282 
6283  http_x_frame_options = http_frame_opts;
6284  http_content_security_policy = http_csp;
6285  http_guest_chart_x_frame_options = http_guest_chart_frame_opts;
6286  http_guest_chart_content_security_policy = http_guest_chart_csp;
6287 
6288  set_http_only (!!http_only);
6289 
6290  if (http_only == FALSE && hsts_enabled)
6291  {
6293  = g_strdup_printf ("max-age=%d",
6294  hsts_max_age >= 0 ? hsts_max_age
6296  }
6297  else
6299 
6300  ignore_http_x_real_ip = ignore_x_real_ip;
6301 
6302  if (register_signal_handlers ())
6303  {
6304  g_critical ("Failed to register signal handlers!\n");
6305  exit (EXIT_FAILURE);
6306  }
6307 
6308  if (print_version)
6309  {
6310  printf ("Greenbone Security Assistant %s\n", GSAD_VERSION);
6311 #ifdef GSAD_GIT_REVISION
6312  printf ("GIT revision %s\n", GSAD_GIT_REVISION);
6313 #endif
6314  if (debug_tls)
6315  {
6316  printf ("gnutls %s\n", gnutls_check_version (NULL));
6317  printf ("libmicrohttpd %s\n", MHD_get_version ());
6318  }
6319  printf ("Copyright (C) 2010-2016 Greenbone Networks GmbH\n");
6320  printf ("License GPLv2+: GNU GPL version 2 or later\n");
6321  printf
6322  ("This is free software: you are free to change and redistribute it.\n"
6323  "There is NO WARRANTY, to the extent permitted by law.\n\n");
6324  exit (EXIT_SUCCESS);
6325  }
6326 
6327  if (debug_tls)
6328  {
6329  gnutls_global_set_log_function (my_gnutls_log_func);
6330  gnutls_global_set_log_level (debug_tls);
6331  }
6332 
6333  switch (gsad_base_init ())
6334  {
6335  case 1:
6336  g_critical ("%s: libxml must be compiled with thread support\n",
6337  __FUNCTION__);
6338  exit (EXIT_FAILURE);
6339  }
6340 
6341  if (gsad_vendor_version_string)
6342  vendor_version_set (gsad_vendor_version_string);
6343 
6344  if (gsad_login_label_name)
6345  {
6346  if (label_name_set (gsad_login_label_name))
6347  {
6348  g_critical ("Invalid character in login label name\n");
6349  exit (EXIT_FAILURE);
6350  }
6351  }
6352 
6353  if (no_redirect && gsad_redirect_port_string)
6354  {
6355  g_warning ("--no-redirect option given with --rport");
6356  return 1;
6357  }
6358 
6359  /* Switch to UTC for scheduling. */
6360 
6361  if (setenv ("TZ", "utc 0", 1) == -1)
6362  {
6363  g_critical ("%s: failed to set timezone\n", __FUNCTION__);
6364  exit (EXIT_FAILURE);
6365  }
6366  tzset ();
6367 
6368  /* Setup logging. */
6369 
6370  rc_name = g_build_filename (GSA_CONFIG_DIR, "gsad_log.conf", NULL);
6371  if (g_file_test (rc_name, G_FILE_TEST_EXISTS))
6372  log_config = load_log_configuration (rc_name);
6373  g_free (rc_name);
6374  setup_log_handlers (log_config);
6375  /* Set to ensure that recursion is left out, in case two threads log
6376  * concurrently. */
6377  g_log_set_always_fatal (G_LOG_FATAL_MASK);
6378 
6379 #ifdef GSAD_GIT_REVISION
6380  g_message ("Starting GSAD version %s (GIT revision %s)\n",
6381  GSAD_VERSION,
6382  GSAD_GIT_REVISION);
6383 #else
6384  g_message ("Starting GSAD version %s\n",
6385  GSAD_VERSION);
6386 #endif
6387 
6388  /* Finish processing the command line options. */
6389 
6390  use_secure_cookie = secure_cookie;
6391 
6392  if ((timeout < 1) || (timeout > 1440))
6393  {
6394  g_critical ("%s: Timeout must be a number from 1 to 1440\n",
6395  __FUNCTION__);
6396  exit (EXIT_FAILURE);
6397  }
6398  session_timeout = timeout;
6399 
6400  if (client_watch_interval < 0)
6401  {
6403  }
6404 
6405  if (guest_user)
6406  {
6407  guest_username = guest_user;
6408  guest_password = guest_pass ? guest_pass : guest_user;
6409  }
6410 
6411  gsad_port = http_only ? DEFAULT_GSAD_HTTP_PORT : DEFAULT_GSAD_HTTPS_PORT;
6412 
6413  if (gsad_port_string)
6414  {
6415  gsad_port = atoi (gsad_port_string);
6416  if (gsad_port <= 0 || gsad_port >= 65536)
6417  {
6418  g_critical ("%s: Port must be a number between 0 and 65536\n",
6419  __FUNCTION__);
6420  exit (EXIT_FAILURE);
6421  }
6422  }
6423 
6424  if (gsad_manager_port_string)
6425  {
6426  gsad_manager_port = atoi (gsad_manager_port_string);
6427  if (gsad_manager_port <= 0 || gsad_manager_port >= 65536)
6428  {
6429  g_critical ("%s: Manager port must be a number between 0 and 65536\n",
6430  __FUNCTION__);
6431  exit (EXIT_FAILURE);
6432  }
6433  }
6434 
6435  /* Set and test the base locale for XSLt gettext */
6436  old_locale = g_strdup (setlocale (LC_ALL, NULL));
6437 
6438  locale = setlocale (LC_ALL, "");
6439  if (locale == NULL)
6440  {
6441  g_warning ("%s: "
6442  "Failed to set locale according to environment variables,"
6443  " gettext translations are disabled.",
6444  __FUNCTION__);
6446  }
6447  else if (strcmp (locale, "C") == 0)
6448  {
6449  g_message ("%s: Locale for gettext extensions set to \"C\","
6450  " gettext translations are disabled.",
6451  __FUNCTION__);
6453  }
6454  else
6455  {
6456  if (strcasestr (locale, "en_") != locale)
6457  {
6458  g_warning ("%s: Locale defined by environment variables"
6459  " is not an \"en_...\" one.",
6460  __FUNCTION__);
6462  }
6463 
6464  if (strcasecmp (nl_langinfo (CODESET), "UTF-8"))
6465  g_warning ("%s: Locale defined by environment variables"
6466  " does not use UTF-8 encoding.",
6467  __FUNCTION__);
6468 
6469  g_debug ("%s: gettext translation extensions are enabled"
6470  " (using locale \"%s\").",
6471  __FUNCTION__, locale);
6473  }
6474 
6475  setlocale (LC_ALL, old_locale);
6476  g_free (old_locale);
6477 
6479 
6480  if (gsad_redirect_port_string)
6481  {
6482  gsad_redirect_port = atoi (gsad_redirect_port_string);
6483  if (gsad_redirect_port <= 0 || gsad_redirect_port >= 65536)
6484  {
6485  g_critical ("%s: Redirect port must be a number between 0 and 65536\n",
6486  __FUNCTION__);
6487  exit (EXIT_FAILURE);
6488  }
6489  }
6490 
6491  if (foreground == FALSE)
6492  {
6493  /* Fork into the background. */
6494  g_debug ("Forking...\n");
6495  pid_t pid = fork ();
6496  switch (pid)
6497  {
6498  case 0:
6499  /* Child. */
6500  break;
6501  case -1:
6502  /* Parent when error. */
6503  g_critical ("%s: Failed to fork!\n", __FUNCTION__);
6504  exit (EXIT_FAILURE);
6505  break;
6506  default:
6507  /* Parent. */
6508  exit (EXIT_SUCCESS);
6509  break;
6510  }
6511  }
6512 
6513  if (http_only)
6514  no_redirect = TRUE;
6515 
6516  if (unix_socket_path)
6517  {
6518  /* Fork for the unix socket server. */
6519  g_debug ("Forking for unix socket...\n");
6520  pid_t pid = fork ();
6521  switch (pid)
6522  {
6523  case 0:
6524  /* Child. */
6525 #if __linux
6526  if (prctl (PR_SET_PDEATHSIG, SIGKILL))
6527  g_warning ("%s: Failed to change parent death signal;"
6528  " unix socket process will remain if parent is killed:"
6529  " %s\n",
6530  __FUNCTION__,
6531  strerror (errno));
6532 #endif
6533  break;
6534  case -1:
6535  /* Parent when error. */
6536  g_warning ("%s: Failed to fork for unix socket!\n", __FUNCTION__);
6537  exit (EXIT_FAILURE);
6538  break;
6539  default:
6540  /* Parent. */
6541  unix_pid = pid;
6542  no_redirect = TRUE;
6543  break;
6544  }
6545  }
6546 
6547  if (!no_redirect)
6548  {
6549  /* Fork for the redirect server. */
6550  g_debug ("Forking for redirect...\n");
6551  pid_t pid = fork ();
6552  switch (pid)
6553  {
6554  case 0:
6555  /* Child. */
6556 #if __linux
6557  if (prctl (PR_SET_PDEATHSIG, SIGKILL))
6558  g_warning ("%s: Failed to change parent death signal;"
6559  " redirect process will remain if parent is killed:"
6560  " %s\n",
6561  __FUNCTION__,
6562  strerror (errno));
6563 #endif
6564  redirect_location = g_strdup_printf ("https://%%s:%i/login/login.html",
6565  gsad_port);
6566  break;
6567  case -1:
6568  /* Parent when error. */
6569  g_critical ("%s: Failed to fork for redirect!\n", __FUNCTION__);
6570  exit (EXIT_FAILURE);
6571  break;
6572  default:
6573  /* Parent. */
6574  redirect_pid = pid;
6575  no_redirect = TRUE;
6576  break;
6577  }
6578  }
6579 
6580  /* Register the cleanup function. */
6581 
6582  if (atexit (&gsad_cleanup))
6583  {
6584  g_critical ("%s: Failed to register cleanup function!\n", __FUNCTION__);
6585  exit (EXIT_FAILURE);
6586  }
6587 
6588  /* Write pidfile. */
6589 
6590  if (pidfile_create ("gsad"))
6591  {
6592  g_critical ("%s: Could not write PID file.\n", __FUNCTION__);
6593  exit (EXIT_FAILURE);
6594  }
6595 
6596  /* Initialize addresses and accepted host headers for HTTP header */
6597  gsad_header_hosts = g_hash_table_new_full (g_str_hash, g_str_equal,
6598  g_free, NULL);
6599 
6600  if (gsad_address_string)
6601  {
6602  // Allow basic loopback addresses in Host header
6603  add_local_addresses (gsad_header_hosts, ipv6_is_enabled (), 1);
6604  // Listen to given addresses and allow them in Host header
6605  while (*gsad_address_string)
6606  {
6607  if (gsad_address_init (*gsad_address_string, gsad_port))
6608  return 1;
6609  gsad_address_string++;
6610  }
6611  }
6612  else
6613  {
6614  // Allow all local interface addresses in Host Header
6615  add_local_addresses (gsad_header_hosts, ipv6_is_enabled (), 0);
6616  // Listen on all addresses
6617  if (gsad_address_init (NULL, gsad_port))
6618  return 1;
6619  }
6620 
6621  if (gsad_header_host_strings)
6622  while (*gsad_header_host_strings)
6623  {
6624  g_hash_table_add (gsad_header_hosts,
6625  g_strdup (*gsad_header_host_strings));
6626  gsad_header_host_strings ++;
6627  }
6628 
6629  g_debug ("Accepting %d host addresses in Host headers",
6630  g_hash_table_size (gsad_header_hosts));
6631  if (verbose)
6632  {
6633  GHashTableIter iter;
6634  char *hostname;
6635  g_hash_table_iter_init (&iter, gsad_header_hosts);
6636  while (g_hash_table_iter_next (&iter, (void**)(&hostname), NULL))
6637  {
6638  g_debug ("- %s\n", hostname);
6639  }
6640  }
6641 
6642  if (!no_redirect)
6643  {
6644  /* Start the HTTP to HTTPS redirect server. */
6645  GSList *list = address_list;
6646 
6647  while (list)
6648  {
6649  gsad_address_set_port (list->data, gsad_redirect_port);
6650  gsad_daemon = start_http_daemon (gsad_redirect_port, redirect_handler,
6651  list->data);
6652  list = list->next;
6653  }
6654 
6655  if (gsad_daemon == NULL)
6656  {
6657  g_warning ("%s: start_http_daemon redirect failed !", __FUNCTION__);
6658  return EXIT_FAILURE;
6659  }
6660  else
6661  {
6662  g_debug ("GSAD started successfully and is redirecting on port %d.\n",
6663  gsad_redirect_port);
6664  }
6665  }
6666  else if (unix_socket_path && !unix_pid)
6667  {
6668  /* Start the unix socket server. */
6669 
6670  omp_init (gsad_manager_unix_socket_path,
6671  gsad_manager_address_string,
6672  gsad_manager_port);
6673 
6674  gsad_daemon = start_unix_http_daemon (unix_socket_path, handle_request);
6675 
6676  if (gsad_daemon == NULL)
6677  {
6678  g_warning ("%s: start_unix_http_daemon failed !", __FUNCTION__);
6679  return EXIT_FAILURE;
6680  }
6681  else
6682  {
6683  g_debug ("GSAD started successfully and is listening on unix"
6684  " socket %s.\n",
6685  unix_socket_path);
6686  }
6687  }
6688  else
6689  {
6690  /* Start the real server. */
6691 
6692  omp_init (gsad_manager_unix_socket_path,
6693  gsad_manager_address_string,
6694  gsad_manager_port);
6695 
6696  if (http_only)
6697  {
6698  GSList *list = address_list;
6699 
6700  while (list)
6701  {
6702  gsad_daemon = start_http_daemon (gsad_port, handle_request,
6703  list->data);
6704  if (gsad_daemon == NULL && gsad_port_string == NULL)
6705  {
6706  g_warning ("Binding to port %d failed, trying default port"
6707  " %d next.", gsad_port, DEFAULT_GSAD_PORT);
6708  gsad_port = DEFAULT_GSAD_PORT;
6709  gsad_address_set_port (list->data, gsad_port);
6710  gsad_daemon = start_http_daemon (gsad_port, handle_request,
6711  list->data);
6712  }
6713  list = list->next;
6714  }
6715  }
6716  else
6717  {
6718  gchar *ssl_private_key = NULL;
6719  gchar *ssl_certificate = NULL;
6720  gchar *dh_params = NULL;
6721  GSList *list = address_list;
6722 
6723  use_secure_cookie = 1;
6724 
6725  if (!g_file_get_contents (ssl_private_key_filename, &ssl_private_key,
6726  NULL, &error))
6727  {
6728  g_critical ("%s: Could not load private SSL key from %s: %s\n",
6729  __FUNCTION__,
6730  ssl_private_key_filename,
6731  error->message);
6732  g_error_free (error);
6733  exit (EXIT_FAILURE);
6734  }
6735 
6736  if (!g_file_get_contents (ssl_certificate_filename, &ssl_certificate,
6737  NULL, &error))
6738  {
6739  g_critical ("%s: Could not load SSL certificate from %s: %s\n",
6740  __FUNCTION__,
6741  ssl_certificate_filename,
6742  error->message);
6743  g_error_free (error);
6744  exit (EXIT_FAILURE);
6745  }
6746 
6747  if (dh_params_filename &&
6748  !g_file_get_contents (dh_params_filename, &dh_params, NULL,
6749  &error))
6750  {
6751  g_critical ("%s: Could not load SSL certificate from %s: %s\n",
6752  __FUNCTION__, dh_params_filename, error->message);
6753  g_error_free (error);
6754  exit (EXIT_FAILURE);
6755  }
6756 
6757  while (list)
6758  {
6759  gsad_daemon = start_https_daemon
6760  (gsad_port, ssl_private_key, ssl_certificate,
6761  gnutls_priorities, dh_params, list->data);
6762  if (gsad_daemon == NULL && gsad_port_string == NULL)
6763  {
6764  g_warning ("Binding to port %d failed, trying default port"
6765  " %d next.", gsad_port, DEFAULT_GSAD_PORT);
6766  gsad_port = DEFAULT_GSAD_PORT;
6767  gsad_address_set_port (list->data, gsad_port);
6768  gsad_daemon = start_https_daemon
6769  (gsad_port, ssl_private_key, ssl_certificate,
6770  gnutls_priorities, dh_params, list->data);
6771  }
6772  list = list->next;
6773  }
6774  }
6775 
6776  if (gsad_daemon == NULL)
6777  {
6778  g_critical ("%s: start_https_daemon failed!\n", __FUNCTION__);
6779  return EXIT_FAILURE;
6780  }
6781  else
6782  {
6783  g_debug ("GSAD started successfully and is listening on port %d.\n",
6784  gsad_port);
6785  }
6786  }
6787 
6788  /* Chroot and drop privileges, if requested. */
6789 
6790  if (chroot_drop_privileges (do_chroot, drop,
6791  face_name ? face_name : DEFAULT_GSAD_FACE))
6792  {
6793  if (face_name && strcmp (face_name, DEFAULT_GSAD_FACE))
6794  {
6795  g_critical ("%s: Cannot use custom face \"%s\".\n",
6796  __FUNCTION__, face_name);
6797  exit (EXIT_FAILURE);
6798  }
6799  else
6800  {
6801  g_critical ("%s: Cannot use default face \"%s\"!\n",
6802  __FUNCTION__, DEFAULT_GSAD_FACE);
6803  exit (EXIT_FAILURE);
6804  }
6805  }
6806 
6807  /* Wait forever for input or interrupts. */
6808 
6809 
6810  if (sigfillset (&sigmask_all))
6811  {
6812  g_critical ("%s: Error filling signal set\n", __FUNCTION__);
6813  exit (EXIT_FAILURE);
6814  }
6815  if (pthread_sigmask (SIG_BLOCK, &sigmask_all, &sigmask_current))
6816  {
6817  g_critical ("%s: Error setting signal mask\n", __FUNCTION__);
6818  exit (EXIT_FAILURE);
6819  }
6820  while (1)
6821  {
6822  if (termination_signal)
6823  {
6824  g_debug ("Received %s signal.\n", sys_siglist[termination_signal]);
6825  gsad_cleanup ();
6826  /* Raise signal again, to exit with the correct return value. */
6827  signal (termination_signal, SIG_DFL);
6828  raise (termination_signal);
6829  }
6830 
6831  if (pselect (0, NULL, NULL, NULL, NULL, &sigmask_current) == -1)
6832  {
6833  if (errno == EINTR)
6834  continue;
6835  g_critical ("%s: pselect: %s\n", __FUNCTION__, strerror (errno));
6836  exit (EXIT_FAILURE);
6837  }
6838  }
6839  return EXIT_SUCCESS;
6840 }
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 * 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
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'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)
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'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'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
#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 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
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 valid_utf8
Definition: gsad_base.h:153
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'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
#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'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
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
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
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 * 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'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
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
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 * 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
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
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 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
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's CA Certificate.
Definition: gsad_omp.c:14841
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
int init_language_lists()
Initialize the list of available languages.
Definition: xslt_i18n.c:580
char * role
User'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
#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
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
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'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'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
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
int token_user(const gchar *token, user_t **user_return)
Find a user, given a token.
Definition: gsad.c:938