php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61258 ssl sockets fail with event_buffer_new
Submitted: 2012-03-03 01:50 UTC Modified: 2017-10-24 04:46 UTC
Votes:4
Avg. Score:5.0 ± 0.0
Reproduced:4 of 4 (100.0%)
Same Version:2 (50.0%)
Same OS:1 (25.0%)
From: Erik dot Haller at gmail dot com Assigned:
Status: Suspended Package: libevent (PECL)
PHP Version: 5.3.10 OS: windows
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2012-03-03 01:50 UTC] Erik dot Haller at gmail dot com
Description:
------------
Socket streams created with fsockopen using ssl scheme fail with the event_buffer_new($socket, readcb, writecb, errorcg, arg) function; i.e. fsockopen("ssl://my_server", ...). The readcb callback is called and buffer returns encrypted data. The readcb works properly with the tcp scheme; i.e. fsockopen("tcp://my_server", ...). The event_buffer_read/event_buffer_write functionality is unusable with ssl sockets.

As a workaround, use the event_new()/event_set() functions with ssl socket streams.

Tested with php 5.3.8 (Windows XP) and php 5.3.10 (Windows Server 2003) and libevent 2.0.12 and php_libevent 0.0.4.

Also tested with php 5.3.8 (Windows XP) and php 5.3.10 (Windows Server 2003) and libevent 2.0.17 (latest) and pecl php_libevent trunk revision 318910 (2012-03-02).

Test script:
---------------
Pseudo Code

$socket = fsockopen("ssl://myserver", 61613, $errno, $errstr);
stream_set_blocking($socket, 0));
$event_buffer = event_buffer_new($socket, 'ev_read', 'ev_write', 'ev_error');			
event_buffer_base_set($event_buffer, self::$event_base);
event_buffer_enable($event_buffer, EV_READ | EV_PERSIST | EV_WRITE);

function ev_read($buffer, $arg) {

  // $in will have encrypted data when using ssl://. 
  // Data should be unencrypted
  // It seems that the event_buffer_read is not allowing the normal php sockets to unencrypt the data first.

   $in = event_buffer_read($buffer, 8192);
}

Expected result:
----------------
The above pseudo code used with ssl:// stream sockets should work as the tcp:// stream sockets with event_buffer_new()/event_buffer_base_set()/event_buffer_enable() functions.

The ssl:// & tcp:// stream sockets both work with the event_new()/event_set()/event_add() functions. When the EV_READ callback is executed the data is read from php as unencrypted.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-06-20 13:47 UTC] rose dot andrew at gmail dot com
I can confirm this problem.
 [2012-06-20 13:52 UTC] tony2001@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.


 [2012-06-20 13:52 UTC] tony2001@php.net
-Status: Open +Status: Feedback
 [2013-02-18 00:35 UTC] pecl-dev at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.
 [2013-04-18 01:24 UTC] Erik dot Haller at gmail dot com
-Status: No Feedback +Status: Closed
 [2013-04-18 01:24 UTC] Erik dot Haller at gmail dot com
php_libevent: 0.0.4
libevent version: 2.0.16-stable

Problem also occurs on linux: Ubuntu 12.04.1 LTS precise

php -version
PHP 5.3.10-1ubuntu3.4 with Suhosin-Patch (cli) (built: Sep 12 2012 19:00:43)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

Here's the test code:

<?php
chdir( __DIR__ );
error_reporting( E_ALL | E_STRICT );
openlog( "le-test", LOG_PERROR, LOG_LOCAL0 );
syslog( LOG_INFO, "begin" );


$url = "tls://www.google.com:443";

// Uncomment below to see libevent code work with no encryption
//$url = "tcp://www.google.com:80";


$get = "GET / HTTP/1.0\r\n\r\n";

$pa = parse_url( $url );

// Socket Test
$res = fsockopen( "{$pa[ 'scheme']}://{$pa[ 'host' ]}", $pa[ "port" ], $errno, $errstr );
fwrite( $res, $get );
$str = fread( $res, 8192 );
syslog( LOG_INFO, sprintf( "Socket Read\n\n%s", $str ) );
fclose( $res );

// Libevent Test
$res = fsockopen( "{$pa[ 'scheme']}://{$pa[ 'host' ]}", $pa[ "port" ], $errno, $errstr, 60 );

stream_set_blocking( $res, 0 );
$get_sent = false;

$event_base = event_base_new();
$event_buffer = event_buffer_new( $res, "ev_read", "ev_write", "ev_error", $event_base );

function s2hex($s, $sep = "", $printable = false) {

	if($printable) {

		$p = array();

		foreach(unpack("C*", $s) as $i) {

			if($i <= 31) {

				$p[] = sprintf("^%c", $i + 64);
			}
			elseif(
				   (32 <= $i)
				&& ($i <= 126)
			) {

				$p[] = sprintf("%c ", $i);
			}
			else {

				$p[] = sprintf("%'02x", $i);
			}
		}

		return join($sep, $p);
	}
	else {
		return preg_replace('/../', '$0'.$sep, join("", unpack("H*", $s)) );
	}
}

