diff --git a/admin/templates/default/config.tpl b/admin/templates/default/config.tpl
index d0a3101492..75877b260c 100644
--- a/admin/templates/default/config.tpl
+++ b/admin/templates/default/config.tpl
@@ -92,10 +92,10 @@
{lang_Enable_spellcheck_in_rich_text_editor}: |
|
@@ -266,15 +266,6 @@
-->
-
- {lang_Enable_the_soap_service} {lang_(default_No,_leave_it_off_if_you_dont_use_it)}: |
-
-
- |
-
{lang_How_many_entries_should_non-admins_be_able_to_export_(empty_=_no_limit,_no_=_no_export)}: {lang_This_controls_exports_and_merging.} |
|
diff --git a/phpgwapi/inc/class.egw_ckeditor_config.inc.php b/phpgwapi/inc/class.egw_ckeditor_config.inc.php
index 10891f4a6c..1ee342bc28 100644
--- a/phpgwapi/inc/class.egw_ckeditor_config.inc.php
+++ b/phpgwapi/inc/class.egw_ckeditor_config.inc.php
@@ -422,6 +422,11 @@ class egw_ckeditor_config
return json_encode(self::get_ckeditor_config_array($mode, $height, $expanded_toolbar, $start_path));
}
+ /**
+ * URL webspellchecker uses for scripts and style-sheets
+ */
+ const WEBSPELLCHECK_HOST = 'svc.webspellchecker.net';
+
/**
* Set for CK-Editor necessary CSP script-src attributes
*
@@ -430,11 +435,14 @@ class egw_ckeditor_config
public static function set_csp_script_src_attrs()
{
$attrs = array('unsafe-eval', 'unsafe-inline');
+ $url = ($_SERVER['HTTPS'] ? 'https://' : 'http://').self::WEBSPELLCHECK_HOST;
// if webspellchecker is enabled in EGroupware config, allow access to it's url
if (in_array($GLOBALS['egw_info']['server']['enabled_spellcheck'], array('True', 'YesUseWebSpellCheck')))
{
- $attrs[] = 'https://svc.webspellchecker.net';
+ $attrs[] = $url;
+
+ egw_framework::csp_style_src_attrs($url);
}
//error_log(__METHOD__."() egw_info[server][enabled_spellcheck]='{$GLOBALS['egw_info']['server']['enabled_spellcheck']}' --> attrs=".array2string($attrs));
// tell framework CK Editor needs eval and inline javascript :(
diff --git a/phpgwapi/inc/class.egw_framework.inc.php b/phpgwapi/inc/class.egw_framework.inc.php
index 67772c395d..131c1f8b12 100644
--- a/phpgwapi/inc/class.egw_framework.inc.php
+++ b/phpgwapi/inc/class.egw_framework.inc.php
@@ -101,7 +101,7 @@ abstract class egw_framework
*
* EGroupware itself currently still requires 'unsafe-eval'!
*
- * @param string|array $set=array() 'unsafe-eval' and/or 'unsafe-inline' (without quotes!)
+ * @param string|array $set =array() 'unsafe-eval' and/or 'unsafe-inline' (without quotes!) or URL (incl. protocol!)
* @return string with attributes eg. "'unsafe-eval' 'unsafe-inline'"
*/
public static function csp_script_src_attrs($set=null)
@@ -122,6 +122,41 @@ abstract class egw_framework
return implode(' ', self::$csp_script_src_attrs);
}
+ /**
+ * Additional attributes or urls for CSP style-src 'self'
+ *
+ * 'unsafe-inline' is currently allways added, as it is used in a couple of places.
+ *
+ * @var array
+ */
+ private static $csp_style_src_attrs = array("'unsafe-inline'");
+
+ /**
+ * Set/get Content-Security-Policy attributes for style-src: 'unsafe-inline'
+ *
+ * EGroupware itself currently still requires 'unsafe-inline'!
+ *
+ * @param string|array $set =array() 'unsafe-inline' (without quotes!) and/or URL (incl. protocol!)
+ * @return string with attributes eg. "'unsafe-inline'"
+ */
+ public static function csp_style_src_attrs($set=null)
+ {
+ foreach((array)$set as $attr)
+ {
+ if (in_array($attr, array('none', 'self', 'unsafe-inline')))
+ {
+ $attr = "'$attr'"; // automatic add quotes
+ }
+ if (!in_array($attr, self::$csp_style_src_attrs))
+ {
+ self::$csp_style_src_attrs[] = $attr;
+ //error_log(__METHOD__."() setting CSP script-src $attr ".function_backtrace());
+ }
+ }
+ //error_log(__METHOD__."(".array2string($set).") returned ".array2string(implode(' ', self::$csp_script_src_attrs)).' '.function_backtrace());
+ return implode(' ', self::$csp_style_src_attrs);
+ }
+
/**
* Query additional CSP frame-src from current app
*
@@ -146,11 +181,13 @@ abstract class egw_framework
// - "style-src 'self' 'unsave-inline'" allows only self and inline style, which we need
// - "frame-src 'self' manual.egroupware.org" allows frame and iframe content only for self or manual.egroupware.org
$frame_src = array("'self'", 'manual.egroupware.org');
- if (($additional = $this->_get_csp_frame_src())) $frame_src = array_merge($frame_src, $additional);
+ if (($additional = $this->_get_csp_frame_src())) $frame_src = array_unique(array_merge($frame_src, $additional));
+
+ $csp = "script-src 'self' ".self::csp_script_src_attrs().
+ "; connect-src 'self'".
+ "; style-src 'self' ".self::csp_style_src_attrs().
+ "; frame-src ".implode(' ', $frame_src);
- $csp = "script-src 'self' ".($script_attrs=self::csp_script_src_attrs()).
- "; connect-src 'self'; style-src 'self' 'unsafe-inline'; frame-src ".implode(' ', $frame_src);
- //error_log(__METHOD__."() script_attrs=$script_attrs");
//$csp = "default-src * 'unsafe-eval' 'unsafe-inline'"; // allow everything
header("Content-Security-Policy: $csp");
header("X-Webkit-CSP: $csp"); // Chrome: <= 24, Safari incl. iOS
@@ -446,7 +483,7 @@ abstract class egw_framework
{
//allow to include JSONP file with social media urls from egroupware.org
self::csp_script_src_attrs('https://www.egroupware.org');
-
+
//error_log(__METHOD__."() server[template_dir]=".array2string($GLOBALS['egw_info']['server']['template_dir']).", this->template=$this->template, this->template_dir=$this->template_dir, get_class(this)=".get_class($this));
$tmpl = new Template($GLOBALS['egw_info']['server']['template_dir']);
diff --git a/setup/inc/class.setup_process.inc.php b/setup/inc/class.setup_process.inc.php
index 6a28e51038..15484dd2d7 100755
--- a/setup/inc/class.setup_process.inc.php
+++ b/setup/inc/class.setup_process.inc.php
@@ -240,8 +240,8 @@ class setup_process
{
unset($current_config['aspell_path']);
}
- // always enable spellchecker, ckeditor now uses spell-as-you-type via a public webservice
- $current_config['enabled_spellcheck'] = 'True';
+ // always enable browser based spellchecker
+ $current_config['enabled_spellcheck'] = 'YesBrowserBased';
// always enable history logging for calendar, addressbook and infolog
$current_config['history'] = 'history'; // addressbook: only admin