php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #70939 socket_import_stream does not indicate missing support for SSL
Submitted: 2015-11-18 20:33 UTC Modified: 2016-02-22 17:52 UTC
Votes:19
Avg. Score:4.8 ± 0.5
Reproduced:18 of 18 (100.0%)
Same Version:4 (22.2%)
Same OS:15 (83.3%)
From: lcharron at meditech dot com Assigned:
Status: Open Package: Sockets related
PHP Version: 5.5.30 OS: Any
Private report: No CVE-ID: None
 [2015-11-18 20:33 UTC] lcharron at meditech dot com
Description:
------------
You should be able to obtain the socket from a socket-based SSL stream so that socket options (ex. SO_KEEPALIVE) can be set.
The documentation makes no mention that this is not possible.

Test script:
---------------
$host = "host";
$port = "443";
$stream = stream_socket_client("ssl://{$host}:{$port}");
$socket = socket_import_stream($stream);
if ($socket) {

    socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);
}

Expected result:
----------------
socket_import_stream should return the underlying socket so options can be set.

Actual result:
--------------
socket_import_stream returns null and the following warning is emitted:
Warning: socket_import_stream(): cannot represent a stream of type tcp_socket/ssl as a Socket Descriptor in ...


Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-12-12 18:16 UTC] contact at sshilko dot com
Same issue, i thought its "by design", at the moment there is no option to enable SO_KEEPALIVE when using stream_socket_client() with SSL/TLS
 [2016-02-21 19:47 UTC] adrian dot sandu at asandu dot eu
Any updates/workarounds ?
 [2016-02-22 17:52 UTC] lcharron at meditech dot com
I could find no work around.
 [2016-02-23 10:02 UTC] adrian dot sandu at asandu dot eu
Someone recommended:

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);
socket_connect($socket, $host, $port);
 [2020-01-13 10:36 UTC] alex dot bucher at myposter dot de
Hi There,
4 Years later - any updates / workarounds for this?

just hitting the Problem with 
https://github.com/php-amqplib/php-amqplib/issues/371


currently adding TICKS and a tickhandler as a workaround, but that's not a really nice solution...
 [2021-02-05 00:07 UTC] bugs dot php at codifier dot nl
This still appears to an issue (at least in PHP 7.3.26). However, I may have found a workaround, albeit a convoluted one and one of which I still don't know the full implications for. I still need to do more testing to actually see what my workaround means for the actual state of the low-level socket, that now can be acquired with socket_import_stream(), and the stream's encryption state when fiddling with the low-level socket. 

==========
WARNING
Because this involves security-sensitive stuff, USE THIS AT YOUR OWN RISK and thoroughly test it, to verify that the intended encryption is not broken!
==========

Here's my temporary workaround:

----------

$host = "host";
$port = "443";
$stream = stream_socket_client( "ssl://{$host}:{$port}" );

stream_socket_enable_crypto( $stream, false );
$socket = socket_import_stream( $stream );
var_dump( gettype( $socket ) ); // string(8) "resource"

// If the stream is blocked, it needs to be temporarily unblocked first,
// otherwise you'll get the warning: SSL/TLS already set-up for this stream
// See https://github.com/php/php-src/blob/3e01f5afb1b52fe26a956190296de0192eedeec1/ext/openssl/xp_ssl.c#L1635
$blocked = stream_get_meta_data( $stream )[ 'blocked' ];
if( $blocked ) {
  stream_set_blocking( $stream, false );
}
// Be sure to apply the correct $crypto_type, if you've used a different one before
stream_socket_enable_crypto( $stream, true, STREAM_CRYPTO_METHOD_ANY_CLIENT );
// Maybe re-apply blocking
if( $blocked ) {
  stream_set_blocking( $stream, true );
}

----------
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 03 17:01:29 2024 UTC