summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Hristov <andrey@php.net>2014-01-29 15:32:02 +0200
committerAndrey Hristov <andrey@php.net>2014-01-29 15:32:02 +0200
commit1c7f54d4f7fe58f1d2c7ed00ca80d93dddc265ab (patch)
treeb981a37d3072a193d0fe9791fc75d3b3b83208f2
parentfb5c7cda5d776a84730c5133f27e72cb427f22ae (diff)
parent253a66c8d56e72b166b2d8ebfbc4b368eed4a9fb (diff)
downloadphp-git-1c7f54d4f7fe58f1d2c7ed00ca80d93dddc265ab.tar.gz
Merge branch 'PHP-5.6'
Conflicts: NEWS ext/openssl/xp_ssl.c
-rwxr-xr-xUPGRADING11
-rw-r--r--ext/mbstring/tests/zend_multibyte-02.phpt6
-rw-r--r--ext/mbstring/tests/zend_multibyte-06.phpt6
-rw-r--r--ext/mbstring/tests/zend_multibyte-10.phpt4
-rw-r--r--ext/mbstring/tests/zend_multibyte-11.phpt4
-rw-r--r--ext/mbstring/tests/zend_multibyte-12.phpt4
-rw-r--r--ext/mysqli/mysqli.c2
-rw-r--r--ext/mysqli/mysqli_api.c14
-rw-r--r--ext/mysqli/mysqli_fe.c4
-rw-r--r--ext/mysqli/mysqli_fe.h1
-rw-r--r--ext/mysqli/mysqli_nonapi.c17
-rw-r--r--ext/mysqli/php_mysqli_structs.h1
-rw-r--r--ext/mysqli/tests/mysqli_pconn_max_links.phpt98
-rw-r--r--ext/openssl/openssl.c54
-rw-r--r--ext/openssl/php_openssl_structs.h42
-rw-r--r--ext/openssl/tests/bug46127.phpt5
-rw-r--r--ext/openssl/tests/bug48182.phpt10
-rw-r--r--ext/openssl/tests/openssl_peer_fingerprint.phpt4
-rw-r--r--ext/openssl/tests/peer_verification.phpt56
-rw-r--r--ext/openssl/tests/sni_001.phpt1
-rw-r--r--ext/openssl/tests/streams_crypto_method.phpt1
-rw-r--r--ext/openssl/xp_ssl.c64
-rw-r--r--ext/zip/lib/zipconf.h2
-rw-r--r--ext/zip/php_zip.h2
-rw-r--r--main/php_ini.c106
25 files changed, 402 insertions, 117 deletions
diff --git a/UPGRADING b/UPGRADING
index f5e36fefc8..79f7875593 100755
--- a/UPGRADING
+++ b/UPGRADING
@@ -24,6 +24,17 @@ PHP X.Y UPGRADE NOTES
. dba_delete() now returns false if the key was not found for the inifile
handler, too.
+- openssl:
+ To prevent Man-in-the-Middle attacks against encrypted transfers client
+ streams now verify peer certificates by default. Previous versions
+ required users to manually enable peer verification. As a result of this
+ change, existing code using ssl:// or tls:// stream wrappers (e.g.
+ file_get_contents(), fsockopen(), stream_socket_client()) may no longer
+ connect successfully without manually disabling peer verification via the
+ stream context's "verify_peer" setting. Encrypted transfers delegate to
+ operating system certificate stores by default, so many/most users *should*
+ be unaffected by this transparent security enhancement.
+
========================================
2. New Features
========================================
diff --git a/ext/mbstring/tests/zend_multibyte-02.phpt b/ext/mbstring/tests/zend_multibyte-02.phpt
index 8e15ae8849..84eae89d9e 100644
--- a/ext/mbstring/tests/zend_multibyte-02.phpt
+++ b/ext/mbstring/tests/zend_multibyte-02.phpt
@@ -1,8 +1,6 @@
--TEST--
zend multibyte (2)
--SKIPIF--
---XFAIL--
-https://bugs.php.net/bug.php?id=66582
--INI--
zend.multibyte=On
zend.script_encoding=UTF-8
@@ -11,5 +9,5 @@ mbstring.internal_encoding=CP932
<?php
var_dump(bin2hex("テスト"));
?>
---EXPECT--
-string(12) "836583588367"
+--EXPECTF--
+php: Zend/zend_language_scanner.l:%d: encoding_filter_script_to_internal: Assertion `internal_encoding && zend_multibyte_check_lexer_compatibility(internal_encoding)' failed.
diff --git a/ext/mbstring/tests/zend_multibyte-06.phpt b/ext/mbstring/tests/zend_multibyte-06.phpt
index 024a67bbb6..11e263f0b6 100644
--- a/ext/mbstring/tests/zend_multibyte-06.phpt
+++ b/ext/mbstring/tests/zend_multibyte-06.phpt
@@ -1,8 +1,6 @@
--TEST--
zend multibyte (6)
--SKIPIF--
---XFAIL--
-https://bugs.php.net/bug.php?id=66582
--INI--
zend.multibyte=On
zend.script_encoding=EUC-JP
@@ -12,5 +10,5 @@ mbstring.internal_encoding=CP932
declare(encoding="UTF-8");
var_dump(bin2hex("テスト"));
?>
---EXPECT--
-string(12) "836583588367"
+--EXPECTF--
+php: Zend/zend_language_scanner.l:%d: encoding_filter_script_to_internal: Assertion `internal_encoding && zend_multibyte_check_lexer_compatibility(internal_encoding)' failed.
diff --git a/ext/mbstring/tests/zend_multibyte-10.phpt b/ext/mbstring/tests/zend_multibyte-10.phpt
index 4d448a8ccf..139d973b95 100644
--- a/ext/mbstring/tests/zend_multibyte-10.phpt
+++ b/ext/mbstring/tests/zend_multibyte-10.phpt
@@ -1,8 +1,8 @@
--TEST--
zend multibyte (10)
--SKIPIF--
---XFAIL--
-https://bugs.php.net/bug.php?id=66582
+--INI--
+zend.multibyte=1
--FILE--
<?php
declare(encoding="ISO-8859-15");
diff --git a/ext/mbstring/tests/zend_multibyte-11.phpt b/ext/mbstring/tests/zend_multibyte-11.phpt
index 91a7d8c44b..c6e45fa5cd 100644
--- a/ext/mbstring/tests/zend_multibyte-11.phpt
+++ b/ext/mbstring/tests/zend_multibyte-11.phpt
@@ -1,8 +1,8 @@
--TEST--
zend multibyte (11)
--SKIPIF--
---XFAIL--
-https://bugs.php.net/bug.php?id=66582
+--INI--
+zend.multibyte=1
--FILE--
<?php
declare(encoding="ISO-8859-15") {
diff --git a/ext/mbstring/tests/zend_multibyte-12.phpt b/ext/mbstring/tests/zend_multibyte-12.phpt
index 2f2606244c..90968e8820 100644
--- a/ext/mbstring/tests/zend_multibyte-12.phpt
+++ b/ext/mbstring/tests/zend_multibyte-12.phpt
@@ -1,8 +1,8 @@
--TEST--
zend multibyte (12)
--SKIPIF--
---XFAIL--
-https://bugs.php.net/bug.php?id=66582
+--INI--
+zend.multibyte=1
--FILE--
<?php
declare(encoding="ISO-8859-15");
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
index 929f776a43..2a5a8c61ff 100644
--- a/ext/mysqli/mysqli.c
+++ b/ext/mysqli/mysqli.c
@@ -558,6 +558,7 @@ PHP_INI_BEGIN()
STD_PHP_INI_ENTRY_EX("mysqli.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_mysqli_globals, mysqli_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX("mysqli.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_mysqli_globals, mysqli_globals, display_link_numbers)
STD_PHP_INI_BOOLEAN("mysqli.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_persistent, zend_mysqli_globals, mysqli_globals)
+ STD_PHP_INI_BOOLEAN("mysqli.rollback_on_cached_plink", "0",PHP_INI_SYSTEM, OnUpdateBool, rollback_on_cached_plink, zend_mysqli_globals, mysqli_globals)
STD_PHP_INI_ENTRY("mysqli.default_host", NULL, PHP_INI_ALL, OnUpdateString, default_host, zend_mysqli_globals, mysqli_globals)
STD_PHP_INI_ENTRY("mysqli.default_user", NULL, PHP_INI_ALL, OnUpdateString, default_user, zend_mysqli_globals, mysqli_globals)
STD_PHP_INI_ENTRY("mysqli.default_pw", NULL, PHP_INI_ALL, OnUpdateString, default_pw, zend_mysqli_globals, mysqli_globals)
@@ -597,6 +598,7 @@ static PHP_GINIT_FUNCTION(mysqli)
#else
mysqli_globals->embedded = 0;
#endif
+ mysqli_globals->rollback_on_cached_plink = FALSE;
}
/* }}} */
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c
index 9028401595..d6f274b569 100644
--- a/ext/mysqli/mysqli_api.c
+++ b/ext/mysqli/mysqli_api.c
@@ -599,10 +599,20 @@ void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status TSRM
#if defined(MYSQLI_USE_MYSQLND)
mysqlnd_end_psession(mysql->mysql);
#endif
- zend_ptr_stack_push(&plist->free_links, mysql->mysql);
+ if (MyG(rollback_on_cached_plink) &&
+#if !defined(MYSQLI_USE_MYSQLND)
+ mysqli_commit_or_rollback_libmysql(mysql->mysql, FALSE, TRANS_COR_NO_OPT, NULL))
+#else
+ FAIL == mysqlnd_rollback(mysql->mysql, TRANS_COR_NO_OPT, NULL))
+#endif
+ {
+ mysqli_close(mysql->mysql, close_type);
+ } else {
+ zend_ptr_stack_push(&plist->free_links, mysql->mysql);
+ MyG(num_inactive_persistent)++;
+ }
MyG(num_active_persistent)--;
- MyG(num_inactive_persistent)++;
}
}
mysql->persistent = FALSE;
diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c
index 61e8e5c81e..3d31b8183c 100644
--- a/ext/mysqli/mysqli_fe.c
+++ b/ext/mysqli/mysqli_fe.c
@@ -373,6 +373,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_refresh, 0, 0, 1)
ZEND_ARG_INFO(0, options)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_no_options, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
/* {{{ mysqli_functions[]
*
@@ -425,6 +428,7 @@ const zend_function_entry mysqli_functions[] = {
#endif
PHP_FE(mysqli_get_client_info, arginfo_mysqli_only_link)
PHP_FE(mysqli_get_client_version, arginfo_mysqli_only_link)
+ PHP_FE(mysqli_get_links_stats, arginfo_mysqli_no_options)
PHP_FE(mysqli_get_host_info, arginfo_mysqli_only_link)
PHP_FE(mysqli_get_proto_info, arginfo_mysqli_only_link)
PHP_FE(mysqli_get_server_info, arginfo_mysqli_only_link)
diff --git a/ext/mysqli/mysqli_fe.h b/ext/mysqli/mysqli_fe.h
index d5ae8a6ff9..9a9f851248 100644
--- a/ext/mysqli/mysqli_fe.h
+++ b/ext/mysqli/mysqli_fe.h
@@ -60,6 +60,7 @@ PHP_FUNCTION(mysqli_get_charset);
PHP_FUNCTION(mysqli_get_client_info);
PHP_FUNCTION(mysqli_get_client_version);
PHP_FUNCTION(mysqli_get_host_info);
+PHP_FUNCTION(mysqli_get_links_stats);
PHP_FUNCTION(mysqli_get_proto_info);
PHP_FUNCTION(mysqli_get_server_info);
PHP_FUNCTION(mysqli_get_server_version);
diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c
index db0352baeb..312f2806ce 100644
--- a/ext/mysqli/mysqli_nonapi.c
+++ b/ext/mysqli/mysqli_nonapi.c
@@ -1207,6 +1207,23 @@ PHP_FUNCTION(mysqli_release_savepoint)
/* }}} */
+/* {{{ proto bool mysqli_get_links_stats()
+ Returns information about open and cached links */
+PHP_FUNCTION(mysqli_get_links_stats)
+{
+ if (ZEND_NUM_ARGS()) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "no parameters expected");
+ return;
+ }
+ array_init(return_value);
+ add_assoc_long_ex(return_value, "total", sizeof("total"), MyG(num_links));
+ add_assoc_long_ex(return_value, "active_plinks", sizeof("active_plinks"), MyG(num_active_persistent));
+ add_assoc_long_ex(return_value, "cached_plinks", sizeof("cached_plinks"), MyG(num_inactive_persistent));
+}
+/* }}} */
+
+
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h
index e7c02f9c9b..cc0c8fe63f 100644
--- a/ext/mysqli/php_mysqli_structs.h
+++ b/ext/mysqli/php_mysqli_structs.h
@@ -334,6 +334,7 @@ ZEND_BEGIN_MODULE_GLOBALS(mysqli)
HashTable *report_ht;
unsigned long multi_query;
unsigned long embedded;
+ zend_bool rollback_on_cached_plink;
ZEND_END_MODULE_GLOBALS(mysqli)
diff --git a/ext/mysqli/tests/mysqli_pconn_max_links.phpt b/ext/mysqli/tests/mysqli_pconn_max_links.phpt
index e87ef00b21..99e51e7c5e 100644
--- a/ext/mysqli/tests/mysqli_pconn_max_links.phpt
+++ b/ext/mysqli/tests/mysqli_pconn_max_links.phpt
@@ -42,6 +42,7 @@ Persistent connections and mysqli.max_links
--INI--
mysqli.allow_persistent=1
mysqli.max_persistent=2
+mysqli.rollback_on_cached_plink=1
--FILE--
<?php
require_once("connect.inc");
@@ -58,10 +59,18 @@ mysqli.max_persistent=2
mysqli_errno($plink), mysqli_error($plink));
}
+ var_dump(mysqli_get_links_stats(1));
+
+ echo "Before pconnect:";
+ var_dump(mysqli_get_links_stats());
+
if (!$plink = my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket))
printf("[001] Cannot connect using the second DB user created during SKIPIF, [%d] %s\n",
mysqli_connect_errno(), mysqli_connect_error());
+ echo "After pconnect:";
+ var_dump(mysqli_get_links_stats());
+
ob_start();
phpinfo();
$phpinfo = strip_tags(ob_get_contents());
@@ -110,11 +119,17 @@ mysqli.max_persistent=2
if (isset($running_threads[$pthread_id]))
printf("[009] Persistent connection has not been killed\n");
+ echo "Before second pconnect:";
+ var_dump(mysqli_get_links_stats());
+
// this fails and we have 0 (<= $num_plinks) connections
if ($plink = @my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket))
printf("[010] Can connect using the old password, [%d] %s\n",
mysqli_connect_errno($link), mysqli_connect_error($link));
+ echo "After second pconnect:";
+ var_dump(mysqli_get_links_stats());
+
ob_start();
phpinfo();
$phpinfo = strip_tags(ob_get_contents());
@@ -123,7 +138,13 @@ mysqli.max_persistent=2
if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches))
printf("[010] Cannot get # of active persistent links from phpinfo()\n");
+ var_dump(mysqli_get_links_stats());
+
$num_plinks_kill = $matches[1];
+ $sstats = mysqli_get_links_stats();
+ if ($sstats['active_plinks'] != $num_plinks_kill) {
+ printf("[010.2] Num of active plinks differ %s %s\n", $sstats['active_plinks'], $num_plinks_kill);
+ }
if ($num_plinks_kill > $num_plinks)
printf("[011] Expecting Active Persistent Links < %d, got %d\n", $num_plinks, $num_plinks_kill);
@@ -141,9 +162,11 @@ mysqli.max_persistent=2
mysqli_free_result($res);
var_dump($row);
- if ($plink2 = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket))
+ if ($plink2 = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) {
printf("[015] Can open more persistent connections than allowed, [%d] %s\n",
mysqli_connect_errno(), mysqli_connect_error());
+ var_dump(mysqli_get_links_stats());
+ }
ob_start();
phpinfo();
@@ -179,18 +202,71 @@ mysqli_query($link, 'DROP USER pcontest');
mysqli_close($link);
?>
--EXPECTF--
-array(2) {
- [%u|b%"id"]=>
- %unicode|string%(1) "1"
- [%u|b%"label"]=>
- %unicode|string%(1) "a"
+Warning: mysqli_get_links_stats(): no parameters expected in %s on line %d
+NULL
+Before pconnect:array(3) {
+ ["total"]=>
+ int(1)
+ ["active_plinks"]=>
+ int(0)
+ ["cached_plinks"]=>
+ int(0)
+}
+After pconnect:array(3) {
+ ["total"]=>
+ int(2)
+ ["active_plinks"]=>
+ int(1)
+ ["cached_plinks"]=>
+ int(0)
}
array(2) {
- [%u|b%"id"]=>
- %unicode|string%(1) "1"
- [%u|b%"label"]=>
- %unicode|string%(1) "a"
+ ["id"]=>
+ string(1) "1"
+ ["label"]=>
+ string(1) "a"
+}
+Before second pconnect:array(3) {
+ ["total"]=>
+ int(2)
+ ["active_plinks"]=>
+ int(1)
+ ["cached_plinks"]=>
+ int(0)
}
-Warning: %s: Too many open persistent links (%d) in %s on line %d
+Warning: main(): MySQL server has gone away in %s on line %d
+
+Warning: main(): Error reading result set's header in %s line %d
+After second pconnect:array(3) {
+ ["total"]=>
+ int(1)
+ ["active_plinks"]=>
+ int(0)
+ ["cached_plinks"]=>
+ int(0)
+}
+array(3) {
+ ["total"]=>
+ int(1)
+ ["active_plinks"]=>
+ int(0)
+ ["cached_plinks"]=>
+ int(0)
+}
+array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["label"]=>
+ string(1) "a"
+}
+[015] Can open more persistent connections than allowed, [0]
+array(3) {
+ ["total"]=>
+ int(3)
+ ["active_plinks"]=>
+ int(2)
+ ["cached_plinks"]=>
+ int(0)
+}
done! \ No newline at end of file
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index b38dd6d206..d57b3eafde 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -27,7 +27,9 @@
#endif
#include "php.h"
+#include "php_ini.h"
#include "php_openssl.h"
+#include "php_openssl_structs.h"
/* PHP Includes */
#include "ext/standard/file.h"
@@ -1071,6 +1073,13 @@ static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(long algo) { /* {
}
/* }}} */
+/* {{{ INI Settings */
+PHP_INI_BEGIN()
+ PHP_INI_ENTRY("openssl.cafile", NULL, PHP_INI_ALL, NULL)
+ PHP_INI_ENTRY("openssl.capath", NULL, PHP_INI_ALL, NULL)
+PHP_INI_END()
+/* }}} */
+
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(openssl)
@@ -1203,7 +1212,9 @@ PHP_MINIT_FUNCTION(openssl)
php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC);
php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC);
-
+
+ REGISTER_INI_ENTRIES();
+
return SUCCESS;
}
/* }}} */
@@ -1217,6 +1228,7 @@ PHP_MINFO_FUNCTION(openssl)
php_info_print_table_row(2, "OpenSSL Library Version", SSLeay_version(SSLEAY_VERSION));
php_info_print_table_row(2, "OpenSSL Header Version", OPENSSL_VERSION_TEXT);
php_info_print_table_end();
+ DISPLAY_INI_ENTRIES();
}
/* }}} */
@@ -1243,6 +1255,8 @@ PHP_MSHUTDOWN_FUNCTION(openssl)
/* reinstate the default tcp handler */
php_stream_xport_register("tcp", php_stream_generic_socket_factory TSRMLS_CC);
+ UNREGISTER_INI_ENTRIES();
+
return SUCCESS;
}
/* }}} */
@@ -5063,9 +5077,13 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
zval **val = NULL;
char *cnmatch = NULL;
int err;
+ php_openssl_netstream_data_t *sslsock;
+
+ sslsock = (php_openssl_netstream_data_t*)stream->abstract;
- /* verification is turned off */
- if (!(GET_VER_OPT("verify_peer") && zval_is_true(*val))) {
+ if (!(GET_VER_OPT("verify_peer") || sslsock->is_client)
+ || (GET_VER_OPT("verify_peer") && !zval_is_true(*val))
+ ) {
return SUCCESS;
}
@@ -5105,6 +5123,11 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
GET_VER_OPT_STRING("CN_match", cnmatch);
+ /* If no CN_match was specified assign the autodetected name when connecting as a client */
+ if (cnmatch == NULL && sslsock->is_client) {
+ cnmatch = sslsock->url_name;
+ }
+
if (cnmatch) {
if (matches_san_list(peer, cnmatch TSRMLS_CC)) {
return SUCCESS;
@@ -5150,7 +5173,9 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{
ERR_clear_error();
/* look at context options in the stream and set appropriate verification flags */
- if (GET_VER_OPT("verify_peer") && zval_is_true(*val)) {
+ if (GET_VER_OPT("verify_peer") && !zval_is_true(*val)) {
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
+ } else {
/* turn on verification callback */
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
@@ -5159,19 +5184,35 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{
GET_VER_OPT_STRING("cafile", cafile);
GET_VER_OPT_STRING("capath", capath);
+ if (!cafile) {
+ zend_bool exists = 1;
+ cafile = zend_ini_string_ex("openssl.cafile", sizeof("openssl.cafile"), 0, &exists);
+ }
+
+ if (!capath) {
+ zend_bool exists = 1;
+ capath = zend_ini_string_ex("openssl.capath", sizeof("openssl.capath"), 0, &exists);
+ }
+
if (cafile || capath) {
if (!SSL_CTX_load_verify_locations(ctx, cafile, capath)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set verify locations `%s' `%s'", cafile, capath);
return NULL;
}
+ } else {
+ php_openssl_netstream_data_t *sslsock;
+ sslsock = (php_openssl_netstream_data_t*)stream->abstract;
+ if (sslsock->is_client && !SSL_CTX_set_default_verify_paths(ctx)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Unable to set default verify locations and no CA settings specified");
+ return NULL;
+ }
}
if (GET_VER_OPT("verify_depth")) {
convert_to_long_ex(val);
SSL_CTX_set_verify_depth(ctx, Z_LVAL_PP(val));
}
- } else {
- SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
}
/* callback for the passphrase (for localcert) */
@@ -5237,6 +5278,7 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{
}
}
}
+
if (ok) {
SSL *ssl = SSL_new(ctx);
diff --git a/ext/openssl/php_openssl_structs.h b/ext/openssl/php_openssl_structs.h
new file mode 100644
index 0000000000..13f8f320f8
--- /dev/null
+++ b/ext/openssl/php_openssl_structs.h
@@ -0,0 +1,42 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Wez Furlong <wez@thebrainroom.com> |
+ | Daniel Lowrey <rdlowrey@gmail.com> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include "php_network.h"
+#include <openssl/ssl.h>
+
+/* This implementation is very closely tied to the that of the native
+ * sockets implemented in the core.
+ * Don't try this technique in other extensions!
+ * */
+
+typedef struct _php_openssl_netstream_data_t {
+ php_netstream_data_t s;
+ SSL *ssl_handle;
+ SSL_CTX *ctx;
+ struct timeval connect_timeout;
+ int enable_on_connect;
+ int is_client;
+ int ssl_active;
+ php_stream_xport_crypt_method_t method;
+ char *url_name;
+ unsigned state_set:1;
+ unsigned _spare:31;
+} php_openssl_netstream_data_t;
diff --git a/ext/openssl/tests/bug46127.phpt b/ext/openssl/tests/bug46127.phpt
index a3bfd3a012..1de4eacd01 100644
--- a/ext/openssl/tests/bug46127.phpt
+++ b/ext/openssl/tests/bug46127.phpt
@@ -45,7 +45,10 @@ if ($pid == 0) { // child
// client or failed
sleep(1);
-$sock = fsockopen('ssl://127.0.0.1', $port, $errno, $errstr);
+$ctx = stream_context_create(['ssl' => [
+ 'verify_peer' => false
+]]);
+$sock = stream_socket_client("ssl://127.0.0.1:{$port}", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ctx);
if (!$sock) exit;
echo fgets($sock);
diff --git a/ext/openssl/tests/bug48182.phpt b/ext/openssl/tests/bug48182.phpt
index 146c4c9226..b78ce57074 100644
--- a/ext/openssl/tests/bug48182.phpt
+++ b/ext/openssl/tests/bug48182.phpt
@@ -13,8 +13,7 @@ function ssl_server($port) {
$host = 'ssl://127.0.0.1'.':'.$port;
$flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
$data = "Sending bug48182\n";
-
- $pem = dirname(__FILE__) . '/bug46127.pem';
+ $pem = dirname(__FILE__) . '/bug54992.pem';
$ssl_params = array( 'verify_peer' => false, 'allow_self_signed' => true, 'local_cert' => $pem);
$ssl = array('ssl' => $ssl_params);
@@ -47,8 +46,11 @@ function ssl_async_client($port) {
$host = 'ssl://127.0.0.1'.':'.$port;
$flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT;
$data = "Sending data over to SSL server in async mode with contents like Hello World\n";
-
- $socket = stream_socket_client($host, $errno, $errstr, 10, $flags);
+ $context = stream_context_create(array('ssl' => array(
+ 'cafile' => dirname(__FILE__) . '/bug54992-ca.pem',
+ 'CN_match' => 'bug54992.local'
+ )));
+ $socket = stream_socket_client($host, $errno, $errstr, 10, $flags, $context);
stream_set_blocking($socket, 0);
while ($socket && $data) {
diff --git a/ext/openssl/tests/openssl_peer_fingerprint.phpt b/ext/openssl/tests/openssl_peer_fingerprint.phpt
index 2960dffae5..2e4c192c03 100644
--- a/ext/openssl/tests/openssl_peer_fingerprint.phpt
+++ b/ext/openssl/tests/openssl_peer_fingerprint.phpt
@@ -24,6 +24,7 @@ if ($pid == -1) {
'verify_peer' => true,
'cafile' => __DIR__ . '/bug54992-ca.pem',
'capture_peer_cert' => true,
+ 'CN_match' => 'bug54992.local',
'peer_fingerprint' => '81cafc260aa8d82956ebc6212a362ece',
)
)
@@ -38,6 +39,7 @@ if ($pid == -1) {
'verify_peer' => true,
'cafile' => __DIR__ . '/bug54992-ca.pem',
'capture_peer_cert' => true,
+ 'CN_match' => 'bug54992.local',
'peer_fingerprint' => array(
'sha256' => '78ea579f2c3b439359dec5dac9d445108772927427c4780037e87df3799a0aa0',
),
@@ -59,4 +61,4 @@ Warning: stream_socket_client(): Failed to enable crypto in %s on line %d
Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 (Unknown error) in %s on line %d
bool(false)
-resource(9) of type (stream)
+resource(%d) of type (stream)
diff --git a/ext/openssl/tests/peer_verification.phpt b/ext/openssl/tests/peer_verification.phpt
new file mode 100644
index 0000000000..7c3347fd65
--- /dev/null
+++ b/ext/openssl/tests/peer_verification.phpt
@@ -0,0 +1,56 @@
+--TEST--
+Peer verification enabled for client streams
+--SKIPIF--
+<?php
+if (!extension_loaded("openssl")) die("skip");
+if (!function_exists('pcntl_fork')) die("skip no fork");
+--FILE--
+<?php
+$flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
+$ctx = stream_context_create(['ssl' => [
+ 'local_cert' => __DIR__ . '/bug54992.pem',
+ 'allow_self_signed' => true
+]]);
+$server = stream_socket_server('ssl://127.0.0.1:64321', $errno, $errstr, $flags, $ctx);
+
+$pid = pcntl_fork();
+if ($pid == -1) {
+ die('could not fork');
+} else if ($pid) {
+ // Expected to fail -- no CA File present
+ var_dump(@stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, STREAM_CLIENT_CONNECT));
+
+ // Expected to fail -- no CA File present
+ $ctx = stream_context_create(['ssl' => ['verify_peer' => true]]);
+ var_dump(@stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, STREAM_CLIENT_CONNECT, $ctx));
+
+ // Should succeed with peer verification disabled in context
+ $ctx = stream_context_create(['ssl' => ['verify_peer' => false]]);
+ var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, STREAM_CLIENT_CONNECT, $ctx));
+
+ // Should succeed with CA file specified in context
+ $ctx = stream_context_create(['ssl' => [
+ 'cafile' => __DIR__ . '/bug54992-ca.pem',
+ 'CN_match' => 'bug54992.local',
+ ]]);
+ var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, STREAM_CLIENT_CONNECT, $ctx));
+
+ // Should succeed with globally available CA file specified via php.ini
+ $cafile = __DIR__ . '/bug54992-ca.pem';
+ ini_set('openssl.cafile', $cafile);
+ var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, STREAM_CLIENT_CONNECT, $ctx));
+
+} else {
+ @pcntl_wait($status);
+ @stream_socket_accept($server, 3);
+ @stream_socket_accept($server, 3);
+ @stream_socket_accept($server, 3);
+ @stream_socket_accept($server, 3);
+ @stream_socket_accept($server, 3);
+}
+--EXPECTF--
+bool(false)
+bool(false)
+resource(%d) of type (stream)
+resource(%d) of type (stream)
+resource(%d) of type (stream)
diff --git a/ext/openssl/tests/sni_001.phpt b/ext/openssl/tests/sni_001.phpt
index 3d7798cf85..2f76a9f918 100644
--- a/ext/openssl/tests/sni_001.phpt
+++ b/ext/openssl/tests/sni_001.phpt
@@ -24,6 +24,7 @@ function context() {
return stream_context_create(array(
'ssl' => array(
'capture_peer_cert' => true,
+ 'verify_peer' => false
),
));
}
diff --git a/ext/openssl/tests/streams_crypto_method.phpt b/ext/openssl/tests/streams_crypto_method.phpt
index 97a6e9ee8b..981f56b399 100644
--- a/ext/openssl/tests/streams_crypto_method.phpt
+++ b/ext/openssl/tests/streams_crypto_method.phpt
@@ -10,6 +10,7 @@ if (!extension_loaded('pcntl')) die('skip, pcntl required');
function client($port, $method) {
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'crypto_method', $method);
+ stream_context_set_option($ctx, 'ssl', 'verify_peer', false);
$fp = @fopen('https://127.0.0.1:' . $port . '/', 'r', false, $ctx);
if ($fp) {
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index 244f04def9..61ba0271cb 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -23,8 +23,8 @@
#include "ext/standard/url.h"
#include "streams/php_streams_int.h"
#include "ext/standard/php_smart_str.h"
-#include "php_network.h"
#include "php_openssl.h"
+#include "php_openssl_structs.h"
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/err.h>
@@ -41,25 +41,6 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC);
int php_openssl_get_x509_list_id(void);
-/* This implementation is very closely tied to the that of the native
- * sockets implemented in the core.
- * Don't try this technique in other extensions!
- * */
-
-typedef struct _php_openssl_netstream_data_t {
- php_netstream_data_t s;
- SSL *ssl_handle;
- SSL_CTX *ctx;
- struct timeval connect_timeout;
- int enable_on_connect;
- int is_client;
- int ssl_active;
- php_stream_xport_crypt_method_t method;
- char *sni;
- unsigned state_set:1;
- unsigned _spare:31;
-} php_openssl_netstream_data_t;
-
php_stream_ops php_openssl_socket_ops;
/* it doesn't matter that we do some hash traversal here, since it is done only
@@ -285,11 +266,12 @@ static int php_openssl_sockop_close(php_stream *stream, int close_handle TSRMLS_
}
}
- if (sslsock->sni) {
- pefree(sslsock->sni, php_stream_is_persistent(stream));
+ if (sslsock->url_name) {
+ pefree(sslsock->url_name, php_stream_is_persistent(stream));
}
+
pefree(sslsock, php_stream_is_persistent(stream));
-
+
return 0;
}
@@ -467,12 +449,25 @@ static inline int php_openssl_setup_crypto(php_stream *stream,
return 0;
}
+static void enable_server_name_indication(php_stream_context *ctx, php_openssl_netstream_data_t *sslsock)
+{
+ zval **val = NULL;
+
+ if (php_stream_context_get_option(ctx, "ssl", "SNI_server_name", &val) == SUCCESS) {
+ convert_to_string_ex(val);
+ SSL_set_tlsext_host_name(sslsock->ssl_handle, &val);
+ } else if (sslsock->url_name) {
+ SSL_set_tlsext_host_name(sslsock->ssl_handle, sslsock->url_name);
+ }
+}
+
static inline int php_openssl_enable_crypto(php_stream *stream,
php_openssl_netstream_data_t *sslsock,
php_stream_xport_crypto_param *cparam
TSRMLS_DC)
{
int n, retry = 1;
+ zval **val = NULL;
if (cparam->inputs.activate && !sslsock->ssl_active) {
struct timeval start_time,
@@ -481,9 +476,14 @@ static inline int php_openssl_enable_crypto(php_stream *stream,
has_timeout = 0;
#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
- if (sslsock->is_client && sslsock->sni) {
- SSL_set_tlsext_host_name(sslsock->ssl_handle, sslsock->sni);
+
+ if (sslsock->is_client
+ && (php_stream_context_get_option(stream->context, "ssl", "SNI_enabled", &val) == FAILURE
+ || zend_is_true(*val TSRMLS_CC))
+ ) {
+ enable_server_name_indication(stream->context, sslsock);
}
+
#endif
if (!sslsock->state_set) {
@@ -920,7 +920,7 @@ static int get_crypto_method(php_stream_context *ctx) {
return STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
}
-static char * get_sni(php_stream_context *ctx, const char *resourcename, size_t resourcenamelen, int is_persistent TSRMLS_DC) {
+static char * get_url_name(const char *resourcename, size_t resourcenamelen, int is_persistent TSRMLS_DC) {
php_url *url;
if (ctx) {
@@ -946,7 +946,7 @@ static char * get_sni(php_stream_context *ctx, const char *resourcename, size_t
if (url->host) {
const char * host = url->host;
- char * sni = NULL;
+ char * url_name = NULL;
size_t len = strlen(host);
/* skip trailing dots */
@@ -955,11 +955,11 @@ static char * get_sni(php_stream_context *ctx, const char *resourcename, size_t
}
if (len) {
- sni = pestrndup(host, len, is_persistent);
+ url_name = pestrndup(host, len, is_persistent);
}
php_url_free(url);
- return sni;
+ return url_name;
}
php_url_free(url);
@@ -1001,8 +1001,6 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
return NULL;
}
- sslsock->sni = get_sni(context, resourcename, resourcenamelen, !!persistent_id TSRMLS_CC);
-
if (strncmp(proto, "ssl", protolen) == 0) {
sslsock->enable_on_connect = 1;
@@ -1042,7 +1040,9 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
return NULL;
#endif
}
-
+
+ sslsock->url_name = get_url_name(resourcename, resourcenamelen, !!persistent_id TSRMLS_CC);
+
return stream;
}
diff --git a/ext/zip/lib/zipconf.h b/ext/zip/lib/zipconf.h
index 1cb5c0467a..955d85b4ef 100644
--- a/ext/zip/lib/zipconf.h
+++ b/ext/zip/lib/zipconf.h
@@ -7,7 +7,7 @@
This file was generated automatically by CMake
based on ../cmake-zipconf.h.in.
*/
-#define LIBZIP_VERSION "0.11.1"
+#define LIBZIP_VERSION "0.11.2"
/* #undef HAVE_INTTYPES_H_LIBZIP */
#if defined(_WIN32)
diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h
index 591b907aa8..ffe4530415 100644
--- a/ext/zip/php_zip.h
+++ b/ext/zip/php_zip.h
@@ -38,7 +38,7 @@ extern zend_module_entry zip_module_entry;
#define ZIP_OVERWRITE ZIP_TRUNCATE
#endif
-#define PHP_ZIP_VERSION "1.12.4-dev"
+#define PHP_ZIP_VERSION "1.12.4"
#if ((PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 2) || PHP_MAJOR_VERSION >= 6)
# define PHP_ZIP_USE_OO 1
diff --git a/main/php_ini.c b/main/php_ini.c
index 3bcb249f84..f7f4686e84 100644
--- a/main/php_ini.c
+++ b/main/php_ini.c
@@ -630,63 +630,81 @@ int php_init_config(TSRMLS_D)
zend_llist scanned_ini_list;
zend_llist_element *element;
int l, total_l = 0;
+ char *bufpath, *debpath, *endpath;
+ int lenpath;
- if ((ndir = php_scandir(php_ini_scanned_path, &namelist, 0, php_alphasort)) > 0) {
- zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
- memset(&fh2, 0, sizeof(fh2));
+ zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
+ memset(&fh2, 0, sizeof(fh2));
- for (i = 0; i < ndir; i++) {
+ bufpath = estrdup(php_ini_scanned_path);
+ for (debpath = bufpath ; debpath ; debpath=endpath) {
+ endpath = strchr(debpath, DEFAULT_DIR_SEPARATOR);
+ if (endpath) {
+ *(endpath++) = 0;
+ }
+ if (!debpath[0]) {
+ /* empty string means default builtin value
+ to allow "/foo/phd.d:" or ":/foo/php.d" */
+ debpath = PHP_CONFIG_FILE_SCAN_DIR;
+ }
+ lenpath = strlen(debpath);
- /* check for any file with .ini extension */
- if (!(p = strrchr(namelist[i]->d_name, '.')) || (p && strcmp(p, ".ini"))) {
- free(namelist[i]);
- continue;
- }
- /* Reset active ini section */
- RESET_ACTIVE_INI_HASH();
+ if (lenpath > 0 && (ndir = php_scandir(debpath, &namelist, 0, php_alphasort)) > 0) {
- if (IS_SLASH(php_ini_scanned_path[php_ini_scanned_path_len - 1])) {
- snprintf(ini_file, MAXPATHLEN, "%s%s", php_ini_scanned_path, namelist[i]->d_name);
- } else {
- snprintf(ini_file, MAXPATHLEN, "%s%c%s", php_ini_scanned_path, DEFAULT_SLASH, namelist[i]->d_name);
- }
- if (VCWD_STAT(ini_file, &sb) == 0) {
- if (S_ISREG(sb.st_mode)) {
- if ((fh2.handle.fp = VCWD_FOPEN(ini_file, "r"))) {
- fh2.filename = ini_file;
- fh2.type = ZEND_HANDLE_FP;
-
- if (zend_parse_ini_file(&fh2, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash TSRMLS_CC) == SUCCESS) {
- /* Here, add it to the list of ini files read */
- l = strlen(ini_file);
- total_l += l + 2;
- p = estrndup(ini_file, l);
- zend_llist_add_element(&scanned_ini_list, &p);
+ for (i = 0; i < ndir; i++) {
+
+ /* check for any file with .ini extension */
+ if (!(p = strrchr(namelist[i]->d_name, '.')) || (p && strcmp(p, ".ini"))) {
+ free(namelist[i]);
+ continue;
+ }
+ /* Reset active ini section */
+ RESET_ACTIVE_INI_HASH();
+
+ if (IS_SLASH(debpath[lenpath - 1])) {
+ snprintf(ini_file, MAXPATHLEN, "%s%s", debpath, namelist[i]->d_name);
+ } else {
+ snprintf(ini_file, MAXPATHLEN, "%s%c%s", debpath, DEFAULT_SLASH, namelist[i]->d_name);
+ }
+ if (VCWD_STAT(ini_file, &sb) == 0) {
+ if (S_ISREG(sb.st_mode)) {
+ if ((fh2.handle.fp = VCWD_FOPEN(ini_file, "r"))) {
+ fh2.filename = ini_file;
+ fh2.type = ZEND_HANDLE_FP;
+
+ if (zend_parse_ini_file(&fh2, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash TSRMLS_CC) == SUCCESS) {
+ /* Here, add it to the list of ini files read */
+ l = strlen(ini_file);
+ total_l += l + 2;
+ p = estrndup(ini_file, l);
+ zend_llist_add_element(&scanned_ini_list, &p);
+ }
}
}
}
+ free(namelist[i]);
}
- free(namelist[i]);
+ free(namelist);
}
- free(namelist);
+ }
+ efree(bufpath);
- if (total_l) {
- int php_ini_scanned_files_len = (php_ini_scanned_files) ? strlen(php_ini_scanned_files) + 1 : 0;
- php_ini_scanned_files = (char *) realloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1);
- if (!php_ini_scanned_files_len) {
- *php_ini_scanned_files = '\0';
- }
- total_l += php_ini_scanned_files_len;
- for (element = scanned_ini_list.head; element; element = element->next) {
- if (php_ini_scanned_files_len) {
- strlcat(php_ini_scanned_files, ",\n", total_l);
- }
- strlcat(php_ini_scanned_files, *(char **)element->data, total_l);
- strlcat(php_ini_scanned_files, element->next ? ",\n" : "\n", total_l);
+ if (total_l) {
+ int php_ini_scanned_files_len = (php_ini_scanned_files) ? strlen(php_ini_scanned_files) + 1 : 0;
+ php_ini_scanned_files = (char *) realloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1);
+ if (!php_ini_scanned_files_len) {
+ *php_ini_scanned_files = '\0';
+ }
+ total_l += php_ini_scanned_files_len;
+ for (element = scanned_ini_list.head; element; element = element->next) {
+ if (php_ini_scanned_files_len) {
+ strlcat(php_ini_scanned_files, ",\n", total_l);
}
+ strlcat(php_ini_scanned_files, *(char **)element->data, total_l);
+ strlcat(php_ini_scanned_files, element->next ? ",\n" : "\n", total_l);
}
- zend_llist_destroy(&scanned_ini_list);
}
+ zend_llist_destroy(&scanned_ini_list);
} else {
/* Make sure an empty php_ini_scanned_path ends up as NULL */
php_ini_scanned_path = NULL;