php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #53795 Connect Error from MySqli (mysqlnd) when using SSL
Submitted: 2011-01-20 01:59 UTC Modified: 2011-01-31 13:51 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: dave dot kelly at dawkco dot com Assigned: kalle
Status: Closed Package: MySQLi related
PHP Version: 5.3.5 OS: Windows
Private report: No CVE-ID:
 [2011-01-20 01:59 UTC] dave dot kelly at dawkco dot com
Description:
------------
- Using PHP 5.3.5 Windows binaries (Zip package).
- extension = php_mysqli.dll is enabled in php.ini.
- trying to use mysqli::real_connect, passing MYSQLI_CLIENT_SSL in the flags parameter.

It returns the following error:

Warning: mysqli::real_connect() [mysqli.real-connect.html]: (28000/1045): Access denied for user 'user'@'host' (using password: YES) in C:\Apache22\htdocs\test.php on line 25
Connect Error (1045)

If I switch to PHP 5.2.17 Windows binaries (Zip package), using the exact same settings and script, I get the following (excerpts):

Success... host via TCP/IP
...
Ssl_cipher DHE-RSA-AES256-SHA
...
Ssl_version TLSv1

I believe the main difference (relevant to this problem) between PHP 5.2.17 and PHP 5.3.5 is that 5.2.17 uses libmysql.dll and 5.3.5 uses built-in mysqlnd (native driver).  So, it appears that libmysql.dll works with SSL, while built-in mysqlnd (native driver) cannot use SSL.  The Windows binaries build has no way to disable/enable mysqlnd and/or libmysql.  If mysqlnd is not going to work with SSL, there should at least be another option that can be configured at runtime with the options file.


Test script:
---------------
<?php $mysqli = new mysqli();
$mysqli->init();
if (!$mysqli->options(MYSQLI_READ_DEFAULT_FILE,
    'C:/Program Files/MySQL/my.ini')) {
  die('Setting MYSQLI_READ_DEFAULT_FILE failed');
}
if (!$mysqli->options(MYSQLI_READ_DEFAULT_GROUP, 'mysql')) {
  die('Setting MYSQLI_READ_DEFAULT_GROUP failed');
}
if (!$mysqli->real_connect('host', 'user', 'pass',
    'mydb', 3306, NULL, MYSQLI_CLIENT_SSL)) {
  echo 'Connect Error (' . mysqli_connect_errno() . ')' . "<br />\n";
}
else {
  echo 'Success... ' . $mysqli->host_info . "<br />\n";
  $sql = "show status like '%ssl%'";
  $result = $mysqli->query($sql);
  while ($row = $result->fetch_array()) {
    echo $row[0] . ' ' . $row[1] . "<br />\n";
  }
  if ($result) { $result->close(); }
}
$mysqli->close(); ?>

Expected result:
----------------
Expect a new SSL connection and a result set from the query indicating that the connection is indeed via SSL/TLS.

Actual result:
--------------
Warning: (28000/1045): Access denied ... Connect Error (1045).

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-01-24 10:21 UTC] uw@php.net
-Assigned To: +Assigned To: mysql
 [2011-01-24 10:21 UTC] uw@php.net
mysqlnd does not read default files, AFAIK. I think Andrey wants to deprecate that, Andrey?
 [2011-01-24 11:12 UTC] andrey@php.net
No, mysqlnd doesn't use my.ini/my.cnf files, as libmysql did. You have to set your options manually.
 [2011-01-29 09:36 UTC] dave dot kelly at dawkco dot com
FYI (you probably already know):  there are currently no SSL/TLS options available to be set with the mysqli::options method.

I tried using the mysqli::ssl_set method as follows, but it didn't work either (same connect error):

$mysqli->ssl_set(NULL, // key file path or NULL
                 NULL, // cert file path or NULL
                 'C:/ssl/ca-cert.pem', // ca cert file path or NULL
                 NULL, // capath directory or NULL
                 'DHE-RSA-AES256-SHA'); // cipher or NULL

Also, tried the following (no luck):

$mysqli->ssl_set('C:/ssl/key.pem', // key file path or NULL
                 'C:/ssl/cert.pem', // cert file path or NULL
                 'C:/ssl/ca-cert.pem', // ca cert file path or NULL
                 NULL, // capath directory or NULL
                 NULL); // cipher or NULL

As noted before, these all work with PHP 5.2.17, but not with PHP 5.3.5.

A fix for mysqlnd would be great because trying to do a custom build on Windows with mysqlnd disabled has become a real ordeal.
 [2011-01-30 11:35 UTC] kalle@php.net
-Assigned To: mysql +Assigned To: kalle
 [2011-01-30 11:35 UTC] kalle@php.net
I got an idea why this fails, as MYSQLND_SSL_SUPPORTED is not defined on Windows, its a simple one line fix that I will commit shortly
 [2011-01-31 13:47 UTC] kalle@php.net
Automatic comment from SVN on behalf of kalle
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=307880
Log: Fixed bug #53795 (Connect Error from MySqli (mysqlnd) when using SSL)
 [2011-01-31 13:51 UTC] kalle@php.net
-Status: Assigned +Status: Closed
 [2011-01-31 13:51 UTC] kalle@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 [2011-02-05 10:54 UTC] dave dot kelly at dawkco dot com
OK, the patch works.  Mysqli (mysqlnd build) on Windows can now use SSL/TLS connections.  Thank you!
 [2011-03-08 13:16 UTC] carsten_sttgt at gmx dot de
@ kalle
> as MYSQLND_SSL_SUPPORTED is not defined on Windows,
> its a simple one line fix that I will commit shortly

How is MySQLnd SSL support related to ZLIB? I think you should move the AC_DEFINE below the "if PHP_ZLIB" block, like this is done in the *nix configure (means always enabled).

Of course, in my opinion both (windows/*nix) is wrong. At the moment phpinfo is always showing you "SSL => supported", even PHP is build without OpenSSL and SSL connection (through the streams) can't work.

So, what is "SSL => supported" telling me?
a) mysqlnd is build with SSL support.
--> In this case there should be a configure switch like "--enable-mysqlnd-ssl" (or only define this, if PHP is also build with OpenSSL)

b) MySQLnd SSL connections are currently working in this installation.
--> in this case this should be a runtime setting and not a compiler define. (because a shared OpenSSL extension maybe loaded or not)
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 17 16:02:22 2014 UTC