summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--application/config/database.php12
-rw-r--r--system/database/drivers/mysqli/mysqli_driver.php49
-rw-r--r--system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php31
-rw-r--r--user_guide_src/source/changelog.rst1
-rw-r--r--user_guide_src/source/database/configuration.rst20
5 files changed, 104 insertions, 9 deletions
diff --git a/application/config/database.php b/application/config/database.php
index 84aab9169..bf9857fff 100644
--- a/application/config/database.php
+++ b/application/config/database.php
@@ -40,9 +40,21 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| Sites using Latin-1 or UTF-8 database character set and collation are unaffected.
| ['swap_pre'] A default table prefix that should be swapped with the dbprefix
| ['encrypt'] Whether or not to use an encrypted connection.
+|
+| 'mysql' (deprecated), 'sqlsrv' and 'pdo/sqlsrv' drivers accept TRUE/FALSE
+| 'mysqli' and 'pdo/mysql' drivers accept an array with the following options:
+|
+| 'ssl_key' - Path to the private key file
+| 'ssl_cert' - Path to the public key certificate file
+| 'ssl_ca' - Path to the certificate authority file
+| 'ssl_capath' - Path to a directory containing trusted CA certificats in PEM format
+| 'ssl_cipher' - List of *allowed* ciphers to be used for the encryption, separated by colons (':')
+| 'ssl_verify' - TRUE/FALSE; Whether verify the server certificate or not ('mysqli' only)
+|
| ['compress'] Whether or not to use client compression (MySQL only)
| ['stricton'] TRUE/FALSE - forces 'Strict Mode' connections
| - good for ensuring strict SQL while developing
+| ['ssl_options'] Used to set various SSL options that can be used when making SSL connections.
| ['failover'] array - A array with 0 or more data for connections if the main should fail.
| ['save_queries'] TRUE/FALSE - Whether to "save" all executed queries.
| NOTE: Disabling this will also effectively disable both
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index e953db052..dd3cc77c6 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -102,7 +102,6 @@ class CI_DB_mysqli_driver extends CI_DB {
*
* @param bool $persistent
* @return object
- * @todo SSL support
*/
public function db_connect($persistent = FALSE)
{
@@ -132,8 +131,52 @@ class CI_DB_mysqli_driver extends CI_DB {
$mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode="STRICT_ALL_TABLES"');
}
- return $mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags)
- ? $mysqli : FALSE;
+ if (is_array($this->encrypt))
+ {
+ $ssl = array();
+ empty($this->encrypt['ssl_key']) OR $ssl['key'] = $this->encrypt['ssl_key'];
+ empty($this->encrypt['ssl_cert']) OR $ssl['cert'] = $this->encrypt['ssl_cert'];
+ empty($this->encrypt['ssl_ca']) OR $ssl['ca'] = $this->encrypt['ssl_ca'];
+ empty($this->encrypt['ssl_capath']) OR $ssl['capath'] = $this->encrypt['ssl_capath'];
+ empty($this->encrypt['ssl_cipher']) OR $ssl['cipher'] = $this->encrypt['ssl_cipher'];
+
+ if ( ! empty($ssl))
+ {
+ if ( ! empty($this->encrypt['ssl_verify']) && defined('MYSQLI_OPT_SSL_VERIFY_SERVER_CERT'))
+ {
+ $mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, TRUE);
+ }
+
+ $client_flags |= MYSQLI_CLIENT_SSL;
+ $mysqli->ssl_set(
+ isset($ssl['key']) ? $ssl['key'] : NULL,
+ isset($ssl['cert']) ? $ssl['cert'] : NULL,
+ isset($ssl['ca']) ? $ssl['ca'] : NULL,
+ isset($ssl['capath']) ? $ssl['capath'] : NULL,
+ isset($ssl['cipher']) ? $ssl['cipher'] : NULL
+ );
+ }
+ }
+
+ if ($mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags))
+ {
+ // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails
+ if (
+ ($client_flags & MYSQLI_CLIENT_SSL)
+ && version_compare($mysqli->client_info, '5.7.3', '<=')
+ && empty($mysqli->query("SHOW STATUS LIKE 'ssl_cipher'")->fetch_object()->Value)
+ )
+ {
+ $mysqli->close();
+ $message = 'MySQLi was configured for an SSL connection, but got an unencrypted connection instead!';
+ log_message('error', $message);
+ return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE;
+ }
+
+ return $mysqli;
+ }
+
+ return FALSE;
}
// --------------------------------------------------------------------
diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
index 206d83595..e9d25cebc 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
@@ -119,7 +119,6 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver {
*
* @param bool $persistent
* @return object
- * @todo SSL support
*/
public function db_connect($persistent = FALSE)
{
@@ -151,7 +150,35 @@ class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver {
$this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE;
}
- return parent::db_connect($persistent);
+ // SSL support was added to PDO_MYSQL in PHP 5.3.7
+ if (is_array($this->encrypt) && is_php('5.3.7'))
+ {
+ $ssl = array();
+ empty($this->encrypt['ssl_key']) OR $ssl[PDO::MYSQL_ATTR_SSL_KEY] = $this->encrypt['ssl_key'];
+ empty($this->encrypt['ssl_cert']) OR $ssl[PDO::MYSQL_ATTR_SSL_CERT] = $this->encrypt['ssl_cert'];
+ empty($this->encrypt['ssl_ca']) OR $ssl[PDO::MYSQL_ATTR_SSL_CA] = $this->encrypt['ssl_ca'];
+ empty($this->encrypt['ssl_capath']) OR $ssl[PDO::MYSQL_ATTR_SSL_CAPATH] = $this->encrypt['ssl_capath'];
+ empty($this->encrypt['ssl_cipher']) OR $ssl[PDO::MYSQL_ATTR_SSL_CIPHER] = $this->encrypt['ssl_cipher'];
+
+ // DO NOT use array_merge() here!
+ // It re-indexes numeric keys and the PDO_MYSQL_ATTR_SSL_* constants are integers.
+ empty($ssl) OR $this->options += $ssl;
+ }
+
+ // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails
+ if (
+ ($pdo = parent::db_connect($persistent)) !== FALSE
+ && ! empty($ssl)
+ && version_compare($pdo->getAttribute(PDO::ATTR_CLIENT_VERSION), '5.7.3', '<=')
+ && empty($pdo->query("SHOW STATUS LIKE 'ssl_cipher'")->fetchObject()->Value)
+ )
+ {
+ $message = 'PDO_MYSQL was configured for an SSL connection, but got an unencrypted connection instead!';
+ log_message('error', $message);
+ return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE;
+ }
+
+ return $pdo;
}
// --------------------------------------------------------------------
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index d175f4b90..2cb5a6cd4 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -14,6 +14,7 @@ Release Date: Not Released
- Database
- Added ``list_fields()`` support for SQLite ('sqlite3' and 'pdo_sqlite' drivers).
+ - Added SSL connection support for the 'mysqli' and 'pdo_mysql' drivers.
- Libraries
diff --git a/user_guide_src/source/database/configuration.rst b/user_guide_src/source/database/configuration.rst
index d21c79e44..8026be63a 100644
--- a/user_guide_src/source/database/configuration.rst
+++ b/user_guide_src/source/database/configuration.rst
@@ -152,9 +152,9 @@ when the database classes are initialized.
Explanation of Values:
----------------------
-====================== ==================================================================================================
+====================== ===========================================================================================================
Name Config Description
-====================== ==================================================================================================
+====================== ===========================================================================================================
**dsn** The DSN connect string (an all-in-one configuration sequence).
**hostname** The hostname of your database server. Often this is 'localhost'.
**username** The username used to connect to the database.
@@ -179,6 +179,17 @@ Explanation of Values:
customizable by the end user.
**schema** The database schema, defaults to 'public'. Used by PostgreSQL and ODBC drivers.
**encrypt** Whether or not to use an encrypted connection.
+
+ - 'mysql' (deprecated), 'sqlsrv' and 'pdo/sqlsrv' drivers accept TRUE/FALSE
+ - 'mysqli' and 'pdo/mysql' drivers accept an array with the following options:
+
+ - 'ssl_key' - Path to the private key file
+ - 'ssl_cert' - Path to the public key certificate file
+ - 'ssl_ca' - Path to the certificate authority file
+ - 'ssl_capath' - Path to a directory containing trusted CA certificats in PEM format
+ - 'ssl_cipher' - List of *allowed* ciphers to be used for the encryption, separated by colons (':')
+ - 'ssl_verify' - TRUE/FALSE; Whether to verify the server certificate or not ('mysqli' only)
+
**compress** Whether or not to use client compression (MySQL only).
**stricton** TRUE/FALSE (boolean) - Whether to force "Strict Mode" connections, good for ensuring strict SQL
while developing an application.
@@ -186,10 +197,11 @@ Explanation of Values:
::
$db['default']['port'] = 5432;
-====================== ==================================================================================================
+
+====================== ===========================================================================================================
.. note:: Depending on what database platform you are using (MySQL, PostgreSQL,
etc.) not all values will be needed. For example, when using SQLite you
will not need to supply a username or password, and the database name
will be the path to your database file. The information above assumes
- you are using MySQL. \ No newline at end of file
+ you are using MySQL.