Skip to content

Commit ae429f1

Browse files
committed
ext/openssl: Restore blocking mode after a handshake timeout
A handshake timeout returned before php_openssl_enable_crypto() restored the socket blocking mode saved at entry. That return now restores it, as the normal return already does. Closes GH-23932
1 parent 2e5bb79 commit ae429f1

3 files changed

Lines changed: 58 additions & 0 deletions

File tree

‎NEWS‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ PHP NEWS
8181
(David Carlier)
8282
. Fix incorrect DCE due to unsound escape analysis. (ndossche)
8383

84+
- OpenSSL:
85+
. Fixed stream_socket_enable_crypto() leaving the socket non-blocking
86+
after a handshake timeout. (Ilia Alshanetsky)
87+
8488
- PCNTL:
8589
. Fixed pcntl_signal_dispatch() dropping the queued signals when it runs while
8690
an exception is pending. (nicolas-grekas)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
--TEST--
2+
OpenSSL handshake timeout restores the stream blocking mode
3+
--EXTENSIONS--
4+
openssl
5+
--SKIPIF--
6+
<?php
7+
if (!function_exists('proc_open')) die('skip no proc_open');
8+
?>
9+
--FILE--
10+
<?php
11+
$serverCode = <<<'CODE'
12+
$server = stream_socket_server('tcp://127.0.0.1:0', $errno, $errstr);
13+
phpt_notify_server_start($server);
14+
15+
$conn = stream_socket_accept($server, 5);
16+
phpt_wait();
17+
fclose($conn);
18+
CODE;
19+
20+
$clientCode = <<<'CODE'
21+
$context = stream_context_create(['ssl' => [
22+
'verify_peer' => false,
23+
'verify_peer_name' => false,
24+
]]);
25+
$client = stream_socket_client('tcp://{{ ADDR }}', $errno, $errstr, 1, STREAM_CLIENT_CONNECT, $context);
26+
27+
$metadata = stream_get_meta_data($client);
28+
var_dump($metadata['blocked']);
29+
30+
set_error_handler(function (int $errno, string $errstr) use ($client): bool {
31+
$metadata = stream_get_meta_data($client);
32+
var_dump($metadata['blocked']);
33+
echo $errstr, "\n";
34+
fclose($client);
35+
return true;
36+
});
37+
38+
var_dump(stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_CLIENT));
39+
restore_error_handler();
40+
var_dump(is_resource($client));
41+
42+
phpt_notify();
43+
CODE;
44+
45+
include 'ServerClientTestCase.inc';
46+
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
47+
?>
48+
--EXPECT--
49+
bool(true)
50+
bool(true)
51+
stream_socket_enable_crypto(): SSL: Handshake timed out
52+
bool(false)
53+
bool(false)

‎ext/openssl/xp_ssl.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,6 +2004,7 @@ static int php_openssl_enable_crypto(php_stream *stream,
20042004
elapsed_time = php_openssl_subtract_timeval(cur_time, start_time);
20052005

20062006
if (php_openssl_compare_timeval( elapsed_time, *timeout) > 0) {
2007+
php_openssl_set_blocking(sslsock, blocked);
20072008
php_error_docref(NULL, E_WARNING, "SSL: Handshake timed out");
20082009
return -1;
20092010
}

0 commit comments

Comments
 (0)