Skip to content

Commit 6192dc0

Browse files
committed
Merge branch 'PHP-8.6'
* PHP-8.6: ext/openssl: Propagate session_get_cb exceptions unchanged
2 parents 0012f1a + 24ca066 commit 6192dc0

2 files changed

Lines changed: 99 additions & 1 deletion

File tree

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
--TEST--
2+
TLS session resumption - exception thrown by session_get_cb propagates unchanged
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+
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'session_get_cb_throws.pem.tmp';
12+
13+
$serverCode = <<<'CODE'
14+
$sessionStore = [];
15+
16+
$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
17+
$ctx = stream_context_create(['ssl' => [
18+
'local_cert' => '%s',
19+
'session_id_context' => 'test-server',
20+
'session_new_cb' => function ($stream, $session) use (&$sessionStore) {
21+
$sessionStore[bin2hex($session->id)] = $session;
22+
},
23+
'session_get_cb' => function ($stream, $sessionId) use (&$sessionStore) {
24+
if (isset($sessionStore[bin2hex($sessionId)])) {
25+
throw new RuntimeException('session_get_cb failed');
26+
}
27+
return null;
28+
},
29+
], 'stream' => ['error_mode' => StreamErrorMode::%s]]);
30+
31+
$server = stream_socket_server('tlsv1.2://127.0.0.1:0', $errno, $errstr, $flags, $ctx);
32+
phpt_notify_server_start($server);
33+
34+
$client = @stream_socket_accept($server, 30);
35+
fwrite($client, "Response 1\n");
36+
fclose($client);
37+
38+
try {
39+
$client = @stream_socket_accept($server, 30);
40+
$result = "accepted " . get_debug_type($client);
41+
} catch (Throwable $e) {
42+
$result = $e::class . ": " . $e->getMessage() . ", previous: " . get_debug_type($e->getPrevious());
43+
}
44+
45+
phpt_notify(message: $result);
46+
CODE;
47+
48+
$clientCode = <<<'CODE'
49+
$sessionData = null;
50+
51+
$flags = STREAM_CLIENT_CONNECT;
52+
$ctx = stream_context_create(['ssl' => [
53+
'verify_peer' => false,
54+
'verify_peer_name' => false,
55+
'session_new_cb' => function ($stream, $session) use (&$sessionData) {
56+
$sessionData = $session;
57+
},
58+
]]);
59+
60+
$client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx);
61+
echo trim(fgets($client1)), "\n";
62+
fclose($client1);
63+
64+
$ctx2 = stream_context_create(['ssl' => [
65+
'verify_peer' => false,
66+
'verify_peer_name' => false,
67+
'session_data' => $sessionData,
68+
]]);
69+
70+
$client2 = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2);
71+
var_dump($client2);
72+
73+
echo "Server: ", trim(phpt_wait()), "\n";
74+
CODE;
75+
76+
include 'CertificateGenerator.inc';
77+
$certificateGenerator = new CertificateGenerator();
78+
$certificateGenerator->saveNewCertAsFileWithKey('session_get_cb_throws', $certFile);
79+
80+
include 'ServerClientTestCase.inc';
81+
foreach (['Error', 'Exception'] as $mode) {
82+
echo "$mode mode:\n";
83+
ServerClientTestCase::getInstance()->run($clientCode, sprintf($serverCode, $certFile, $mode));
84+
}
85+
?>
86+
--CLEAN--
87+
<?php
88+
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'session_get_cb_throws.pem.tmp');
89+
?>
90+
--EXPECTF--
91+
Error mode:
92+
Response 1
93+
resource(%d) of type (stream)
94+
Server: RuntimeException: session_get_cb failed, previous: null
95+
Exception mode:
96+
Response 1
97+
resource(%d) of type (stream)
98+
Server: RuntimeException: session_get_cb failed, previous: null

‎ext/openssl/xp_ssl.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2262,7 +2262,7 @@ static SSL_SESSION *php_openssl_session_get_cb(SSL *ssl, const unsigned char *se
22622262
SSL_SESSION_up_ref(obj->session);
22632263
session = obj->session;
22642264
}
2265-
} else if (Z_TYPE(retval) != IS_NULL) {
2265+
} else if (!Z_ISUNDEF(retval) && Z_TYPE(retval) != IS_NULL) {
22662266
zend_type_error("session_get_cb return type must be null or Openssl\\Session");
22672267
}
22682268

0 commit comments

Comments
 (0)