|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-02-27 11:12 UTC] nj506 at zepler dot net
Description: ------------ This is the same issue as presented in #67609 - but manifested in the SOAP extension. The SOAP extension uses it's own HTTP handling code (i.e. not http_fopen_wrapper.c where the issue was patched for #67609). (i) The crypto method defaults to SSL v2/3 - https://github.com/php/php-src/blob/942809909e1bc125db038796c0a1a0b53eeaca7d/ext/soap/php_http.c#L273 - this causes problems when the SOAP endpoint only accepts TLS. This can be worked around by setting 'ssl_method' to SOAP_SSL_METHOD_TLS in the options supplied to \SoapClient::__construct(). (ii) The name in the peer certificate, by default, is compared to the "url_name" of the SSL socket - https://github.com/php/php-src/blob/c17e007a293356a5b1e511626addb9f13d4eaaee/ext/openssl/xp_ssl.c#L489 - when a proxy is in use, this is the proxy host, not SOAP endpoint host. This can be worked around by setting "verify_peer_name" to FALSE, or specifying the correct "peer_name" value in the SSL portion of stream context that can be supplied within in the "stream_context" option for \SoapClient::__construct(). By the way, the error raised by SOAP where peer verification fails is very generic, to the point that it is basically impossible to work out what exactly the problem is. I couldn't see anything in the Exception context that indicated the exact problem. Test script: --------------- $options = [ 'proxy_host' => '..', 'proxy_port' => .. ]; $client = new \SoapClient($wsdl, $options); $client->__soapCall(..); Expected result: ---------------- Call succeeds Actual result: -------------- \SoapFault: Could not connect to host Patchesphp-soap-patch-2152.patch (last revision 2018-11-14 14:53 UTC by tomp at tomp dot uk)Pull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 13:00:02 2025 UTC |
I can confirm this problem. You need a SSL connection via a proxy to reproduce it. The exact error can be made visible by using your own error-handler before sending the SOAP request, e.g. set_error_handler( function ($errno , $errstr, $errfile = null, $errline = null) { printf( "ERROR #%d: %s in %s line %s\n", $errno, $errstr, $errfile, $errline ); } ); This produces an error like: > ERROR #2: SoapClient::__doRequest(): Peer certificate CN=`correct-domain.exmaple.com' did not match expected CN=`proxy.example.net' The SOAP Fault itself is little saying as reported: > Fatal error: Uncaught SoapFault exception: [HTTP] Could not connect to hostOur company is running PHP 5.6 as we have PECL modules that don't support PHP 7. We experienced this issue and the PHP 7 patch wouldn't apply cleanly to the PHP 5.6 tree, so I have backported it to PHP 5.6. This has been tested to work and is in production. diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 3246091..fcf593e 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -163,7 +163,7 @@ void http_context_headers(php_stream_context* context, static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, php_stream_context *context, int *use_proxy TSRMLS_DC) { php_stream *stream; - zval **proxy_host, **proxy_port, **tmp; + zval **proxy_host, **proxy_port, **tmp, ssl_proxy_peer_name; char *host; char *name; char *protocol; @@ -245,6 +245,13 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph char *http_headers; int http_header_size; + /* Set peer_name or name verification will try to use the proxy server name */ + if (!stream->context || php_stream_context_get_option(stream->context, "ssl", "peer_name", &tmp) != SUCCESS) { + ZVAL_STRING(&ssl_proxy_peer_name, phpurl->host, 1); + php_stream_context_set_option(stream->context, "ssl", "peer_name", &ssl_proxy_peer_name); + zval_dtor(&ssl_proxy_peer_name); + } + smart_str_append_const(&soap_headers, "CONNECT "); smart_str_appends(&soap_headers, phpurl->host); smart_str_appendc(&soap_headers, ':'); diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 569701a..571db1f 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -2398,7 +2398,9 @@ PHP_METHOD(SoapClient, SoapClient) Z_TYPE_PP(tmp) == IS_RESOURCE) { context = php_stream_context_from_zval(*tmp, 1); zend_list_addref(context->rsrc_id); - } + } else { + context = php_stream_context_alloc(); + } if (zend_hash_find(ht, "location", sizeof("location"), (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) {