Nico Westerdale
Nico Westerdale

Reputation: 2186

Joomla can't connect to SSL enabled database

I'm using the latest version of Joomla, v3.6, and I'm surprised to see no support for connecting through SSL to a MySQL database.

It appears that what's required is a hack of the core Joomla db driver file: /libraries/joomla/database/driver/mysqli.php

What's more disheartening is that this file appears to use mysqli_connect(), which from what I can see has no inbuilt support for SSL connections, so it won't be as simple as just adding a few attributes.

Before I start hacking, has anyone successfully connected to a secure DB with Joomla? Is there a different driver I'm not aware of?

I've included the full Joomla DB connect function here for reference:

public function connect()
{
    if ($this->connection)
    {
        return;
    }

    /*
     * Unlike mysql_connect(), mysqli_connect() takes the port and socket as separate arguments. Therefore, we
     * have to extract them from the host string.
     */
    $port = isset($this->options['port']) ? $this->options['port'] : 3306;
    $regex = '/^(?P<host>((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(:(?P<port>.+))?$/';

    if (preg_match($regex, $this->options['host'], $matches))
    {
        // It's an IPv4 address with or without port
        $this->options['host'] = $matches['host'];

        if (!empty($matches['port']))
        {
            $port = $matches['port'];
        }
    }
    elseif (preg_match('/^(?P<host>\[.*\])(:(?P<port>.+))?$/', $this->options['host'], $matches))
    {
        // We assume square-bracketed IPv6 address with or without port, e.g. [fe80:102::2%eth1]:3306
        $this->options['host'] = $matches['host'];

        if (!empty($matches['port']))
        {
            $port = $matches['port'];
        }
    }
    elseif (preg_match('/^(?P<host>(\w+:\/{2,3})?[a-z0-9\.\-]+)(:(?P<port>[^:]+))?$/i', $this->options['host'], $matches))
    {
        // Named host (e.g example.com or localhost) with or without port
        $this->options['host'] = $matches['host'];

        if (!empty($matches['port']))
        {
            $port = $matches['port'];
        }
    }
    elseif (preg_match('/^:(?P<port>[^:]+)$/', $this->options['host'], $matches))
    {
        // Empty host, just port, e.g. ':3306'
        $this->options['host'] = 'localhost';
        $port = $matches['port'];
    }
    // ... else we assume normal (naked) IPv6 address, so host and port stay as they are or default

    // Get the port number or socket name
    if (is_numeric($port))
    {
        $this->options['port'] = (int) $port;
    }
    else
    {
        $this->options['socket'] = $port;
    }

    // Make sure the MySQLi extension for PHP is installed and enabled.
    if (!self::isSupported())
    {
        throw new JDatabaseExceptionUnsupported('The MySQL adapter mysqli is not available');
    }

    $this->connection = @mysqli_connect(
        $this->options['host'], $this->options['user'], $this->options['password'], null, $this->options['port'], $this->options['socket']
    );

    // Attempt to connect to the server.
    if (!$this->connection)
    {
        throw new JDatabaseExceptionConnecting('Could not connect to MySQL.');
    }

    // Set sql_mode to non_strict mode
    mysqli_query($this->connection, "SET @@SESSION.sql_mode = '';");

    // If auto-select is enabled select the given database.
    if ($this->options['select'] && !empty($this->options['database']))
    {
        $this->select($this->options['database']);
    }

    // Pre-populate the UTF-8 Multibyte compatibility flag based on server version
    $this->utf8mb4 = $this->serverClaimsUtf8mb4Support();

    // Set the character set (needed for MySQL 4.1.2+).
    $this->utf = $this->setUtf();

    // Turn MySQL profiling ON in debug mode:
    if ($this->debug && $this->hasProfiling())
    {
        mysqli_query($this->connection, "SET profiling_history_size = 100;");
        mysqli_query($this->connection, "SET profiling = 1;");
    }
}

Upvotes: 2

Views: 862

Answers (1)

itoctopus
itoctopus

Reputation: 4251

The solution to your problem is an MySQL ssh tunnel. If you do that then you won't have to modify anything in Joomla's core. See: http://chxo.com/be2/20040511_5667.html

Upvotes: 1

Related Questions