function ev_read( $buf, $arg ) {

	global $res;
	$str = event_buffer_read( $buf, 1000000 );
	syslog( LOG_INFO, sprintf( "Libevent Read\n\nlen: %s %s", strlen( $str ), $str ) );

	if( strlen( $str ) < 100 ) {
	
		syslog( LOG_INFO, sprintf( "hex:\n%s\n", s2hex( $str, ' ', true ) ) );
	}
}

function ev_write( $buf, $arg ) {

	global $get, $event_buffer, $get_sent;

	if( ! $get_sent ) { 

		$res = event_buffer_write( $buf, $get );
		syslog( LOG_INFO, "ev_write result: $res" );
		$get_sent = true;
	}
}

function ev_error( $buf, $what, $arg) {

	syslog( LOG_INFO, sprintf( "Libevent Error:\n\n%s\n\n%s"

		, print_r( func_get_args(), true )
		, event_buffer_read( $buf, 8192 ) 
	) );
}

echo "buffer: $event_buffer base: $event_base\n";

event_buffer_base_set( $event_buffer, $event_base ); 
event_buffer_enable( $event_buffer, EV_READ | EV_WRITE );
event_base_loop( $event_base );
syslog( LOG_INFO, "base_loop ended" );
event_buffer_disable( $event_buffer, EV_READ | EV_WRITE );
event_buffer_free( $event_buffer );
event_base_free( $event_base  );

closelog();
?>
 [2013-04-18 01:25 UTC] Erik dot Haller at gmail dot com
php_libevent: 0.0.4
libevent version: 2.0.16-stable

Problem also occurs on linux: Ubuntu 12.04.1 LTS precise

php -version
PHP 5.3.10-1ubuntu3.4 with Suhosin-Patch (cli) (built: Sep 12 2012 19:00:43)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

Here's the test code:

<?php
chdir( __DIR__ );
error_reporting( E_ALL | E_STRICT );
openlog( "le-test", LOG_PERROR, LOG_LOCAL0 );
syslog( LOG_INFO, "begin" );


$url = "tls://www.google.com:443";

// Uncomment below to see libevent code work with no encryption
//$url = "tcp://www.google.com:80";


$get = "GET / HTTP/1.0\r\n\r\n";

$pa = parse_url( $url );

// Socket Test
$res = fsockopen( "{$pa[ 'scheme']}://{$pa[ 'host' ]}", $pa[ "port" ], $errno, $errstr );
fwrite( $res, $get );
$str = fread( $res, 8192 );
syslog( LOG_INFO, sprintf( "Socket Read\n\n%s", $str ) );
fclose( $res );

// Libevent Test
$res = fsockopen( "{$pa[ 'scheme']}://{$pa[ 'host' ]}", $pa[ "port" ], $errno, $errstr, 60 );

stream_set_blocking( $res, 0 );
$get_sent = false;

$event_base = event_base_new();
$event_buffer = event_buffer_new( $res, "ev_read", "ev_write", "ev_error", $event_base );

function s2hex($s, $sep = "", $printable = false) {

	if($printable) {

		$p = array();

		foreach(unpack("C*", $s) as $i) {

			if($i <= 31) {

				$p[] = sprintf("^%c", $i + 64);
			}
			elseif(
				   (32 <= $i)
				&& ($i <= 126)
			) {

				$p[] = sprintf("%c ", $i);
			}
			else {

				$p[] = sprintf("%'02x", $i);
			}
		}

		return join($sep, $p);
	}
	else {
		return preg_replace('/../', '$0'.$sep, join("", unpack("H*", $s)) );
	}
}

function ev_read( $buf, $arg ) {

	global $res;
	$str = event_buffer_read( $buf, 1000000 );
	syslog( LOG_INFO, sprintf( "Libevent Read\n\nlen: %s %s", strlen( $str ), $str ) );

	if( strlen( $str ) < 100 ) {
	
		syslog( LOG_INFO, sprintf( "hex:\n%s\n", s2hex( $str, ' ', true ) ) );
	}
}

function ev_write( $buf, $arg ) {

	global $get, $event_buffer, $get_sent;

	if( ! $get_sent ) { 

		$res = event_buffer_write( $buf, $get );
		syslog( LOG_INFO, "ev_write result: $res" );
		$get_sent = true;
	}
}

function ev_error( $buf, $what, $arg) {

	syslog( LOG_INFO, sprintf( "Libevent Error:\n\n%s\n\n%s"

		, print_r( func_get_args(), true )
		, event_buffer_read( $buf, 8192 ) 
	) );
}

echo "buffer: $event_buffer base: $event_base\n";

event_buffer_base_set( $event_buffer, $event_base ); 
event_buffer_enable( $event_buffer, EV_READ | EV_WRITE );
event_base_loop( $event_base );
syslog( LOG_INFO, "base_loop ended" );
event_buffer_disable( $event_buffer, EV_READ | EV_WRITE );
event_buffer_free( $event_buffer );
event_base_free( $event_base  );

closelog();
?>
 [2013-04-18 01:25 UTC] Erik dot Haller at gmail dot com
-Status: Closed +Status: Assigned
 [2017-10-24 04:46 UTC] kalle@php.net
-Status: Assigned +Status: Suspended
 [2017-10-24 04:46 UTC] kalle@php.net
I'm gonna close this as the libevent package on PECL had no had a release for 4 years, and there haven't really been much acitivity since. If development picks back up then this report should be re-opened
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Fri Jul 10 01:01:27 2020 UTC