diff --git a/administrator/components/com_config/Controller/ApplicationController.php b/administrator/components/com_config/Controller/ApplicationController.php index a5a4a930672a4..2e1ee55a53c93 100644 --- a/administrator/components/com_config/Controller/ApplicationController.php +++ b/administrator/components/com_config/Controller/ApplicationController.php @@ -145,6 +145,29 @@ public function save() return false; } + // Validate database connection data. + $data = $return; + $return = $model->validateDbConnection($data); + + // Check for validation errors. + if ($return === false) + { + /* + * The validateDbConnection method enqueued all messages for us. + */ + + // Save the posted data in the session. + $this->app->setUserState('com_config.config.global.data', $data); + + // Redirect back to the edit screen. + $this->setRedirect(Route::_('index.php?option=com_config', false)); + + return false; + } + + // Save the validated data in the session. + $this->app->setUserState('com_config.config.global.data', $return); + // Attempt to save the configuration. $data = $return; $return = $model->save($data); diff --git a/administrator/components/com_config/Model/ApplicationModel.php b/administrator/components/com_config/Model/ApplicationModel.php index d753aa639653a..191e570d97582 100644 --- a/administrator/components/com_config/Model/ApplicationModel.php +++ b/administrator/components/com_config/Model/ApplicationModel.php @@ -111,6 +111,167 @@ public function getData() return $data; } + /** + * Method to validate the db connection properties. + * + * @param array $data An array containing all global config data. + * + * @return array|boolean Array with the validated global config data or boolean false on a validation failure. + * + * @since 4.0.0 + */ + public function validateDbConnection($data) + { + // Validate database connection encryption options + if ((int) $data['dbencryption'] === 0) + { + // Reset unused options + if (!empty($data['dbsslkey'])) + { + $data['dbsslkey'] = ''; + } + + if (!empty($data['dbsslcert'])) + { + $data['dbsslcert'] = ''; + } + + if ((bool) $data['dbsslverifyservercert'] === true) + { + $data['dbsslverifyservercert'] = false; + } + + if (!empty($data['dbsslca'])) + { + $data['dbsslca'] = ''; + } + + if (!empty($data['dbsslcipher'])) + { + $data['dbsslcipher'] = ''; + } + } + else + { + // Check localhost + if (strtolower($data['host']) === 'localhost') + { + Factory::getApplication()->enqueueMessage(Text::_('COM_CONFIG_ERROR_DATABASE_ENCRYPTION_LOCALHOST'), 'error'); + + return false; + } + + // Check CA file and folder depending on database type if server certificate verification + if ((bool) $data['dbsslverifyservercert'] === true) + { + if (empty($data['dbsslca'])) + { + Factory::getApplication()->enqueueMessage( + Text::sprintf( + 'COM_CONFIG_ERROR_DATABASE_ENCRYPTION_FILE_FIELD_EMPTY', + Text::_('COM_CONFIG_FIELD_DATABASE_ENCRYPTION_CA_LABEL') + ), + 'error' + ); + + return false; + } + + if (!File::exists(Path::clean($data['dbsslca']))) + { + Factory::getApplication()->enqueueMessage( + Text::sprintf( + 'COM_CONFIG_ERROR_DATABASE_ENCRYPTION_FILE_FIELD_BAD', + Text::_('COM_CONFIG_FIELD_DATABASE_ENCRYPTION_CA_LABEL') + ), + 'error' + ); + + return false; + } + } + else + { + // Reset unused option + if (!empty($data['dbsslca'])) + { + $data['dbsslca'] = ''; + } + } + + // Check key and certificate if two-way encryption + if ((int) $data['dbencryption'] === 2) + { + if (empty($data['dbsslkey'])) + { + Factory::getApplication()->enqueueMessage( + Text::sprintf( + 'COM_CONFIG_ERROR_DATABASE_ENCRYPTION_FILE_FIELD_EMPTY', + Text::_('COM_CONFIG_FIELD_DATABASE_ENCRYPTION_KEY_LABEL') + ), + 'error' + ); + + return false; + } + + if (!File::exists(Path::clean($data['dbsslkey']))) + { + Factory::getApplication()->enqueueMessage( + Text::sprintf( + 'COM_CONFIG_ERROR_DATABASE_ENCRYPTION_FILE_FIELD_BAD', + Text::_('COM_CONFIG_FIELD_DATABASE_ENCRYPTION_KEY_LABEL') + ), + 'error' + ); + + return false; + } + + if (empty($data['dbsslcert'])) + { + Factory::getApplication()->enqueueMessage( + Text::sprintf( + 'COM_CONFIG_ERROR_DATABASE_ENCRYPTION_FILE_FIELD_EMPTY', + Text::_('COM_CONFIG_FIELD_DATABASE_ENCRYPTION_CERT_LABEL') + ), + 'error' + ); + + return false; + } + + if (!File::exists(Path::clean($data['dbsslcert']))) + { + Factory::getApplication()->enqueueMessage( + Text::sprintf( + 'COM_CONFIG_ERROR_DATABASE_ENCRYPTION_FILE_FIELD_BAD', + Text::_('COM_CONFIG_FIELD_DATABASE_ENCRYPTION_CERT_LABEL') + ), + 'error' + ); + + return false; + } + } + else + { + // Reset unused options + if (!empty($data['dbsslkey'])) + { + $data['dbsslkey'] = ''; + } + + if (!empty($data['dbsslcert'])) + { + $data['dbsslcert'] = ''; + } + } + } + + return $data; + } + /** * Method to save the configuration data. * @@ -141,7 +302,7 @@ public function save($data) 'verify_server_cert' => (bool) $data['dbsslverifyservercert'], ]; - foreach (['cipher', 'ca', 'capath', 'key', 'cert'] as $value) + foreach (['cipher', 'ca', 'key', 'cert'] as $value) { $confVal = trim($data['dbssl' . $value]); @@ -164,6 +325,20 @@ public function save($data) return false; } + if ((int) $data['dbencryption'] !== 0 && empty($revisedDbo->getConnectionEncryption())) + { + if ($revisedDbo->isConnectionEncryptionSupported()) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_CONFIG_ERROR_DATABASE_ENCRYPTION_CONN_NOT_ENCRYPT'), 'error'); + } + else + { + Factory::getApplication()->enqueueMessage(Text::_('COM_CONFIG_ERROR_DATABASE_ENCRYPTION_SRV_NOT_SUPPORTS'), 'error'); + } + + return false; + } + // Check if we can set the Force SSL option if ((int) $data['force_ssl'] !== 0 && (int) $data['force_ssl'] !== (int) $app->get('force_ssl', '0')) { diff --git a/administrator/components/com_config/forms/application.xml b/administrator/components/com_config/forms/application.xml index 152d52be27d08..c73bdb73165f9 100644 --- a/administrator/components/com_config/forms/application.xml +++ b/administrator/components/com_config/forms/application.xml @@ -201,7 +201,6 @@ label="COM_CONFIG_FIELD_DATABASE_HOST_LABEL" required="true" filter="string" - onchange="Joomla.resetDbEncryptionFields(this)" size="30" /> @@ -235,63 +234,50 @@ - - - - - - - - + + + + name="dbsslverifyservercert" + type="radio" + label="COM_CONFIG_FIELD_DATABASE_ENCRYPTION_VERIFY_SERVER_CERT_LABEL" + class="switcher" + default="0" + filter="boolean" + showon="dbencryption:1,2" + > + + + diff --git a/administrator/components/com_config/tmpl/application/default.php b/administrator/components/com_config/tmpl/application/default.php index 6c29ed5e4f4f9..d091dd0a64e03 100644 --- a/administrator/components/com_config/tmpl/application/default.php +++ b/administrator/components/com_config/tmpl/application/default.php @@ -19,9 +19,6 @@ HTMLHelper::_('behavior.formvalidator'); HTMLHelper::_('behavior.keepalive'); -// Load config JS -HTMLHelper::_('script', 'com_config/admin-config-default.js', ['version' => 'auto', 'relative' => true]); - // Load JS message titles Text::script('ERROR'); Text::script('WARNING'); diff --git a/administrator/language/en-GB/com_config.ini b/administrator/language/en-GB/com_config.ini index 01887044cbfc4..2fc6dc72976a2 100644 --- a/administrator/language/en-GB/com_config.ini +++ b/administrator/language/en-GB/com_config.ini @@ -20,6 +20,11 @@ COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE="Could not make configuration.p COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE="Could not make configuration.php writable." COM_CONFIG_ERROR_CUSTOM_CACHE_PATH_NOTWRITABLE_USING_DEFAULT="The folder at %1$s is not writable and cannot be used for the cache, using the default %2$s instead." COM_CONFIG_ERROR_CUSTOM_SESSION_FILESYSTEM_PATH_NOTWRITABLE_USING_DEFAULT="The folder at %s is not writable and cannot be used to store session data, the default PHP path will be used instead." +COM_CONFIG_ERROR_DATABASE_ENCRYPTION_CONN_NOT_ENCRYPT="You have selected database connection enryption to be used, and a connection could be established, but it was not encrypted. The reason might be that the database server is configured to fall back to an unencrypted connection in case of bad encryption parameters. Either check and correct the database encryption parameters, or change field \"Connection Encryption\" back to \"Default (server controlled)\"." +COM_CONFIG_ERROR_DATABASE_ENCRYPTION_FILE_FIELD_BAD="The file entered in field \"%s\" does not exist or is not accessible." +COM_CONFIG_ERROR_DATABASE_ENCRYPTION_FILE_FIELD_EMPTY="Field \"%s\" is empty or doesn't contain a valid path." +COM_CONFIG_ERROR_DATABASE_ENCRYPTION_LOCALHOST="You have entered \"localhost\" as host name. Connecting to the database with connection encryption might fail with this. Either change \"localhost\" to \"127.0.0.1\" or \"::1\" or a different host name, or change field \"Connection Encryption\" back to \"Default (server controlled)\"." +COM_CONFIG_ERROR_DATABASE_ENCRYPTION_SRV_NOT_SUPPORTS="The database server doesn't support connection encryption. Either enable TLS (often called SSL in docs) support on your database server, or change field \"Connection Encryption\" back to \"Default (server controlled)\"." COM_CONFIG_ERROR_DATABASE_NOT_AVAILABLE="Database connection test failed with the following error: %s: %s
Database connection settings changes were not saved." COM_CONFIG_ERROR_ROOT_ASSET_NOT_FOUND="The asset for global configuration could not be found. Permissions have not been saved." COM_CONFIG_ERROR_SSL_NOT_AVAILABLE="HTTPS has not been enabled as it is not available on this server. HTTPS connection test failed with the following error: %s" @@ -37,14 +42,13 @@ COM_CONFIG_FIELD_COOKIE_DOMAIN_DESC="Precede domain with '.' if cookie should be COM_CONFIG_FIELD_COOKIE_DOMAIN_LABEL="Cookie Domain" COM_CONFIG_FIELD_COOKIE_PATH_LABEL="Cookie Path" COM_CONFIG_FIELD_DATABASE_ENCRYPTION_CA_LABEL="Path to CA File" -COM_CONFIG_FIELD_DATABASE_ENCRYPTION_CAPATH_LABEL="Path to CA Folder" COM_CONFIG_FIELD_DATABASE_ENCRYPTION_CERT_LABEL="Path to Certificate File" -COM_CONFIG_FIELD_DATABASE_ENCRYPTION_CIPHER_LABEL="Supported Cipher Suite" -COM_CONFIG_FIELD_DATABASE_ENCRYPTION_ENABLE_LABEL="Connection Encryption" -COM_CONFIG_FIELD_DATABASE_ENCRYPTION_ENABLE_VALUE_NONE="Default (server controlled)" -COM_CONFIG_FIELD_DATABASE_ENCRYPTION_ENABLE_VALUE_ONE_WAY="One-way encryption" -COM_CONFIG_FIELD_DATABASE_ENCRYPTION_ENABLE_VALUE_TWO_WAY="Two-way encryption" +COM_CONFIG_FIELD_DATABASE_ENCRYPTION_CIPHER_LABEL="Supported Cipher Suite (optional)" COM_CONFIG_FIELD_DATABASE_ENCRYPTION_KEY_LABEL="Path to Private Key File" +COM_CONFIG_FIELD_DATABASE_ENCRYPTION_MODE_LABEL="Connection Encryption" +COM_CONFIG_FIELD_DATABASE_ENCRYPTION_MODE_VALUE_NONE="Default (server controlled)" +COM_CONFIG_FIELD_DATABASE_ENCRYPTION_MODE_VALUE_ONE_WAY="One-way authentication" +COM_CONFIG_FIELD_DATABASE_ENCRYPTION_MODE_VALUE_TWO_WAY="Two-way authentication" COM_CONFIG_FIELD_DATABASE_ENCRYPTION_VERIFY_SERVER_CERT_LABEL="Verify Server Certificate" COM_CONFIG_FIELD_DATABASE_HOST_LABEL="Host" COM_CONFIG_FIELD_DATABASE_NAME_LABEL="Database Name" diff --git a/build/media_source/com_config/js/admin-config-default.es6.js b/build/media_source/com_config/js/admin-config-default.es6.js deleted file mode 100644 index 666d161faeb3f..0000000000000 --- a/build/media_source/com_config/js/admin-config-default.es6.js +++ /dev/null @@ -1,25 +0,0 @@ -Joomla = window.Joomla || {}; - -((Joomla) => { - 'use strict'; - - /** - * Method reset DB Encryption fields when localhost is chosen - * - * @param {HTMLElement} element The element that initiates the call - * @returns {void} - * @since 4.0 - */ - Joomla.resetDbEncryptionFields = (element) => { - if (element.value === 'localhost') { - document.getElementById('jform_dbsslverifyservercert0').checked = true; - document.getElementById('jform_dbsslverifyservercert1').checked = false; - document.getElementById('jform_dbsslkey').value = ''; - document.getElementById('jform_dbsslcert').value = ''; - document.getElementById('jform_dbsslca').value = ''; - document.getElementById('jform_dbsslcapath').value = ''; - document.getElementById('jform_dbsslcipher').value = ''; - document.getElementById('jform_dbencryption').value = 0; - } - }; -})(Joomla); diff --git a/installation/configuration.php-dist b/installation/configuration.php-dist index dbaebecebe0fc..572dc36803405 100644 --- a/installation/configuration.php-dist +++ b/installation/configuration.php-dist @@ -49,7 +49,6 @@ class JConfig public $dbsslkey = ''; public $dbsslcert = ''; public $dbsslca = ''; - public $dbsslcapath = ''; public $dbsslcipher = ''; /* Server Settings */ diff --git a/installation/src/Model/ConfigurationModel.php b/installation/src/Model/ConfigurationModel.php index c39986f8c7356..8e8f5efd5f24a 100644 --- a/installation/src/Model/ConfigurationModel.php +++ b/installation/src/Model/ConfigurationModel.php @@ -138,7 +138,6 @@ public function createConfiguration($options) $registry->set('dbsslkey', ''); $registry->set('dbsslcert', ''); $registry->set('dbsslca', ''); - $registry->set('dbsslcapath', ''); $registry->set('dbsslcipher', ''); // Server settings. diff --git a/libraries/src/Factory.php b/libraries/src/Factory.php index d7aaa84f01d4c..fcfd94e189f71 100644 --- a/libraries/src/Factory.php +++ b/libraries/src/Factory.php @@ -674,7 +674,7 @@ protected static function createDbo() 'verify_server_cert' => (bool) $conf->get('dbsslverifyservercert'), ]; - foreach (['cipher', 'ca', 'capath', 'key', 'cert'] as $value) + foreach (['cipher', 'ca', 'key', 'cert'] as $value) { $confVal = trim($conf->get('dbssl' . $value, '')); diff --git a/libraries/src/Service/Provider/Database.php b/libraries/src/Service/Provider/Database.php index 5fad50698e1fc..39ddb9ed41bd2 100644 --- a/libraries/src/Service/Provider/Database.php +++ b/libraries/src/Service/Provider/Database.php @@ -97,7 +97,7 @@ function (Container $container) 'verify_server_cert' => (bool) $conf->get('dbsslverifyservercert'), ]; - foreach (['cipher', 'ca', 'capath', 'key', 'cert'] as $value) + foreach (['cipher', 'ca', 'key', 'cert'] as $value) { $confVal = trim($conf->get('dbssl' . $value, ''));