Greenbone Security Assistant  7.0.0
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 
54 #define _GNU_SOURCE /* for strcasecmp */
55 
56 #include <arpa/inet.h>
57 #include <assert.h>
58 #include <errno.h>
59 #include <gcrypt.h>
60 #include <glib.h>
61 #include <gnutls/gnutls.h>
62 #include <langinfo.h>
63 #include <locale.h>
64 #include <netinet/in.h>
65 #include <openvas/misc/openvas_logging.h>
66 #include <openvas/base/openvas_file.h>
67 #include <openvas/base/openvas_networking.h>
68 #include <openvas/base/pidfile.h>
69 #include <openvas/omp/xml.h>
70 #include <openvas/misc/openvas_uuid.h>
71 #include <pthread.h>
72 #include <pwd.h> /* for getpwnam */
73 #include <grp.h> /* for setgroups */
74 #include <signal.h>
75 #include <stdint.h>
76 #include <stdio.h>
77 #include <stdlib.h>
78 #include <string.h>
79 #if __linux
80 #include <sys/prctl.h>
81 #endif
82 #include <sys/socket.h>
83 #include <sys/un.h>
84 #include <sys/stat.h>
85 #include <sys/types.h>
86 #include <unistd.h>
87 /* This must follow the system includes. */
88 #include <microhttpd.h>
89 
90 #include "gsad_base.h"
91 #include "gsad_omp.h"
92 #include "validator.h"
93 #include "xslt_i18n.h"
94 
95 #ifdef SVN_REV_AVAILABLE
96 #include "svnrevision.h"
97 #endif
98 
99 #undef G_LOG_DOMAIN
100 
103 #define G_LOG_DOMAIN "gsad main"
104 
105 #undef G_LOG_FATAL_MASK
106 #define G_LOG_FATAL_MASK G_LOG_LEVEL_ERROR
107 
112 #ifndef MHD_HTTP_NOT_ACCEPTABLE
113 #define MHD_HTTP_NOT_ACCEPTABLE MHD_HTTP_METHOD_NOT_ACCEPTABLE
114 #endif
115 
119 #define SID_COOKIE_NAME "GSAD_SID"
120 
124 #define DEFAULT_GSAD_HTTPS_PORT 443
125 
129 #define DEFAULT_GSAD_HTTP_PORT 80
130 
134 #define DEFAULT_GSAD_PORT 9392
135 
139 #define DEFAULT_GSAD_REDIRECT_PORT 80
140 
144 #define DEFAULT_OPENVAS_MANAGER_PORT 9390
145 
149 #define POST_BUFFER_SIZE 500000
150 
154 #define MAX_FILE_NAME_SIZE 128
155 
159 #define SESSION_TIMEOUT 15
160 
164 #define DEFAULT_GSAD_FACE "classic"
165 
169 #define DEFAULT_GSAD_X_FRAME_OPTIONS "SAMEORIGIN"
170 
174 #define DEFAULT_GSAD_CONTENT_SECURITY_POLICY \
175  "default-src 'self' 'unsafe-inline';" \
176  " img-src 'self' blob:;" \
177  " frame-ancestors 'self'"
178 
182 #define DEFAULT_GSAD_GUEST_CHART_X_FRAME_OPTIONS "SAMEORIGIN"
183 
187 #define DEFAULT_GSAD_GUEST_CHART_CONTENT_SECURITY_POLICY \
188  "default-src 'self' 'unsafe-inline';" \
189  " img-src 'self' blob:;" \
190  " frame-ancestors *"
191 
195 #define DEFAULT_GSAD_HSTS_MAX_AGE 31536000
196 
200 volatile int termination_signal = 0;
201 
205 #if GCRYPT_VERSION_NUMBER < 0x010600
207 #endif
208 
212 const char *NOT_FOUND_TITLE
213  = "Invalid request";
214 
218 const char *NOT_FOUND_MESSAGE
219  = "The requested page or file does not exist.";
220 
224 const char *ERROR_PAGE = "<html><body>HTTP Method not supported</body></html>";
225 
230  "<html><body>Bad request.</body></html>";
231 
236  "<html><body>An internal server error has occurred.</body></html>";
237 
238 /*
239  * UTF-8 Error page HTML.
240  */
241 #define UTF8_ERROR_PAGE(location) \
242  "<html>" \
243  "<head><title>Invalid request</title></head>" \
244  "<body>The request contained invalid UTF-8 in " location ".</body>" \
245  "</html>"
246 
250 struct MHD_Daemon *gsad_daemon;
251 
255 struct sockaddr_storage address;
256 
260 gchar *redirect_location = NULL;
261 
265 pid_t redirect_pid = 0;
266 
270 pid_t unix_pid = 0;
271 
275 int unix_socket = 0;
276 
282 GSList *log_config = NULL;
283 
290 
295 
299 gchar *guest_username = NULL;
300 
304 gchar *guest_password = NULL;
305 
309 GPtrArray *users = NULL;
310 
315 
320 
325 
330 
335 
340 
344 int chroot_state = 0;
345 
349 void
350 add_security_headers (struct MHD_Response *response)
351 {
352  if (strcmp (http_x_frame_options, ""))
353  MHD_add_response_header (response, "X-Frame-Options",
355  if (strcmp (http_content_security_policy, ""))
356  MHD_add_response_header (response, "Content-Security-Policy",
359  MHD_add_response_header (response, "Strict-Transport-Security",
361 }
362 
366 void
367 add_guest_chart_content_security_headers (struct MHD_Response *response)
368 {
369  if (strcmp (http_x_frame_options, ""))
370  MHD_add_response_header (response, "X-Frame-Options",
372  if (strcmp (http_content_security_policy, ""))
373  MHD_add_response_header (response, "Content-Security-Policy",
375 }
376 
380 struct user
381 {
382  char *cookie;
383  char *token;
384  gchar *username;
385  gchar *password;
386  gchar *role;
387  gchar *timezone;
388  gchar *severity;
389  gchar *capabilities;
390  gchar *language;
391  gchar *pw_warning;
392  char *address;
393  time_t time;
394  int charts;
395  GTree *chart_prefs;
396  gchar *autorefresh;
398  int guest;
399 };
400 
404 typedef struct user user_t;
405 
409 static GMutex *mutex = NULL;
410 
432 user_t *
433 user_add (const gchar *username, const gchar *password, const gchar *timezone,
434  const gchar *severity, const gchar *role, const gchar *capabilities,
435  const gchar *language, const gchar *pw_warning, GTree *chart_prefs,
436  const gchar *autorefresh, const char *address)
437 {
438  user_t *user = NULL;
439  int index;
440  g_mutex_lock (mutex);
441  for (index = 0; index < users->len; index++)
442  {
443  user_t *item;
444  item = (user_t*) g_ptr_array_index (users, index);
445  if (strcmp (item->username, username) == 0)
446  {
447  if (time (NULL) - item->time > (session_timeout * 60))
448  g_ptr_array_remove (users, (gpointer) item);
449  }
450  }
451  user = g_malloc (sizeof (user_t));
452  user->cookie = openvas_uuid_make ();
453  user->token = openvas_uuid_make ();
454  user->username = g_strdup (username);
455  user->password = g_strdup (password);
456  user->role = g_strdup (role);
457  user->timezone = g_strdup (timezone);
458  user->severity = g_strdup (severity);
459  user->capabilities = g_strdup (capabilities);
460  user->pw_warning = pw_warning ? g_strdup (pw_warning) : NULL;
461  user->chart_prefs = chart_prefs;
462  user->autorefresh = g_strdup (autorefresh);
463  user->last_filt_ids = g_tree_new_full ((GCompareDataFunc) g_strcmp0,
464  NULL, g_free, g_free);
465  g_ptr_array_add (users, (gpointer) user);
466  set_language_code (&user->language, language);
467  user->time = time (NULL);
468  user->charts = 0;
469  if (guest_username)
470  user->guest = strcmp (username, guest_username) ? 0 : 1;
471  else
472  user->guest = 0;
473  user->address = g_strdup (address);
474  return user;
475 }
476 
477 #define USER_OK 0
478 #define USER_BAD_TOKEN 1
479 #define USER_EXPIRED_TOKEN 2
480 #define USER_BAD_MISSING_COOKIE 3
481 #define USER_BAD_MISSING_TOKEN 4
482 #define USER_GUEST_LOGIN_FAILED 5
483 #define USER_OMP_DOWN 6
484 #define USER_IP_ADDRESS_MISSMATCH 7
485 #define USER_GUEST_LOGIN_ERROR -1
486 
502 int
503 user_find (const gchar *cookie, const gchar *token, const char *address,
504  user_t **user_return)
505 {
506  int ret;
507  user_t *user = NULL;
508  int index;
509  if (token == NULL)
510  return USER_BAD_MISSING_TOKEN;
511 
512  if (guest_username && token && (strcmp (token, "guest") == 0))
513  {
514  int ret;
515  gchar *timezone, *role, *capabilities, *severity, *language;
516  gchar *pw_warning, *autorefresh;
517  GTree *chart_prefs;
518 
519  if (cookie)
520  {
521  /* Look for an existing guest user from the same browser (that is,
522  * with the same cookie). */
523 
524  g_mutex_lock (mutex);
525  for (index = 0; index < users->len; index++)
526  {
527  user_t *item;
528  item = (user_t*) g_ptr_array_index (users, index);
529  if (item->guest && (strcmp (item->cookie, cookie) == 0))
530  {
531  user = item;
532  break;
533  }
534  }
535  if (user)
536  {
537  *user_return = user;
538  user->time = time (NULL);
539  return USER_OK;
540  }
541  g_mutex_unlock (mutex);
542  }
543 
544  /* Log in as guest. */
545 
548  &role,
549  &timezone,
550  &severity,
551  &capabilities,
552  &language,
553  &pw_warning,
554  &chart_prefs,
555  &autorefresh);
556  if (ret == 1)
558  else if (ret == 2)
559  return USER_OMP_DOWN;
560  else if (ret == -1)
561  return USER_GUEST_LOGIN_ERROR;
562  else
563  {
564  user_t *user;
565  user = user_add (guest_username, guest_password, timezone, severity,
566  role, capabilities, language, pw_warning,
567  chart_prefs, autorefresh, address);
568  *user_return = user;
569  g_free (timezone);
570  g_free (severity);
571  g_free (capabilities);
572  g_free (language);
573  g_free (role);
574  g_free (pw_warning);
575  g_free (autorefresh);
576  return USER_OK;
577  }
578  }
579 
580  g_mutex_lock (mutex);
581  ret = USER_OK;
582  for (index = 0; index < users->len; index++)
583  {
584  user_t *item;
585  item = (user_t*) g_ptr_array_index (users, index);
586  if (strcmp (item->token, token) == 0)
587  {
588  if ((cookie == NULL) || strcmp (item->cookie, cookie))
589  {
590  /* Check if the session has expired. */
591  if (time (NULL) - item->time > (session_timeout * 60))
592  /* Probably the browser removed the cookie. */
593  ret = USER_EXPIRED_TOKEN;
594  else
596  break;
597  }
598  user = item;
599  break;
600  }
601  }
602  if (user)
603  {
604  /* Verify that the user address matches the client's address. */
605  if (strcmp (address, user->address))
607  else if (time (NULL) - user->time > (session_timeout * 60))
608  ret = USER_EXPIRED_TOKEN;
609  else
610  {
611  *user_return = user;
612  user->time = time (NULL);
613  /* FIXME mutex is not unlocked */
614  return USER_OK;
615  }
616  }
617  else if (ret == 0)
618  /* should it be really USER_EXPIRED_TOKEN?
619  * No user has been found therefore the token couldn't even expire */
620  ret = USER_EXPIRED_TOKEN;
621  g_mutex_unlock (mutex);
622  return ret;
623 }
624 
633 int
634 user_set_timezone (const gchar *token, const gchar *timezone)
635 {
636  int index, ret;
637  ret = 1;
638  g_mutex_lock (mutex);
639  for (index = 0; index < users->len; index++)
640  {
641  user_t *item;
642  item = (user_t*) g_ptr_array_index (users, index);
643  if (strcmp (item->token, token) == 0)
644  {
645  g_free (item->timezone);
646  item->timezone = g_strdup (timezone);
647  ret = 0;
648  break;
649  }
650  }
651  g_mutex_unlock (mutex);
652  return ret;
653 }
654 
663 int
664 user_set_password (const gchar *token, const gchar *password)
665 {
666  int index, ret;
667  ret = 1;
668  g_mutex_lock (mutex);
669  for (index = 0; index < users->len; index++)
670  {
671  user_t *item;
672  item = (user_t*) g_ptr_array_index (users, index);
673  if (strcmp (item->token, token) == 0)
674  {
675  g_free (item->password);
676  g_free (item->pw_warning);
677  item->password = g_strdup (password);
678  item->pw_warning = NULL;
679  ret = 0;
680  break;
681  }
682  }
683  g_mutex_unlock (mutex);
684  return ret;
685 }
686 
695 int
696 user_set_severity (const gchar *token, const gchar *severity)
697 {
698  int index, ret;
699  ret = 1;
700  g_mutex_lock (mutex);
701  for (index = 0; index < users->len; index++)
702  {
703  user_t *item;
704  item = (user_t*) g_ptr_array_index (users, index);
705  if (strcmp (item->token, token) == 0)
706  {
707  g_free (item->severity);
708  item->severity = g_strdup (severity);
709  ret = 0;
710  break;
711  }
712  }
713  g_mutex_unlock (mutex);
714  return ret;
715 }
716 
725 int
726 user_set_language (const gchar *token, const gchar *language)
727 {
728  int index, ret;
729  ret = 1;
730  g_mutex_lock (mutex);
731  for (index = 0; index < users->len; index++)
732  {
733  user_t *item;
734  item = (user_t*) g_ptr_array_index (users, index);
735  if (strcmp (item->token, token) == 0)
736  {
737  g_free (item->language);
738  set_language_code (&item->language, language);
739  ret = 0;
740  break;
741  }
742  }
743  g_mutex_unlock (mutex);
744  return ret;
745 }
746 
755 int
756 user_set_charts (const gchar *token, const int charts)
757 {
758  int index, ret;
759  ret = 1;
760  g_mutex_lock (mutex);
761  for (index = 0; index < users->len; index++)
762  {
763  user_t *item;
764  item = (user_t*) g_ptr_array_index (users, index);
765  if (strcmp (item->token, token) == 0)
766  {
767  item->charts = charts;
768  ret = 0;
769  break;
770  }
771  }
772  g_mutex_unlock (mutex);
773  return ret;
774 }
775 
785 int
786 user_set_chart_pref (const gchar *token, gchar* pref_id, gchar *pref_value)
787 {
788  int index, ret;
789  ret = 1;
790  g_mutex_lock (mutex);
791  for (index = 0; index < users->len; index++)
792  {
793  user_t *item;
794  item = (user_t*) g_ptr_array_index (users, index);
795  if (strcmp (item->token, token) == 0)
796  {
797  g_tree_replace (item->chart_prefs,
798  pref_id, pref_value);
799  ret = 0;
800  break;
801  }
802  }
803  g_mutex_unlock (mutex);
804  return ret;
805 }
806 
815 int
816 user_set_autorefresh (const gchar *token, const gchar *autorefresh)
817 {
818  int index, ret;
819  ret = 1;
820  g_mutex_lock (mutex);
821  for (index = 0; index < users->len; index++)
822  {
823  user_t *item;
824  item = (user_t*) g_ptr_array_index (users, index);
825  if (strcmp (item->token, token) == 0)
826  {
827  g_free (item->autorefresh);
828  item->autorefresh = g_strdup (autorefresh);
829  ret = 0;
830  break;
831  }
832  }
833  g_mutex_unlock (mutex);
834  return ret;
835 }
836 
845 int
846 user_logout_all_sessions (const gchar *username, credentials_t *credentials)
847 {
848  int index;
849  g_mutex_lock (mutex);
850  for (index = 0; index < users->len; index++)
851  {
852  user_t *item;
853  item = (user_t*) g_ptr_array_index (users, index);
854  if (strcmp (item->username, username) == 0
855  && strcmp (item->token, credentials->token))
856  {
857  g_debug ("%s: logging out user '%s', token '%s'",
858  __FUNCTION__, item->username, item->token);
859  g_ptr_array_remove (users, (gpointer) item);
860  index --;
861  }
862  }
863  g_mutex_unlock (mutex);
864 
865  return 0;
866 }
867 
873 void
875 {
876  g_mutex_unlock (mutex);
877 }
878 
884 void
886 {
887  g_ptr_array_remove (users, (gpointer) user);
888  g_mutex_unlock (mutex);
889 }
890 
901 int
902 token_user (const gchar *token, user_t **user_return)
903 {
904  int ret;
905  user_t *user = NULL;
906  int index;
907  g_mutex_lock (mutex);
908  for (index = 0; index < users->len; index++)
909  {
910  user_t *item;
911  item = (user_t*) g_ptr_array_index (users, index);
912  if (strcmp (item->token, token) == 0)
913  {
914  user = item;
915  break;
916  }
917  }
918  if (user)
919  {
920  if (time (NULL) - user->time > (session_timeout * 60))
921  ret = 2;
922  else
923  {
924  *user_return = user;
925  ret = 0;
926  user->time = time (NULL);
927  return ret;
928  }
929  }
930  else
931  ret = 1;
932  g_mutex_unlock (mutex);
933  return ret;
934 }
935 
943 int
945 {
946  user_t *user;
947  if (token_user (token, &user))
948  return -1;
949  g_ptr_array_remove (users, (gpointer) user);
950  g_mutex_unlock (mutex);
951  return 0;
952 }
953 
958 
962 void
964 {
966 
968  "cmd",
969  "^((bulk_delete)"
970  "|(clone)"
971  "|(create_agent)"
972  "|(create_asset)"
973  "|(create_config)"
974  "|(create_container_task)"
975  "|(create_credential)"
976  "|(create_alert)"
977  "|(create_filter)"
978  "|(create_group)"
979  "|(create_host)"
980  "|(create_note)"
981  "|(create_override)"
982  "|(create_permission)"
983  "|(create_permissions)"
984  "|(create_port_list)"
985  "|(create_port_range)"
986  "|(create_report)"
987  "|(create_role)"
988  "|(create_scanner)"
989  "|(create_schedule)"
990  "|(create_tag)"
991  "|(create_target)"
992  "|(create_task)"
993  "|(cvss_calculator)"
994  "|(create_user)"
995  "|(dashboard)"
996  "|(delete_agent)"
997  "|(delete_asset)"
998  "|(delete_config)"
999  "|(delete_credential)"
1000  "|(delete_alert)"
1001  "|(delete_filter)"
1002  "|(delete_group)"
1003  "|(delete_note)"
1004  "|(delete_override)"
1005  "|(delete_permission)"
1006  "|(delete_port_list)"
1007  "|(delete_port_range)"
1008  "|(delete_report)"
1009  "|(delete_report_format)"
1010  "|(delete_role)"
1011  "|(delete_scanner)"
1012  "|(delete_schedule)"
1013  "|(delete_tag)"
1014  "|(delete_target)"
1015  "|(delete_task)"
1016  "|(delete_trash_agent)"
1017  "|(delete_trash_config)"
1018  "|(delete_trash_alert)"
1019  "|(delete_trash_credential)"
1020  "|(delete_trash_filter)"
1021  "|(delete_trash_group)"
1022  "|(delete_trash_note)"
1023  "|(delete_trash_override)"
1024  "|(delete_trash_permission)"
1025  "|(delete_trash_port_list)"
1026  "|(delete_trash_report_format)"
1027  "|(delete_trash_role)"
1028  "|(delete_trash_scanner)"
1029  "|(delete_trash_schedule)"
1030  "|(delete_trash_tag)"
1031  "|(delete_trash_target)"
1032  "|(delete_trash_task)"
1033  "|(delete_user)"
1034  "|(delete_user_confirm)"
1035  "|(download_agent)"
1036  "|(download_credential)"
1037  "|(download_ssl_cert)"
1038  "|(download_ca_pub)"
1039  "|(download_key_pub)"
1040  "|(edit_agent)"
1041  "|(edit_alert)"
1042  "|(edit_asset)"
1043  "|(edit_config)"
1044  "|(edit_config_family)"
1045  "|(edit_config_nvt)"
1046  "|(edit_credential)"
1047  "|(edit_filter)"
1048  "|(edit_group)"
1049  "|(edit_my_settings)"
1050  "|(edit_note)"
1051  "|(edit_override)"
1052  "|(edit_permission)"
1053  "|(edit_port_list)"
1054  "|(edit_report_format)"
1055  "|(edit_role)"
1056  "|(edit_scanner)"
1057  "|(edit_schedule)"
1058  "|(edit_tag)"
1059  "|(edit_target)"
1060  "|(edit_task)"
1061  "|(edit_user)"
1062  "|(auth_settings)"
1063  "|(empty_trashcan)"
1064  "|(alert_report)"
1065  "|(export_agent)"
1066  "|(export_agents)"
1067  "|(export_alert)"
1068  "|(export_alerts)"
1069  "|(export_asset)"
1070  "|(export_assets)"
1071  "|(export_config)"
1072  "|(export_configs)"
1073  "|(export_credential)"
1074  "|(export_credentials)"
1075  "|(export_filter)"
1076  "|(export_filters)"
1077  "|(export_group)"
1078  "|(export_groups)"
1079  "|(export_note)"
1080  "|(export_notes)"
1081  "|(export_omp_doc)"
1082  "|(export_override)"
1083  "|(export_overrides)"
1084  "|(export_permission)"
1085  "|(export_permissions)"
1086  "|(export_port_list)"
1087  "|(export_port_lists)"
1088  "|(export_preference_file)"
1089  "|(export_report_format)"
1090  "|(export_report_formats)"
1091  "|(export_result)"
1092  "|(export_results)"
1093  "|(export_role)"
1094  "|(export_roles)"
1095  "|(export_scanner)"
1096  "|(export_scanners)"
1097  "|(export_schedule)"
1098  "|(export_schedules)"
1099  "|(export_tag)"
1100  "|(export_tags)"
1101  "|(export_target)"
1102  "|(export_targets)"
1103  "|(export_task)"
1104  "|(export_tasks)"
1105  "|(export_user)"
1106  "|(export_users)"
1107  "|(get_agent)"
1108  "|(get_agents)"
1109  "|(get_aggregate)"
1110  "|(get_asset)"
1111  "|(get_assets)"
1112  "|(get_assets_chart)"
1113  "|(get_config)"
1114  "|(get_config_family)"
1115  "|(get_config_nvt)"
1116  "|(get_configs)"
1117  "|(get_feeds)"
1118  "|(get_credential)"
1119  "|(get_credentials)"
1120  "|(get_filter)"
1121  "|(get_filters)"
1122  "|(get_alert)"
1123  "|(get_alerts)"
1124  "|(get_group)"
1125  "|(get_groups)"
1126  "|(get_info)"
1127  "|(get_my_settings)"
1128  "|(get_note)"
1129  "|(get_notes)"
1130  "|(get_nvts)"
1131  "|(get_override)"
1132  "|(get_overrides)"
1133  "|(get_permission)"
1134  "|(get_permissions)"
1135  "|(get_port_list)"
1136  "|(get_port_lists)"
1137  "|(get_protocol_doc)"
1138  "|(get_report)"
1139  "|(get_reports)"
1140  "|(get_report_format)"
1141  "|(get_report_formats)"
1142  "|(get_report_section)"
1143  "|(get_result)"
1144  "|(get_results)"
1145  "|(get_role)"
1146  "|(get_roles)"
1147  "|(get_scanner)"
1148  "|(get_scanners)"
1149  "|(get_schedule)"
1150  "|(get_schedules)"
1151  "|(get_system_reports)"
1152  "|(get_tag)"
1153  "|(get_tags)"
1154  "|(get_target)"
1155  "|(get_targets)"
1156  "|(get_task)"
1157  "|(get_tasks)"
1158  "|(get_tasks_chart)"
1159  "|(get_trash)"
1160  "|(get_user)"
1161  "|(get_users)"
1162  "|(import_config)"
1163  "|(import_port_list)"
1164  "|(import_report)"
1165  "|(import_report_format)"
1166  "|(login)"
1167  "|(move_task)"
1168  "|(new_agent)"
1169  "|(new_alert)"
1170  "|(new_config)"
1171  "|(new_container_task)"
1172  "|(new_credential)"
1173  "|(new_filter)"
1174  "|(new_group)"
1175  "|(new_host)"
1176  "|(new_note)"
1177  "|(new_override)"
1178  "|(new_permission)"
1179  "|(new_permissions)"
1180  "|(new_port_list)"
1181  "|(new_port_range)"
1182  "|(new_report_format)"
1183  "|(new_role)"
1184  "|(new_scanner)"
1185  "|(new_schedule)"
1186  "|(new_tag)"
1187  "|(new_target)"
1188  "|(new_task)"
1189  "|(new_user)"
1190  "|(process_bulk)"
1191  "|(restore)"
1192  "|(resume_task)"
1193  "|(run_wizard)"
1194  "|(test_alert)"
1195  "|(save_agent)"
1196  "|(save_alert)"
1197  "|(save_asset)"
1198  "|(save_auth)"
1199  "|(save_chart_preference)"
1200  "|(save_config)"
1201  "|(save_config_family)"
1202  "|(save_config_nvt)"
1203  "|(save_container_task)"
1204  "|(save_credential)"
1205  "|(save_filter)"
1206  "|(save_group)"
1207  "|(save_my_settings)"
1208  "|(save_note)"
1209  "|(save_override)"
1210  "|(save_permission)"
1211  "|(save_port_list)"
1212  "|(save_report_format)"
1213  "|(save_role)"
1214  "|(save_scanner)"
1215  "|(save_schedule)"
1216  "|(save_tag)"
1217  "|(save_target)"
1218  "|(save_task)"
1219  "|(save_user)"
1220  "|(start_task)"
1221  "|(stop_task)"
1222  "|(sync_feed)"
1223  "|(sync_scap)"
1224  "|(sync_cert)"
1225  "|(sync_config)"
1226  "|(toggle_tag)"
1227  "|(upload_config)"
1228  "|(upload_port_list)"
1229  "|(upload_report)"
1230  "|(verify_agent)"
1231  "|(verify_report_format)"
1232  "|(verify_scanner)"
1233  "|(wizard)"
1234  "|(wizard_get))$");
1235 
1236  openvas_validator_add (validator, "action_message", "(?s)^.*$");
1237  openvas_validator_add (validator, "action_status", "(?s)^.*$");
1238  openvas_validator_add (validator, "active", "^(-1|-2|[0-9]+)$");
1239  openvas_validator_add (validator, "agent_format", "^(installer)$");
1240  openvas_validator_add (validator, "agent_id", "^[a-z0-9\\-]+$");
1241  openvas_validator_add (validator, "aggregate_mode", "^[a-z0-9_]+$");
1242  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)$");
1243  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)$");
1244  openvas_validator_add (validator, "apply_filter", "^(no|no_pagination|full)$");
1245  openvas_validator_add (validator, "asset_name", "(?s)^.*$");
1246  openvas_validator_add (validator, "asset_type", "^(host|os)$");
1247  openvas_validator_add (validator, "asset_id", "^([[:alnum:]-_.:\\/~()']|&amp;)+$");
1248  openvas_validator_add (validator, "auth_algorithm", "^(md5|sha1)$");
1249  openvas_validator_add (validator, "auth_method", "^(0|1|2)$");
1250  /* Defined in RFC 2253. */
1251  openvas_validator_add (validator, "authdn", "^.{0,200}%s.{0,200}$");
1252  openvas_validator_add (validator, "auto_delete", "^(no|keep)$");
1253  openvas_validator_add (validator, "auto_delete_data", "^(.*){0,10}$");
1254  openvas_validator_add (validator, "autofp", "^(0|1|2)$");
1255  openvas_validator_add (validator, "autofp_value", "^(1|2)$");
1256  openvas_validator_add (validator, "boolean", "^(0|1)$");
1257  openvas_validator_add (validator, "bulk_selected:name", "^(.*){0,400}$");
1258  openvas_validator_add (validator, "bulk_selected:value", "(?s)^.*$");
1259  openvas_validator_add (validator, "caller", "^.*$");
1260  openvas_validator_add (validator, "certificate", "(?s)^.*$");
1261  openvas_validator_add (validator, "chart_gen:name", "^(.*){0,400}$");
1262  openvas_validator_add (validator, "chart_gen:value", "(?s)^.*$");
1263  openvas_validator_add (validator, "chart_init:name", "^(.*){0,400}$");
1264  openvas_validator_add (validator, "chart_init:value", "(?s)^.*$");
1265  openvas_validator_add (validator, "chart_preference_id", "^(.*){0,400}$");
1266  openvas_validator_add (validator, "chart_preference_value", "^(.*){0,400}$");
1267  openvas_validator_add (validator, "comment", "^[-_;':()@[:alnum:]äüöÄÜÖß, \\./]{0,400}$");
1268  openvas_validator_add (validator, "config_id", "^[a-z0-9\\-]+$");
1269  openvas_validator_add (validator, "osp_config_id", "^[a-z0-9\\-]+$");
1270  openvas_validator_add (validator, "condition", "^[[:alnum:] ]{0,100}$");
1271  openvas_validator_add (validator, "credential_id", "^[a-z0-9\\-]+$");
1272  openvas_validator_add (validator, "create_credentials_type", "^(gen|pass|key)$");
1273  openvas_validator_add (validator, "credential_login", "^[-_[:alnum:]\\.@\\\\]{0,40}$");
1274  openvas_validator_add (validator, "condition_data:name", "^(.*){0,400}$");
1275  openvas_validator_add (validator, "condition_data:value", "(?s)^.*$");
1276  openvas_validator_add (validator, "cvss_av", "^(L|A|N)$");
1277  openvas_validator_add (validator, "cvss_ac", "^(H|M|L)$");
1278  openvas_validator_add (validator, "cvss_au", "^(M|S|N)$");
1279  openvas_validator_add (validator, "cvss_c", "^(N|P|C)$");
1280  openvas_validator_add (validator, "cvss_i", "^(N|P|C)$");
1281  openvas_validator_add (validator, "cvss_a", "^(N|P|C)$");
1282  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)$");
1283  openvas_validator_add (validator, "min_qod", "^(|100|[1-9]?[0-9]|)$");
1284  openvas_validator_add (validator, "day_of_month", "^(0??[1-9]|[12][0-9]|30|31)$");
1285  openvas_validator_add (validator, "days", "^(-1|[0-9]+)$");
1286  openvas_validator_add (validator, "data_column", "^[_[:alnum:]]{1,80}$");
1287  openvas_validator_add (validator, "data_columns:name", "^[0123456789]{1,5}$");
1288  openvas_validator_add (validator, "data_columns:value", "^[_[:alnum:]]{1,80}$");
1289  openvas_validator_add (validator, "default_severity", "^(|10\\.0|[0-9]\\.[0-9])$");
1290  openvas_validator_add (validator, "delta_states", "^(c|g|n|s){0,4}$");
1291  openvas_validator_add (validator, "details_fname", "^([[:alnum:]_-]|%[%CcDFMmNTtUu])+$");
1292  openvas_validator_add (validator, "domain", "^[-[:alnum:]\\.]{1,80}$");
1293  openvas_validator_add (validator, "email", "^[^@ ]{1,150}@[^@ ]{1,150}$");
1294  openvas_validator_add (validator, "email_list", "^[^@ ]{1,150}@[^@ ]{1,150}(, *[^@ ]{1,150}@[^@ ]{1,150})*$");
1295  openvas_validator_add (validator, "alert_id", "^[a-z0-9\\-]+$");
1296  openvas_validator_add (validator, "alert_id_optional", "^(--|[a-z0-9\\-]+)$");
1297  openvas_validator_add (validator, "event_data:name", "^(.*){0,400}$");
1298  openvas_validator_add (validator, "event_data:value", "(?s)^.*$");
1299  openvas_validator_add (validator, "family", "^[-_[:alnum:] :.]{1,200}$");
1300  openvas_validator_add (validator, "family_page", "^[-_[:alnum:] :.]{1,200}$");
1301  openvas_validator_add (validator, "file", "(?s)^.*$");
1302  openvas_validator_add (validator, "file:name", "^.*[[0-9abcdefABCDEF\\-]{1,40}]:.*$");
1303  openvas_validator_add (validator, "file:value", "^yes$");
1304  openvas_validator_add (validator, "settings_changed:name", "^(.*){0,400}$");
1305  openvas_validator_add (validator, "settings_changed:value", "^[a-z0-9\\-]+$");
1306  openvas_validator_add (validator, "settings_default:name", "^(.*){0,400}$");
1307  openvas_validator_add (validator, "settings_default:value", "^[a-z0-9\\-]+$");
1308  openvas_validator_add (validator, "settings_filter:name", "^(.*){0,400}$");
1309  openvas_validator_add (validator, "settings_filter:value", "^[a-z0-9\\-]+$");
1310  openvas_validator_add (validator, "first", "^[0-9]+$");
1311  openvas_validator_add (validator, "first_group", "^[0-9]+$");
1312  openvas_validator_add (validator, "first_result", "^[0-9]+$");
1313  openvas_validator_add (validator, "filter", "^(.*){0,1000}$");
1314  openvas_validator_add (validator, "format_id", "^[a-z0-9\\-]+$");
1315  /* Validator for save_auth group, e.g. "method:ldap_connect". */
1316  openvas_validator_add (validator, "group", "^method:(ldap_connect|radius_connect)$");
1317  openvas_validator_add (validator, "group_column", "^[_[:alnum:]]{1,80}$");
1318  openvas_validator_add (validator, "max", "^(-?[0-9]+|)$");
1319  openvas_validator_add (validator, "max_results", "^[0-9]+$");
1320  openvas_validator_add (validator, "format", "^[-[:alnum:]]{1,15}$");
1321  openvas_validator_add (validator, "host", "^[[:alnum:]:\\.]{1,80}$");
1322  openvas_validator_add (validator, "hostport", "^[-[:alnum:]\\. :]{1,80}$");
1323  openvas_validator_add (validator, "hostpath", "^[-[:alnum:]\\. :/]{1,80}$");
1324  openvas_validator_add (validator, "hosts", "^[-[:alnum:],: \\./]{1,2000}$");
1325  openvas_validator_add (validator, "hosts_allow", "^(0|1)$");
1326  openvas_validator_add (validator, "hosts_opt", "^[-[:alnum:], \\./]{0,2000}$");
1327  openvas_validator_add (validator, "hosts_ordering", "^(sequential|random|reverse)$");
1328  openvas_validator_add (validator, "hour", "^([01]?[0-9]|2[0-3])$");
1329  openvas_validator_add (validator, "howto_use", "(?s)^.*$");
1330  openvas_validator_add (validator, "howto_install", "(?s)^.*$");
1331  openvas_validator_add (validator, "id", "^[a-z0-9\\-]+$");
1332  openvas_validator_add (validator, "id_optional", "^(--|[a-z0-9\\-]+)$");
1333  openvas_validator_add (validator, "id_or_empty", "^(|[a-z0-9\\-]+)$");
1334  openvas_validator_add (validator, "id_list:name", "^ *[0-9]+ *$");
1335  openvas_validator_add (validator, "id_list:value", "^[[:alnum:]\\-_ ]+:[a-z0-9\\-]+$");
1336  openvas_validator_add (validator, "ifaces_allow", "^(0|1)$");
1337  openvas_validator_add (validator, "include_id_list:name", "^[[:alnum:]\\-_ ]+$");
1338  openvas_validator_add (validator, "include_id_list:value", "^(0|1)$");
1339  openvas_validator_add (validator, "installer", "(?s)^.*$");
1340  openvas_validator_add (validator, "installer_sig", "(?s)^.*$");
1342  "^(Browser Language|"
1343  "([a-z]{2,3})(_[A-Z]{2})?(@[[:alnum:]_-]+)?"
1344  "(:([a-z]{2,3})(_[A-Z]{2})?(@[[:alnum:]_-]+)?)*)$");
1345  openvas_validator_add (validator, "levels", "^(h|m|l|g|f){0,5}$");
1346  openvas_validator_add (validator, "list_fname", "^([[:alnum:]_-]|%[%CcDFMmNTtUu])+$");
1347  /* Used for users, credentials, and scanner login name. */
1348  openvas_validator_add (validator, "login", "^[[:alnum:]-_@.]+$");
1349  openvas_validator_add (validator, "lsc_password", "^.{0,40}$");
1350  openvas_validator_add (validator, "max_result", "^[0-9]+$");
1351  openvas_validator_add (validator, "max_groups", "^-?[0-9]+$");
1352  openvas_validator_add (validator, "minute", "^[0-5]{0,1}[0-9]{1,1}$");
1353  openvas_validator_add (validator, "month", "^((0??[1-9])|1[012])$");
1354  openvas_validator_add (validator, "note_id", "^[a-z0-9\\-]+$");
1355  openvas_validator_add (validator, "note_result_id", "^[a-z0-9\\-]*$");
1356  openvas_validator_add (validator, "override_id", "^[a-z0-9\\-]+$");
1357  openvas_validator_add (validator, "override_result_id", "^[a-z0-9\\-]*$");
1358  openvas_validator_add (validator, "name", "^[#-_[:alnum:], \\./]{1,80}$");
1359  openvas_validator_add (validator, "info_name", "(?s)^.*$");
1360  openvas_validator_add (validator, "info_type", "(?s)^.*$");
1361  openvas_validator_add (validator, "info_id", "^([[:alnum:]-_.:\\/~()']|&amp;)+$");
1362  openvas_validator_add (validator, "details", "^[0-1]$");
1363  /* Number is special cased in params_mhd_validate to remove the space. */
1364  openvas_validator_add (validator, "number", "^ *[0-9]+ *$");
1365  openvas_validator_add (validator, "optional_number", "^[0-9]*$");
1366  openvas_validator_add (validator, "oid", "^([0-9.]{1,80}|CVE-[-0-9]{1,14})$");
1367  openvas_validator_add (validator, "page", "^[_[:alnum:] ]{1,40}$");
1368  openvas_validator_add (validator, "package_format", "^(pem|key|rpm|deb|exe)$");
1369  openvas_validator_add (validator, "password", "^.{0,40}$");
1370  openvas_validator_add (validator, "password:value", "(?s)^.*$");
1371  openvas_validator_add (validator, "port", "^.{1,60}$");
1372  openvas_validator_add (validator, "port_range", "^((default)|([-0-9, TU:]{1,400}))$");
1373  openvas_validator_add (validator, "port_type", "^(tcp|udp)$");
1375  openvas_validator_add (validator, "preference_name", "^(.*){0,400}$");
1376  openvas_validator_add (validator, "preference:name", "^([^[]*\\[[^]]*\\]:.*){0,400}$");
1377  openvas_validator_add (validator, "preference:value", "(?s)^.*$");
1378  openvas_validator_add (validator, "prev_action", "(?s)^.*$");
1379  openvas_validator_add (validator, "privacy_algorithm", "^(aes|des|)$");
1380  openvas_validator_add (validator, "private_key", "(?s)^.*$");
1381  openvas_validator_add (validator, "protocol_format", "^(html|rnc|xml)$");
1382  openvas_validator_add (validator, "pw", "^[[:alnum:]]{1,10}$");
1383  openvas_validator_add (validator, "xml_file", "(?s)^.*$");
1384  openvas_validator_add (validator, "definitions_file", "(?s)^.*$");
1385  openvas_validator_add (validator, "ca_pub", "(?s)^.*$");
1386  openvas_validator_add (validator, "which_cert", "^(default|existing|new)$");
1387  openvas_validator_add (validator, "key_pub", "(?s)^.*$");
1388  openvas_validator_add (validator, "key_priv", "(?s)^.*$");
1389  openvas_validator_add (validator, "radiuskey", "^.{0,40}$");
1390  openvas_validator_add (validator, "range_type", "^(duration|until_end|from_start|start_to_end)$");
1391  openvas_validator_add (validator, "related:name", "^(.*){0,400}$");
1392  openvas_validator_add (validator, "related:value", "^(.*){0,400}$");
1393  openvas_validator_add (validator, "report_id", "^[a-z0-9\\-]+$");
1394  openvas_validator_add (validator, "report_fname", "^([[:alnum:]_-]|%[%CcDFMmNTtUu])+$");
1395  openvas_validator_add (validator, "report_format_id", "^[a-z0-9\\-]+$");
1396  openvas_validator_add (validator, "report_section",
1397  "^(summary|results|hosts|ports"
1398  "|closed_cves|vulns|os|apps|errors"
1399  "|topology|ssl_certs|cves)$");
1400  openvas_validator_add (validator, "result_id", "^[a-z0-9\\-]+$");
1401  openvas_validator_add (validator, "role", "^[[:alnum:] ]{1,40}$");
1402  openvas_validator_add (validator, "optional_task_id", "^[a-z0-9\\-]*$");
1403  openvas_validator_add (validator, "permission", "^([_a-z]{1,1000}|Super)$");
1404  openvas_validator_add (validator, "port_list_id", "^[a-z0-9\\-]+$");
1405  openvas_validator_add (validator, "port_range_id", "^[a-z0-9\\-]+$");
1406  openvas_validator_add (validator, "resource_type",
1407  "^(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|"
1408  "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)$");
1409  openvas_validator_add (validator, "resource_id", "^[[:alnum:]-_.:\\/~]*$");
1410  openvas_validator_add (validator, "optional_resource_type",
1411  "^(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|"
1412  "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|)$");
1413  openvas_validator_add (validator, "select:value", "^(.*){0,400}$");
1414  openvas_validator_add (validator, "ssl_cert", "^(.*){0,2000}$");
1415  openvas_validator_add (validator, "method_data:name", "^(.*){0,400}$");
1416  openvas_validator_add (validator, "method_data:value", "(?s)^.*$");
1417  openvas_validator_add (validator, "nvt:name", "(?s)^.*$");
1418  openvas_validator_add (validator, "restrict_credential_type", "^[a-z0-9\\_|]+$");
1419  openvas_validator_add (validator, "subject_type", "^(group|role|user)$");
1420  openvas_validator_add (validator, "summary", "^.{0,400}$");
1421  openvas_validator_add (validator, "tag_id", "^[a-z0-9\\-]+$");
1422  openvas_validator_add (validator, "tag_name", "^[\\:-_[:alnum:], \\./]{1,80}$");
1423  openvas_validator_add (validator, "tag_value", "^[\\-_@[:alnum:], \\./]{0,200}$");
1424  openvas_validator_add (validator, "target_id", "^[a-z0-9\\-]+$");
1425  openvas_validator_add (validator, "task_id", "^[a-z0-9\\-]+$");
1426  openvas_validator_add (validator, "term", "^.{0,1000}");
1427  openvas_validator_add (validator, "text", "^.{0,1000}");
1428  openvas_validator_add (validator, "text_columns:name", "^[0123456789]{1,5}$");
1429  openvas_validator_add (validator, "text_columns:value", "^[_[:alnum:]]{1,80}$");
1430  openvas_validator_add (validator, "threat", "^(High|Medium|Low|Alarm|Log|False Positive|)$");
1431  openvas_validator_add (validator, "trend", "^(0|1)$");
1432  openvas_validator_add (validator, "trend:value", "^(0|1)$");
1433  openvas_validator_add (validator, "type", "^(assets|prognostic)$");
1434  openvas_validator_add (validator, "search_phrase", "^[[:alnum:][:punct:] äöüÄÖÜß]{0,400}$");
1435  openvas_validator_add (validator, "sort_field", "^[_[:alnum:] ]{1,40}$");
1436  openvas_validator_add (validator, "sort_order", "^(ascending|descending)$");
1437  openvas_validator_add (validator, "sort_stat", "^[_[:alnum:] ]{1,40}$");
1438  openvas_validator_add (validator, "sort_fields:name", "^[0123456789]{1,5}$");
1439  openvas_validator_add (validator, "sort_fields:value", "^[_[:alnum:] ]{1,40}$");
1440  openvas_validator_add (validator, "sort_orders:name", "^[0123456789]{1,5}$");
1441  openvas_validator_add (validator, "sort_orders:value", "^(ascending|descending)$");
1442  openvas_validator_add (validator, "sort_stats:name", "^[0123456789]{1,5}$");
1443  openvas_validator_add (validator, "sort_stats:value", "^[_[:alnum:] ]{1,40}$");
1444  openvas_validator_add (validator, "target_source", "^(asset_hosts|file|import|manual)$");
1445  openvas_validator_add (validator, "timezone", "^.{0,1000}$");
1446  openvas_validator_add (validator, "token", "^[a-z0-9\\-]+$");
1447  openvas_validator_add (validator, "scanner_id", "^[a-z0-9\\-]+$");
1448  openvas_validator_add (validator, "cve_scanner_id", "^[a-z0-9\\-]+$");
1449  openvas_validator_add (validator, "osp_scanner_id", "^[a-z0-9\\-]+$");
1450  openvas_validator_add (validator, "schedule_id", "^[a-z0-9\\-]+$");
1451  openvas_validator_add (validator, "severity", "^(-1(\\.0)?|[0-9](\\.[0-9])?|10(\\.0)?)$");
1452  openvas_validator_add (validator, "severity_class", "^(classic|nist|bsi|pci\\-dss)$");
1453  openvas_validator_add (validator, "severity_optional", "^(-1(\\.0)?|[0-9](\\.[0-9])?|10(\\.0)?)?$");
1454  openvas_validator_add (validator, "source_iface", "^(.*){1,16}$");
1455  openvas_validator_add (validator, "uuid", "^[0-9abcdefABCDEF\\-]{1,40}$");
1456  /* This must be "login" with space and comma. */
1457  openvas_validator_add (validator, "users", "^[[:alnum:]-_@., ]*$");
1458  openvas_validator_add (validator, "x_field", "^[\\[\\]_[:alnum:]]{1,80}$");
1459  openvas_validator_add (validator, "y_fields:name", "^[0-9]{1,5}$");
1460  openvas_validator_add (validator, "y_fields:value", "^[\\[\\]_[:alnum:]]{1,80}$");
1461  openvas_validator_add (validator, "year", "^[0-9]+$");
1462  openvas_validator_add (validator, "z_fields:name", "^[0-9]{1,5}$");
1463  openvas_validator_add (validator, "z_fields:value", "^[\\[\\]_[:alnum:]]{1,80}$");
1464  openvas_validator_add (validator, "calendar_unit", "^(second|minute|hour|day|week|month|year|decade)$");
1465  openvas_validator_add (validator, "chart_title", "(?s)^.*$");
1466 
1467  /* Beware, the rule must be defined before the alias. */
1468 
1469  openvas_validator_alias (validator, "add_tag", "boolean");
1470  openvas_validator_alias (validator, "alert_id_2", "alert_id");
1471  openvas_validator_alias (validator, "alert_id_optional:name", "number");
1472  openvas_validator_alias (validator, "alert_id_optional:value", "alert_id_optional");
1473  openvas_validator_alias (validator, "alerts", "optional_number");
1474  openvas_validator_alias (validator, "alert_ids:name", "number");
1475  openvas_validator_alias (validator, "alert_ids:value", "alert_id_optional");
1476  openvas_validator_alias (validator, "allow_insecure", "boolean");
1477  openvas_validator_alias (validator, "alterable", "boolean");
1478  openvas_validator_alias (validator, "apply_overrides", "boolean");
1479  openvas_validator_alias (validator, "autogenerate", "boolean");
1480  openvas_validator_alias (validator, "base", "name");
1481  openvas_validator_alias (validator, "build_filter", "boolean");
1482  /* the "bulk_[...].x" parameters are used to identify the image type
1483  * form element used to submit the form for process_bulk */
1484  openvas_validator_alias (validator, "bulk_create.x", "number");
1485  openvas_validator_alias (validator, "bulk_delete.x", "number");
1486  openvas_validator_alias (validator, "bulk_export.x", "number");
1487  openvas_validator_alias (validator, "bulk_trash.x", "number");
1488  openvas_validator_alias (validator, "bulk_select", "number");
1489  openvas_validator_alias (validator, "change_community", "boolean");
1490  openvas_validator_alias (validator, "change_passphrase", "boolean");
1491  openvas_validator_alias (validator, "change_password", "boolean");
1492  openvas_validator_alias (validator, "change_privacy_password", "boolean");
1493  openvas_validator_alias (validator, "charts", "boolean");
1494  openvas_validator_alias (validator, "chart_type", "name");
1495  openvas_validator_alias (validator, "chart_template", "name");
1496  openvas_validator_alias (validator, "community", "lsc_password");
1497  openvas_validator_alias (validator, "custom_severity", "boolean");
1498  openvas_validator_alias (validator, "current_user", "boolean");
1499  openvas_validator_alias (validator, "dashboard_name", "name");
1500  openvas_validator_alias (validator, "debug", "boolean");
1501  openvas_validator_alias (validator, "delta_report_id", "report_id");
1502  openvas_validator_alias (validator, "delta_state_changed", "boolean");
1503  openvas_validator_alias (validator, "delta_state_gone", "boolean");
1504  openvas_validator_alias (validator, "delta_state_new", "boolean");
1505  openvas_validator_alias (validator, "delta_state_same", "boolean");
1506  openvas_validator_alias (validator, "duration", "optional_number");
1507  openvas_validator_alias (validator, "duration_unit", "calendar_unit");
1508  openvas_validator_alias (validator, "dynamic_severity", "boolean");
1509  openvas_validator_alias (validator, "enable", "boolean");
1510  openvas_validator_alias (validator, "enable_stop", "boolean");
1511  openvas_validator_alias (validator, "end_day", "day_of_month");
1512  openvas_validator_alias (validator, "end_hour", "hour");
1513  openvas_validator_alias (validator, "end_minute", "minute");
1514  openvas_validator_alias (validator, "end_month", "month");
1515  openvas_validator_alias (validator, "end_year", "year");
1516  openvas_validator_alias (validator, "esxi_credential_id", "credential_id");
1517  openvas_validator_alias (validator, "filt_id", "id");
1518  openvas_validator_alias (validator, "filter_extra", "filter");
1519  openvas_validator_alias (validator, "filter_id", "id");
1520  openvas_validator_alias (validator, "filterbox", "boolean");
1521  openvas_validator_alias (validator, "from_file", "boolean");
1522  openvas_validator_alias (validator, "force_wizard", "boolean");
1523  openvas_validator_alias (validator, "get_name", "name");
1524  openvas_validator_alias (validator, "grant_full", "boolean");
1525  openvas_validator_alias (validator, "group_id", "id");
1526  openvas_validator_alias (validator, "group_ids:name", "number");
1527  openvas_validator_alias (validator, "group_ids:value", "id_optional");
1528  openvas_validator_alias (validator, "groups", "optional_number");
1529  openvas_validator_alias (validator, "host_search_phrase", "search_phrase");
1530  openvas_validator_alias (validator, "host_first_result", "first_result");
1531  openvas_validator_alias (validator, "host_max_results", "max_results");
1532  openvas_validator_alias (validator, "host_levels", "levels");
1533  openvas_validator_alias (validator, "host_count", "number");
1534  openvas_validator_alias (validator, "hosts_manual", "hosts");
1535  openvas_validator_alias (validator, "hosts_filter", "filter");
1536  openvas_validator_alias (validator, "exclude_hosts", "hosts");
1537  openvas_validator_alias (validator, "in_assets", "boolean");
1538  openvas_validator_alias (validator, "in_use", "boolean");
1539  openvas_validator_alias (validator, "include_related", "number");
1540  openvas_validator_alias (validator, "inheritor_id", "id");
1541  openvas_validator_alias (validator, "ignore_pagination", "boolean");
1542  openvas_validator_alias (validator, "refresh_interval", "number");
1543  openvas_validator_alias (validator, "event", "condition");
1544  openvas_validator_alias (validator, "access_hosts", "hosts_opt");
1545  openvas_validator_alias (validator, "access_ifaces", "hosts_opt");
1546  openvas_validator_alias (validator, "max_checks", "number");
1547  openvas_validator_alias (validator, "max_hosts", "number");
1548  openvas_validator_alias (validator, "method", "condition");
1549  openvas_validator_alias (validator, "modify_password", "number");
1550  openvas_validator_alias (validator, "ldaphost", "hostport");
1551  openvas_validator_alias (validator, "level_high", "boolean");
1552  openvas_validator_alias (validator, "level_medium", "boolean");
1553  openvas_validator_alias (validator, "level_low", "boolean");
1554  openvas_validator_alias (validator, "level_log", "boolean");
1555  openvas_validator_alias (validator, "level_false_positive", "boolean");
1556  openvas_validator_alias (validator, "method_data:to_address:", "email_list");
1557  openvas_validator_alias (validator, "method_data:from_address:", "email");
1558  openvas_validator_alias (validator, "new_severity", "severity_optional");
1559  openvas_validator_alias (validator, "new_severity_from_list", "severity_optional");
1560  openvas_validator_alias (validator, "new_threat", "threat");
1561  openvas_validator_alias (validator, "next", "page");
1562  openvas_validator_alias (validator, "next_next", "page");
1563  openvas_validator_alias (validator, "next_error", "page");
1564  openvas_validator_alias (validator, "next_id", "info_id");
1565  openvas_validator_alias (validator, "next_type", "resource_type");
1566  openvas_validator_alias (validator, "next_subtype", "info_type");
1567  openvas_validator_alias (validator, "next_xml", "boolean");
1568  openvas_validator_alias (validator, "notes", "boolean");
1569  openvas_validator_alias (validator, "note_task_id", "optional_task_id");
1570  openvas_validator_alias (validator, "note_task_uuid", "note_task_id");
1571  openvas_validator_alias (validator, "note_result_uuid", "note_result_id");
1572  openvas_validator_alias (validator, "no_chart_links", "boolean");
1573  openvas_validator_alias (validator, "no_filter_history", "boolean");
1574  openvas_validator_alias (validator, "no_redirect", "boolean");
1575  openvas_validator_alias (validator, "nvt:value", "uuid");
1576  openvas_validator_alias (validator, "old_login", "login");
1577  openvas_validator_alias (validator, "old_password", "password");
1578  openvas_validator_alias (validator, "original_overrides", "boolean");
1579  openvas_validator_alias (validator, "overrides", "boolean");
1580  openvas_validator_alias (validator, "override_task_id", "optional_task_id");
1581  openvas_validator_alias (validator, "override_task_uuid", "override_task_id");
1582  openvas_validator_alias (validator, "override_result_uuid", "override_result_id");
1583  openvas_validator_alias (validator, "owner", "name");
1584  openvas_validator_alias (validator, "passphrase", "lsc_password");
1585  openvas_validator_alias (validator, "password:name", "preference_name");
1586  openvas_validator_alias (validator, "permission", "name");
1587  openvas_validator_alias (validator, "permission_id", "id");
1588  openvas_validator_alias (validator, "permission_group_id", "id");
1589  openvas_validator_alias (validator, "permission_role_id", "id");
1590  openvas_validator_alias (validator, "permission_user_id", "id");
1591  openvas_validator_alias (validator, "port_manual", "port");
1592  openvas_validator_alias (validator, "port_range_end", "number");
1593  openvas_validator_alias (validator, "port_range_start", "number");
1594  openvas_validator_alias (validator, "pos", "number");
1595  openvas_validator_alias (validator, "privacy_password", "lsc_password");
1596  openvas_validator_alias (validator, "radiushost", "hostport");
1597  openvas_validator_alias (validator, "restrict_type", "resource_type");
1598  openvas_validator_alias (validator, "result_hosts_only", "boolean");
1599  openvas_validator_alias (validator, "result_task_id", "optional_task_id");
1600  openvas_validator_alias (validator, "report_result_id", "result_id");
1601  openvas_validator_alias (validator, "replace_task_id", "boolean");
1602  openvas_validator_alias (validator, "reverse_lookup_only", "boolean");
1603  openvas_validator_alias (validator, "reverse_lookup_unify", "boolean");
1604  openvas_validator_alias (validator, "role_id", "id");
1605  openvas_validator_alias (validator, "role_ids:name", "number");
1606  openvas_validator_alias (validator, "role_ids:value", "id_optional");
1607  openvas_validator_alias (validator, "roles", "optional_number");
1608  openvas_validator_alias (validator, "period", "optional_number");
1609  openvas_validator_alias (validator, "period_unit", "calendar_unit");
1610  openvas_validator_alias (validator, "scanner_host", "hostpath");
1611  openvas_validator_alias (validator, "scanner_type", "number");
1612  openvas_validator_alias (validator, "schedules_only", "boolean");
1613  openvas_validator_alias (validator, "schedule_periods", "number");
1614  openvas_validator_alias (validator, "select:name", "family");
1615  openvas_validator_alias (validator, "show_all", "boolean");
1616  openvas_validator_alias (validator, "slave_id", "id");
1617  openvas_validator_alias (validator, "smb_credential_id", "credential_id");
1618  openvas_validator_alias (validator, "snmp_credential_id", "credential_id");
1619  openvas_validator_alias (validator, "ssh_credential_id", "credential_id");
1620  openvas_validator_alias (validator, "start_day", "day_of_month");
1621  openvas_validator_alias (validator, "start_hour", "hour");
1622  openvas_validator_alias (validator, "start_minute", "minute");
1623  openvas_validator_alias (validator, "start_month", "month");
1624  openvas_validator_alias (validator, "start_year", "year");
1625  openvas_validator_alias (validator, "subgroup_column", "group_column");
1626  openvas_validator_alias (validator, "subject_id", "id");
1627  openvas_validator_alias (validator, "subject_id_optional", "id_optional");
1628  openvas_validator_alias (validator, "subject_name", "name");
1629  openvas_validator_alias (validator, "subtype", "asset_type");
1630  openvas_validator_alias (validator, "task_filter", "filter");
1631  openvas_validator_alias (validator, "task_filt_id", "filt_id");
1632  openvas_validator_alias (validator, "timeout", "boolean");
1633  openvas_validator_alias (validator, "trend:name", "family");
1634  openvas_validator_alias (validator, "user_id", "id");
1635  openvas_validator_alias (validator, "user_id_optional", "id_optional");
1636  openvas_validator_alias (validator, "xml", "boolean");
1637  openvas_validator_alias (validator, "esc_filter", "filter");
1638 }
1639 
1651 static void
1652 content_type_from_format_string (enum content_type* content_type,
1653  const char* format)
1654 {
1655  if (!format)
1656  *content_type = GSAD_CONTENT_TYPE_APP_HTML;
1657 
1658  else if (strcmp (format, "deb") == 0)
1659  *content_type = GSAD_CONTENT_TYPE_APP_DEB;
1660  else if (strcmp (format, "exe") == 0)
1661  *content_type = GSAD_CONTENT_TYPE_APP_EXE;
1662  else if (strcmp (format, "html") == 0)
1663  *content_type = GSAD_CONTENT_TYPE_APP_HTML;
1664  else if (strcmp (format, "key") == 0)
1665  *content_type = GSAD_CONTENT_TYPE_APP_KEY;
1666  else if (strcmp (format, "nbe") == 0)
1667  *content_type = GSAD_CONTENT_TYPE_APP_NBE;
1668  else if (strcmp (format, "pdf") == 0)
1669  *content_type = GSAD_CONTENT_TYPE_APP_PDF;
1670  else if (strcmp (format, "rpm") == 0)
1671  *content_type = GSAD_CONTENT_TYPE_APP_RPM;
1672  else if (strcmp (format, "xml") == 0)
1673  *content_type = GSAD_CONTENT_TYPE_APP_XML;
1674  // Defaults to GSAD_CONTENT_TYPE_APP_HTML
1675  else
1676  *content_type = GSAD_CONTENT_TYPE_APP_HTML;
1677 }
1678 
1689 {
1690  struct MHD_PostProcessor *postprocessor;
1691  char *response;
1693  char *cookie;
1694  char *language;
1697  enum content_type content_type;
1700  gchar *redirect;
1701 };
1702 
1703 #ifdef SERVE_STATIC_ASSETS
1704 
1714 static int
1715 file_reader (void *cls, uint64_t pos, char *buf, int max)
1716 {
1717  FILE *file = cls;
1718 
1719  fseek (file, pos, SEEK_SET);
1720  return fread (buf, 1, max, file);
1721 }
1722 #endif
1723 
1734 void
1735 free_resources (void *cls, struct MHD_Connection *connection,
1736  void **con_cls, enum MHD_RequestTerminationCode toe)
1737 {
1738  struct gsad_connection_info *con_info =
1739  (struct gsad_connection_info *) *con_cls;
1740 
1741  if (NULL == con_info)
1742  {
1743  g_debug ("con_info was NULL!\n");
1744  return;
1745  }
1746 
1747  g_debug ("connectiontype=%d\n", con_info->connectiontype);
1748 
1749  if (con_info->connectiontype == 1)
1750  {
1751  if (NULL != con_info->postprocessor)
1752  {
1753  MHD_destroy_post_processor (con_info->postprocessor);
1754  }
1755  }
1756 
1757  params_free (con_info->params);
1758  g_free (con_info->cookie);
1759  g_free (con_info->content_disposition);
1760  g_free (con_info->language);
1761  g_free (con_info);
1762  *con_cls = NULL;
1763 }
1764 
1777 static int
1778 params_append_mhd (params_t *params,
1779  const char *name,
1780  const char *filename,
1781  const char *chunk_data,
1782  int chunk_size,
1783  int chunk_offset)
1784 {
1785  if ((strncmp (name, "bulk_selected:", strlen ("bulk_selected:")) == 0)
1786  || (strncmp (name, "chart_gen:", strlen ("chart_gen:")) == 0)
1787  || (strncmp (name, "chart_init:", strlen ("chart_init:")) == 0)
1788  || (strncmp (name, "condition_data:", strlen ("condition_data:")) == 0)
1789  || (strncmp (name, "data_columns:", strlen ("data_columns:")) == 0)
1790  || (strncmp (name, "event_data:", strlen ("event_data:")) == 0)
1791  || (strncmp (name, "settings_changed:", strlen ("settings_changed:"))
1792  == 0)
1793  || (strncmp (name, "settings_default:", strlen ("settings_default:"))
1794  == 0)
1795  || (strncmp (name, "settings_filter:", strlen ("settings_filter:")) == 0)
1796  || (strncmp (name, "file:", strlen ("file:")) == 0)
1797  || (strncmp (name, "include_id_list:", strlen ("include_id_list:")) == 0)
1798  || (strncmp (name, "parameter:", strlen ("parameter:")) == 0)
1799  || (strncmp (name, "password:", strlen ("password:")) == 0)
1800  || (strncmp (name, "preference:", strlen ("preference:")) == 0)
1801  || (strncmp (name, "select:", strlen ("select:")) == 0)
1802  || (strncmp (name, "text_columns:", strlen ("text_columns:")) == 0)
1803  || (strncmp (name, "trend:", strlen ("trend:")) == 0)
1804  || (strncmp (name, "method_data:", strlen ("method_data:")) == 0)
1805  || (strncmp (name, "nvt:", strlen ("nvt:")) == 0)
1806  || (strncmp (name, "alert_id_optional:", strlen ("alert_id_optional:"))
1807  == 0)
1808  || (strncmp (name, "group_id_optional:", strlen ("group_id_optional:"))
1809  == 0)
1810  || (strncmp (name, "role_id_optional:", strlen ("role_id_optional:"))
1811  == 0)
1812  || (strncmp (name, "related:", strlen ("related:")) == 0)
1813  || (strncmp (name, "sort_fields:", strlen ("sort_fields:")) == 0)
1814  || (strncmp (name, "sort_orders:", strlen ("sort_orders:")) == 0)
1815  || (strncmp (name, "sort_stats:", strlen ("sort_stats:")) == 0)
1816  || (strncmp (name, "y_fields:", strlen ("y_fields:")) == 0)
1817  || (strncmp (name, "z_fields:", strlen ("z_fields:")) == 0))
1818  {
1819  param_t *param;
1820  const char *colon;
1821  gchar *prefix;
1822 
1823  colon = strchr (name, ':');
1824 
1825  /* Hashtable param, like for radios. */
1826 
1827  if ((colon - name) == (strlen (name) - 1))
1828  {
1829  /* name: "example:", value "abc". */
1830 
1831  params_append_bin (params, name, chunk_data, chunk_size, chunk_offset);
1832 
1833  return MHD_YES;
1834  }
1835 
1836  /* name: "nvt:1.3.6.1.4.1.25623.1.0.105058", value "1". */
1837 
1838  prefix = g_strndup (name, 1 + colon - name);
1839  param = params_get (params, prefix);
1840 
1841  if (param == NULL)
1842  {
1843  param = params_add (params, prefix, "");
1844  param->values = params_new ();
1845  }
1846  else if (param->values == NULL)
1847  param->values = params_new ();
1848 
1849  g_free (prefix);
1850 
1851  params_append_bin (param->values, colon + 1, chunk_data, chunk_size,
1852  chunk_offset);
1853  if (filename)
1854  param->filename = g_strdup (filename);
1855 
1856  return MHD_YES;
1857  }
1858 
1859  /*
1860  * Array param
1861  * Can be accessed like a hashtable param,with ascending numbers as the
1862  * key, which are automatically generated instead of being part of the
1863  * full name.
1864  * For example multiple instances of "x:" in the request
1865  * become "x:1", "x:2", "x:3", etc.
1866  */
1867  if ((strcmp (name, "alert_ids:") == 0)
1868  || (strcmp(name, "role_ids:") == 0)
1869  || (strcmp(name, "group_ids:") == 0)
1870  || (strcmp(name, "id_list:") == 0))
1871  {
1872  param_t *param;
1873  gchar *index_str;
1874 
1875  param = params_get (params, name);
1876 
1877  if (param == NULL)
1878  {
1879  param = params_add (params, name, "");
1880  param->values = params_new ();
1881  }
1882  else if (param->values == NULL)
1883  param->values = params_new ();
1884 
1885  if (chunk_offset == 0)
1886  param->array_len += 1;
1887 
1888  index_str = g_strdup_printf ("%d", param->array_len);
1889 
1890  params_append_bin (param->values, index_str, chunk_data, chunk_size,
1891  chunk_offset);
1892 
1893  g_free (index_str);
1894 
1895  if (filename)
1896  param->filename = g_strdup (filename);
1897 
1898  return MHD_YES;
1899  }
1900 
1901  /* Single value param. */
1902 
1903  params_append_bin (params, name, chunk_data, chunk_size, chunk_offset);
1904 
1905  return MHD_YES;
1906 }
1907 
1930 int
1931 serve_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key,
1932  const char *filename, const char *content_type,
1933  const char *transfer_encoding, const char *data, uint64_t off,
1934  size_t size)
1935 {
1936  struct gsad_connection_info *con_info =
1937  (struct gsad_connection_info *) coninfo_cls;
1938 
1939  con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
1940  con_info->response = SERVER_ERROR;
1941 
1942  if (NULL != key)
1943  {
1944  params_append_mhd (con_info->params, key, filename, data, size, off);
1945  con_info->answercode = MHD_HTTP_OK;
1946  return MHD_YES;
1947  }
1948  return MHD_NO;
1949 }
1950 
1957 void
1958 params_mhd_validate_values (const char *parent_name, void *params)
1959 {
1960  params_iterator_t iter;
1961  param_t *param;
1962  gchar *name, *name_name, *value_name;
1963 
1964  name_name = g_strdup_printf ("%sname", parent_name);
1965  value_name = g_strdup_printf ("%svalue", parent_name);
1966 
1967  params_iterator_init (&iter, params);
1968  while (params_iterator_next (&iter, &name, &param))
1969  {
1970  gchar *item_name;
1971 
1972  /* Item specific value validator like "method_data:to_adddress:". */
1973  if ((g_utf8_validate (name, -1, NULL) == FALSE)
1974  || (g_utf8_validate (param->value, -1, NULL) == FALSE))
1975  {
1976  param->original_value = param->value;
1977  param->value = NULL;
1978  param->value_size = 0;
1979  param->valid = 0;
1980  param->valid_utf8 = 0;
1981  item_name = NULL;
1982  }
1983  else switch (openvas_validate (validator,
1984  (item_name = g_strdup_printf ("%s%s:",
1985  parent_name,
1986  name)),
1987  param->value))
1988  {
1989  case 0:
1990  break;
1991  case 1:
1992  /* General name validator for collection like "method_data:name". */
1993  if (openvas_validate (validator, name_name, name))
1994  {
1995  param->original_value = param->value;
1996  param->value = NULL;
1997  param->value_size = 0;
1998  param->valid = 0;
1999  param->valid_utf8 = 0;
2000  }
2001  /* General value validator like "method_data:value". */
2002  else if (openvas_validate (validator, value_name, param->value))
2003  {
2004  param->original_value = param->value;
2005  param->value = NULL;
2006  param->value_size = 0;
2007  param->valid = 0;
2008  param->valid_utf8 = 0;
2009  }
2010  else
2011  {
2012  const gchar *alias_for;
2013 
2014  param->valid = 1;
2015  param->valid_utf8 = 1;
2016 
2017  alias_for = openvas_validator_alias_for (validator, name);
2018  if ((param->value && (strcmp ((gchar*) name, "number") == 0))
2019  || (alias_for && (strcmp ((gchar*) alias_for, "number") == 0)))
2020  /* Remove any leading or trailing space from numbers. */
2021  param->value = g_strstrip (param->value);
2022  }
2023  break;
2024  case 2:
2025  default:
2026  {
2027  param->original_value = param->value;
2028  param->value = NULL;
2029  param->value_size = 0;
2030  param->valid = 0;
2031  param->valid_utf8 = 0;
2032  }
2033  }
2034 
2035  g_free (item_name);
2036  }
2037 
2038  g_free (name_name);
2039  g_free (value_name);
2040 }
2041 
2047 static void
2048 params_mhd_validate (void *params)
2049 {
2050  GHashTableIter iter;
2051  gpointer name, value;
2052 
2053  g_hash_table_iter_init (&iter, params);
2054  while (g_hash_table_iter_next (&iter, &name, &value))
2055  {
2056  param_t *param;
2057  param = (param_t*) value;
2058 
2059  param->valid_utf8 = (g_utf8_validate (name, -1, NULL)
2060  && (param->value == NULL
2061  || g_utf8_validate (param->value, -1, NULL)));
2062 
2063  if ((!g_str_has_prefix (name, "osp_pref_")
2064  && openvas_validate (validator, name, param->value)))
2065  {
2066  param->original_value = param->value;
2067  param->value = NULL;
2068  param->valid = 0;
2069  }
2070  else
2071  {
2072  const gchar *alias_for;
2073 
2074  param->valid = 1;
2075 
2076  alias_for = openvas_validator_alias_for (validator, name);
2077  if ((param->value && (strcmp ((gchar*) name, "number") == 0))
2078  || (alias_for && (strcmp ((gchar*) alias_for, "number") == 0)))
2079  /* Remove any leading or trailing space from numbers. */
2080  param->value = g_strstrip (param->value);
2081  }
2082 
2083  if (param->values)
2084  params_mhd_validate_values (name, param->values);
2085  }
2086 }
2087 
2091 #define ELSE(name) \
2092  else if (!strcmp (cmd, G_STRINGIFY (name))) \
2093  con_info->response = name ## _omp (credentials, con_info->params, \
2094  &response_data);
2095 
2096 static credentials_t *
2097 credentials_new (user_t *user, const char *language, const char *client_address)
2098 {
2099  credentials_t *credentials;
2100 
2101  assert (user->username);
2102  assert (user->password);
2103  assert (user->role);
2104  assert (user->timezone);
2105  assert (user->capabilities);
2106  assert (user->token);
2107  credentials = g_malloc0 (sizeof (credentials_t));
2108  credentials->username = g_strdup (user->username);
2109  credentials->password = g_strdup (user->password);
2110  credentials->role = g_strdup (user->role);
2111  credentials->timezone = g_strdup (user->timezone);
2112  credentials->severity = g_strdup (user->severity);
2113  credentials->capabilities = g_strdup (user->capabilities);
2114  credentials->token = g_strdup (user->token);
2115  credentials->charts = user->charts;
2116  credentials->chart_prefs = user->chart_prefs;
2117  credentials->pw_warning = user->pw_warning ? g_strdup (user->pw_warning)
2118  : NULL;
2119  credentials->language = g_strdup (language);
2120  credentials->autorefresh = user->autorefresh
2121  ? g_strdup (user->autorefresh) : NULL;
2122  credentials->last_filt_ids = user->last_filt_ids;
2123  credentials->client_address = g_strdup (client_address);
2124  credentials->guest = user->guest;
2125 
2126  return credentials;
2127 }
2128 
2129 static void
2130 credentials_free (credentials_t *creds)
2131 {
2132  if (!creds)
2133  return;
2134 
2135  g_free (creds->username);
2136  g_free (creds->password);
2137  g_free (creds->role);
2138  g_free (creds->timezone);
2139  g_free (creds->token);
2140  g_free (creds->caller);
2141  g_free (creds->current_page);
2142  g_free (creds->capabilities);
2143  g_free (creds->language);
2144  g_free (creds->severity);
2145  g_free (creds->pw_warning);
2146  g_free (creds->client_address);
2147  g_free (creds->autorefresh);
2148  /* params, chart_prefs and last_filt_ids are not duplicated. */
2149  g_free (creds);
2150 }
2151 
2167 int
2168 exec_omp_post (struct gsad_connection_info *con_info, user_t **user_return,
2169  gchar **new_sid, const char *client_address)
2170 {
2171  int ret;
2172  user_t *user;
2173  credentials_t *credentials;
2174  const char *cmd, *caller, *language;
2175  cmd_response_data_t response_data;
2176  cmd_response_data_init (&response_data);
2177  const char *xml_flag;
2178  xml_flag = params_value (con_info->params, "xml");
2179 
2180  /* Handle the login command specially. */
2181 
2182  params_mhd_validate (con_info->params);
2183 
2184  cmd = params_value (con_info->params, "cmd");
2185 
2186  if (cmd && !strcmp (cmd, "login"))
2187  {
2188  const char *password;
2189 
2190  password = params_value (con_info->params, "password");
2191  if ((password == NULL)
2192  && (params_original_value (con_info->params, "password") == NULL))
2193  password = "";
2194 
2195  if (params_value (con_info->params, "login")
2196  && password)
2197  {
2198  int ret;
2199  gchar *timezone, *role, *capabilities, *severity, *language;
2200  gchar *pw_warning, *autorefresh;
2201  GTree *chart_prefs;
2202  ret = authenticate_omp (params_value (con_info->params, "login"),
2203  password,
2204  &role,
2205  &timezone,
2206  &severity,
2207  &capabilities,
2208  &language,
2209  &pw_warning,
2210  &chart_prefs,
2211  &autorefresh);
2212  if (ret)
2213  {
2214  time_t now;
2215  gchar *xml;
2216  char *res;
2217  char ctime_now[200];
2218 
2219  if (ret == -1 || ret == 2)
2220  response_data.http_status_code = MHD_HTTP_SERVICE_UNAVAILABLE;
2221  else
2222  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
2223 
2224  now = time (NULL);
2225  ctime_r_strip_newline (&now, ctime_now);
2226 
2227  xml = login_xml
2228  (ret == 2
2229  ? "Login failed."
2230  " Waiting for OMP service to become available."
2231  : (ret == -1
2232  ? "Login failed."
2233  " Error during authentication."
2234  : "Login failed."),
2235  NULL,
2236  ctime_now,
2237  NULL,
2238  con_info->language
2239  ? con_info->language
2242 
2243  if (xml_flag && strcmp (xml_flag, "0"))
2244  res = xml;
2245  else
2246  {
2247  res = xsl_transform (xml, &response_data);
2248  g_free (xml);
2249  }
2250  con_info->response = res;
2251  con_info->answercode = response_data.http_status_code;
2252 
2253  g_warning ("Authentication failure for '%s' from %s",
2254  params_value (con_info->params, "login") ?: "",
2255  client_address);
2256  }
2257  else
2258  {
2259  user_t *user;
2260  user = user_add (params_value (con_info->params, "login"),
2261  password, timezone, severity, role, capabilities,
2262  language, pw_warning, chart_prefs, autorefresh,
2263  client_address);
2264  /* Redirect to get_tasks. */
2265  *user_return = user;
2266  g_free (timezone);
2267  g_free (severity);
2268  g_free (capabilities);
2269  g_free (language);
2270  g_free (role);
2271  g_free (pw_warning);
2272  g_free (autorefresh);
2273  cmd_response_data_reset (&response_data);
2274  return 1;
2275  }
2276  }
2277  else
2278  {
2279  time_t now;
2280  gchar *xml;
2281  char *res;
2282  char ctime_now[200];
2283 
2284  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
2285 
2286  now = time (NULL);
2287  ctime_r_strip_newline (&now, ctime_now);
2288 
2289  xml = login_xml ("Login failed.", NULL, ctime_now, NULL,
2290  con_info->language ? con_info->language
2293  if (xml_flag && strcmp (xml_flag, "0"))
2294  res = xml;
2295  else
2296  {
2297  res = xsl_transform (xml, &response_data);
2298  g_free (xml);
2299  }
2300  con_info->response = res;
2301  con_info->answercode = response_data.http_status_code;
2302  g_warning ("Authentication failure for '%s' from %s",
2303  params_value (con_info->params, "login") ?: "",
2304  client_address);
2305  }
2306  cmd_response_data_reset (&response_data);
2307  return 3;
2308  }
2309 
2310  /* Check the session. */
2311 
2312  if (params_value (con_info->params, "token") == NULL)
2313  {
2314  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
2315  if (params_given (con_info->params, "token") == 0)
2316  con_info->response
2317  = gsad_message (NULL,
2318  "Internal error", __FUNCTION__, __LINE__,
2319  "An internal error occurred inside GSA daemon. "
2320  "Diagnostics: Token missing.",
2321  "/omp?cmd=get_tasks", &response_data);
2322  else
2323  con_info->response
2324  = gsad_message (NULL,
2325  "Internal error", __FUNCTION__, __LINE__,
2326  "An internal error occurred inside GSA daemon. "
2327  "Diagnostics: Token bad.",
2328  "/omp?cmd=get_tasks", &response_data);
2329  con_info->answercode = response_data.http_status_code;
2330  cmd_response_data_reset (&response_data);
2331  return 3;
2332  }
2333 
2334  ret = user_find (con_info->cookie, params_value (con_info->params, "token"),
2335  client_address, &user);
2336  if (ret == USER_BAD_TOKEN)
2337  {
2338  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
2339  con_info->response
2340  = gsad_message (NULL,
2341  "Internal error", __FUNCTION__, __LINE__,
2342  "An internal error occurred inside GSA daemon. "
2343  "Diagnostics: Bad token.",
2344  "/omp?cmd=get_tasks", &response_data);
2345  con_info->answercode = response_data.http_status_code;
2346  cmd_response_data_reset (&response_data);
2347  return 3;
2348  }
2349 
2350  if (ret == USER_EXPIRED_TOKEN)
2351  {
2352  time_t now;
2353  gchar *xml;
2354  char ctime_now[200];
2355 
2356  now = time (NULL);
2357  ctime_r_strip_newline (&now, ctime_now);
2358 
2359  caller = params_value (con_info->params, "caller");
2360 
2361  if (caller && g_utf8_validate (caller, -1, NULL) == FALSE)
2362  {
2363  caller = NULL;
2364  g_warning ("%s - caller is not valid UTF-8", __FUNCTION__);
2365  }
2366 
2367  /* @todo Validate caller. */
2368 
2369  xml = login_xml ("Session has expired. Please login again.",
2370  NULL,
2371  ctime_now,
2372  caller
2373  ? caller
2374  : "",
2375  con_info->language
2376  ? con_info->language
2379  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
2380  if (xml_flag && strcmp (xml_flag, "0"))
2381  con_info->response = xml;
2382  else
2383  {
2384  con_info->response = xsl_transform (xml, &response_data);
2385  g_free (xml);
2386  }
2387  con_info->answercode = response_data.http_status_code;
2388  cmd_response_data_reset (&response_data);
2389  return 2;
2390  }
2391 
2393  {
2394  time_t now;
2395  gchar *xml;
2396  char ctime_now[200];
2397 
2398  now = time (NULL);
2399  ctime_r_strip_newline (&now, ctime_now);
2400 
2401  xml = login_xml ("Cookie missing or bad. Please login again.",
2402  NULL,
2403  ctime_now,
2404  NULL,
2405  con_info->language
2406  ? con_info->language
2409  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
2410  if (xml_flag && strcmp (xml_flag, "0"))
2411  con_info->response = xml;
2412  else
2413  {
2414  con_info->response = xsl_transform (xml, &response_data);
2415  g_free (xml);
2416  }
2417  con_info->answercode = response_data.http_status_code;
2418  cmd_response_data_reset (&response_data);
2419  return 2;
2420  }
2421 
2422  if (ret == USER_GUEST_LOGIN_FAILED || ret == USER_OMP_DOWN ||
2423  ret == USER_GUEST_LOGIN_ERROR)
2424  {
2425  time_t now;
2426  gchar *xml;
2427  char ctime_now[200];
2428 
2429  now = time (NULL);
2430  ctime_r_strip_newline (&now, ctime_now);
2431 
2432  response_data.http_status_code = MHD_HTTP_SERVICE_UNAVAILABLE;
2433  xml = login_xml (ret == USER_OMP_DOWN
2434  ? "Login failed. OMP service is down."
2435  : (ret == USER_GUEST_LOGIN_ERROR
2436  ? "Login failed. Error during authentication."
2437  : "Login failed."),
2438  NULL,
2439  ctime_now,
2440  NULL,
2441  con_info->language
2442  ? con_info->language
2445  if (xml_flag && strcmp (xml_flag, "0"))
2446  con_info->response = xml;
2447  else
2448  {
2449  con_info->response = xsl_transform (xml, &response_data);
2450  g_free (xml);
2451  }
2452  con_info->answercode = response_data.http_status_code;
2453  cmd_response_data_reset (&response_data);
2454  return 2;
2455  }
2456 
2457  if (ret)
2458  abort ();
2459 
2460  /* From here, the user is authenticated. */
2461 
2462 
2463  language = user->language ?: con_info->language ?: DEFAULT_GSAD_LANGUAGE;
2464  credentials = credentials_new (user, language, client_address);
2465  credentials->params = con_info->params;
2466  gettimeofday (&credentials->cmd_start, NULL);
2467 
2468  /* The caller of a POST is usually the caller of the page that the POST form
2469  * was on. */
2470  caller = params_value (con_info->params, "caller");
2471  if (caller && g_utf8_validate (caller, -1, NULL) == FALSE)
2472  {
2473  g_warning ("%s - caller is not valid UTF-8", __FUNCTION__);
2474  caller = NULL;
2475  }
2476  credentials->caller = g_strdup (caller ?: "");
2477 
2478  if (new_sid) *new_sid = g_strdup (user->cookie);
2479 
2480  user_release (user);
2481 
2482  /* Set the timezone. */
2483 
2484  if (credentials->timezone)
2485  {
2486  if (setenv ("TZ", credentials->timezone, 1) == -1)
2487  {
2488  g_critical ("%s: failed to set TZ\n", __FUNCTION__);
2489  exit (EXIT_FAILURE);
2490  }
2491  tzset ();
2492  }
2493 
2494  /* Handle the usual commands. */
2495 
2496  if (!cmd)
2497  {
2498  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
2499  con_info->response = gsad_message (credentials,
2500  "Internal error",
2501  __FUNCTION__,
2502  __LINE__,
2503  "An internal error occurred inside GSA daemon. "
2504  "Diagnostics: Empty command.",
2505  "/omp?cmd=get_tasks", &response_data);
2506  }
2507  ELSE (bulk_delete)
2508  ELSE (clone)
2509  ELSE (create_agent)
2510  ELSE (create_alert)
2511  ELSE (create_asset)
2512  ELSE (create_container_task)
2513  ELSE (create_credential)
2514  ELSE (create_filter)
2515  ELSE (create_group)
2516  ELSE (create_host)
2517  ELSE (create_permission)
2518  ELSE (create_permissions)
2519  ELSE (create_port_list)
2520  ELSE (create_port_range)
2521  ELSE (create_report)
2522  ELSE (create_task)
2523  ELSE (create_user)
2524  ELSE (create_role)
2525  ELSE (create_scanner)
2526  ELSE (create_schedule)
2527  ELSE (create_tag)
2528  ELSE (create_target)
2529  ELSE (create_config)
2530  ELSE (create_note)
2531  ELSE (create_override)
2532  ELSE (delete_agent)
2533  ELSE (delete_asset)
2534  ELSE (delete_task)
2535  ELSE (delete_alert)
2536  ELSE (delete_credential)
2537  ELSE (delete_filter)
2538  ELSE (delete_group)
2539  ELSE (delete_note)
2540  ELSE (delete_override)
2541  ELSE (delete_permission)
2542  ELSE (delete_port_list)
2543  ELSE (delete_port_range)
2544  ELSE (delete_report)
2545  ELSE (delete_report_format)
2546  ELSE (delete_role)
2547  ELSE (delete_scanner)
2548  ELSE (delete_schedule)
2549  ELSE (delete_user)
2550  ELSE (delete_tag)
2551  ELSE (delete_target)
2552  ELSE (delete_trash_agent)
2553  ELSE (delete_trash_config)
2554  ELSE (delete_trash_alert)
2555  ELSE (delete_trash_credential)
2556  ELSE (delete_trash_filter)
2557  ELSE (delete_trash_group)
2558  ELSE (delete_trash_note)
2559  ELSE (delete_trash_override)
2560  ELSE (delete_trash_permission)
2561  ELSE (delete_trash_port_list)
2562  ELSE (delete_trash_report_format)
2563  ELSE (delete_trash_role)
2564  ELSE (delete_trash_scanner)
2565  ELSE (delete_trash_schedule)
2566  ELSE (delete_trash_tag)
2567  ELSE (delete_trash_target)
2568  ELSE (delete_trash_task)
2569  ELSE (delete_config)
2570  ELSE (empty_trashcan)
2571  else if (!strcmp (cmd, "alert_report"))
2572  {
2573  con_info->response = get_report_section_omp
2574  (credentials, con_info->params, &response_data);
2575  }
2576  ELSE (import_config)
2577  ELSE (import_port_list)
2578  ELSE (import_report)
2579  ELSE (import_report_format)
2580  else if (!strcmp (cmd, "process_bulk"))
2581  {
2582  con_info->response = process_bulk_omp (credentials,
2583  con_info->params,
2584  &con_info->content_type,
2585  &con_info->content_disposition,
2586  &con_info->content_length,
2587  &response_data);
2588  }
2589  ELSE (move_task)
2590  ELSE (restore)
2591  ELSE (resume_task)
2592  ELSE (run_wizard)
2593  ELSE (save_agent)
2594  ELSE (save_alert)
2595  ELSE (save_asset)
2596  ELSE (save_auth)
2597  else if (!strcmp (cmd, "save_chart_preference"))
2598  {
2599  gchar *pref_id, *pref_value;
2600 
2601  con_info->response = save_chart_preference_omp (credentials,
2602  con_info->params,
2603  &pref_id, &pref_value,
2604  &response_data);
2605  if (pref_id && pref_value)
2606  user_set_chart_pref (credentials->token, pref_id, pref_value);
2607  }
2608  ELSE (save_config)
2609  ELSE (save_config_family)
2610  ELSE (save_config_nvt)
2611  ELSE (save_credential)
2612  ELSE (save_filter)
2613  ELSE (save_group)
2614  else if (!strcmp (cmd, "save_my_settings"))
2615  {
2616  char *timezone, *password, *severity, *language;
2617  con_info->response = save_my_settings_omp (credentials, con_info->params,
2618  con_info->language,
2619  &timezone, &password,
2620  &severity, &language,
2621  &response_data);
2622  if (timezone)
2623  /* credentials->timezone set in save_my_settings_omp before XSLT. */
2624  user_set_timezone (credentials->token, timezone);
2625  if (password)
2626  {
2627  /* credentials->password set in save_my_settings_omp before XSLT. */
2628  user_set_password (credentials->token, password);
2629 
2630  user_logout_all_sessions (credentials->username, credentials);
2631  }
2632  if (severity)
2633  /* credentials->severity set in save_my_settings_omp before XSLT. */
2634  user_set_severity (credentials->token, severity);
2635  /* credentials->language is set in save_my_settings_omp before XSLT. */
2636  user_set_language (credentials->token, language);
2637 
2638  g_free (timezone);
2639  g_free (password);
2640  g_free (severity);
2641  g_free (language);
2642  }
2643  ELSE (save_note)
2644  ELSE (save_override)
2645  ELSE (save_permission)
2646  ELSE (save_port_list)
2647  ELSE (save_report_format)
2648  ELSE (save_role)
2649  ELSE (save_scanner)
2650  ELSE (save_schedule)
2651  ELSE (save_tag)
2652  ELSE (save_target)
2653  ELSE (save_task)
2654  ELSE (save_container_task)
2655  else if (!strcmp (cmd, "save_user"))
2656  {
2657  char *password, *modified_user;
2658  int logout;
2659  con_info->response = save_user_omp (credentials, con_info->params,
2660  &password, &modified_user, &logout,
2661  &response_data);
2662  if (modified_user && logout)
2663  user_logout_all_sessions (modified_user, credentials);
2664 
2665  if (password)
2666  /* credentials->password set in save_user_omp before XSLT. */
2667  user_set_password (credentials->token, password);
2668 
2669  g_free (password);
2670  }
2671  ELSE (start_task)
2672  ELSE (stop_task)
2673  ELSE (sync_feed)
2674  ELSE (sync_scap)
2675  ELSE (sync_cert)
2676  ELSE (test_alert)
2677  ELSE (toggle_tag)
2678  ELSE (verify_agent)
2679  ELSE (verify_report_format)
2680  ELSE (verify_scanner)
2681  else
2682  {
2683  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
2684  con_info->response = gsad_message (credentials,
2685  "Internal error",
2686  __FUNCTION__,
2687  __LINE__,
2688  "An internal error occurred inside GSA daemon. "
2689  "Diagnostics: Unknown command.",
2690  "/omp?cmd=get_tasks", &response_data);
2691  }
2692 
2693  if (response_data.redirect)
2694  {
2695  con_info->answercode = MHD_HTTP_SEE_OTHER;
2696  con_info->redirect = response_data.redirect;
2697  }
2698  else
2699  con_info->answercode = response_data.http_status_code;
2700 
2701  cmd_response_data_reset (&response_data);
2702  credentials_free (credentials);
2703  return 0;
2704 }
2705 
2714 static int
2715 params_mhd_add (void *params, enum MHD_ValueKind kind, const char *name,
2716  const char *value)
2717 {
2718  if ((strncmp (name, "bulk_selected:", strlen ("bulk_selected:")) == 0)
2719  || (strncmp (name, "chart_gen:", strlen ("chart_gen:")) == 0)
2720  || (strncmp (name, "chart_init:", strlen ("chart_init:")) == 0)
2721  || (strncmp (name, "condition_data:", strlen ("condition_data:")) == 0)
2722  || (strncmp (name, "data_columns:", strlen ("data_columns:")) == 0)
2723  || (strncmp (name, "event_data:", strlen ("event_data:")) == 0)
2724  || (strncmp (name, "settings_changed:", strlen ("settings_changed:"))
2725  == 0)
2726  || (strncmp (name, "settings_default:", strlen ("settings_default:"))
2727  == 0)
2728  || (strncmp (name, "settings_filter:", strlen ("settings_filter:")) == 0)
2729  || (strncmp (name, "file:", strlen ("file:")) == 0)
2730  || (strncmp (name, "include_id_list:", strlen ("include_id_list:")) == 0)
2731  || (strncmp (name, "parameter:", strlen ("parameter:")) == 0)
2732  || (strncmp (name, "password:", strlen ("password:")) == 0)
2733  || (strncmp (name, "preference:", strlen ("preference:")) == 0)
2734  || (strncmp (name, "select:", strlen ("select:")) == 0)
2735  || (strncmp (name, "text_columns:", strlen ("text_columns:")) == 0)
2736  || (strncmp (name, "trend:", strlen ("trend:")) == 0)
2737  || (strncmp (name, "method_data:", strlen ("method_data:")) == 0)
2738  || (strncmp (name, "nvt:", strlen ("nvt:")) == 0)
2739  || (strncmp (name, "alert_id_optional:", strlen ("alert_id_optional:"))
2740  == 0)
2741  || (strncmp (name, "group_id_optional:", strlen ("group_id_optional:"))
2742  == 0)
2743  || (strncmp (name, "role_id_optional:", strlen ("role_id_optional:"))
2744  == 0)
2745  || (strncmp (name, "related:", strlen ("related:")) == 0)
2746  || (strncmp (name, "sort_fields:", strlen ("sort_fields:")) == 0)
2747  || (strncmp (name, "sort_orders:", strlen ("sort_orders:")) == 0)
2748  || (strncmp (name, "sort_stats:", strlen ("sort_stats:")) == 0)
2749  || (strncmp (name, "y_fields:", strlen ("y_fields:")) == 0)
2750  || (strncmp (name, "z_fields:", strlen ("z_fields:")) == 0))
2751  {
2752  param_t *param;
2753  const char *colon;
2754  gchar *prefix;
2755 
2756  /* Hashtable param, like for radios. */
2757 
2758  colon = strchr (name, ':');
2759 
2760  if ((colon - name) == (strlen (name) - 1))
2761  {
2762  params_append_bin (params, name, value, strlen (value), 0);
2763 
2764  return MHD_YES;
2765  }
2766 
2767  prefix = g_strndup (name, 1 + colon - name);
2768  param = params_get (params, prefix);
2769 
2770  if (param == NULL)
2771  {
2772  param = params_add (params, prefix, "");
2773  param->values = params_new ();
2774  }
2775  else if (param->values == NULL)
2776  param->values = params_new ();
2777 
2778  g_free (prefix);
2779 
2780  params_append_bin (param->values, colon + 1, value, strlen (value), 0);
2781 
2782  return MHD_YES;
2783  }
2784 
2785  /*
2786  * Array param (See params_append_mhd for a description)
2787  */
2788  if ((strcmp (name, "alert_ids:") == 0)
2789  || (strcmp(name, "role_ids:") == 0)
2790  || (strcmp(name, "group_ids:") == 0)
2791  || (strcmp(name, "id_list:") == 0))
2792  {
2793  param_t *param;
2794  gchar *index_str;
2795 
2796  param = params_get (params, name);
2797 
2798  if (param == NULL)
2799  {
2800  param = params_add (params, name, "");
2801  param->values = params_new ();
2802  }
2803  else if (param->values == NULL)
2804  param->values = params_new ();
2805 
2806  param->array_len += 1;
2807 
2808  index_str = g_strdup_printf ("%d", param->array_len);
2809 
2810  params_append_bin (param->values, index_str, value, strlen (value), 0);
2811 
2812  g_free (index_str);
2813 
2814  return MHD_YES;
2815  }
2816 
2817  /* Single value param. */
2818 
2819  params_add ((params_t *) params, name, value);
2820  return MHD_YES;
2821 }
2822 
2823 #undef ELSE
2824 
2828 #define ELSE(name) \
2829  else if (!strcmp (cmd, G_STRINGIFY (name))) \
2830  return name ## _omp (credentials, params, response_data);
2831 
2851 char *
2852 exec_omp_get (struct MHD_Connection *connection,
2853  credentials_t *credentials,
2854  enum content_type* content_type,
2855  gchar **content_type_string,
2856  char** content_disposition,
2857  gsize* response_size,
2858  cmd_response_data_t *response_data)
2859 {
2860  char *cmd = NULL;
2861  const int CMD_MAX_SIZE = 27; /* delete_trash_lsc_credential */
2862  params_t *params;
2863 
2864  cmd =
2865  (char *) MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND,
2866  "cmd");
2867  if (cmd == NULL)
2868  {
2869  cmd = "dashboard"; // TODO: Allow settings for face + users(?)
2870  }
2871 
2872  if (openvas_validate (validator, "cmd", cmd))
2873  cmd = NULL;
2874 
2875  if ((cmd != NULL) && (strlen (cmd) <= CMD_MAX_SIZE))
2876  {
2877  g_debug ("cmd: [%s]\n", cmd);
2878 
2879  params = params_new ();
2880 
2881  MHD_get_connection_values (connection, MHD_GET_ARGUMENT_KIND,
2882  params_mhd_add, params);
2883 
2884  params_mhd_validate (params);
2885  credentials->params = params;
2886  }
2887  else
2888  {
2889  response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
2890  return gsad_message (credentials,
2891  "Internal error", __FUNCTION__, __LINE__,
2892  "An internal error occurred inside GSA daemon. "
2893  "Diagnostics: No valid command for omp.",
2894  "/omp?cmd=get_tasks", response_data);
2895  }
2896 
2897 
2898  /* Set the timezone. */
2899 
2900  if (credentials->timezone)
2901  {
2902  if (setenv ("TZ", credentials->timezone, 1) == -1)
2903  {
2904  g_critical ("%s: failed to set TZ\n", __FUNCTION__);
2905  exit (EXIT_FAILURE);
2906  }
2907  tzset ();
2908  }
2909 
2910  /* Set page display settings */
2911 
2912  /* Show / hide charts */
2913  if (params_given (params, "charts"))
2914  {
2915  const char* charts;
2916  charts = params_value (params, "charts");
2917  credentials->charts = atoi (charts);
2918  user_set_charts (credentials->token, credentials->charts);
2919  }
2920 
2921  gettimeofday (&credentials->cmd_start, NULL);
2922 
2925  /* Check cmd and precondition, start respective OMP command(s). */
2926 
2927  if (!strcmp (cmd, "cvss_calculator"))
2928  return cvss_calculator (credentials, params, response_data);
2929 
2930  else if (!strcmp (cmd, "dashboard"))
2931  return dashboard (credentials, params, response_data);
2932 
2933  else if (!strcmp (cmd, "new_filter"))
2934  return new_filter_omp (credentials, params, response_data);
2935 
2936  ELSE (new_container_task)
2937  ELSE (new_target)
2938  ELSE (new_tag)
2939  ELSE (new_task)
2940  ELSE (new_user)
2941  ELSE (new_alert)
2942  ELSE (new_group)
2943  ELSE (new_role)
2944  ELSE (get_assets_chart)
2945  ELSE (get_task)
2946  ELSE (get_tasks)
2947  ELSE (get_tasks_chart)
2948  ELSE (delete_user_confirm)
2949  ELSE (edit_agent)
2950  ELSE (edit_alert)
2951  ELSE (edit_asset)
2952  ELSE (edit_config)
2953  ELSE (edit_config_family)
2954  ELSE (edit_config_nvt)
2955  ELSE (edit_credential)
2956  ELSE (edit_filter)
2957  ELSE (edit_group)
2958  ELSE (edit_my_settings)
2959  ELSE (edit_note)
2962  ELSE (edit_port_list)
2963  ELSE (edit_report_format)
2964  ELSE (edit_role)
2965  ELSE (edit_scanner)
2967  ELSE (edit_tag)
2968  ELSE (edit_target)
2969  ELSE (edit_task)
2970  ELSE (edit_user)
2971  ELSE (auth_settings)
2972 
2973  else if (!strcmp (cmd, "export_agent"))
2974  return export_agent_omp (credentials, params, content_type,
2975  content_disposition, response_size,
2976  response_data);
2977 
2978  else if (!strcmp (cmd, "export_agents"))
2979  return export_agents_omp (credentials, params, content_type,
2980  content_disposition, response_size,
2981  response_data);
2982 
2983  else if (!strcmp (cmd, "export_alert"))
2984  return export_alert_omp (credentials, params, content_type,
2985  content_disposition, response_size,
2986  response_data);
2987 
2988  else if (!strcmp (cmd, "export_alerts"))
2989  return export_alerts_omp (credentials, params, content_type,
2990  content_disposition, response_size,
2991  response_data);
2992 
2993  else if (!strcmp (cmd, "export_asset"))
2994  return export_asset_omp (credentials, params, content_type,
2995  content_disposition, response_size,
2996  response_data);
2997 
2998  else if (!strcmp (cmd, "export_assets"))
2999  return export_assets_omp (credentials, params, content_type,
3000  content_disposition, response_size,
3001  response_data);
3002 
3003  else if (!strcmp (cmd, "export_config"))
3004  return export_config_omp (credentials, params, content_type,
3005  content_disposition, response_size,
3006  response_data);
3007 
3008  else if (!strcmp (cmd, "export_configs"))
3009  return export_configs_omp (credentials, params, content_type,
3010  content_disposition, response_size,
3011  response_data);
3012 
3013  else if (!strcmp (cmd, "download_credential"))
3014  {
3015  char *html;
3016  gchar *credential_login;
3017  const char *credential_id;
3018  const char *package_format;
3019 
3020  package_format = params_value (params, "package_format");
3021  credential_login = NULL;
3022  credential_id = params_value (params, "credential_id");
3023 
3024  if (download_credential_omp (credentials,
3025  params,
3026  response_size,
3027  &html,
3028  &credential_login,
3029  response_data))
3030  return html;
3031 
3032  /* Returned above if package_format was NULL. */
3033  content_type_from_format_string (content_type, package_format);
3034  g_free (*content_disposition);
3035  *content_disposition = g_strdup_printf
3036  ("attachment; filename=credential-%s.%s",
3037  (credential_login
3038  && strcmp (credential_login, ""))
3039  ? credential_login
3040  : credential_id,
3041  (strcmp (package_format, "key") == 0
3042  ? "pub"
3043  : package_format));
3044  g_free (credential_login);
3045 
3046  return html;
3047  }
3048 
3049  else if (!strcmp (cmd, "export_credential"))
3050  return export_credential_omp (credentials, params, content_type,
3051  content_disposition, response_size,
3052  response_data);
3053 
3054  else if (!strcmp (cmd, "export_credentials"))
3055  return export_credentials_omp (credentials, params, content_type,
3056  content_disposition, response_size,
3057  response_data);
3058 
3059  else if (!strcmp (cmd, "export_filter"))
3060  return export_filter_omp (credentials, params, content_type,
3061  content_disposition, response_size,
3062  response_data);
3063 
3064  else if (!strcmp (cmd, "export_filters"))
3065  return export_filters_omp (credentials, params, content_type,
3066  content_disposition, response_size,
3067  response_data);
3068 
3069  else if (!strcmp (cmd, "export_group"))
3070  return export_group_omp (credentials, params, content_type,
3071  content_disposition, response_size,
3072  response_data);
3073 
3074  else if (!strcmp (cmd, "export_groups"))
3075  return export_groups_omp (credentials, params, content_type,
3076  content_disposition, response_size,
3077  response_data);
3078 
3079  else if (!strcmp (cmd, "export_note"))
3080  return export_note_omp (credentials, params, content_type,
3081  content_disposition, response_size,
3082  response_data);
3083 
3084  else if (!strcmp (cmd, "export_notes"))
3085  return export_notes_omp (credentials, params, content_type,
3086  content_disposition, response_size,
3087  response_data);
3088 
3089  else if (!strcmp (cmd, "export_omp_doc"))
3090  return export_omp_doc_omp (credentials, params, content_type,
3091  content_disposition, response_size,
3092  response_data);
3093 
3094  else if (!strcmp (cmd, "export_override"))
3095  return export_override_omp (credentials, params, content_type,
3096  content_disposition, response_size,
3097  response_data);
3098 
3099  else if (!strcmp (cmd, "export_overrides"))
3100  return export_overrides_omp (credentials, params, content_type,
3101  content_disposition, response_size,
3102  response_data);
3103 
3104  else if (!strcmp (cmd, "export_permission"))
3105  return export_permission_omp (credentials, params, content_type,
3106  content_disposition, response_size,
3107  response_data);
3108 
3109  else if (!strcmp (cmd, "export_permissions"))
3110  return export_permissions_omp (credentials, params, content_type,
3111  content_disposition, response_size,
3112  response_data);
3113 
3114  else if (!strcmp (cmd, "export_port_list"))
3115  return export_port_list_omp (credentials, params, content_type,
3116  content_disposition, response_size,
3117  response_data);
3118 
3119  else if (!strcmp (cmd, "export_port_lists"))
3120  return export_port_lists_omp (credentials, params, content_type,
3121  content_disposition, response_size,
3122  response_data);
3123 
3124  else if (!strcmp (cmd, "export_preference_file"))
3125  return export_preference_file_omp (credentials, params, content_type,
3126  content_disposition, response_size,
3127  response_data);
3128 
3129  else if (!strcmp (cmd, "export_report_format"))
3130  return export_report_format_omp (credentials, params, content_type,
3131  content_disposition, response_size,
3132  response_data);
3133 
3134  else if (!strcmp (cmd, "export_report_formats"))
3135  return export_report_formats_omp (credentials, params, content_type,
3136  content_disposition, response_size,
3137  response_data);
3138 
3139  else if (!strcmp (cmd, "export_result"))
3140  return export_result_omp (credentials, params, content_type,
3141  content_disposition, response_size,
3142  response_data);
3143 
3144  else if (!strcmp (cmd, "export_results"))
3145  return export_results_omp (credentials, params, content_type,
3146  content_disposition, response_size,
3147  response_data);
3148 
3149  else if (!strcmp (cmd, "export_role"))
3150  return export_role_omp (credentials, params, content_type,
3151  content_disposition, response_size,
3152  response_data);
3153 
3154  else if (!strcmp (cmd, "export_roles"))
3155  return export_roles_omp (credentials, params, content_type,
3156  content_disposition, response_size,
3157  response_data);
3158 
3159  else if (!strcmp (cmd, "export_scanner"))
3160  return export_scanner_omp (credentials, params, content_type,
3161  content_disposition, response_size,
3162  response_data);
3163 
3164  else if (!strcmp (cmd, "export_scanners"))
3165  return export_scanners_omp (credentials, params, content_type,
3166  content_disposition, response_size,
3167  response_data);
3168 
3169  else if (!strcmp (cmd, "export_schedule"))
3170  return export_schedule_omp (credentials, params, content_type,
3171  content_disposition, response_size,
3172  response_data);
3173 
3174  else if (!strcmp (cmd, "export_schedules"))
3175  return export_schedules_omp (credentials, params, content_type,
3176  content_disposition, response_size,
3177  response_data);
3178 
3179  else if (!strcmp (cmd, "export_tag"))
3180  return export_tag_omp (credentials, params, content_type,
3181  content_disposition, response_size,
3182  response_data);
3183 
3184  else if (!strcmp (cmd, "export_tags"))
3185  return export_tags_omp (credentials, params, content_type,
3186  content_disposition, response_size,
3187  response_data);
3188 
3189  else if (!strcmp (cmd, "export_target"))
3190  return export_target_omp (credentials, params, content_type,
3191  content_disposition, response_size,
3192  response_data);
3193 
3194  else if (!strcmp (cmd, "export_targets"))
3195  return export_targets_omp (credentials, params, content_type,
3196  content_disposition, response_size,
3197  response_data);
3198 
3199  else if (!strcmp (cmd, "export_task"))
3200  return export_task_omp (credentials, params, content_type,
3201  content_disposition, response_size,
3202  response_data);
3203 
3204  else if (!strcmp (cmd, "export_tasks"))
3205  return export_tasks_omp (credentials, params, content_type,
3206  content_disposition, response_size,
3207  response_data);
3208 
3209  else if (!strcmp (cmd, "export_user"))
3210  return export_user_omp (credentials, params, content_type,
3211  content_disposition, response_size,
3212  response_data);
3213 
3214  else if (!strcmp (cmd, "export_users"))
3215  return export_users_omp (credentials, params, content_type,
3216  content_disposition, response_size,
3217  response_data);
3218 
3219  ELSE (get_agent)
3220  ELSE (get_agents)
3221  ELSE (get_asset)
3222  ELSE (get_assets)
3223 
3224  else if (!strcmp (cmd, "download_agent"))
3225  {
3226  char *html, *filename;
3227 
3228  if (download_agent_omp (credentials,
3229  params,
3230  response_size,
3231  &html,
3232  &filename,
3233  response_data))
3234  return html;
3235 
3236  *content_type = GSAD_CONTENT_TYPE_OCTET_STREAM;
3237  g_free (*content_disposition);
3238  *content_disposition = g_strdup_printf ("attachment; filename=%s",
3239  filename);
3240  g_free (filename);
3241 
3242  return html;
3243  }
3244 
3245  else if (!strcmp (cmd, "download_ssl_cert"))
3246  {
3247  *content_type = GSAD_CONTENT_TYPE_APP_KEY;
3248  g_free (*content_disposition);
3249  *content_disposition = g_strdup_printf
3250  ("attachment; filename=ssl-cert-%s.pem",
3251  params_value (params, "name"));
3252 
3253  return download_ssl_cert (credentials, params, response_size,
3254  response_data);
3255  }
3256 
3257  else if (!strcmp (cmd, "download_ca_pub"))
3258  {
3259  *content_type = GSAD_CONTENT_TYPE_APP_KEY;
3260  g_free (*content_disposition);
3261  *content_disposition = g_strdup_printf
3262  ("attachment; filename=scanner-ca-pub-%s.pem",
3263  params_value (params, "scanner_id"));
3264  return download_ca_pub (credentials, params, response_size,
3265  response_data);
3266  }
3267 
3268  else if (!strcmp (cmd, "download_key_pub"))
3269  {
3270  *content_type = GSAD_CONTENT_TYPE_APP_KEY;
3271  g_free (*content_disposition);
3272  *content_disposition = g_strdup_printf
3273  ("attachment; filename=scanner-key-pub-%s.pem",
3274  params_value (params, "scanner_id"));
3275  return download_key_pub (credentials, params, response_size,
3276  response_data);
3277  }
3278 
3279  ELSE (get_aggregate)
3280  ELSE (get_alert)
3281  ELSE (get_alerts)
3282  ELSE (get_credential)
3283  ELSE (get_credentials)
3284  ELSE (get_filter)
3285  ELSE (get_filters)
3286  ELSE (get_group)
3287  ELSE (get_groups)
3288  ELSE (get_info)
3289  ELSE (get_my_settings)
3290  ELSE (get_note)
3291  ELSE (get_notes)
3292  ELSE (get_override)
3293  ELSE (get_overrides)
3294  ELSE (get_permission)
3295  ELSE (get_permissions)
3296  ELSE (get_port_list)
3297  ELSE (get_port_lists)
3298 
3299  else if (!strcmp (cmd, "get_report"))
3300  {
3301  char *ret;
3302  gchar *content_type_omp;
3303  ret = get_report_omp (credentials,
3304  params,
3305  response_size,
3306  &content_type_omp,
3307  content_disposition,
3308  response_data);
3309 
3310  if (content_type_omp)
3311  {
3312  *content_type = GSAD_CONTENT_TYPE_DONE;
3313  *content_type_string = content_type_omp;
3314  }
3315 
3316  return ret;
3317  }
3318 
3319  ELSE (get_reports)
3320  ELSE (get_result)
3321  ELSE (get_results)
3322  ELSE (get_report_format)
3323  ELSE (get_report_formats)
3324  ELSE (get_report_section)
3325  ELSE (get_role)
3326  ELSE (get_roles)
3327  ELSE (get_scanner)
3328  ELSE (get_scanners)
3329  ELSE (get_schedule)
3330  ELSE (get_schedules)
3331  ELSE (get_system_reports)
3332  ELSE (get_tag)
3333  ELSE (get_tags)
3334  ELSE (get_target)
3335  ELSE (get_targets)
3336  ELSE (get_trash)
3337  ELSE (get_user)
3338  ELSE (get_users)
3339  ELSE (get_feeds)
3340  ELSE (get_config)
3341  ELSE (get_configs)
3342  ELSE (get_config_family)
3343  ELSE (get_config_nvt)
3344  ELSE (get_nvts)
3345  ELSE (get_protocol_doc)
3346  ELSE (new_agent)
3347  ELSE (new_host)
3348  ELSE (new_config)
3349  ELSE (new_credential)
3350  ELSE (new_note)
3351  ELSE (new_override)
3354  ELSE (new_port_list)
3355  ELSE (new_port_range)
3356  ELSE (new_report_format)
3357  ELSE (new_scanner)
3358  ELSE (new_schedule)
3359  ELSE (upload_config)
3360  ELSE (upload_port_list)
3361  ELSE (upload_report)
3362  ELSE (sync_config)
3363  ELSE (wizard)
3364  ELSE (wizard_get)
3365 
3366  else
3367  {
3368  response_data->http_status_code = MHD_HTTP_BAD_REQUEST;
3369  return gsad_message (credentials,
3370  "Internal error", __FUNCTION__, __LINE__,
3371  "An internal error occurred inside GSA daemon. "
3372  "Diagnostics: Unknown command.",
3373  "/omp?cmd=get_tasks", response_data);
3374  }
3375 }
3376 
3380 #define EXPIRES_LENGTH 100
3381 
3390 static int
3391 attach_sid (struct MHD_Response *response, const char *sid)
3392 {
3393  int ret;
3394  gchar *value;
3395  gchar *locale;
3396  char expires[EXPIRES_LENGTH + 1];
3397  struct tm expire_time_broken;
3398  time_t now, expire_time;
3399  gchar *tz;
3400 
3401  /* Set up the expires param. */
3402 
3403  /* Store current TZ, switch to GMT. */
3404  tz = getenv ("TZ") ? g_strdup (getenv ("TZ")) : NULL;
3405  if (setenv ("TZ", "GMT", 1) == -1)
3406  {
3407  g_critical ("%s: failed to set TZ\n", __FUNCTION__);
3408  g_free (tz);
3409  exit (EXIT_FAILURE);
3410  }
3411  tzset ();
3412 
3413  locale = g_strdup (setlocale (LC_ALL, NULL));
3414  setlocale (LC_ALL, "C");
3415 
3416  now = time (NULL);
3417  expire_time = now + (session_timeout * 60) + 30;
3418  if (localtime_r (&expire_time, &expire_time_broken) == NULL)
3419  abort ();
3420  ret = strftime (expires, EXPIRES_LENGTH, "%a, %d-%b-%Y %T GMT",
3421  &expire_time_broken);
3422  if (ret == 0)
3423  abort ();
3424 
3425  setlocale (LC_ALL, locale);
3426  g_free (locale);
3427 
3428  /* Revert to stored TZ. */
3429  if (tz)
3430  {
3431  if (setenv ("TZ", tz, 1) == -1)
3432  {
3433  g_warning ("%s: Failed to switch to original TZ", __FUNCTION__);
3434  g_free (tz);
3435  exit (EXIT_FAILURE);
3436  }
3437  }
3438  else
3439  unsetenv ("TZ");
3440  g_free (tz);
3441 
3442  /* Add the cookie.
3443  *
3444  * Tim Brown's suggested cookie included a domain attribute. How would
3445  * we get the domain in here? Maybe a --domain option. */
3446 
3447  value = g_strdup_printf (SID_COOKIE_NAME
3448  "=%s; expires=%s; path=/; %sHTTPonly",
3449  sid,
3450  expires,
3451  (use_secure_cookie ? "secure; " : ""));
3452  ret = MHD_add_response_header (response, "Set-Cookie", value);
3453  g_free (value);
3454  return ret;
3455 }
3456 
3464 static int
3465 remove_sid (struct MHD_Response *response)
3466 {
3467  int ret;
3468  gchar *value;
3469  gchar *locale;
3470  char expires[EXPIRES_LENGTH + 1];
3471  struct tm expire_time_broken;
3472  time_t expire_time;
3473 
3474  /* Set up the expires param. */
3475  locale = g_strdup (setlocale (LC_ALL, NULL));
3476  setlocale (LC_ALL, "C");
3477 
3478  expire_time = time (NULL);
3479  if (localtime_r (&expire_time, &expire_time_broken) == NULL)
3480  abort ();
3481  ret = strftime (expires, EXPIRES_LENGTH, "%a, %d-%b-%Y %T GMT",
3482  &expire_time_broken);
3483  if (ret == 0)
3484  abort ();
3485 
3486  setlocale (LC_ALL, locale);
3487  g_free (locale);
3488 
3489  /* Add the cookie.
3490  *
3491  * Tim Brown's suggested cookie included a domain attribute. How would
3492  * we get the domain in here? Maybe a --domain option. */
3493 
3494  value = g_strdup_printf (SID_COOKIE_NAME "=0; expires=%s; path=/; %sHTTPonly",
3495  expires,
3496  (use_secure_cookie ? "secure; " : ""));
3497  ret = MHD_add_response_header (response, "Set-Cookie", value);
3498  g_free (value);
3499  return ret;
3500 }
3501 
3511 static void
3512 gsad_add_content_type_header (struct MHD_Response *response,
3513  enum content_type* ct)
3514 {
3515  if (!response)
3516  return;
3517 
3518  switch (*ct)
3519  {
3521  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3522  "application/deb");
3523  break;
3525  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3526  "application/exe");
3527  break;
3529  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3530  "application/html");
3531  break;
3533  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3534  "application/key");
3535  break;
3537  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3538  "application/nbe");
3539  break;
3541  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3542  "application/pdf");
3543  break;
3545  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3546  "application/rpm");
3547  break;
3549  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3550  "application/xml; charset=utf-8");
3551  break;
3553  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3554  "image/png");
3555  break;
3557  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3558  "image/svg+xml");
3559  break;
3561  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3562  "application/octet-stream");
3563  break;
3565  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3566  "text/css");
3567  break;
3569  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3570  "text/html; charset=utf-8");
3571  break;
3573  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3574  "text/javascript");
3575  break;
3577  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3578  "text/plain; charset=utf-8");
3579  break;
3581  break;
3582  default:
3583  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
3584  "text/plain; charset=utf-8");
3585  break;
3586  }
3587 }
3588 
3602 int
3603 send_response (struct MHD_Connection *connection, const char *content,
3604  int status_code, const gchar *sid,
3605  enum content_type content_type,
3606  const char *content_disposition,
3607  size_t content_length)
3608 {
3609  struct MHD_Response *response;
3610  size_t size = (content_length ? content_length : strlen (content));
3611  int ret;
3612 
3613  response = MHD_create_response_from_buffer (size, (void *) content,
3614  MHD_RESPMEM_MUST_COPY);
3615  gsad_add_content_type_header (response, &content_type);
3616 
3617  if (content_disposition)
3618  MHD_add_response_header (response, "Content-Disposition",
3619  content_disposition);
3620 
3621  if (sid)
3622  {
3623  if (strcmp (sid, "0"))
3624  {
3625  if (attach_sid (response, sid) == MHD_NO)
3626  {
3627  MHD_destroy_response (response);
3628  return MHD_NO;
3629  }
3630  }
3631  else
3632  {
3633  if (remove_sid (response) == MHD_NO)
3634  {
3635  MHD_destroy_response (response);
3636  return MHD_NO;
3637  }
3638  }
3639  }
3640  add_security_headers (response);
3641  ret = MHD_queue_response (connection, status_code, response);
3642  MHD_destroy_response (response);
3643  return ret;
3644 }
3645 
3655 int
3656 send_redirect_to_uri (struct MHD_Connection *connection, const char *uri,
3657  user_t *user)
3658 {
3659  int ret;
3660  struct MHD_Response *response;
3661  char *body;
3662 
3663  /* Some libmicrohttp versions get into an endless loop in https mode
3664  if an empty body is passed. As a workaround and because it is
3665  anyway suggested by the HTTP specs, we provide a short body. We
3666  assume that uri does not need to be quoted. */
3667  body = g_strdup_printf ("<html><body>Code 303 - Redirecting to"
3668  " <a href=\"%s\">%s<a/></body></html>\n",
3669  uri, uri);
3670  response = MHD_create_response_from_buffer (strlen (body), body,
3671  MHD_RESPMEM_MUST_FREE);
3672 
3673  if (!response)
3674  {
3675  g_warning ("%s: failed to create response, dropping request",
3676  __FUNCTION__);
3677  return MHD_NO;
3678  }
3679  ret = MHD_add_response_header (response, MHD_HTTP_HEADER_LOCATION, uri);
3680  if (!ret)
3681  {
3682  MHD_destroy_response (response);
3683  g_warning ("%s: failed to add location header, dropping request",
3684  __FUNCTION__);
3685  return MHD_NO;
3686  }
3687 
3688  if (user)
3689  {
3690  if (attach_sid (response, user->cookie) == MHD_NO)
3691  {
3692  MHD_destroy_response (response);
3693  g_warning ("%s: failed to attach SID, dropping request",
3694  __FUNCTION__);
3695  return MHD_NO;
3696  }
3697  }
3698 
3699  MHD_add_response_header (response, MHD_HTTP_HEADER_EXPIRES, "-1");
3700  MHD_add_response_header (response, MHD_HTTP_HEADER_CACHE_CONTROL, "no-cache");
3701 
3702  add_security_headers (response);
3703  ret = MHD_queue_response (connection, MHD_HTTP_SEE_OTHER, response);
3704  MHD_destroy_response (response);
3705  return ret;
3706 }
3707 
3708 #undef MAX_HOST_LEN
3709 
3713 #define MAX_HOST_LEN 1000
3714 
3724 int
3725 send_redirect_to_urn (struct MHD_Connection *connection, const char *urn,
3726  user_t *user)
3727 {
3728  const char *host, *protocol;
3729  char uri[MAX_HOST_LEN];
3730 
3731  host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
3732  MHD_HTTP_HEADER_HOST);
3733  if (host && g_utf8_validate (host, -1, NULL) == FALSE)
3734  {
3735  send_response (connection,
3736  UTF8_ERROR_PAGE ("'Host' header"),
3737  MHD_HTTP_BAD_REQUEST, NULL,
3738  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
3739  return MHD_YES;
3740  }
3741  if (host == NULL)
3742  {
3744  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
3745  return MHD_YES;
3746  }
3747 
3748  protocol = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
3749  "X-Forwarded-Protocol");
3750  if (protocol && g_utf8_validate (protocol, -1, NULL) == FALSE)
3751  {
3752  send_response (connection,
3753  UTF8_ERROR_PAGE ("'X-Forwarded-Protocol' header"),
3754  MHD_HTTP_BAD_REQUEST, NULL,
3755  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
3756  return MHD_YES;
3757  }
3758  else if ((protocol == NULL)
3759  || (strcmp(protocol, "http") && strcmp(protocol, "https")))
3760  {
3761  if (use_secure_cookie)
3762  protocol = "https";
3763  else
3764  protocol = "http";
3765  }
3766 
3767  snprintf (uri, sizeof (uri), "%s://%s%s", protocol, host, urn);
3768  return send_redirect_to_uri (connection, uri, user);
3769 }
3770 
3789 int
3790 redirect_handler (void *cls, struct MHD_Connection *connection,
3791  const char *url, const char *method,
3792  const char *version, const char *upload_data,
3793  size_t *upload_data_size, void **con_cls)
3794 {
3795  gchar *location;
3796  const char *host;
3797  char name[MAX_HOST_LEN + 1];
3798 
3799  /* Never respond on first call of a GET. */
3800  if ((!strcmp (method, "GET")) && *con_cls == NULL)
3801  {
3802  struct gsad_connection_info *con_info;
3803 
3804  /* Freed by MHD_OPTION_NOTIFY_COMPLETED callback, free_resources. */
3805  con_info = g_malloc0 (sizeof (struct gsad_connection_info));
3806  con_info->params = params_new ();
3807  con_info->connectiontype = 2;
3808 
3809  *con_cls = (void *) con_info;
3810  return MHD_YES;
3811  }
3812 
3813  /* If called with undefined URL, abort request handler. */
3814  if (&url[0] == NULL)
3815  return MHD_NO;
3816 
3817  /* Only accept GET and POST methods and send ERROR_PAGE in other cases. */
3818  if (strcmp (method, "GET") && strcmp (method, "POST"))
3819  {
3821  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
3822  return MHD_YES;
3823  }
3824 
3825  /* Redirect every URL to the default file on the HTTPS port. */
3826  host = MHD_lookup_connection_value (connection,
3827  MHD_HEADER_KIND,
3828  "Host");
3829  if (host && g_utf8_validate (host, -1, NULL) == FALSE)
3830  {
3831  send_response (connection,
3832  UTF8_ERROR_PAGE ("'Host' header"),
3833  MHD_HTTP_BAD_REQUEST, NULL,
3834  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
3835  return MHD_YES;
3836  }
3837  else if (host == NULL)
3838  return MHD_NO;
3839  /* [IPv6 or IPv4-mapped IPv6]:port */
3840  if (sscanf (host, "[%" G_STRINGIFY(MAX_HOST_LEN) "[0-9a-f:.]]:%*i", name)
3841  == 1)
3842  {
3843  char *name6 = g_strdup_printf ("[%s]", name);
3844  location = g_strdup_printf (redirect_location, name6);
3845  g_free (name6);
3846  }
3847  /* IPv4:port */
3848  else if (sscanf (host, "%" G_STRINGIFY(MAX_HOST_LEN) "[^:]:%*i", name) == 1)
3849  location = g_strdup_printf (redirect_location, name);
3850  else
3851  location = g_strdup_printf (redirect_location, host);
3852  if (send_redirect_to_uri (connection, location, NULL) == MHD_NO)
3853  {
3854  g_free (location);
3855  return MHD_NO;
3856  }
3857  g_free (location);
3858  return MHD_YES;
3859 }
3860 
3864 #define DATE_2822_LEN 100
3865 
3866 #ifdef SERVE_STATIC_ASSETS
3867 
3883 static struct MHD_Response*
3884 file_content_response (credentials_t *credentials,
3885  struct MHD_Connection *connection, const char* url,
3886  int* http_response_code, enum content_type* content_type,
3887  char** content_disposition)
3888 {
3889  FILE* file;
3890  gchar* path;
3891  char *default_file = "login/login.html";
3892  struct MHD_Response* response;
3893  char date_2822[DATE_2822_LEN];
3894  struct tm *mtime;
3895  time_t next_week;
3896  cmd_response_data_t response_data;
3897 
3898  cmd_response_data_init (&response_data);
3899 
3903  /* Attempt to prevent disclosing non-gsa content. */
3904  if (strstr (url, ".."))
3905  path = g_strconcat (default_file, NULL);
3906  else
3907  {
3908  /* Ensure that url is relative. */
3909  const char* relative_url = url;
3910  if (*url == '/') relative_url = url + 1;
3911  path = g_strconcat (relative_url, NULL);
3912  }
3913 
3914  file = fopen (path, "r"); /* this file is just read and sent */
3915 
3916  if (file == NULL)
3917  {
3918  g_debug ("File %s failed, ", path);
3919  g_free (path);
3920  struct MHD_Response *response;
3921 
3922  *http_response_code = MHD_HTTP_NOT_FOUND;
3923  cmd_response_data_reset (&response_data);
3924  gchar *msg = gsad_message (NULL,
3925  NOT_FOUND_TITLE, NULL, 0,
3927  "/login/login.html", NULL);
3928  response = MHD_create_response_from_buffer (strlen (msg),
3929  (void *) msg,
3930  MHD_RESPMEM_MUST_COPY);
3931  g_free (msg);
3932  return response;
3933  }
3934 
3935  /* Guess content type. */
3936  if (strstr (path, ".png"))
3937  *content_type = GSAD_CONTENT_TYPE_IMAGE_PNG;
3938  else if (strstr (path, ".svg"))
3939  *content_type = GSAD_CONTENT_TYPE_IMAGE_SVG;
3940  else if (strstr (path, ".html"))
3941  *content_type = GSAD_CONTENT_TYPE_TEXT_HTML;
3942  else if (strstr (path, ".css"))
3943  *content_type = GSAD_CONTENT_TYPE_TEXT_CSS;
3944  else if (strstr (path, ".js"))
3945  *content_type = GSAD_CONTENT_TYPE_TEXT_JS;
3948  struct stat buf;
3949  g_debug ("Default file successful.\n");
3950  if (stat (path, &buf))
3951  {
3952  /* File information could not be retrieved. */
3953  g_critical ("%s: file <%s> can not be stat'ed.\n",
3954  __FUNCTION__,
3955  path);
3956  g_free (path);
3957  fclose (file);
3958  return NULL;
3959  }
3960 
3961  /* Make sure the requested path really is a file. */
3962  if ((buf.st_mode & S_IFMT) != S_IFREG)
3963  {
3964  struct MHD_Response *ret;
3965  response_data.http_status_code = MHD_HTTP_NOT_FOUND;
3966  char *res = gsad_message (NULL,
3967  NOT_FOUND_TITLE, NULL, 0,
3969  NULL, &response_data);
3970  *http_response_code = response_data.http_status_code;
3971  g_free (path);
3972  fclose (file);
3973  cmd_response_data_reset (&response_data);
3974  ret = MHD_create_response_from_buffer (strlen (res), (void *) res,
3975  MHD_RESPMEM_MUST_FREE);
3976  return ret;
3977  }
3978 
3979  response = MHD_create_response_from_callback (buf.st_size, 32 * 1024,
3980  (MHD_ContentReaderCallback) &file_reader,
3981  file,
3982  (MHD_ContentReaderFreeCallback)
3983  &fclose);
3984 
3985  mtime = localtime (&buf.st_mtime);
3986  if (mtime
3987  && strftime (date_2822, DATE_2822_LEN, "%a, %d %b %Y %H:%M:%S %Z", mtime))
3988  {
3989  MHD_add_response_header (response, "Last-Modified", date_2822);
3990  }
3991 
3992  next_week = time (NULL) + 7 * 24 * 60 * 60;
3993  mtime = localtime (&next_week);
3994  if (mtime
3995  && strftime (date_2822, DATE_2822_LEN, "%a, %d %b %Y %H:%M:%S %Z", mtime))
3996  {
3997  MHD_add_response_header (response, "Expires", date_2822);
3998  }
3999 
4000  g_free (path);
4001  *http_response_code = response_data.http_status_code;
4002  cmd_response_data_reset (&response_data);
4003  return response;
4004 }
4005 #endif
4006 
4019 static int
4020 handler_send_response (struct MHD_Connection *connection,
4021  struct MHD_Response *response,
4022  enum content_type *content_type,
4023  char *content_disposition,
4024  int http_response_code,
4025  int remove_cookie)
4026 {
4027  int ret;
4028 
4029  if (remove_cookie)
4030  if (remove_sid (response) == MHD_NO)
4031  {
4032  MHD_destroy_response (response);
4033  g_warning ("%s: failed to remove SID, dropping request",
4034  __FUNCTION__);
4035  return MHD_NO;
4036  }
4037  gsad_add_content_type_header (response, content_type);
4038  if (content_disposition != NULL)
4039  {
4040  MHD_add_response_header (response, "Content-Disposition",
4041  content_disposition);
4042  g_free (content_disposition);
4043  }
4044  ret = MHD_queue_response (connection, http_response_code, response);
4045  if (ret == MHD_NO)
4046  {
4047  /* Assume this was due to a bad request, to keep the MHD "Internal
4048  * application error" out of the log. */
4050  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4051  return MHD_YES;
4052  }
4053  MHD_destroy_response (response);
4054  return ret;
4055 }
4056 
4067 static int
4068 append_param (void *string, enum MHD_ValueKind kind, const char *key,
4069  const char *value)
4070 {
4071  if (value == NULL)
4072  /* http://foo/bar?key */
4073  return MHD_YES;
4074  if (key == NULL)
4075  {
4076  assert (0);
4077  return MHD_YES;
4078  }
4079  /* http://foo/bar?key=value */
4080  if (strcmp (key, "token") && strcmp (key, "r"))
4081  {
4082  g_string_append ((GString*) string, key);
4083  g_string_append ((GString*) string, "=");
4084  g_string_append ((GString*) string, value);
4085  g_string_append ((GString*) string, "&");
4086  }
4087  return MHD_YES;
4088 }
4089 
4098 static gchar *
4099 reconstruct_url (struct MHD_Connection *connection, const char *url)
4100 {
4101  GString *full_url;
4102 
4103  full_url = g_string_new (url);
4104  /* To simplify appending the token later, ensure there is at least
4105  * one param. */
4106  g_string_append (full_url, "?r=1&");
4107 
4108  MHD_get_connection_values (connection, MHD_GET_ARGUMENT_KIND,
4109  append_param, full_url);
4110 
4111  if (full_url->str[strlen (full_url->str) - 1] == '&')
4112  full_url->str[strlen (full_url->str) - 1] = '\0';
4113 
4114  return g_string_free (full_url, FALSE);
4115 }
4116 
4126 static int
4127 get_client_address (struct MHD_Connection *conn, char *client_address)
4128 {
4129  const char* x_real_ip;
4130 
4131  /* First try X-Real-IP header (unless told to ignore), then MHD connection. */
4132 
4133  x_real_ip = MHD_lookup_connection_value (conn,
4134  MHD_HEADER_KIND,
4135  "X-Real-IP");
4136 
4138  && x_real_ip && g_utf8_validate (x_real_ip, -1, NULL) == FALSE)
4139  return 1;
4140  else if (!ignore_http_x_real_ip && x_real_ip != NULL)
4141  strncpy (client_address, x_real_ip, INET6_ADDRSTRLEN);
4142  else if (unix_socket)
4143  strncpy (client_address, "unix_socket", INET6_ADDRSTRLEN);
4144  else
4145  {
4146  const union MHD_ConnectionInfo* info;
4147 
4148  info = MHD_get_connection_info (conn, MHD_CONNECTION_INFO_CLIENT_ADDRESS);
4149  sockaddr_as_str ((struct sockaddr_storage *) info->client_addr,
4150  client_address);
4151  }
4152  return 0;
4153 }
4154 
4173 int
4174 handle_request (void *cls, struct MHD_Connection *connection,
4175  const char *url, const char *method,
4176  const char *version, const char *upload_data,
4177  size_t * upload_data_size, void **con_cls)
4178 {
4179  const char *url_base = "/";
4180  char *default_file = "/login/login.html", client_address[INET6_ADDRSTRLEN];
4181  enum content_type content_type;
4182  char *content_disposition = NULL;
4183  gsize response_size = 0;
4184  int http_response_code = MHD_HTTP_OK;
4185  const char *xml_flag = NULL;
4186  int ret;
4187 
4188  /* Never respond on first call of a GET. */
4189  if ((!strcmp (method, "GET")) && *con_cls == NULL)
4190  {
4191  struct gsad_connection_info *con_info;
4192 
4193  /* First call for this request, a GET. */
4194 
4195  /* Freed by MHD_OPTION_NOTIFY_COMPLETED callback, free_resources. */
4196  con_info = g_malloc0 (sizeof (struct gsad_connection_info));
4197  con_info->params = params_new ();
4198  con_info->connectiontype = 2;
4199 
4200  *con_cls = (void *) con_info;
4201  return MHD_YES;
4202  }
4203 
4204  /* If called with undefined URL, abort request handler. */
4205  if (&url[0] == NULL)
4206  {
4208  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4209  return MHD_YES;
4210  }
4211 
4212  /* Prevent guest link from leading to URL redirection. */
4213  if (url && (url[0] == '/') && (url[1] == '/'))
4214  {
4215  gchar *msg = gsad_message (NULL,
4216  NOT_FOUND_TITLE, NULL, 0,
4218  "/login/login.html", NULL);
4219  send_response (connection, msg, MHD_HTTP_NOT_FOUND,
4220  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4221  g_free (msg);
4222  return MHD_YES;
4223  }
4224 
4225  /* Many Glib functions require valid UTF-8. */
4226  if (url && (g_utf8_validate (url, -1, NULL) == FALSE))
4227  {
4228  send_response (connection,
4229  UTF8_ERROR_PAGE ("URL"),
4230  MHD_HTTP_BAD_REQUEST, NULL,
4231  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4232  return MHD_YES;
4233  }
4234 
4235  /* Only accept GET and POST methods and send ERROR_PAGE in other cases. */
4236  if (strcmp (method, "GET") && strcmp (method, "POST"))
4237  {
4238  send_response (connection, ERROR_PAGE, MHD_HTTP_METHOD_NOT_ALLOWED,
4239  NULL, GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4240  return MHD_YES;
4241  }
4242 
4243  /* Redirect the base URL to the login page. Serve the login page
4244  * even if the user is already logged in.
4245  *
4246  * This might make users think that they have been logged out. The only
4247  * way to logout, however, is with a token. I guess this is where a cookie
4248  * would be useful. */
4249 
4250  g_debug ("============= url: %s\n", reconstruct_url (connection, url));
4251 
4252  if (!strcmp (&url[0], url_base))
4253  {
4254  return send_redirect_to_urn (connection, default_file, NULL);
4255  }
4256 
4257  if ((!strcmp (method, "GET"))
4258  && (!strncmp (&url[0], "/login/", strlen ("/login/")))
4259  && !url[strlen ("/login/")])
4260  {
4261  return send_redirect_to_urn (connection, default_file, NULL);
4262  }
4263 
4264  /* Set HTTP Header values. */
4265 
4266  if (!strcmp (method, "GET"))
4267  {
4268  const char *token, *cookie, *accept_language, *xml_flag;
4269  const char *omp_cgi_base = "/omp";
4270  gchar *language;
4271  struct MHD_Response *response;
4272  credentials_t *credentials;
4273  user_t *user;
4274  gchar *sid;
4275  char *res;
4276 
4277  token = NULL;
4278  cookie = NULL;
4279 
4280  xml_flag = MHD_lookup_connection_value (connection,
4281  MHD_GET_ARGUMENT_KIND,
4282  "xml");
4283 
4284  /* Second or later call for this request, a GET. */
4285 
4286  content_type = GSAD_CONTENT_TYPE_TEXT_HTML;
4287 
4288  /* Special case the login page, stylesheet and icon. */
4289 
4290  if (!strcmp (url, default_file))
4291  {
4292  time_t now;
4293  gchar *xml;
4294  char *res;
4295  char ctime_now[200];
4296  const char* accept_language;
4297  gchar *language;
4298  cmd_response_data_t response_data;
4299  cmd_response_data_init (&response_data);
4300 
4301  now = time (NULL);
4302  ctime_r_strip_newline (&now, ctime_now);
4303 
4304  accept_language = MHD_lookup_connection_value (connection,
4305  MHD_HEADER_KIND,
4306  "Accept-Language");
4307  if (accept_language
4308  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
4309  {
4310  send_response (connection,
4311  UTF8_ERROR_PAGE ("'Accept-Language' header"),
4312  MHD_HTTP_BAD_REQUEST, NULL,
4313  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4314  return MHD_YES;
4315  }
4316  language = accept_language_to_env_fmt (accept_language);
4317  xml = login_xml (NULL,
4318  NULL,
4319  ctime_now,
4320  NULL,
4321  language,
4323  g_free (language);
4324  if (xml_flag && strcmp (xml_flag, "0"))
4325  res = xml;
4326  else
4327  {
4328  res = xsl_transform (xml, &response_data);
4329  g_free (xml);
4330  }
4331  response = MHD_create_response_from_buffer (strlen (res), res,
4332  MHD_RESPMEM_MUST_FREE);
4333  add_security_headers (response);
4334  cmd_response_data_reset (&response_data);
4335  return handler_send_response (connection,
4336  response,
4337  &content_type,
4338  content_disposition,
4339  http_response_code,
4340  1);
4341  }
4342 
4343 #ifdef SERVE_STATIC_ASSETS
4344 
4345  if (!strcmp (url, "/favicon.ico")
4346  || !strcmp (url, "/favicon.gif"))
4347  {
4348  response = file_content_response (NULL,
4349  connection, url,
4350  &http_response_code,
4351  &content_type,
4352  &content_disposition);
4353  add_security_headers (response);
4354  return handler_send_response (connection,
4355  response,
4356  &content_type,
4357  content_disposition,
4358  http_response_code,
4359  0);
4360  }
4361 
4362  /* Allow the decorative images and scripts to anyone. */
4363 
4364  if (strncmp (url, "/img/", strlen ("/img/")) == 0
4365  || strncmp (url, "/js/", strlen ("/js/")) == 0
4366  || strncmp (url, "/css/", strlen ("/css/")) == 0)
4367  {
4368  response = file_content_response (NULL,
4369  connection, url,
4370  &http_response_code,
4371  &content_type,
4372  &content_disposition);
4373  add_security_headers (response);
4374  return handler_send_response (connection,
4375  response,
4376  &content_type,
4377  content_disposition,
4378  http_response_code,
4379  0);
4380  }
4381 #endif
4382 
4383  /* Setup credentials from token. */
4384 
4385  token = MHD_lookup_connection_value (connection,
4386  MHD_GET_ARGUMENT_KIND,
4387  "token");
4388  if (token == NULL)
4389  {
4390  g_debug ("%s: Missing token in arguments", __FUNCTION__);
4391  cookie = NULL;
4392  ret = USER_BAD_MISSING_TOKEN;
4393  }
4394  else
4395  {
4396  if (openvas_validate (validator, "token", token))
4397  token = NULL;
4398 
4399  cookie = MHD_lookup_connection_value (connection,
4400  MHD_COOKIE_KIND,
4401  SID_COOKIE_NAME);
4402  if (openvas_validate (validator, "token", cookie))
4403  cookie = NULL;
4404 
4405  get_client_address (connection, client_address);
4406  ret = get_client_address (connection, client_address);
4407  if (ret == 1)
4408  {
4409  send_response (connection,
4410  UTF8_ERROR_PAGE ("'X-Real-IP' header"),
4411  MHD_HTTP_BAD_REQUEST, NULL,
4412  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4413  return MHD_YES;
4414  }
4415 
4416  ret = user_find (cookie, token, client_address, &user);
4417  }
4418 
4419  if (ret == USER_BAD_TOKEN || ret == USER_GUEST_LOGIN_FAILED
4420  || ret == USER_OMP_DOWN || ret == USER_GUEST_LOGIN_ERROR)
4421  {
4422  cmd_response_data_t response_data;
4423  cmd_response_data_init (&response_data);
4424  if (ret == 1)
4425  {
4426  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
4427  res = gsad_message (NULL,
4428  "Internal error", __FUNCTION__, __LINE__,
4429  "An internal error occurred inside GSA daemon. "
4430  "Diagnostics: Bad token.",
4431  "/omp?cmd=get_tasks", &response_data);
4432  }
4433  else
4434  {
4435  time_t now;
4436  gchar *xml;
4437  char ctime_now[200];
4438 
4439  now = time (NULL);
4440  ctime_r_strip_newline (&now, ctime_now);
4441 
4442  accept_language = MHD_lookup_connection_value (connection,
4443  MHD_HEADER_KIND,
4444  "Accept-Language");
4445  if (accept_language
4446  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
4447  {
4448  send_response (connection,
4449  UTF8_ERROR_PAGE ("'Accept-Language' header"),
4450  MHD_HTTP_BAD_REQUEST, NULL,
4451  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4452  return MHD_YES;
4453  }
4454  language = accept_language_to_env_fmt (accept_language);
4455  xml = login_xml (ret == 6
4456  ? "Login failed. OMP service is down."
4457  : (ret == -1
4458  ? "Login failed. Error during authentication."
4459  : "Login failed."),
4460  NULL,
4461  ctime_now,
4462  NULL,
4463  language,
4465  response_data.http_status_code = MHD_HTTP_SERVICE_UNAVAILABLE;
4466  g_free (language);
4467  if (xml_flag && strcmp (xml_flag, "0"))
4468  res = xml;
4469  else
4470  {
4471  res = xsl_transform (xml, &response_data);
4472  g_free (xml);
4473  }
4474  }
4475  response = MHD_create_response_from_buffer (strlen (res), res,
4476  MHD_RESPMEM_MUST_FREE);
4477  http_response_code = response_data.http_status_code;
4478  add_security_headers (response);
4479  cmd_response_data_reset (&response_data);
4480  return handler_send_response (connection,
4481  response,
4482  &content_type,
4483  content_disposition,
4484  http_response_code,
4485  1);
4486  }
4487 
4488  if ((ret == USER_EXPIRED_TOKEN) || (ret == USER_BAD_MISSING_COOKIE)
4489  || (ret == USER_BAD_MISSING_TOKEN)
4490  || (ret == USER_IP_ADDRESS_MISSMATCH))
4491  {
4492  time_t now;
4493  gchar *xml;
4494  char *res;
4495  gchar *full_url;
4496  char ctime_now[200];
4497  const char *cmd;
4498  int export;
4499  cmd_response_data_t response_data;
4500  cmd_response_data_init (&response_data);
4501 
4502  now = time (NULL);
4503  ctime_r_strip_newline (&now, ctime_now);
4504 
4505  cmd = MHD_lookup_connection_value (connection,
4506  MHD_GET_ARGUMENT_KIND,
4507  "cmd");
4508 
4509  export = 0;
4510  if (cmd && g_utf8_validate (cmd, -1, NULL))
4511  {
4512  if (strncmp (cmd, "export", strlen ("export")) == 0)
4513  export = 1;
4514  else if (strcmp (cmd, "get_report") == 0)
4515  {
4516  const char *report_format_id;
4517 
4518  report_format_id = MHD_lookup_connection_value
4519  (connection,
4520  MHD_GET_ARGUMENT_KIND,
4521  "report_format_id");
4522  if (report_format_id
4523  && g_utf8_validate (report_format_id, -1, NULL))
4524  export = 1;
4525  }
4526  }
4527 
4528  accept_language = MHD_lookup_connection_value (connection,
4529  MHD_HEADER_KIND,
4530  "Accept-Language");
4531  if (accept_language
4532  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
4533  {
4534  send_response (connection,
4535  UTF8_ERROR_PAGE ("'Accept-Language' header"),
4536  MHD_HTTP_BAD_REQUEST, NULL,
4537  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4538  return MHD_YES;
4539  }
4540  language = accept_language_to_env_fmt (accept_language);
4541 
4542  if ((export == 0) && strncmp (url, "/logout", strlen ("/logout")))
4543  {
4544  full_url = reconstruct_url (connection, url);
4545  if (full_url && g_utf8_validate (full_url, -1, NULL) == FALSE)
4546  {
4547  g_free (full_url);
4548  full_url = NULL;
4549  }
4550  }
4551  else
4552  full_url = NULL;
4553 
4554  if (ret == USER_EXPIRED_TOKEN)
4555  {
4556  if (strncmp (url, "/logout", strlen ("/logout")))
4557  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
4558  else
4559  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
4560  }
4561  else
4562  response_data.http_status_code = MHD_HTTP_UNAUTHORIZED;
4563 
4564  xml = login_xml
4565  ((ret == USER_EXPIRED_TOKEN)
4566  ? (strncmp (url, "/logout", strlen ("/logout"))
4567  ? "Session has expired. Please login again."
4568  : "Already logged out.")
4569  : ((ret == USER_BAD_MISSING_COOKIE)
4570  ? "Cookie missing or bad. Please login again."
4571  : "Token missing or bad. Please login again."),
4572  NULL,
4573  ctime_now,
4574  full_url ? full_url : "",
4575  language,
4577 
4578  g_free (language);
4579  g_free (full_url);
4580  if (xml_flag && strcmp (xml_flag, "0"))
4581  res = xml;
4582  else
4583  {
4584  res = xsl_transform (xml, &response_data);
4585  g_free (xml);
4586  }
4587 
4588  http_response_code = response_data.http_status_code;
4589  response = MHD_create_response_from_buffer (strlen (res), res,
4590  MHD_RESPMEM_MUST_FREE);
4591  add_security_headers (response);
4592  cmd_response_data_reset (&response_data);
4593  return handler_send_response (connection,
4594  response,
4595  &content_type,
4596  content_disposition,
4597  http_response_code,
4598  1);
4599  }
4600 
4601  if (ret)
4602  abort ();
4603 
4604  /* From here on, the user is authenticated. */
4605 
4606  if (!strncmp (url, "/logout", strlen ("/logout")))
4607  {
4608  time_t now;
4609  gchar *xml;
4610  char ctime_now[200];
4611  cmd_response_data_t response_data;
4612  cmd_response_data_init (&response_data);
4613 
4614  now = time (NULL);
4615  ctime_r_strip_newline (&now, ctime_now);
4616 
4617  user_remove (user);
4618 
4619  accept_language = MHD_lookup_connection_value (connection,
4620  MHD_HEADER_KIND,
4621  "Accept-Language");
4622  if (accept_language
4623  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
4624  {
4625  send_response (connection,
4626  UTF8_ERROR_PAGE ("'Accept-Language' header"),
4627  MHD_HTTP_BAD_REQUEST, NULL,
4628  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4629  return MHD_YES;
4630  }
4631  language = accept_language_to_env_fmt (accept_language);
4632  xml = login_xml ("Successfully logged out.",
4633  NULL,
4634  ctime_now,
4635  NULL,
4636  language,
4638  g_free (language);
4639  http_response_code = response_data.http_status_code;
4640  if (xml_flag && strcmp (xml_flag, "0"))
4641  res = xml;
4642  else
4643  {
4644  res = xsl_transform (xml, &response_data);
4645  g_free (xml);
4646  }
4647  response = MHD_create_response_from_buffer (strlen (res), res,
4648  MHD_RESPMEM_MUST_FREE);
4649  cmd_response_data_reset (&response_data);
4650  add_security_headers (response);
4651  return handler_send_response (connection,
4652  response,
4653  &content_type,
4654  content_disposition,
4655  http_response_code,
4656  1);
4657  }
4658 
4659  language = g_strdup (user->language);
4660  if (!language)
4661  /* Accept-Language: de; q=1.0, en; q=0.5 */
4662  {
4663  accept_language = MHD_lookup_connection_value
4664  (connection, MHD_HEADER_KIND, "Accept-Language");
4665  if (accept_language
4666  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
4667  {
4668  send_response (connection,
4669  UTF8_ERROR_PAGE ("'Accept-Language' header"),
4670  MHD_HTTP_BAD_REQUEST, NULL,
4671  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
4672  return MHD_YES;
4673  }
4674  language = accept_language_to_env_fmt (accept_language);
4675  credentials = credentials_new (user, language, client_address);
4676  g_free (language);
4677  }
4678  else
4679  credentials = credentials_new (user, language, client_address);
4680 
4681  credentials->caller = reconstruct_url (connection, url);
4682  if (credentials->caller
4683  && g_utf8_validate (credentials->caller, -1, NULL) == FALSE)
4684  {
4685  g_free (credentials->caller);
4686  credentials->caller = NULL;
4687  }
4688 
4689  sid = g_strdup (user->cookie);
4690 
4691  user_release (user);
4692 
4693  /* Serve the request. */
4694 
4695  if (!strncmp (&url[0], omp_cgi_base, strlen (omp_cgi_base)))
4696  {
4697  /* URL requests to run OMP command. */
4698 
4699  unsigned int res_len = 0;
4700  gchar *content_type_string = NULL;
4701 
4702  cmd_response_data_t response_data;
4703  cmd_response_data_init (&response_data);
4704 
4705  res = exec_omp_get (connection, credentials, &content_type,
4706  &content_type_string, &content_disposition,
4707  &response_size, &response_data);
4708  if (response_size > 0)
4709  {
4710  res_len = response_size;
4711  response_size = 0;
4712  }
4713  else
4714  {
4715  res_len = strlen (res);
4716 
4717  xml_flag = credentials->params
4718  ? params_value (credentials->params, "xml")
4719  : NULL;
4720  if (xml_flag && strcmp (xml_flag, "0"))
4721  content_type = GSAD_CONTENT_TYPE_APP_XML;
4722  }
4723 
4724  response = MHD_create_response_from_buffer (res_len, (void *) res,
4725  MHD_RESPMEM_MUST_FREE);
4726  if (content_type_string)
4727  {
4728  MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE,
4729  content_type_string);
4730  g_free (content_type_string);
4731  }
4732  http_response_code = response_data.http_status_code;
4733  cmd_response_data_reset (&response_data);
4734  }
4735  /* URL does not request OMP command but perhaps a special GSAD command? */
4736  else if (!strncmp (&url[0], "/system_report/",
4737  strlen ("/system_report/")))
4738  {
4739  params_t *params;
4740  gsize res_len;
4741  const char *slave_id;
4742 
4743  params = params_new ();
4744 
4745  MHD_get_connection_values (connection, MHD_GET_ARGUMENT_KIND,
4746  params_mhd_add, params);
4747 
4748  params_mhd_validate (params);
4749 
4750  slave_id = MHD_lookup_connection_value (connection,
4751  MHD_GET_ARGUMENT_KIND,
4752  "slave_id");
4753  if (slave_id && openvas_validate (validator, "slave_id", slave_id))
4754  {
4755  g_free (sid);
4756  credentials_free (credentials);
4757  g_warning ("%s: failed to validate slave_id, dropping request",
4758  __FUNCTION__);
4759  return MHD_NO;
4760  }
4761 
4762  cmd_response_data_t response_data;
4763  cmd_response_data_init (&response_data);
4764 
4765  res = get_system_report_omp (credentials,
4766  &url[0] + strlen ("/system_report/"),
4767  params,
4768  &content_type,
4769  &res_len,
4770  &response_data);
4771  if (res == NULL)
4772  {
4773  g_free (sid);
4774  credentials_free (credentials);
4775  g_warning ("%s: failed to get system reports, dropping request",
4776  __FUNCTION__);
4777  return MHD_NO;
4778  }
4779  response = MHD_create_response_from_buffer ((unsigned int) res_len,
4780  res, MHD_RESPMEM_MUST_FREE);
4781 
4782  http_response_code = response_data.http_status_code;
4783  cmd_response_data_reset (&response_data);
4784  }
4785  else if (!strncmp (&url[0], "/help/",
4786  strlen ("/help/")))
4787  {
4788  cmd_response_data_t response_data;
4789  cmd_response_data_init (&response_data);
4790 
4791  if (!g_ascii_isalpha (url[6]))
4792  {
4793  response_data.http_status_code = MHD_HTTP_BAD_REQUEST;
4794  res = gsad_message (credentials,
4795  "Invalid request", __FUNCTION__, __LINE__,
4796  "The requested help page does not exist.",
4797  "/help/contents.html", &response_data);
4798  }
4799  else
4800  {
4801  gchar **preferred_languages;
4802  gchar *xsl_filename = NULL;
4803  gchar *page = g_strndup ((gchar *) &url[6], MAX_FILE_NAME_SIZE);
4804  GHashTable *template_attributes;
4805  int template_found = 0;
4806 
4807  // Disallow names that would be invalid for XML elements
4808  if (g_regex_match_simple ("^(?!xml)[[:alpha:]_][[:alnum:]-_.]*$",
4809  page, G_REGEX_CASELESS, 0) == 0)
4810  {
4811  g_free (page);
4812  page = g_strdup ("_invalid_");
4813  }
4814  // XXX: url subsearch could be nicer and xsl transform could
4815  // be generalized with the other transforms.
4816  time_t now;
4817  char ctime_now[200];
4818  gchar *xml, *pre;
4819  int index;
4820 
4821  assert (credentials->token);
4822 
4823  now = time (NULL);
4824  ctime_r_strip_newline (&now, ctime_now);
4825 
4826  pre = g_markup_printf_escaped
4827  ("<envelope>"
4828  "<version>%s</version>"
4829  "<vendor_version>%s</vendor_version>"
4830  "<token>%s</token>"
4831  "<time>%s</time>"
4832  "<login>%s</login>"
4833  "<role>%s</role>"
4834  "<i18n>%s</i18n>"
4835  "<charts>%i</charts>"
4836  "<guest>%d</guest>"
4837  "<client_address>%s</client_address>"
4838  "<help><%s/></help>",
4839  GSAD_VERSION,
4840  vendor_version_get (),
4841  credentials->token,
4842  ctime_now,
4843  credentials->username,
4844  credentials->role,
4845  credentials->language,
4846  credentials->charts,
4847  credentials->guest,
4848  credentials->client_address,
4849  page);
4850  xml = g_strdup_printf ("%s"
4851  "<capabilities>%s</capabilities>"
4852  "</envelope>",
4853  pre,
4854  credentials->capabilities);
4855  g_free (pre);
4856 
4857  preferred_languages = g_strsplit (credentials->language, ":", 0);
4858 
4859  index = 0;
4860  while (preferred_languages [index] && xsl_filename == NULL)
4861  {
4862  gchar *help_language;
4863  help_language = g_strdup (preferred_languages [index]);
4864  xsl_filename = g_strdup_printf ("help_%s.xsl",
4865  help_language);
4866  if (access (xsl_filename, R_OK) != 0)
4867  {
4868  g_free (xsl_filename);
4869  xsl_filename = NULL;
4870  if (strchr (help_language, '_'))
4871  {
4872  *strchr (help_language, '_') = '\0';
4873  xsl_filename = g_strdup_printf ("help_%s.xsl",
4874  help_language);
4875  if (access (xsl_filename, R_OK) != 0)
4876  {
4877  g_free (xsl_filename);
4878  xsl_filename = NULL;
4879  }
4880  }
4881  }
4882  g_free (help_language);
4883  index ++;
4884  }
4885 
4886  template_attributes
4887  = g_hash_table_new (g_str_hash, g_str_equal);
4888 
4889  g_hash_table_insert (template_attributes, "match", page);
4890  g_hash_table_insert (template_attributes, "mode", "help");
4891 
4892  // Try to find the requested page template
4893  template_found
4894  = find_element_in_xml_file (xsl_filename, "xsl:template",
4895  template_attributes);
4896 
4897  if (template_found == 0)
4898  {
4899  // Try finding page template again in default help
4900  template_found
4901  = find_element_in_xml_file ("help.xsl", "xsl:template",
4902  template_attributes);
4903  }
4904 
4905  if (template_found == 0)
4906  {
4907  response_data.http_status_code = MHD_HTTP_NOT_FOUND;
4908  res = gsad_message (credentials,
4909  NOT_FOUND_TITLE, NULL, 0,
4911  "/help/contents.html", &response_data);
4912  }
4913  else if (xsl_filename)
4914  {
4915  res = xsl_transform_with_stylesheet (xml, xsl_filename,
4916  &response_data);
4917 
4918  }
4919  else
4920  {
4921  res = xsl_transform_with_stylesheet (xml, "help.xsl",
4922  &response_data);
4923  }
4924 
4925  g_strfreev (preferred_languages);
4926  g_free (xsl_filename);
4927  g_free (page);
4928  }
4929  if (res == NULL)
4930  {
4931  response_data.http_status_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
4932  res = gsad_message (credentials,
4933  "Invalid request", __FUNCTION__, __LINE__,
4934  "Error generating help page.",
4935  "/help/contents.html", &response_data);
4936  }
4937  http_response_code = response_data.http_status_code;
4938  response = MHD_create_response_from_buffer (strlen (res), res,
4939  MHD_RESPMEM_MUST_FREE);
4940  cmd_response_data_reset (&response_data);
4941  }
4942  else
4943  {
4944  /* URL requests neither an OMP command nor a special GSAD command,
4945  * so it is a simple file. */
4946  /* Serve a file. */
4947 #ifdef SERVE_STATIC_ASSETS
4948  response = file_content_response (credentials,
4949  connection, url,
4950  &http_response_code,
4951  &content_type,
4952  &content_disposition);
4953 #else
4954  gchar *msg = gsad_message (NULL,
4955  NOT_FOUND_TITLE, NULL, 0,
4957  "/login/login.html", NULL);
4958  response = MHD_create_response_from_buffer (strlen (msg),
4959  (void *) msg,
4960  MHD_RESPMEM_MUST_COPY);
4961  g_free (msg);
4962 #endif
4963  }
4964 
4965  if (response)
4966  {
4967  const char* cmd;
4968 
4969  if (credentials->params)
4970  cmd = params_value (credentials->params, "cmd");
4971  else
4972  cmd = NULL;
4973 
4974  if (attach_sid (response, sid) == MHD_NO)
4975  {
4976  g_free (sid);
4977  MHD_destroy_response (response);
4978  g_warning ("%s: failed to attach SID, dropping request",
4979  __FUNCTION__);
4980  return MHD_NO;
4981  }
4982  g_free (sid);
4983 
4984  if (guest_password
4985  && strcmp (credentials->username, guest_username) == 0
4986  && cmd
4987  && (strcmp (cmd, "get_aggregate") == 0
4988  || strcmp (cmd, "get_assets_chart") == 0
4989  || strcmp (cmd, "get_tasks_chart") == 0))
4990  {
4992  }
4993  else
4994  {
4995  add_security_headers (response);
4996  }
4997 
4998  credentials_free (credentials);
4999  return handler_send_response (connection,
5000  response,
5001  &content_type,
5002  content_disposition,
5003  http_response_code,
5004  0);
5005  }
5006  else
5007  {
5008  /* Severe memory or file access problem. */
5009  g_free (sid);
5010  credentials_free (credentials);
5011  g_warning ("%s: memory or file access problem, dropping request",
5012  __FUNCTION__);
5013  return MHD_NO;
5014  }
5015  }
5016 
5017  if (!strcmp (method, "POST"))
5018  {
5019  user_t *user;
5020  const char *sid, *accept_language;
5021  gchar *new_sid;
5022  int ret;
5023 
5024  if (NULL == *con_cls)
5025  {
5026  /* First call for this request, a POST. */
5027 
5028  struct gsad_connection_info *con_info;
5029 
5030  /* Freed by MHD_OPTION_NOTIFY_COMPLETED callback, free_resources. */
5031  con_info = g_malloc0 (sizeof (struct gsad_connection_info));
5032 
5033  con_info->postprocessor =
5034  MHD_create_post_processor (connection, POST_BUFFER_SIZE,
5035  serve_post, (void *) con_info);
5036  if (NULL == con_info->postprocessor)
5037  {
5038  g_free (con_info);
5039  /* Both bad request or running out of memory will lead here, but
5040  * we return the Bad Request page always, to prevent bad requests
5041  * from leading to "Internal application error" in the log. */
5042  send_response (connection, BAD_REQUEST_PAGE,
5044  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
5045  return MHD_YES;
5046  }
5047  con_info->params = params_new ();
5048  con_info->connectiontype = 1;
5049  con_info->answercode = MHD_HTTP_OK;
5051  con_info->content_disposition = NULL;
5052  con_info->content_length = 0;
5053  con_info->redirect = NULL;
5054 
5055  *con_cls = (void *) con_info;
5056  return MHD_YES;
5057  }
5058 
5059  /* Second or later call for this request, a POST. */
5060 
5061  struct gsad_connection_info *con_info = *con_cls;
5062  if (0 != *upload_data_size)
5063  {
5064  MHD_post_process (con_info->postprocessor, upload_data,
5065  *upload_data_size);
5066  *upload_data_size = 0;
5067  return MHD_YES;
5068  }
5069 
5070  sid = MHD_lookup_connection_value (connection,
5071  MHD_COOKIE_KIND,
5072  SID_COOKIE_NAME);
5073  if (openvas_validate (validator, "token", sid))
5074  con_info->cookie = NULL;
5075  else
5076  con_info->cookie = g_strdup (sid);
5077 
5078  accept_language = MHD_lookup_connection_value (connection,
5079  MHD_HEADER_KIND,
5080  "Accept-Language");
5081  if (accept_language
5082  && g_utf8_validate (accept_language, -1, NULL) == FALSE)
5083  {
5084  send_response (connection,
5085  UTF8_ERROR_PAGE ("'Accept-Language' header"),
5086  MHD_HTTP_BAD_REQUEST, NULL,
5087  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
5088  return MHD_YES;
5089  }
5090  con_info->language = accept_language_to_env_fmt (accept_language);
5091 
5092  get_client_address (connection, client_address);
5093  ret = get_client_address (connection, client_address);
5094  if (ret == 1)
5095  {
5096  send_response (connection,
5097  UTF8_ERROR_PAGE ("'X-Real-IP' header"),
5098  MHD_HTTP_BAD_REQUEST, NULL,
5099  GSAD_CONTENT_TYPE_TEXT_HTML, NULL, 0);
5100  return MHD_YES;
5101  }
5102 
5103  user = NULL;
5104  new_sid = NULL;
5105  ret = exec_omp_post (con_info, &user, &new_sid, client_address);
5106 
5107  if (ret == 1)
5108  {
5109  gchar *url;
5110  url = g_strdup_printf ("%s&token=%s",
5111  params_value (con_info->params, "text"),
5112  user->token);
5113  user_release (user);
5114  ret = send_redirect_to_urn (connection, url, user);
5115  g_free (url);
5116  return ret;
5117  }
5118 
5119  if (con_info->redirect)
5120  {
5121  ret = send_redirect_to_uri (connection, con_info->redirect, user);
5122  g_free (con_info->redirect);
5123  con_info->redirect = NULL;
5124  }
5125  else
5126  {
5127  xml_flag = con_info->params
5128  ? params_value (con_info->params, "xml")
5129  : NULL;
5130 
5131  if (xml_flag && strcmp (xml_flag, "0"))
5132  {
5133  content_type = GSAD_CONTENT_TYPE_APP_XML;
5134  }
5135  else
5136  {
5137  content_type = con_info->content_type;
5138  }
5139 
5140  ret = send_response (connection, con_info->response,
5141  con_info->answercode,
5142  new_sid ? new_sid : "0",
5143  content_type,
5144  con_info->content_disposition,
5145  con_info->content_length);
5146  }
5147 
5148  g_free (new_sid);
5149  return ret;
5150  }
5151 
5152  assert (0);
5153  g_warning ("%s: something went wrong, dropping request",
5154  __FUNCTION__);
5155  return MHD_NO;
5156 }
5157 
5158 
5166 static gboolean
5167 drop_privileges (struct passwd * user_pw)
5168 {
5169  if (setgroups (0, NULL))
5170  {
5171  g_critical ("%s: failed to set groups: %s\n", __FUNCTION__,
5172  strerror (errno));
5173  return FALSE;
5174  }
5175  if (setgid (user_pw->pw_gid))
5176  {
5177  g_critical ("%s: failed to drop group privileges: %s\n", __FUNCTION__,
5178  strerror (errno));
5179  return FALSE;
5180  }
5181  if (setuid (user_pw->pw_uid))
5182  {
5183  g_critical ("%s: failed to drop user privileges: %s\n", __FUNCTION__,
5184  strerror (errno));
5185  return FALSE;
5186  }
5187 
5188  return TRUE;
5189 }
5190 
5200 static int
5201 chroot_drop_privileges (gboolean do_chroot, gchar *drop,
5202  const gchar *subdir)
5203 {
5204  struct passwd *user_pw;
5205 
5206  if (drop)
5207  {
5208  user_pw = getpwnam (drop);
5209  if (user_pw == NULL)
5210  {
5211  g_critical ("%s: Failed to drop privileges."
5212  " Could not determine UID and GID for user \"%s\"!\n",
5213  __FUNCTION__,
5214  drop);
5215  return 1;
5216  }
5217  }
5218  else
5219  user_pw = NULL;
5220 
5221  if (do_chroot)
5222  {
5223  /* Chroot into state dir. */
5224 
5225  if (chroot (GSA_DATA_DIR))
5226  {
5227  g_critical ("%s: Failed to chroot to \"%s\": %s\n",
5228  __FUNCTION__,
5229  GSA_DATA_DIR,
5230  strerror (errno));
5231  return 1;
5232  }
5233  set_chroot_state (1);
5234  }
5235 
5236  if (user_pw && (drop_privileges (user_pw) == FALSE))
5237  {
5238  g_critical ("%s: Failed to drop privileges\n",
5239  __FUNCTION__);
5240  return 1;
5241  }
5242 
5243  if (do_chroot)
5244  {
5245  gchar* root_face_dir = g_build_filename ("/", subdir, NULL);
5246  if (chdir (root_face_dir))
5247  {
5248  g_critical ("%s: failed change to chroot root directory (%s): %s\n",
5249  __FUNCTION__,
5250  root_face_dir,
5251  strerror (errno));
5252  g_free (root_face_dir);
5253  return 1;
5254  }
5255  g_free (root_face_dir);
5256  }
5257  else
5258  {
5259  gchar* data_dir = g_build_filename (GSA_DATA_DIR, subdir, NULL);
5260  if (chdir (data_dir))
5261  {
5262  g_critical ("%s: failed to change to \"%s\": %s\n",
5263  __FUNCTION__,
5264  data_dir,
5265  strerror (errno));
5266  g_free (data_dir);
5267  return 1;
5268  }
5269  g_free (data_dir);
5270  }
5271 
5272  return 0;
5273 }
5274 
5283 static void
5284 my_gnutls_log_func (int level, const char *text)
5285 {
5286  fprintf (stderr, "[%d] (%d) %s", getpid (), level, text);
5287  if (*text && text[strlen (text) -1] != '\n')
5288  putc ('\n', stderr);
5289 }
5290 
5291 
5300 int
5302 {
5303  g_debug ("Initializing the Greenbone Security Assistant...\n");
5304 
5305  /* Init Glib. */
5306  mutex = g_malloc (sizeof (GMutex));
5307  g_mutex_init (mutex);
5308  users = g_ptr_array_new ();
5309 
5310  /* Check for required files. */
5311  if (openvas_file_check_is_dir (GSA_DATA_DIR) < 1)
5312  {
5313  g_critical ("%s: Could not access %s!\n", __FUNCTION__, GSA_DATA_DIR);
5314  return MHD_NO;
5315  }
5316 
5317  /* Init GCRYPT. */
5318  /* Register thread callback structure for libgcrypt < 1.6.0. */
5319 #if GCRYPT_VERSION_NUMBER < 0x010600
5320  gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
5321 #endif
5322 
5323  /* Version check should be the very first call because it makes sure that
5324  * important subsystems are intialized.
5325  * We pass NULL to gcry_check_version to disable the internal version mismatch
5326  * test. */
5327  if (!gcry_check_version (NULL))
5328  {
5329  g_critical ("%s: libgcrypt version check failed\n", __FUNCTION__);
5330  return MHD_NO;
5331  }
5332 
5333  /* We don't want to see any warnings, e.g. because we have not yet parsed
5334  * program options which might be used to suppress such warnings. */
5335  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
5336 
5337  /* ... If required, other initialization goes here. Note that the process
5338  * might still be running with increased privileges and that the secure
5339  * memory has not been intialized. */
5340 
5341  /* Allocate a pool of 16k secure memory. This make the secure memory
5342  * available and also drops privileges where needed. */
5343  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
5344 
5345  /* It is now okay to let Libgcrypt complain when there was/is a problem with
5346  * the secure memory. */
5347  gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
5348 
5349  /* ... If required, other initialization goes here. */
5350 
5351  /* Tell Libgcrypt that initialization has completed. */
5352  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
5353 
5354  /* Init GNUTLS. */
5355  int ret = gnutls_global_init ();
5356  if (ret < 0)
5357  {
5358  g_critical ("%s: Failed to initialize GNUTLS.\n", __FUNCTION__);
5359  return MHD_NO;
5360  }
5361 
5362  /* Init the validator. */
5363  init_validator ();
5364 
5365  g_debug ("Initialization of GSA successful.\n");
5366  return MHD_YES;
5367 }
5368 
5375 void
5377 {
5378  if (redirect_pid) kill (redirect_pid, SIGTERM);
5379  if (unix_pid) kill (unix_pid, SIGTERM);
5380 
5381  MHD_stop_daemon (gsad_daemon);
5382 
5383  if (log_config) free_log_configuration (log_config);
5384 
5385  gsad_base_cleanup ();
5386 
5387  pidfile_remove ("gsad");
5388 }
5389 
5395 void
5397 {
5398  termination_signal = signal;
5399 }
5400 
5408 static int
5409 register_signal_handlers ()
5410 {
5411  if (signal (SIGTERM, handle_signal_exit) == SIG_ERR
5412  || signal (SIGINT, handle_signal_exit) == SIG_ERR
5413  || signal (SIGHUP, SIG_IGN) == SIG_ERR
5414  || signal (SIGPIPE, SIG_IGN) == SIG_ERR
5415 #ifdef USE_LIBXSLT
5416  || signal (SIGCHLD, SIG_IGN) == SIG_ERR)
5417 #else
5418  || signal (SIGCHLD, SIG_DFL) == SIG_ERR)
5419 #endif
5420  return -1;
5421  return 0;
5422 }
5423 
5424 static void
5425 mhd_logger (void *arg, const char *fmt, va_list ap)
5426 {
5427  char buf[1024];
5428 
5429  vsnprintf (buf, sizeof (buf), fmt, ap);
5430  va_end (ap);
5431  g_warning ("MHD: %s", buf);
5432 }
5433 
5434 static struct MHD_Daemon *
5435 start_unix_http_daemon (const char *unix_socket_path,
5436  int handler (void *, struct MHD_Connection *,
5437  const char *, const char *, const char *,
5438  const char *, size_t *, void **))
5439 {
5440  struct sockaddr_un addr;
5441  struct stat ustat;
5442  mode_t oldmask = 0;
5443 
5444  unix_socket = socket (AF_UNIX, SOCK_STREAM, 0);
5445  if (unix_socket == -1)
5446  {
5447  g_warning ("%s: Couldn't create UNIX socket", __FUNCTION__);
5448  return NULL;
5449  }
5450  addr.sun_family = AF_UNIX;
5451  strncpy (addr.sun_path, unix_socket_path, sizeof (addr.sun_path));
5452  if (!stat (addr.sun_path, &ustat))
5453  {
5454  /* Remove socket so we can bind(). Keep same permissions when recreating
5455  * it. */
5456  unlink (addr.sun_path);
5457  oldmask = umask (~ustat.st_mode);
5458  }
5459  if (bind (unix_socket, (struct sockaddr *) &addr, sizeof (struct sockaddr_un))
5460  == -1)
5461  {
5462  g_warning ("%s: Error on bind(%s): %s", __FUNCTION__,
5463  unix_socket_path, strerror (errno));
5464  return NULL;
5465  }
5466  if (oldmask)
5467  umask (oldmask);
5468  if (listen (unix_socket, 128) == -1)
5469  {
5470  g_warning ("%s: Error on listen(): %s", __FUNCTION__, strerror (errno));
5471  return NULL;
5472  }
5473 
5474  return MHD_start_daemon
5475  (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, 0,
5476  NULL, NULL, handler, NULL, MHD_OPTION_NOTIFY_COMPLETED,
5477  free_resources, NULL, MHD_OPTION_LISTEN_SOCKET, unix_socket,
5478  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 30,
5479  MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, NULL, MHD_OPTION_END);
5480 }
5481 
5482 static struct MHD_Daemon *
5483 start_http_daemon (int port,
5484  int handler (void *, struct MHD_Connection *, const char *,
5485  const char *, const char *, const char *,
5486  size_t *, void **))
5487 {
5488  int ipv6_flag;
5489 
5490  if (address.ss_family == AF_INET6)
5491 /* LibmicroHTTPD 0.9.28 and higher. */
5492 #if MHD_VERSION >= 0x00092800
5493  ipv6_flag = MHD_USE_DUAL_STACK;
5494 #else
5495  ipv6_flag = MHD_USE_IPv6;
5496 #endif
5497  else
5498  ipv6_flag = MHD_NO_FLAG;
5499  return MHD_start_daemon
5500  (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | ipv6_flag, port,
5501  NULL, NULL, handler, NULL, MHD_OPTION_NOTIFY_COMPLETED,
5502  free_resources, NULL, MHD_OPTION_SOCK_ADDR, &address,
5503  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 30,
5504  MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, NULL, MHD_OPTION_END);
5505 }
5506 
5507 static struct MHD_Daemon *
5508 start_https_daemon (int port, const char *key, const char *cert,
5509  const char *priorities, const char *dh_params)
5510 {
5511  int ipv6_flag;
5512 
5513  if (address.ss_family == AF_INET6)
5514 /* LibmicroHTTPD 0.9.28 and higher. */
5515 #if MHD_VERSION >= 0x00092800
5516  ipv6_flag = MHD_USE_DUAL_STACK;
5517 #else
5518  ipv6_flag = MHD_USE_IPv6;
5519 #endif
5520  else
5521  ipv6_flag = MHD_NO_FLAG;
5522  return MHD_start_daemon
5523  (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | MHD_USE_SSL
5524  | ipv6_flag, port, NULL, NULL, &handle_request, NULL,
5525  MHD_OPTION_HTTPS_MEM_KEY, key,
5526  MHD_OPTION_HTTPS_MEM_CERT, cert,
5527  MHD_OPTION_NOTIFY_COMPLETED, free_resources, NULL,
5528  MHD_OPTION_SOCK_ADDR, &address,
5529  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 30,
5530  MHD_OPTION_HTTPS_PRIORITIES, priorities,
5531  MHD_OPTION_EXTERNAL_LOGGER, mhd_logger, NULL,
5532 /* LibmicroHTTPD 0.9.35 and higher. */
5533 #if MHD_VERSION >= 0x00093500
5534  dh_params ? MHD_OPTION_HTTPS_MEM_DHPARAMS : MHD_OPTION_END,
5535  dh_params,
5536 #endif
5537  MHD_OPTION_END);
5538 }
5539 
5545 static void
5546 gsad_address_set_port (int port)
5547 {
5548  struct sockaddr_in *gsad_address = (struct sockaddr_in *) &address;
5549  struct sockaddr_in6 *gsad_address6 = (struct sockaddr_in6 *) &address;
5550 
5551  gsad_address->sin_port = htons (port);
5552  gsad_address6->sin6_port = htons (port);
5553 }
5554 
5563 static int
5564 gsad_address_init (const char *address_str, int port)
5565 {
5566  struct sockaddr_in *gsad_address = (struct sockaddr_in *) &address;
5567  struct sockaddr_in6 *gsad_address6 = (struct sockaddr_in6 *) &address;
5568 
5569  gsad_address_set_port (port);
5570  if (address_str)
5571  {
5572  if (inet_pton (AF_INET6, address_str, &gsad_address6->sin6_addr) > 0)
5573  address.ss_family = AF_INET6;
5574  else if (inet_pton (AF_INET, address_str, &gsad_address->sin_addr) > 0)
5575  address.ss_family = AF_INET;
5576  else
5577  {
5578  g_warning ("Failed to create GSAD address %s", address_str);
5579  return 1;
5580  }
5581  }
5582  else
5583  {
5584  gsad_address->sin_addr.s_addr = INADDR_ANY;
5585  gsad_address6->sin6_addr = in6addr_any;
5586  if (ipv6_is_enabled ())
5587  address.ss_family = AF_INET6;
5588  else
5589  address.ss_family = AF_INET;
5590  }
5591  return 0;
5592 }
5593 
5602 int
5603 main (int argc, char **argv)
5604 {
5605  gchar *rc_name;
5606  gchar *old_locale;
5607  char *locale;
5608  int gsad_port;
5609  int gsad_redirect_port = DEFAULT_GSAD_REDIRECT_PORT;
5610  int gsad_manager_port = DEFAULT_OPENVAS_MANAGER_PORT;
5611  sigset_t sigmask_all, sigmask_current;
5612 
5613  /* Initialise. */
5614 
5615  if (gsad_init () == MHD_NO)
5616  {
5617  g_critical ("%s: Initialization failed!\nExiting...\n", __FUNCTION__);
5618  exit (EXIT_FAILURE);
5619  }
5620 
5621  /* Process command line options. */
5622 
5623  static gboolean do_chroot = FALSE;
5624  static gchar *drop = NULL;
5625  static gboolean foreground = FALSE;
5626  static gboolean http_only = FALSE;
5627  static gboolean print_version = FALSE;
5628  static gboolean no_redirect = FALSE;
5629  static gboolean secure_cookie = FALSE;
5630  static int timeout = SESSION_TIMEOUT;
5631  static gchar *gsad_address_string = NULL;
5632  static gchar *gsad_manager_address_string = NULL;
5633  static gchar *gsad_manager_unix_socket_path = NULL;
5634  static gchar *gsad_port_string = NULL;
5635  static gchar *gsad_redirect_port_string = NULL;
5636  static gchar *gsad_manager_port_string = NULL;
5637  static gchar *gsad_vendor_version_string = NULL;
5638  static gchar *gsad_login_label_name = NULL;
5639  static gchar *ssl_private_key_filename = OPENVAS_SERVER_KEY;
5640  static gchar *ssl_certificate_filename = OPENVAS_SERVER_CERTIFICATE;
5641  static gchar *dh_params_filename = NULL;
5642  static gchar *unix_socket_path = NULL;
5643  static gchar *gnutls_priorities = "NORMAL";
5644  static int debug_tls = 0;
5645  static gchar *face_name = NULL;
5646  static gchar *guest_user = NULL;
5647  static gchar *guest_pass = NULL;
5648  static gchar *http_frame_opts = DEFAULT_GSAD_X_FRAME_OPTIONS;
5649  static gchar *http_csp = DEFAULT_GSAD_CONTENT_SECURITY_POLICY;
5650  static gchar *http_guest_chart_frame_opts
5652  static gchar *http_guest_chart_csp
5654  static int hsts_enabled = FALSE;
5655  static int hsts_max_age = DEFAULT_GSAD_HSTS_MAX_AGE;
5656  static gboolean ignore_x_real_ip = FALSE;
5657  static int verbose = 0;
5658  GError *error = NULL;
5659  GOptionContext *option_context;
5660  static GOptionEntry option_entries[] = {
5661  {"drop-privileges", '\0',
5662  0, G_OPTION_ARG_STRING, &drop,
5663  "Drop privileges to <user>.", "<user>" },
5664  {"foreground", 'f',
5665  0, G_OPTION_ARG_NONE, &foreground,
5666  "Run in foreground.", NULL},
5667  {"http-only", '\0',
5668  0, G_OPTION_ARG_NONE, &http_only,
5669  "Serve HTTP only, without SSL.", NULL},
5671  {"listen", '\0',
5672  0, G_OPTION_ARG_STRING, &gsad_address_string,
5673  "Listen on <address>.", "<address>" },
5674  {"mlisten", '\0',
5675  0, G_OPTION_ARG_STRING, &gsad_manager_address_string,
5676  "Manager address.", "<address>" },
5677  {"port", 'p',
5678  0, G_OPTION_ARG_STRING, &gsad_port_string,
5679  "Use port number <number>.", "<number>"},
5680  {"mport", 'm',
5681  0, G_OPTION_ARG_STRING, &gsad_manager_port_string,
5682  "Use manager port number <number>.", "<number>"},
5683  {"rport", 'r',
5684  0, G_OPTION_ARG_STRING, &gsad_redirect_port_string,
5685  "Redirect HTTP from this port number <number>.", "<number>"},
5686  {"no-redirect", '\0',
5687  0, G_OPTION_ARG_NONE, &no_redirect,
5688  "Don't redirect HTTP to HTTPS.", NULL },
5689  {"verbose", 'v',
5690  0, G_OPTION_ARG_NONE, &verbose,
5691  "Has no effect. See INSTALL for logging config.", NULL },
5692  {"version", 'V',
5693  0, G_OPTION_ARG_NONE, &print_version,
5694  "Print version and exit.", NULL},
5695  {"vendor-version", '\0',
5696  0, G_OPTION_ARG_STRING, &gsad_vendor_version_string,
5697  "Use <string> as version in interface.", "<string>"},
5698  {"login-label", '\0',
5699  0, G_OPTION_ARG_STRING, &gsad_login_label_name,
5700  "Use <string> as login label.", "<string>"},
5701  {"ssl-private-key", 'k',
5702  0, G_OPTION_ARG_FILENAME, &ssl_private_key_filename,
5703  "Use <file> as the private key for HTTPS", "<file>"},
5704  {"ssl-certificate", 'c',
5705  0, G_OPTION_ARG_FILENAME, &ssl_certificate_filename,
5706  "Use <file> as the certificate for HTTPS", "<file>"},
5707  {"dh-params", '\0',
5708  0, G_OPTION_ARG_FILENAME, &dh_params_filename,
5709  "Diffie-Hellman parameters file", "<file>"},
5710  {"do-chroot", '\0',
5711  0, G_OPTION_ARG_NONE, &do_chroot,
5712  "Do chroot.", NULL},
5713  {"secure-cookie", '\0',
5714  0, G_OPTION_ARG_NONE, &secure_cookie,
5715  "Use a secure cookie (implied when using HTTPS).", NULL},
5716  {"timeout", '\0',
5717  0, G_OPTION_ARG_INT, &timeout,
5718  "Minutes of user idle time before session expires.", "<number>"},
5719  {"debug-tls", 0,
5720  0, G_OPTION_ARG_INT, &debug_tls,
5721  "Enable TLS debugging at <level>", "<level>"},
5722  {"gnutls-priorities", '\0',
5723  0, G_OPTION_ARG_STRING, &gnutls_priorities,
5724  "GnuTLS priorities string.", "<string>"},
5725  {"face", 0,
5726  0, G_OPTION_ARG_STRING, &face_name,
5727  "Use interface files from subdirectory <dir>", "<dir>"},
5728  {"guest-username", 0,
5729  0, G_OPTION_ARG_STRING, &guest_user,
5730  "Username for guest user. Enables guest logins.", "<name>"},
5731  {"guest-password", 0,
5732  0, G_OPTION_ARG_STRING, &guest_pass,
5733  "Password for guest user. Defaults to guest username.", "<password>"},
5734  {"http-frame-opts", 0,
5735  0, G_OPTION_ARG_STRING, &http_frame_opts,
5736  "X-Frame-Options HTTP header. Defaults to \""
5737  DEFAULT_GSAD_X_FRAME_OPTIONS "\".", "<frame-opts>"},
5738  {"http-csp", 0,
5739  0, G_OPTION_ARG_STRING, &http_csp,
5740  "Content-Security-Policy HTTP header. Defaults to \""
5741  DEFAULT_GSAD_CONTENT_SECURITY_POLICY"\".", "<csp>"},
5742  {"http-guest-chart-frame-opts", 0,
5743  0, G_OPTION_ARG_STRING, &http_guest_chart_frame_opts,
5744  "X-Frame-Options HTTP header for guest charts. Defaults to \""
5745  DEFAULT_GSAD_GUEST_CHART_X_FRAME_OPTIONS "\".", "<frame-opts>"},
5746  {"http-guest-chart-csp", 0,
5747  0, G_OPTION_ARG_STRING, &http_guest_chart_csp,
5748  "Content-Security-Policy HTTP header. Defaults to \""
5750  {"http-sts", 0,
5751  0, G_OPTION_ARG_NONE, &hsts_enabled,
5752  "Enable HTTP Strict-Tranport-Security header.", NULL},
5753  {"http-sts-max-age", 0,
5754  0, G_OPTION_ARG_INT, &hsts_max_age,
5755  "max-age in seconds for HTTP Strict-Tranport-Security header."
5756  " Defaults to \"" G_STRINGIFY (DEFAULT_GSAD_HSTS_MAX_AGE) "\".",
5757  "<max-age>"},
5758  {"ignore-x-real-ip", '\0',
5759  0, G_OPTION_ARG_NONE, &ignore_x_real_ip,
5760  "Do not use X-Real-IP to determine the client address.", NULL},
5761  {"unix-socket", '\0',
5762  0, G_OPTION_ARG_FILENAME, &unix_socket_path,
5763  "Path to unix socket to listen on", "<file>"},
5764  {"munix-socket", '\0',
5765  0, G_OPTION_ARG_FILENAME, &gsad_manager_unix_socket_path,
5766  "Path to Manager unix socket", "<file>"},
5767  {NULL}
5768  };
5769 
5770  option_context =
5771  g_option_context_new ("- Greenbone Security Assistant Daemon");
5772  g_option_context_add_main_entries (option_context, option_entries, NULL);
5773  if (!g_option_context_parse (option_context, &argc, &argv, &error))
5774  {
5775  g_critical ("%s: %s\n\n", __FUNCTION__, error->message);
5776  exit (EXIT_FAILURE);
5777  }
5778  g_option_context_free (option_context);
5779 
5780  http_x_frame_options = http_frame_opts;
5781  http_content_security_policy = http_csp;
5782  http_guest_chart_x_frame_options = http_guest_chart_frame_opts;
5783  http_guest_chart_content_security_policy = http_guest_chart_csp;
5784 
5785  if (http_only == FALSE && hsts_enabled)
5786  {
5788  = g_strdup_printf ("max-age=%d",
5789  hsts_max_age >= 0 ? hsts_max_age
5791  }
5792  else
5794 
5795  ignore_http_x_real_ip = ignore_x_real_ip;
5796 
5797  if (register_signal_handlers ())
5798  {
5799  g_critical ("Failed to register signal handlers!\n");
5800  exit (EXIT_FAILURE);
5801  }
5802 
5803  if (print_version)
5804  {
5805  printf ("Greenbone Security Assistant %s\n", GSAD_VERSION);
5806 #ifdef GSAD_SVN_REVISION
5807  printf ("SVN revision %i\n", GSAD_SVN_REVISION);
5808 #endif
5809  if (debug_tls)
5810  {
5811  printf ("gnutls %s\n", gnutls_check_version (NULL));
5812  printf ("libmicrohttpd %s\n", MHD_get_version ());
5813  }
5814  printf ("Copyright (C) 2010-2016 Greenbone Networks GmbH\n");
5815  printf ("License GPLv2+: GNU GPL version 2 or later\n");
5816  printf
5817  ("This is free software: you are free to change and redistribute it.\n"
5818  "There is NO WARRANTY, to the extent permitted by law.\n\n");
5819  exit (EXIT_SUCCESS);
5820  }
5821 
5822  if (debug_tls)
5823  {
5824  gnutls_global_set_log_function (my_gnutls_log_func);
5825  gnutls_global_set_log_level (debug_tls);
5826  }
5827 
5828  switch (gsad_base_init ())
5829  {
5830  case 1:
5831  g_critical ("%s: libxml must be compiled with thread support\n",
5832  __FUNCTION__);
5833  exit (EXIT_FAILURE);
5834  }
5835 
5836  if (gsad_vendor_version_string)
5837  vendor_version_set (gsad_vendor_version_string);
5838 
5839  if (gsad_login_label_name)
5840  {
5841  if (label_name_set (gsad_login_label_name))
5842  {
5843  g_critical ("Invalid character in login label name\n");
5844  exit (EXIT_FAILURE);
5845  }
5846  }
5847 
5848  if (no_redirect && gsad_redirect_port_string)
5849  {
5850  g_warning ("--no-redirect option given with --rport");
5851  return 1;
5852  }
5853 
5854  /* Switch to UTC for scheduling. */
5855 
5856  if (setenv ("TZ", "utc 0", 1) == -1)
5857  {
5858  g_critical ("%s: failed to set timezone\n", __FUNCTION__);
5859  exit (EXIT_FAILURE);
5860  }
5861  tzset ();
5862 
5863  /* Setup logging. */
5864 
5865  rc_name = g_build_filename (GSA_CONFIG_DIR, "gsad_log.conf", NULL);
5866  if (g_file_test (rc_name, G_FILE_TEST_EXISTS))
5867  log_config = load_log_configuration (rc_name);
5868  g_free (rc_name);
5869  setup_log_handlers (log_config);
5870  /* Set to ensure that recursion is left out, in case two threads log
5871  * concurrently. */
5872  g_log_set_always_fatal (G_LOG_FATAL_MASK);
5873 
5874 #ifdef GSAD_SVN_REVISION
5875  g_message ("Starting GSAD version %s (SVN revision %i)\n",
5876  GSAD_VERSION,
5877  GSAD_SVN_REVISION);
5878 #else
5879  g_message ("Starting GSAD version %s\n",
5880  GSAD_VERSION);
5881 #endif
5882 
5883  /* Finish processing the command line options. */
5884 
5885  use_secure_cookie = secure_cookie;
5886 
5887  if ((timeout < 1) || (timeout > 1440))
5888  {
5889  g_critical ("%s: Timeout must be a number from 1 to 1440\n",
5890  __FUNCTION__);
5891  exit (EXIT_FAILURE);
5892  }
5893  session_timeout = timeout;
5894 
5895  if (guest_user)
5896  {
5897  guest_username = guest_user;
5898  guest_password = guest_pass ? guest_pass : guest_user;
5899  }
5900 
5901  gsad_port = http_only ? DEFAULT_GSAD_HTTP_PORT : DEFAULT_GSAD_HTTPS_PORT;
5902 
5903  if (gsad_port_string)
5904  {
5905  gsad_port = atoi (gsad_port_string);
5906  if (gsad_port <= 0 || gsad_port >= 65536)
5907  {
5908  g_critical ("%s: Port must be a number between 0 and 65536\n",
5909  __FUNCTION__);
5910  exit (EXIT_FAILURE);
5911  }
5912  }
5913 
5914  if (gsad_manager_port_string)
5915  {
5916  gsad_manager_port = atoi (gsad_manager_port_string);
5917  if (gsad_manager_port <= 0 || gsad_manager_port >= 65536)
5918  {
5919  g_critical ("%s: Manager port must be a number between 0 and 65536\n",
5920  __FUNCTION__);
5921  exit (EXIT_FAILURE);
5922  }
5923  }
5924 
5925  /* Set and test the base locale for XSLt gettext */
5926  old_locale = g_strdup (setlocale (LC_ALL, NULL));
5927 
5928  locale = setlocale (LC_ALL, "");
5929  if (locale == NULL)
5930  {
5931  g_warning ("%s: "
5932  "Failed to set locale according to environment variables,"
5933  " gettext translations are disabled.",
5934  __FUNCTION__);
5936  }
5937  else if (strcmp (locale, "C") == 0)
5938  {
5939  g_message ("%s: Locale for gettext extensions set to \"C\","
5940  " gettext translations are disabled.",
5941  __FUNCTION__);
5943  }
5944  else
5945  {
5946  if (strcasestr (locale, "en_") != locale)
5947  {
5948  g_warning ("%s: Locale defined by environment variables"
5949  " is not an \"en_...\" one.",
5950  __FUNCTION__);
5952  }
5953 
5954  if (strcasecmp (nl_langinfo (CODESET), "UTF-8"))
5955  g_warning ("%s: Locale defined by environment variables"
5956  " does not use UTF-8 encoding.",
5957  __FUNCTION__);
5958 
5959  g_debug ("%s: gettext translation extensions are enabled"
5960  " (using locale \"%s\").",
5961  __FUNCTION__, locale);
5963  }
5964 
5965  setlocale (LC_ALL, old_locale);
5966  g_free (old_locale);
5967 
5969 
5970  if (gsad_redirect_port_string)
5971  {
5972  gsad_redirect_port = atoi (gsad_redirect_port_string);
5973  if (gsad_redirect_port <= 0 || gsad_redirect_port >= 65536)
5974  {
5975  g_critical ("%s: Redirect port must be a number between 0 and 65536\n",
5976  __FUNCTION__);
5977  exit (EXIT_FAILURE);
5978  }
5979  }
5980 
5981  if (foreground == FALSE)
5982  {
5983  /* Fork into the background. */
5984  g_debug ("Forking...\n");
5985  pid_t pid = fork ();
5986  switch (pid)
5987  {
5988  case 0:
5989  /* Child. */
5990  break;
5991  case -1:
5992  /* Parent when error. */
5993  g_critical ("%s: Failed to fork!\n", __FUNCTION__);
5994  exit (EXIT_FAILURE);
5995  break;
5996  default:
5997  /* Parent. */
5998  exit (EXIT_SUCCESS);
5999  break;
6000  }
6001  }
6002 
6003  if (http_only)
6004  no_redirect = TRUE;
6005 
6006  if (unix_socket_path)
6007  {
6008  /* Fork for the unix socket server. */
6009  g_debug ("Forking for unix socket...\n");
6010  pid_t pid = fork ();
6011  switch (pid)
6012  {
6013  case 0:
6014  /* Child. */
6015 #if __linux
6016  if (prctl (PR_SET_PDEATHSIG, SIGKILL))
6017  g_warning ("%s: Failed to change parent death signal;"
6018  " unix socket process will remain if parent is killed:"
6019  " %s\n",
6020  __FUNCTION__,
6021  strerror (errno));
6022 #endif
6023  break;
6024  case -1:
6025  /* Parent when error. */
6026  g_warning ("%s: Failed to fork for unix socket!\n", __FUNCTION__);
6027  exit (EXIT_FAILURE);
6028  break;
6029  default:
6030  /* Parent. */
6031  unix_pid = pid;
6032  no_redirect = TRUE;
6033  break;
6034  }
6035  }
6036 
6037  if (!no_redirect)
6038  {
6039  /* Fork for the redirect server. */
6040  g_debug ("Forking for redirect...\n");
6041  pid_t pid = fork ();
6042  switch (pid)
6043  {
6044  case 0:
6045  /* Child. */
6046 #if __linux
6047  if (prctl (PR_SET_PDEATHSIG, SIGKILL))
6048  g_warning ("%s: Failed to change parent death signal;"
6049  " redirect process will remain if parent is killed:"
6050  " %s\n",
6051  __FUNCTION__,
6052  strerror (errno));
6053 #endif
6054  redirect_location = g_strdup_printf ("https://%%s:%i/login/login.html",
6055  gsad_port);
6056  break;
6057  case -1:
6058  /* Parent when error. */
6059  g_critical ("%s: Failed to fork for redirect!\n", __FUNCTION__);
6060  exit (EXIT_FAILURE);
6061  break;
6062  default:
6063  /* Parent. */
6064  redirect_pid = pid;
6065  no_redirect = TRUE;
6066  break;
6067  }
6068  }
6069 
6070  /* Register the cleanup function. */
6071 
6072  if (atexit (&gsad_cleanup))
6073  {
6074  g_critical ("%s: Failed to register cleanup function!\n", __FUNCTION__);
6075  exit (EXIT_FAILURE);
6076  }
6077 
6078  /* Write pidfile. */
6079 
6080  if (pidfile_create ("gsad"))
6081  {
6082  g_critical ("%s: Could not write PID file.\n", __FUNCTION__);
6083  exit (EXIT_FAILURE);
6084  }
6085 
6086  if (gsad_address_init (gsad_address_string, gsad_port))
6087  return 1;
6088  if (!no_redirect)
6089  {
6090  /* Start the HTTP to HTTPS redirect server. */
6091 
6092  gsad_address_set_port (gsad_redirect_port);
6093  gsad_daemon = start_http_daemon (gsad_redirect_port, redirect_handler);
6094 
6095  if (gsad_daemon == NULL)
6096  {
6097  g_warning ("%s: start_http_daemon redirect failed !", __FUNCTION__);
6098  return EXIT_FAILURE;
6099  }
6100  else
6101  {
6102  g_debug ("GSAD started successfully and is redirecting on port %d.\n",
6103  gsad_redirect_port);
6104  }
6105  }
6106  else if (unix_socket_path && !unix_pid)
6107  {
6108  /* Start the unix socket server. */
6109 
6110  omp_init (gsad_manager_unix_socket_path,
6111  gsad_manager_address_string,
6112  gsad_manager_port);
6113 
6114  gsad_daemon = start_unix_http_daemon (unix_socket_path, handle_request);
6115 
6116  if (gsad_daemon == NULL)
6117  {
6118  g_warning ("%s: start_unix_http_daemon failed !", __FUNCTION__);
6119  return EXIT_FAILURE;
6120  }
6121  else
6122  {
6123  g_debug ("GSAD started successfully and is listening on unix"
6124  " socket %s.\n",
6125  unix_socket_path);
6126  }
6127  }
6128  else
6129  {
6130  /* Start the real server. */
6131 
6132  omp_init (gsad_manager_unix_socket_path,
6133  gsad_manager_address_string,
6134  gsad_manager_port);
6135 
6136  if (http_only)
6137  {
6138  gsad_daemon = start_http_daemon (gsad_port, handle_request);
6139  if (gsad_daemon == NULL && gsad_port_string == NULL)
6140  {
6141  g_warning ("Binding to port %d failed, trying default port %d next.",
6142  gsad_port, DEFAULT_GSAD_PORT);
6143  gsad_port = DEFAULT_GSAD_PORT;
6144  gsad_address_set_port (gsad_port);
6145  gsad_daemon = start_http_daemon (gsad_port, handle_request);
6146  }
6147  }
6148  else
6149  {
6150  gchar *ssl_private_key = NULL;
6151  gchar *ssl_certificate = NULL;
6152  gchar *dh_params = NULL;
6153 
6154  use_secure_cookie = 1;
6155 
6156  if (!g_file_get_contents (ssl_private_key_filename, &ssl_private_key,
6157  NULL, &error))
6158  {
6159  g_critical ("%s: Could not load private SSL key from %s: %s\n",
6160  __FUNCTION__,
6161  ssl_private_key_filename,
6162  error->message);
6163  g_error_free (error);
6164  exit (EXIT_FAILURE);
6165  }
6166 
6167  if (!g_file_get_contents (ssl_certificate_filename, &ssl_certificate,
6168  NULL, &error))
6169  {
6170  g_critical ("%s: Could not load SSL certificate from %s: %s\n",
6171  __FUNCTION__,
6172  ssl_certificate_filename,
6173  error->message);
6174  g_error_free (error);
6175  exit (EXIT_FAILURE);
6176  }
6177 
6178  if (dh_params_filename &&
6179  !g_file_get_contents (dh_params_filename, &dh_params, NULL,
6180  &error))
6181  {
6182  g_critical ("%s: Could not load SSL certificate from %s: %s\n",
6183  __FUNCTION__, dh_params_filename, error->message);
6184  g_error_free (error);
6185  exit (EXIT_FAILURE);
6186  }
6187 
6188  gsad_daemon = start_https_daemon (gsad_port, ssl_private_key,
6189  ssl_certificate, gnutls_priorities,
6190  dh_params);
6191  if (gsad_daemon == NULL && gsad_port_string == NULL)
6192  {
6193  g_warning ("Binding to port %d failed, trying default port %d next.",
6194  gsad_port, DEFAULT_GSAD_PORT);
6195  gsad_port = DEFAULT_GSAD_PORT;
6196  gsad_address_set_port (gsad_port);
6197  gsad_daemon = start_https_daemon
6198  (gsad_port, ssl_private_key, ssl_certificate,
6199  gnutls_priorities, dh_params);
6200  }
6201 
6202  }
6203 
6204  if (gsad_daemon == NULL)
6205  {
6206  g_critical ("%s: start_https_daemon failed!\n", __FUNCTION__);
6207  return EXIT_FAILURE;
6208  }
6209  else
6210  {
6211  g_debug ("GSAD started successfully and is listening on port %d.\n",
6212  gsad_port);
6213  }
6214  }
6215 
6216  /* Chroot and drop privileges, if requested. */
6217 
6218  if (chroot_drop_privileges (do_chroot, drop,
6219  face_name ? face_name : DEFAULT_GSAD_FACE))
6220  {
6221  if (face_name && strcmp (face_name, DEFAULT_GSAD_FACE))
6222  {
6223  g_critical ("%s: Cannot use custom face \"%s\".\n",
6224  __FUNCTION__, face_name);
6225  exit (EXIT_FAILURE);
6226  }
6227  else
6228  {
6229  g_critical ("%s: Cannot use default face \"%s\"!\n",
6230  __FUNCTION__, DEFAULT_GSAD_FACE);
6231  exit (EXIT_FAILURE);
6232  }
6233  }
6234 
6235  /* Wait forever for input or interrupts. */
6236 
6237 
6238  if (sigfillset (&sigmask_all))
6239  {
6240  g_critical ("%s: Error filling signal set\n", __FUNCTION__);
6241  exit (EXIT_FAILURE);
6242  }
6243  if (pthread_sigmask (SIG_BLOCK, &sigmask_all, &sigmask_current))
6244  {
6245  g_critical ("%s: Error setting signal mask\n", __FUNCTION__);
6246  exit (EXIT_FAILURE);
6247  }
6248  while (1)
6249  {
6250  if (termination_signal)
6251  {
6252  g_debug ("Received %s signal.\n", sys_siglist[termination_signal]);
6253  gsad_cleanup ();
6254  /* Raise signal again, to exit with the correct return value. */
6255  signal (termination_signal, SIG_DFL);
6256  raise (termination_signal);
6257  }
6258 
6259  if (pselect (0, NULL, NULL, NULL, NULL, &sigmask_current) == -1)
6260  {
6261  if (errno == EINTR)
6262  continue;
6263  g_critical ("%s: pselect: %s\n", __FUNCTION__, strerror (errno));
6264  exit (EXIT_FAILURE);
6265  }
6266  }
6267  return EXIT_SUCCESS;
6268 }
char * export_notes_omp(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:13371
int openvas_validator_alias(validator_t validator, const char *alias, const char *name)
Make an alias for a rule name.
Definition: validator.c:125
char * get_report_omp(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:15060
#define DEFAULT_GSAD_HTTP_PORT
Fallback GSAD port for HTTP.
Definition: gsad.c:129
size_t content_length
Content length.
Definition: gsad.c:1699
int answercode
HTTP response code.
Definition: gsad.c:1696
int gsad_init()
Initialization routine for GSAD.
Definition: gsad.c:5301
struct MHD_Daemon * gsad_daemon
The handle on the embedded HTTP daemon.
Definition: gsad.c:250
char * export_scanners_omp(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:17217
char * export_permission_omp(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:22698
char * address
Client's IP address.
Definition: gsad.c:392
gchar * pw_warning
Password policy warning.
Definition: gsad.c:391
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:28065
char * export_role_omp(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:23821
#define ELSE(name)
Add else branch for an OMP operation.
Definition: gsad.c:2828
char * export_result_omp(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:15365
char * new_filter_omp(credentials_t *credentials, params_t *params, cmd_response_data_t *response_data)
Returns page to create a new filter.
Definition: gsad_omp.c:24546
char * process_bulk_omp(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:26768
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:146
int gsad_base_cleanup()
Base init.
Definition: gsad_base.c:99
char * edit_schedule(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:24676
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:433
char * export_users_omp(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:26019
void cmd_response_data_init(cmd_response_data_t *data)
Initializes a cmd_response_data_t struct.
Definition: gsad_omp.c:347
int user_set_chart_pref(const gchar *token, gchar *pref_id, gchar *pref_value)
Set a chart preference of a user.
Definition: gsad.c:786
time_t time
Login time.
Definition: gsad.c:393
char * edit_note(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:16136
#define G_LOG_FATAL_MASK
Definition: gsad.c:106
char * capabilities
Capabilites of manager.
Definition: gsad_base.h:76
#define USER_GUEST_LOGIN_ERROR
Definition: gsad.c:485
#define DEFAULT_GSAD_FACE
Default face name.
Definition: gsad.c:164
param_t * params_get(params_t *params, const char *name)
Get param.
Definition: gsad_base.c:650
char * timezone
User's timezone.
Definition: gsad_base.h:72
content_type
Content types.
Definition: gsad_base.h:118
gchar * language
User Interface Language, in short form like "en".
Definition: gsad.c:390
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:440
char * dashboard(credentials_t *credentials, params_t *params, cmd_response_data_t *response_data)
Show a dashboard.
Definition: gsad_omp.c:26122
char * export_preference_file_omp(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:13484
char * edit_override(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:16881
char * SERVER_ERROR
Server error HTML.
Definition: gsad.c:235
char * export_alert_omp(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:9331
params_t * params
Request parameters.
Definition: gsad.c:1692
#define DEFAULT_GSAD_LANGUAGE
Default language code, used when Accept-Language header is missing.
Definition: xslt_i18n.h:35
char * download_ssl_cert(credentials_t *credentials, params_t *params, gsize *response_size, cmd_response_data_t *response_data)
Get an SSL Certificate.
Definition: gsad_omp.c:15254
int params_given(params_t *params, const char *name)
Get whether a param was given at all.
Definition: gsad_base.c:666
#define USER_BAD_MISSING_COOKIE
Definition: gsad.c:480
struct sockaddr_storage address
The IP address of this program, "the GSAD".
Definition: gsad.c:255
gchar * guest_username
Guest username.
Definition: gsad.c:299
int user_set_language(const gchar *token, const gchar *language)
Set language of user.
Definition: gsad.c:726
gchar * http_guest_chart_x_frame_options
Current guest chart specific value for HTTP header "X-Frame-Options".
Definition: gsad.c:324
int unix_socket
Unix socket to listen on.
Definition: gsad.c:275
char * caller
Caller URL, for POST relogin.
Definition: gsad_base.h:74
int send_response(struct MHD_Connection *connection, const char *content, int status_code, const gchar *sid, enum content_type content_type, const char *content_disposition, size_t content_length)
Sends a HTTP response.
Definition: gsad.c:3603
char * export_tag_omp(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:10710
char * export_port_lists_omp(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:13462
char * edit_target(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:10931
int charts
Whether to show charts for this user.
Definition: gsad.c:394
Response information for commands.
Definition: gsad_base.h:92
char * edit_permission(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:22518
char * export_tags_omp(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:10732
char * edit_user(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:25490
#define EXPIRES_LENGTH
Max length of cookie expires param.
Definition: gsad.c:3380
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:318
#define DEFAULT_GSAD_X_FRAME_OPTIONS
Default value for HTTP header "X-Frame-Options".
Definition: gsad.c:169
int main(int argc, char **argv)
Main routine of Greenbone Security Assistant daemon.
Definition: gsad.c:5603
int valid_utf8
Definition: gsad_base.h:151
char * export_credentials_omp(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:6696
void params_mhd_validate_values(const char *parent_name, void *params)
Validate param values.
Definition: gsad.c:1958
gchar * filename
Definition: gsad_base.h:148
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:885
void params_free(params_t *params)
Make a params.
Definition: gsad_base.c:635
void set_chroot_state(int state)
Sets the chroot state.
Definition: gsad_base.c:125
int download_credential_omp(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:6455
int session_timeout
Maximum number of minutes of user idle time.
Definition: gsad.c:294
#define DEFAULT_GSAD_GUEST_CHART_X_FRAME_OPTIONS
Default value for HTTP header "X-Frame-Options" for guest charts.
Definition: gsad.c:182
char * export_agent_omp(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:7695
void set_language_code(gchar **lang, const gchar *language)
Set language code of user.
Definition: gsad_base.c:191
#define DATE_2822_LEN
At least maximum length of rfc2822 format date.
Definition: gsad.c:3864
#define USER_GUEST_LOGIN_FAILED
Definition: gsad.c:482
char * export_override_omp(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:13392
#define SESSION_TIMEOUT
Max number of minutes between activity in a session.
Definition: gsad.c:159
#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:113
gchar * capabilities
Capabilities.
Definition: gsad.c:389
char * export_schedule_omp(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:24712
void openvas_validator_add(validator_t validator, const char *name, const char *regex)
Add or overwrite a validation rule.
Definition: validator.c:106
char * export_config_omp(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:13306
int connectiontype
1=POST, 2=GET.
Definition: gsad.c:1695
void cmd_response_data_reset(cmd_response_data_t *data)
Clears a cmd_response_data_t struct.
Definition: gsad_omp.c:359
#define USER_IP_ADDRESS_MISSMATCH
Definition: gsad.c:484
gchar * guest_password
Guest password.
Definition: gsad.c:304
int serve_post(void *coninfo_cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size)
Serves part of a POST request.
Definition: gsad.c:1931
char * get_report_section_omp(credentials_t *credentials, params_t *params, cmd_response_data_t *response_data)
Get a report section, XSL transform the result.
Definition: gsad_omp.c:15237
Structure of credential related information.
Definition: gsad_base.h:66
char * export_groups_omp(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:20976
const char * params_original_value(params_t *params, const char *name)
Get original value of param, before validation.
Definition: gsad_base.c:716
GTree * chart_prefs
Chart preferences.
Definition: gsad.c:395
gchar * severity
Severity class.
Definition: gsad.c:388
#define DEFAULT_GSAD_PORT
Fallback unprivileged GSAD port.
Definition: gsad.c:134
gchar * original_value
Definition: gsad_base.h:147
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:664
char * username
Name of user.
Definition: gsad_base.h:69
char * export_assets_omp(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:27749
const char * NOT_FOUND_TITLE
Title for "Page not found" messages.
Definition: gsad.c:213
char * export_filters_omp(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:24528
int exec_omp_post(struct gsad_connection_info *con_info, user_t **user_return, gchar **new_sid, const char *client_address)
Handle a complete POST request.
Definition: gsad.c:2168
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 * content_disposition
Content disposition of reponse.
Definition: gsad.c:1698
char * new_override(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:16436
int user_set_autorefresh(const gchar *token, const gchar *autorefresh)
Set default autorefresh interval of user.
Definition: gsad.c:816
GSList * log_config
Logging parameters, as passed to setup_log_handlers.
Definition: gsad.c:282
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:128
int openvas_validate(validator_t validator, const char *name, const char *value)
Validate a string for a given rule.
Definition: validator.c:182
char * export_user_omp(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:25997
gchar * redirect
Redirect URL.
Definition: gsad.c:1700
Connection information.
Definition: gsad.c:1688
char * token
Request session token.
Definition: gsad.c:383
gchar * timezone
Timezone.
Definition: gsad.c:387
#define DEFAULT_GSAD_HSTS_MAX_AGE
Default "max-age" for HTTP header "Strict-Transport-Security".
Definition: gsad.c:195
char * edit_agent(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:7414
Headers/structs used generally in GSA.
int value_size
Definition: gsad_base.h:152
char * edit_tag(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:10489
#define MAX_FILE_NAME_SIZE
Maximum length of "file name" for /help/ URLs.
Definition: gsad.c:154
char * edit_scanner(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:17546
char * export_roles_omp(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:23843
char * cvss_calculator(credentials_t *credentials, params_t *params, cmd_response_data_t *response_data)
Definition: gsad_omp.c:26028
void vendor_version_set(const gchar *version)
Set the vendor version.
Definition: gsad_base.c:136
char * new_permission(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:21188
char * export_results_omp(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:15387
char * export_tasks_omp(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:5126
pid_t unix_pid
PID of unix socket child in parent, 0 in child.
Definition: gsad.c:270
validator_t validator
Parameter validator.
Definition: gsad.c:957
struct timeval cmd_start
Seconds since command page handler started.
Definition: gsad_base.h:68
char * save_user_omp(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:25767
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:557
char * export_overrides_omp(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:13415
pid_t redirect_pid
PID of redirect child in parent, 0 in child.
Definition: gsad.c:265
int guest
Whether the user is a guest.
Definition: gsad.c:398
char * export_schedules_omp(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:24734
char * export_configs_omp(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:13328
char * response
HTTP response text.
Definition: gsad.c:1691
char * BAD_REQUEST_PAGE
Bad request error HTML.
Definition: gsad.c:229
#define SID_COOKIE_NAME
Name of the cookie used to store the SID.
Definition: gsad.c:119
int array_len
Definition: gsad_base.h:153
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:254
params_t * params_new()
Make a params.
Definition: gsad_base.c:624
#define USER_BAD_MISSING_TOKEN
Definition: gsad.c:481
#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:874
char * export_alerts_omp(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:9353
#define DEFAULT_GSAD_HTTPS_PORT
Fallback GSAD port for HTTPS.
Definition: gsad.c:124
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:846
char * edit_alert(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:8828
char * export_report_formats_omp(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:13632
struct MHD_PostProcessor * postprocessor
POST processor.
Definition: gsad.c:1690
char * edit_filter(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:24470
char * edit_asset(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:27768
char * new_note(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:15722
int chroot_state
Whether chroot is used.
Definition: gsad.c:344
int user_set_severity(const gchar *token, const gchar *severity)
Set severity class of user.
Definition: gsad.c:696
int send_redirect_to_uri(struct MHD_Connection *connection, const char *uri, user_t *user)
Sends a HTTP redirection to an uri.
Definition: gsad.c:3656
Request parameter.
Definition: gsad_base.h:144
gchar * http_x_frame_options
Current value for HTTP header "X-Frame-Options".
Definition: gsad.c:314
char * export_scanner_omp(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:17195
int send_redirect_to_urn(struct MHD_Connection *connection, const char *urn, user_t *user)
Sends an HTTP redirection response to an urn.
Definition: gsad.c:3725
void free_resources(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Free resources.
Definition: gsad.c:1735
int gsad_base_init()
Base init.
Definition: gsad_base.c:82
GPtrArray * users
User session data.
Definition: gsad.c:309
char * download_ca_pub(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:15295
char * export_agents_omp(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:7717
#define USER_EXPIRED_TOKEN
Definition: gsad.c:479
void gsad_cleanup()
Cleanup routine for GSAD.
Definition: gsad.c:5376
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:812
char * new_permissions(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:21708
gchar * username
Login name.
Definition: gsad.c:384
char * export_credential_omp(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:6673
char * export_omp_doc_omp(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:20550
char * token
Session token.
Definition: gsad_base.h:73
const char * params_value(params_t *params, const char *name)
Get value of param.
Definition: gsad_base.c:682
char * export_report_format_omp(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:13609
char * exec_omp_get(struct MHD_Connection *connection, credentials_t *credentials, enum content_type *content_type, gchar **content_type_string, char **content_disposition, gsize *response_size, cmd_response_data_t *response_data)
Handle a complete GET request.
Definition: gsad.c:2852
void handle_signal_exit(int signal)
Handle a SIGINT signal.
Definition: gsad.c:5396
gboolean params_iterator_next(params_iterator_t *iterator, char **name, param_t **param)
Increment a params iterator.
Definition: gsad_base.c:858
GTree * last_filt_ids
Last used filter ids.
Definition: gsad.c:397
char * language
Language code e.g. en.
Definition: gsad.c:1694
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 * get_system_report_omp(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:18276
char * download_key_pub(credentials_t *credentials, params_t *params, gsize *response_size, cmd_response_data_t *response_data)
Get a Scanner's Certificate.
Definition: gsad_omp.c:15328
const gchar * vendor_version_get()
Get the vendor version.
Definition: gsad_base.c:148
int charts
Whether to show charts for this user.
Definition: gsad_base.h:85
char * export_task_omp(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:5104
char * pw_warning
Password policy warning message.
Definition: gsad_base.h:79
User information structure, for sessions.
Definition: gsad.c:380
char * get_info(credentials_t *credentials, params_t *params, const char *extra_xml, cmd_response_data_t *response_data)
Requests SecInfo.
Definition: gsad_omp.c:5403
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:503
gchar * redirect
HTTP status code.
Definition: gsad_base.h:94
void add_guest_chart_content_security_headers(struct MHD_Response *response)
Add guest chart content security headers to a MHD response.
Definition: gsad.c:367
gchar * http_content_security_policy
Current value for HTTP header "Content-Security-Policy".
Definition: gsad.c:319
char * xsl_transform(const char *xml_text, cmd_response_data_t *response_data)
XSL Transformation.
Definition: gsad_base.c:418
#define UTF8_ERROR_PAGE(location)
Definition: gsad.c:241
void init_validator()
Initialise the parameter validator.
Definition: gsad.c:963
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:483
volatile int termination_signal
Flag for signal handler.
Definition: gsad.c:200
#define USER_BAD_TOKEN
Definition: gsad.c:478
char * export_group_omp(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:20954
const char * ERROR_PAGE
Error page HTML.
Definition: gsad.c:224
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:329
int download_agent_omp(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:7219
#define MAX_HOST_LEN
Maximum length of the host portion of the redirect address.
Definition: gsad.c:3713
#define DEFAULT_GSAD_REDIRECT_PORT
Fallback GSAD port.
Definition: gsad.c:139
gboolean ignore_http_x_real_ip
Current preference for using X_Real_IP from HTTP header.
Definition: gsad.c:339
gchar * password
Password.
Definition: gsad.c:385
void add_security_headers(struct MHD_Response *response)
Add security headers to a MHD response.
Definition: gsad.c:350
#define params_iterator_init
Definition: gsad_base.h:187
char * current_page
Current page URL, for refresh.
Definition: gsad_base.h:75
gchar * role
Role.
Definition: gsad.c:386
char * cookie
Value of SID cookie param.
Definition: gsad.c:1693
char * export_port_list_omp(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:13438
const char * NOT_FOUND_MESSAGE
Main message for "Page not found" messages.
Definition: gsad.c:219
char * language
Accept-Language browser header.
Definition: gsad_base.h:77
gchar * redirect_location
Location for redirection server.
Definition: gsad.c:260
int user_set_timezone(const gchar *token, const gchar *timezone)
Set timezone of user.
Definition: gsad.c:634
char * export_targets_omp(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:11508
char * cookie
Cookie token.
Definition: gsad.c:382
char * save_my_settings_omp(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:19731
char * export_note_omp(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:13349
int use_secure_cookie
Whether to use a secure cookie.
Definition: gsad.c:289
char * export_target_omp(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:11486
#define DEFAULT_OPENVAS_MANAGER_PORT
Fallback Manager port.
Definition: gsad.c:144
int valid
Definition: gsad_base.h:150
int redirect_handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
HTTP request handler for GSAD.
Definition: gsad.c:3790
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:214
char * edit_group(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:20918
gchar * autorefresh
Auto-Refresh interval.
Definition: gsad.c:396
#define params_iterator_t
Definition: gsad_base.h:185
#define USER_OK
Definition: gsad.c:477
GCRY_THREAD_OPTION_PTHREAD_IMPL
Libgcrypt thread callback definition for libgcrypt < 1.6.0.
Definition: gsad.c:206
Headers for GSA's OMP communication module.
char * export_asset_omp(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:27727
char * save_chart_preference_omp(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:26406
#define POST_BUFFER_SIZE
Buffer size for POST processor.
Definition: gsad.c:149
int user_set_charts(const gchar *token, const int charts)
Set charts setting of user.
Definition: gsad.c:756
int label_name_set(const gchar *name)
Set the login label.
Definition: gsad_base.c:172
gchar * http_strict_transport_security
Current value of for HTTP header "Strict-Transport-Security".
Definition: gsad.c:334
params_t * values
Definition: gsad_base.h:149
int token_user_remove(const char *token)
Remove a user from the session "database", releasing the user_t too.
Definition: gsad.c:944
char * password
User's password.
Definition: gsad_base.h:70
char * export_filter_omp(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:24506
char * export_permissions_omp(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:22721
param_t * params_add(params_t *params, const char *name, const char *value)
Add a param.
Definition: gsad_base.c:779
#define DEFAULT_GSAD_GUEST_CHART_CONTENT_SECURITY_POLICY
Default guest charts value for HTTP header "Content-Security-Policy".
Definition: gsad.c:187
int handle_request(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
HTTP request handler for GSAD.
Definition: gsad.c:4174
#define DEFAULT_GSAD_CONTENT_SECURITY_POLICY
Default value for HTTP header "Content-Security-Policy".
Definition: gsad.c:174
enum content_type content_type
Content type of response.
Definition: gsad.c:1697
int token_user(const gchar *token, user_t **user_return)
Find a user, given a token.
Definition: gsad.c:902