ID:               48182
 User updated by:  frase at cs dot wisc dot edu
 Reported By:      frase at cs dot wisc dot edu
 Status:           Open
 Bug Type:         OpenSSL related
-Operating System: Windows 2000 Pro SP4
+Operating System: all
-PHP Version:      5.2.9
+PHP Version:      5.2.9, 5.3.0RC4
 New Comment:

This bug is still present in 5.3.0 as of RC4, and also affects Linux
hosts.


Previous Comments:
------------------------------------------------------------------------

[2009-06-08 14:14:30] frase at cs dot wisc dot edu

Hate to bump my own bug, but it's been a month.

Nobody's concerned that ssl:// streams + ASYNC_CONNECT has this silent
failure?  And that there's a chance it's causing data intended for
ssl:// to instead be transmitted in plaintext?

------------------------------------------------------------------------

[2009-05-07 16:23:49] frase at cs dot wisc dot edu

Description:
------------
When opening a socket connection with stream_socket_client() and the
ssl:// wrapper, the connect-asynchronously flag
(STREAM_CLIENT_ASYNC_CONNECT) causes ssl encryption to fail.  Connecting
asynchronously with tcp:// works, as does connecting synchronously with
ssl://.

If I remove the ASYNC flag from the example code, I get normal HTTP
headers and HTML content.  If I leave the flag but change the scheme to
tcp:// and port to 80, launchpad.net gives me a normal HTTP/HTML
redirect to the encrypted url (https://...).  But as written, I instead
get an error from the server indicating that my request could not be
decrypted via SSL, and no HTTP headers whatsoever.

I'm not sure if this bug is more properly "OpenSSL related" or "Sockets
related", so I've guessed the former.  But I wonder if maybe
stream_select() considers the socket writable once it's opened, but
before the SSL handshake is complete; that might cause this code to
fwrite() too early, possibly going out plaintext.  Then I suppose the
solution is for stream_select() to not return ssl:// sockets until the
handshake is complete, in addition to simply being opened.

Reproduce code:
---------------
<?php
header('Content-type: text/plain');
$scheme = 'ssl://';
$host = 'launchpad.net';
$port = 443;
$path = '/';
$begin = microtime(true);
$flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT;
echo "resolving ".$host."...\n";
$ip = gethostbyname($host);
echo "connecting to ".$ip."...\n";
$errno = null;
$errstr = null;
$socket = stream_socket_client($scheme.$ip.':'.$port, $errno, $errstr,
10, $flags);
stream_set_blocking($socket, 0);
echo "sending HTTP GET ".$path."...\n";
$data = "GET ".$path." HTTP/1.0\r\n" .
                "Host: ".$host."\r\n" .
                "Connection: close\r\n" .
                "\r\n";
$selR = null;
$selW = array($socket);
$selE = null;
while ($data) {
        $selW[0] = $socket;
        if (stream_select($selR, $selW, $selE, 0, 50000)) {
                $wrote = fwrite($socket, $data, strlen($data));
                $data = substr($data, $wrote);
        }
}
echo "waiting for data...\n";
$html = "";
$selR = array($socket);
$selW = null;
$selE = null;
$timeout = microtime(true) + 30;
while (!feof($socket)) {
        $selR[0] = $socket;
        if (stream_select($selR, $selW, $selE, 0, 50000))
                $html .= fread($socket, 8192);
}
fclose($socket);
echo "got ".strlen($html)." bytes in ".(microtime(true)-$begin)."
seconds\n";
echo "----------\n".$html;


Expected result:
----------------
The HTTP headers and HTML source for launchpad.net's main page, i.e.:

HTTP/1.1 200 OK
...
<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en"
      lang="en" dir="ltr">
  <head>
    <title>Launchpad</title>
...

etc

Actual result:
--------------
An HTML source error message:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not
understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br
/>
Instead use the HTTPS scheme to access this URL, please.<br />
<blockquote>Hint: <a
href="https://launchpad.net/";><b>https://launchpad.net/</b></a></blockquote></p>
<hr>
<address>Apache/2.2.8 (Ubuntu) mod_ssl/2.2.8 OpenSSL/0.9.8g Server at
launchpad.net Port 443</address>
</body></html>



------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=48182&edit=1

Reply via email to