Skip to content

Added SoapClient constructor option 'ssl_method' to specify ssl method #335

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 64 additions & 2 deletions ext/soap/php_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
zval **proxy_host, **proxy_port, **tmp;
char *host;
char *name;
char *protocol;
long namelen;
int port;
int old_error_reporting;
Expand Down Expand Up @@ -189,7 +190,41 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
old_error_reporting = EG(error_reporting);
EG(error_reporting) &= ~(E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE);

namelen = spprintf(&name, 0, "%s://%s:%d", (use_ssl && !*use_proxy)? "ssl" : "tcp", host, port);
/* Changed ternary operator to an if/else so that additional comparisons can be done on the ssl_method property */
if (use_ssl && !*use_proxy) {
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_ssl_method", sizeof("_ssl_method"), (void **) &tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_LONG) {
/* uses contants declared in soap.c to determine ssl uri protocol */
switch (Z_LVAL_PP(tmp)) {
case SOAP_SSL_METHOD_TLS:
protocol = "tls";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which TLS version is this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if TLS is specified it will use TLS 1.0. This is a similar issue to this bug report: https://bugs.php.net/bug.php?id=65329

Essentially, specifying TLS will use the STREAM_CRYPTO_METHOD_TLS_CLIENT option when the OpenSSL library encryption methods are called. Specifying the crypto method STREAM_CRYPTO_METHOD_SSLv23_CLIENT will negotiate TLS 1.1 and 1.2 if OpenSSL is recent enough. The latest versions of the OpenSSL extensions do give specifications for crypto methods for TLS 1.1 and 1.2:

STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT

Given that the OpenSSL extension has been brought up to date with the new crypto methods, the SOAP extension could be patched to include a specification for TLS 1.1 and 1.2 as well.

On Jan 9, 2014, at 5:35 AM, dargolf notifications@github.com wrote:

In ext/soap/php_http.c:

@@ -189,7 +190,41 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
old_error_reporting = EG(error_reporting);
EG(error_reporting) &= ~(E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE);

  • namelen = spprintf(&name, 0, "%s://%s:%d", (use_ssl && !*use_proxy)? "ssl" : "tcp", host, port);
  • /* Changed ternary operator to an if/else so that additional comparisons can be done on the ssl_method property */
  • if (use_ssl && !*use_proxy) {
  •   if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_ssl_method", sizeof("_ssl_method"), (void **) &tmp) == SUCCESS &&
    
  •       Z_TYPE_PP(tmp) == IS_LONG) {
    
  •       /\* uses contants declared in soap.c to determine ssl uri protocol */
    
  •       switch (Z_LVAL_PP(tmp)) {
    
  •           case SOAP_SSL_METHOD_TLS:
    
  •               protocol = "tls";
    
    Which TLS version is this?


Reply to this email directly or view it on GitHub.

break;

case SOAP_SSL_METHOD_SSLv2:
protocol = "sslv2";
break;

case SOAP_SSL_METHOD_SSLv3:
protocol = "sslv3";
break;

case SOAP_SSL_METHOD_SSLv23:
protocol = "ssl";
break;

default:
protocol = "ssl";
break;

}
} else {
protocol = "ssl";
}
} else {
protocol = "tcp";
}

namelen = spprintf(&name, 0, "%s://%s:%d", protocol, host, port);

stream = php_stream_xport_create(name, namelen,
ENFORCE_SAFE_MODE | REPORT_ERRORS,
Expand Down Expand Up @@ -237,7 +272,34 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
}
/* enable SSL transport layer */
if (stream) {
if (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL TSRMLS_CC) < 0 ||
/* if a stream is created without encryption, check to see if SSL method parameter is specified and use
proper encrypyion method based on constants defined in soap.c */
int crypto_method = STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_ssl_method", sizeof("_ssl_method"), (void **) &tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_LONG) {
switch (Z_LVAL_PP(tmp)) {
case SOAP_SSL_METHOD_TLS:
crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
break;

case SOAP_SSL_METHOD_SSLv2:
crypto_method = STREAM_CRYPTO_METHOD_SSLv2_CLIENT;
break;

case SOAP_SSL_METHOD_SSLv3:
crypto_method = STREAM_CRYPTO_METHOD_SSLv3_CLIENT;
break;

case SOAP_SSL_METHOD_SSLv23:
crypto_method = STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
break;

default:
crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
break;
}
}
if (php_stream_xport_crypto_setup(stream, crypto_method, NULL TSRMLS_CC) < 0 ||
php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) {
php_stream_close(stream);
stream = NULL;
Expand Down
7 changes: 7 additions & 0 deletions ext/soap/php_soap.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ struct _soapService {
#define WSDL_CACHE_MEMORY 0x2
#define WSDL_CACHE_BOTH 0x3

/* New SOAP SSL Method Constants */
#define SOAP_SSL_METHOD_TLS 0
#define SOAP_SSL_METHOD_SSLv2 1
#define SOAP_SSL_METHOD_SSLv3 2
#define SOAP_SSL_METHOD_SSLv23 3


ZEND_BEGIN_MODULE_GLOBALS(soap)
HashTable defEncNs; /* mapping of default namespaces to prefixes */
HashTable defEnc;
Expand Down
11 changes: 11 additions & 0 deletions ext/soap/soap.c
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,12 @@ PHP_MINIT_FUNCTION(soap)
REGISTER_LONG_CONSTANT("WSDL_CACHE_MEMORY", WSDL_CACHE_MEMORY, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("WSDL_CACHE_BOTH", WSDL_CACHE_BOTH, CONST_CS | CONST_PERSISTENT);

/* New SOAP SSL Method Constants */
REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_TLS", SOAP_SSL_METHOD_TLS, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv2", SOAP_SSL_METHOD_SSLv2, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv3", SOAP_SSL_METHOD_SSLv3, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv23", SOAP_SSL_METHOD_SSLv23, CONST_CS | CONST_PERSISTENT);

old_error_handler = zend_error_cb;
zend_error_cb = soap_error_handler;

Expand Down Expand Up @@ -2691,6 +2697,11 @@ PHP_METHOD(SoapClient, SoapClient)
Z_TYPE_PP(tmp) == IS_STRING) {
add_property_stringl(this_ptr, "_user_agent", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
}

if (zend_hash_find(ht, "ssl_method", sizeof("ssl_method"), (void**)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_LONG) {
add_property_long(this_ptr, "_ssl_method", Z_LVAL_PP(tmp));
}
} else if (Z_TYPE_P(wsdl) == IS_NULL) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "'location' and 'uri' options are required in nonWSDL mode");
}
Expand Down