From: Sriram Natarajan Date: Tue, 28 Jul 2009 19:28:08 +0000 (+0000) Subject: - 48182 ssl handshake fails during asynchronous socket connection X-Git-Tag: php-5.3.1RC1~241 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=34d8ee27ccfe92c8281ff7001d8737881557981d;p=php - 48182 ssl handshake fails during asynchronous socket connection --- diff --git a/NEWS b/NEWS index 81280830a1..95a3bd4ced 100644 --- a/NEWS +++ b/NEWS @@ -73,6 +73,8 @@ (Kalle, Rick Yorgason) - Fixed bug #48774 (SIGSEGVs when using curl_copy_handle()). (Sriram Natarajan) +- Fixed bug #48182 (ssl handshake fails during asynchronous socket connection). + (Sriram Natarajan) 30 Jun 2009, PHP 5.3.0 - Upgraded bundled PCRE to version 7.9. (Nuno) diff --git a/ext/openssl/tests/bug48182.phpt b/ext/openssl/tests/bug48182.phpt new file mode 100644 index 0000000000..0af04e1a95 --- /dev/null +++ b/ext/openssl/tests/bug48182.phpt @@ -0,0 +1,92 @@ +--TEST-- +#48182,ssl handshake fails during asynchronous socket connection +--SKIPIF-- + +--FILE-- + false, 'allow_self_signed' => true, 'local_cert' => $pem); + $ssl = array('ssl' => $ssl_params); + + $context = stream_context_create($ssl); + $sock = stream_socket_server($host, $errno, $errstr, $flags, $context); + if (!$sock) return false; + + $link = stream_socket_accept($sock); + if (!$link) return false; // bad link? + + $r = array($link); + $w = array(); + $e = array(); + if (stream_select($r, $w, $e, 0, 1000) != 0) + $data .= fread($link, 8192); + + $r = array(); + $w = array($link); + if (stream_select($r, $w, $e, 0, 1000) != 0) + $wrote = fwrite($link, $data, strlen($data)); + + // close stuff + fclose($link); + fclose($sock); + + exit; +} + +function ssl_async_client($port) { + $host = 'ssl://127.0.0.1'.':'.$port; + $flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT; + $data = "Sending data over to SSL server in async mode with contents like Hello World\n"; + + $socket = stream_socket_client($host, $errno, $errstr, 10, $flags); + stream_set_blocking($socket, 0); + + while ($data) { + $wrote = fwrite($socket, $data, strlen($data)); + $data = substr($data, $wrote); + } + + $r = array($socket); + $w = array(); + $e = array(); + if (stream_select($r, $w, $e, 0, 10) != 0) + { + $data .= fread($socket, 1024); + } + + echo "$data"; + + fclose($socket); +} + +echo "Running bug48182\n"; + +$port = rand(15000, 32000); + +$pid = pcntl_fork(); +if ($pid == 0) { // child + ssl_server($port); + exit; +} + +// client or failed +sleep(1); +ssl_async_client($port); + +pcntl_waitpid($pid, $status); + +?> +--EXPECTF-- +Running bug48182 +Sending bug48182 +Sending data over to SSL server in async mode with contents like Hello World diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 5cd202e7d8..07180729a3 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -672,7 +672,11 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val * we notice that the connect has actually been established */ php_stream_socket_ops.set_option(stream, option, value, ptrparam TSRMLS_CC); - if (xparam->outputs.returncode == 0 && sslsock->enable_on_connect) { + if ((sslsock->enable_on_connect) && + ((xparam->outputs.returncode == 0) || + (xparam->op == STREAM_XPORT_OP_CONNECT_ASYNC && + xparam->outputs.returncode == 1 && xparam->outputs.error_code == EINPROGRESS))) + { if (php_stream_xport_crypto_setup(stream, sslsock->method, NULL TSRMLS_CC) < 0 || php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to enable crypto");