Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/global.ini.php27
-rw-r--r--core/Db/Adapter/Mysqli.php22
-rw-r--r--core/Db/Adapter/Pdo/Mysql.php22
-rw-r--r--libs/Zend/Db/Adapter/Mysqli.php40
-rw-r--r--plugins/Diagnostics/Diagnostic/DbOverSSLCheck.php62
-rw-r--r--plugins/Diagnostics/config/config.php1
-rw-r--r--plugins/Installation/lang/en.json6
-rw-r--r--tests/PHPUnit/Integration/DbSSLTest.php30
8 files changed, 207 insertions, 3 deletions
diff --git a/config/global.ini.php b/config/global.ini.php
index ea707a097e..e51cd09561 100644
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -21,6 +21,25 @@ port = 3306
adapter = PDO\MYSQL
type = InnoDB
schema = Mysql
+
+; Database SSL Options START
+; Turn on or off SSL connection to database, possible values for enable_ssl: 1 or 0
+enable_ssl = 0
+; Direct path to server CA file, CA bundle supported (required for ssl connection)
+ssl_ca =
+; Direct path to client cert file (optional)
+ssl_cert =
+; Direct path to client key file (optional)
+ssl_key =
+; Direct path to CA cert files directory (optional)
+ssl_ca_path =
+; List of one or more ciphers for SSL encryption, in OpenSSL format (optional)
+ssl_cipher =
+; Whether to skip verification of self signed certificates (optional, only supported
+; w/ specific PHP versions, and is mostly for testing purposes)
+ssl_no_verify =
+; Database SSL Options END
+
; if charset is set to utf8, Matomo will ensure that it is storing its data using UTF8 charset.
; it will add a sql query SET at each page view.
; Matomo should work correctly without this setting but we recommend to have a charset set.
@@ -37,6 +56,13 @@ adapter = PDO\MYSQL
type = InnoDB
schema = Mysql
charset = utf8
+enable_ssl = 0
+ssl_ca =
+ssl_cert =
+ssl_key =
+ssl_ca_path =
+ssl_cipher =
+ssl_no_verify = 1
[tests]
; needed in order to run tests.
@@ -904,4 +930,3 @@ SDK_batch_size = 10
SDK_interval_value = 30
; NOTE: do not directly edit this file! See notice at the top
-
diff --git a/core/Db/Adapter/Mysqli.php b/core/Db/Adapter/Mysqli.php
index 396ab60343..4c8c7fed81 100644
--- a/core/Db/Adapter/Mysqli.php
+++ b/core/Db/Adapter/Mysqli.php
@@ -29,6 +29,28 @@ class Mysqli extends Zend_Db_Adapter_Mysqli implements AdapterInterface
{
// Enable LOAD DATA INFILE
$config['driver_options'][MYSQLI_OPT_LOCAL_INFILE] = true;
+
+ if ($config['enable_ssl']) {
+ if (!empty($config['ssl_key'])) {
+ $config['driver_options']['ssl_key'] = $config['ssl_key'];
+ }
+ if (!empty($config['ssl_cert'])) {
+ $config['driver_options']['ssl_cert'] = $config['ssl_cert'];
+ }
+ if (!empty($config['ssl_ca'])) {
+ $config['driver_options']['ssl_ca'] = $config['ssl_ca'];
+ }
+ if (!empty($config['ssl_ca_path'])) {
+ $config['driver_options']['ssl_ca_path'] = $config['ssl_ca_path'];
+ }
+ if (!empty($config['ssl_cipher'])) {
+ $config['driver_options']['ssl_cipher'] = $config['ssl_cipher'];
+ }
+ if (!empty($config['ssl_no_verify'])) {
+ $config['driver_options']['ssl_no_verify'] = $config['ssl_no_verify'];
+ }
+ }
+
parent::__construct($config);
}
diff --git a/core/Db/Adapter/Pdo/Mysql.php b/core/Db/Adapter/Pdo/Mysql.php
index 360e6a57e8..b9b250081f 100644
--- a/core/Db/Adapter/Pdo/Mysql.php
+++ b/core/Db/Adapter/Pdo/Mysql.php
@@ -35,6 +35,28 @@ class Mysql extends Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
if (defined('PDO::MYSQL_ATTR_LOCAL_INFILE')) {
$config['driver_options'][PDO::MYSQL_ATTR_LOCAL_INFILE] = true;
}
+ if ($config['enable_ssl']) {
+ if (!empty($config['ssl_key'])) {
+ $config['driver_options'][PDO::MYSQL_ATTR_SSL_KEY] = $config['ssl_key'];
+ }
+ if (!empty($config['ssl_cert'])) {
+ $config['driver_options'][PDO::MYSQL_ATTR_SSL_CERT] = $config['ssl_cert'];
+ }
+ if (!empty($config['ssl_ca'])) {
+ $config['driver_options'][PDO::MYSQL_ATTR_SSL_CA] = $config['ssl_ca'];
+ }
+ if (!empty($config['ssl_ca_path'])) {
+ $config['driver_options'][PDO::MYSQL_ATTR_SSL_CAPATH] = $config['ssl_ca_path'];
+ }
+ if (!empty($config['ssl_cipher'])) {
+ $config['driver_options'][PDO::MYSQL_ATTR_SSL_CIPHER] = $config['ssl_cipher'];
+ }
+ if (!empty($config['ssl_no_verify'])
+ && defined('PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT')
+ ) {
+ $config['driver_options'][PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = false;
+ }
+ }
parent::__construct($config);
}
diff --git a/libs/Zend/Db/Adapter/Mysqli.php b/libs/Zend/Db/Adapter/Mysqli.php
index 84dd9cab0b..e94ec26b37 100644
--- a/libs/Zend/Db/Adapter/Mysqli.php
+++ b/libs/Zend/Db/Adapter/Mysqli.php
@@ -299,9 +299,21 @@ class Zend_Db_Adapter_Mysqli extends Zend_Db_Adapter_Abstract
$this->_connection = mysqli_init();
+ $enable_ssl = false;
+ $ssl_options = array (
+ 'ssl_ca' => null,
+ 'ssl_ca_path' => null,
+ 'ssl_cert' => null,
+ 'ssl_cipher' => null,
+ 'ssl_key' => null,
+ );
+
if(!empty($this->_config['driver_options'])) {
foreach($this->_config['driver_options'] as $option=>$value) {
- if(is_string($option)) {
+ if(array_key_exists($option, $ssl_options)) {
+ $ssl_options[$option] = $value;
+ $enable_ssl = true;
+ } elseif(is_string($option)) {
// Suppress warnings here
// Ignore it if it's not a valid constant
$option = @constant(strtoupper($option));
@@ -312,6 +324,28 @@ class Zend_Db_Adapter_Mysqli extends Zend_Db_Adapter_Abstract
}
}
+
+ if ($enable_ssl) {
+ mysqli_ssl_set(
+ $this->_connection,
+ $ssl_options['ssl_key'],
+ $ssl_options['ssl_cert'],
+ $ssl_options['ssl_ca'],
+ $ssl_options['ssl_ca_path'],
+ $ssl_options['ssl_cipher']
+ );
+ }
+
+ $flags = null;
+ if ($enable_ssl) {
+ $flags = MYSQLI_CLIENT_SSL;
+ if (!empty($this->_config['driver_options']['ssl_no_verify'])
+ && defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT')
+ ) {
+ $flags = MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT;
+ }
+ }
+
// Suppress connection warnings here.
// Throw an exception instead.
$_isConnected = @mysqli_real_connect(
@@ -320,7 +354,9 @@ class Zend_Db_Adapter_Mysqli extends Zend_Db_Adapter_Abstract
$this->_config['username'],
$this->_config['password'],
$this->_config['dbname'],
- $port
+ $port,
+ $socket = null,
+ $enable_ssl ? $flags : null
);
if ($_isConnected === false || mysqli_connect_errno()) {
diff --git a/plugins/Diagnostics/Diagnostic/DbOverSSLCheck.php b/plugins/Diagnostics/Diagnostic/DbOverSSLCheck.php
new file mode 100644
index 0000000000..07b8942da5
--- /dev/null
+++ b/plugins/Diagnostics/Diagnostic/DbOverSSLCheck.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Piwik\Plugins\Diagnostics\Diagnostic;
+
+use Piwik\Common;
+use Piwik\Config;
+use Piwik\Db;
+use Piwik\Translation\Translator;
+
+/**
+ * Check if Piwik is connected with database through ssl.
+ */
+class DbOverSSLCheck implements Diagnostic
+{
+ /**
+ * @var Translator
+ */
+ private $translator;
+
+ public function __construct(Translator $translator)
+ {
+ $this->translator = $translator;
+ }
+
+ public function execute()
+ {
+ $enable_ssl = Config::getInstance()->database['enable_ssl'];
+ if (!$enable_ssl) {
+ return array();
+ }
+
+ $label = $this->translator->translate('Installation_SystemCheckDatabaseSSL');
+
+ $cipher = Db::fetchRow("show status like 'Ssl_cipher'");
+ if(!empty($cipher['Value'])) {
+ return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, $this->translator->translate('Installation_SystemCheckDatabaseSSLCipher') . ': ' . $cipher['Value']));
+ }
+
+ //no cipher, not working
+ $comment = sprintf($this->translator->translate('Installation_SystemCheckDatabaseSSLNotWorking'), "enable_ssl") . "<br />";
+
+ // test ssl support
+ $ssl_support = Db::fetchRow("SHOW VARIABLES LIKE 'have_ssl'");
+ if(!empty($ssl_support['Value'])) {
+ switch ($ssl_support['Value']) {
+ case 'YES':
+ $comment .= $this->translator->translate('Installation_SystemCheckDatabaseSSLOn');
+ break;
+ case 'DISABLED':
+ $comment .= $this->translator->translate('Installation_SystemCheckDatabaseSSLDisabled');
+ break;
+ case 'NO':
+ $comment .= $this->translator->translate('Installation_SystemCheckDatabaseSSLNo');
+ break;
+ }
+ }
+
+ $comment .= '<br />' . '<a target="_blank" href="?module=Proxy&action=redirect&url=http://piwik.org/faq/"> FAQ on piwik.org</a>';
+
+ return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment));
+ }
+}
diff --git a/plugins/Diagnostics/config/config.php b/plugins/Diagnostics/config/config.php
index 566b476535..4e300166e7 100644
--- a/plugins/Diagnostics/config/config.php
+++ b/plugins/Diagnostics/config/config.php
@@ -24,6 +24,7 @@ return array(
DI\get('Piwik\Plugins\Diagnostics\Diagnostic\NfsDiskCheck'),
DI\get('Piwik\Plugins\Diagnostics\Diagnostic\CronArchivingCheck'),
DI\get('Piwik\Plugins\Diagnostics\Diagnostic\LoadDataInfileCheck'),
+ Di\get('Piwik\Plugins\Diagnostics\Diagnostic\DbOverSSLCheck'),
),
// Allows other plugins to disable diagnostics that were previously registered
'diagnostics.disabled' => array(),
diff --git a/plugins/Installation/lang/en.json b/plugins/Installation/lang/en.json
index 406a499200..d6812de344 100644
--- a/plugins/Installation/lang/en.json
+++ b/plugins/Installation/lang/en.json
@@ -72,6 +72,12 @@
"SystemCheckCreateFunctionHelp": "Matomo uses anonymous functions for callbacks.",
"SystemCheckDatabaseExtensions": "MySQL extensions",
"SystemCheckDatabaseHelp": "Matomo requires either the mysqli extension or both the PDO and pdo_mysql extensions.",
+ "SystemCheckDatabaseSSL": "Database SSL Connection",
+ "SystemCheckDatabaseSSLCipher": "SSL cipher being used",
+ "SystemCheckDatabaseSSLDisabled": "SSL support in your database server is disabled",
+ "SystemCheckDatabaseSSLNo": "Database server is not compiled with SSL support",
+ "SystemCheckDatabaseSSLNotWorking": "%s is set to '1' but SSL connection is not working",
+ "SystemCheckDatabaseSSLOn": "Your database supports SSL connections but SSL connection is not used. Check your database SSL settings in your Matomo config file",
"SystemCheckDebugBacktraceHelp": "View::factory won't be able to create views for the calling module.",
"SystemCheckError": "An error occured - must be fixed before you proceed",
"SystemCheckEvalHelp": "Required by HTML QuickForm and Smarty templating system.",
diff --git a/tests/PHPUnit/Integration/DbSSLTest.php b/tests/PHPUnit/Integration/DbSSLTest.php
new file mode 100644
index 0000000000..30b554e884
--- /dev/null
+++ b/tests/PHPUnit/Integration/DbSSLTest.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Tests\Integration;
+
+use Piwik\Db;
+use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
+use Piwik\Config;
+
+/**
+ * @group Core
+ */
+class DbSSLTest extends IntegrationTestCase
+{
+ public function testMysqlSSLConnection() {
+ $dbConfig = Config::getInstance()->database;
+ if(isset($dbConfig['enable_ssl']) && $dbConfig['enable_ssl'] == true) {
+ Db::createDatabaseObject($dbConfig);
+ $cipher = Db::fetchRow("show status like 'Ssl_cipher'");
+ $this->assertNotEmpty($cipher['Value']);
+ } else {
+ $this->markTestSkipped(true);
+ }
+ }
+}