Commit 51b934d4450 for php.net
commit 51b934d445074fdae28a744d2b094297136137cd
Author: Gina Peter Banyard <girgias@php.net>
Date: Sun Jun 28 18:54:51 2026 +0100
ext/openssl: convert stream errors to new stream error API (#22318)
Convert the ext/openssl stream messages to the new stream error API so they
honour the context error_mode/store like the other converted streams.
All messages emitted while a stream error operation is open must go through
the new API, otherwise mixing immediate php_error_docref() with buffered
reporting reorders the output. This required emitting "Accept failed" via
php_stream_warn() (adding StreamErrorCode::AcceptFailed) and threading a
php_stream* through php_openssl_check_path_ex() (NULL for non-stream callers).
Fingerprint changes: refactor php_openssl_x509_fingerprint_cmp() into an
'is equal' variant using zend_string; make php_openssl_x509_fingerprint_match()
warn on all failure cases to avoid double warnings; thread a php_stream* into
php_openssl_x509_fingerprint() so it reports through the operation, and demote
its internal "Could not generate signature" failure from E_ERROR to a warning.
Co-authored-by: Jakub Zelenka <bukka@php.net>
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 6b29471b248..1e63eb1381f 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -651,7 +651,8 @@ static void php_openssl_check_path_error(uint32_t arg_num, int type, const char
/* openssl file path check extended */
bool php_openssl_check_path_ex(
const char *file_path, size_t file_path_len, char *real_path, uint32_t arg_num,
- bool contains_file_protocol, bool is_from_array, const char *option_name)
+ bool contains_file_protocol, bool is_from_array, const char *option_name,
+ php_stream *stream)
{
const char *fs_file_path;
size_t fs_file_path_len;
@@ -686,8 +687,13 @@ bool php_openssl_check_path_ex(
if (arg_num == 0) {
const char *option_title = option_name ? option_name : "unknown";
const char *option_label = is_from_array ? "array item" : "option";
- php_error_docref(NULL, E_WARNING, "Path for %s %s %s",
- option_title, option_label, error_msg);
+ if (stream != NULL) {
+ php_stream_warn(stream, InvalidPath, "Path for %s %s %s",
+ option_title, option_label, error_msg);
+ } else {
+ php_error_docref(NULL, E_WARNING, "Path for %s %s %s",
+ option_title, option_label, error_msg);
+ }
} else if (is_from_array && option_name != NULL) {
php_openssl_check_path_error(
arg_num, error_type, "option %s array item %s", option_name, error_msg);
@@ -1294,7 +1300,7 @@ PHP_FUNCTION(openssl_x509_fingerprint)
RETURN_FALSE;
}
- fingerprint = php_openssl_x509_fingerprint(cert, method, raw_output);
+ fingerprint = php_openssl_x509_fingerprint(cert, method, raw_output, NULL);
if (fingerprint) {
RETVAL_STR(fingerprint);
} else {
diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c
index ba9bccff98c..8115a7c91b3 100644
--- a/ext/openssl/openssl_backend_common.c
+++ b/ext/openssl/openssl_backend_common.c
@@ -307,7 +307,7 @@ int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args
/* read in the oids */
str = php_openssl_conf_get_string(req->req_config, NULL, "oid_file");
- if (str != NULL && php_openssl_check_path_ex(str, strlen(str), path, 0, false, false, "oid_file")) {
+ if (str != NULL && php_openssl_check_path_ex(str, strlen(str), path, 0, false, false, "oid_file", NULL)) {
BIO *oid_bio = BIO_new_file(path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY));
if (oid_bio) {
OBJ_create_objects(oid_bio);
@@ -513,7 +513,7 @@ X509 *php_openssl_x509_from_str(
BIO *in;
if (ZSTR_LEN(cert_str) > 7 && memcmp(ZSTR_VAL(cert_str), "file://", sizeof("file://") - 1) == 0) {
- if (!php_openssl_check_path_str_ex(cert_str, cert_path, arg_num, true, is_from_array, option_name)) {
+ if (!php_openssl_check_path_str_ex(cert_str, cert_path, arg_num, true, is_from_array, option_name, NULL)) {
return NULL;
}
@@ -582,7 +582,7 @@ X509 *php_openssl_x509_from_zval(
return cert;
}
-zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw)
+zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw, php_stream *stream)
{
unsigned char md[EVP_MAX_MD_SIZE];
const EVP_MD *mdtype;
@@ -590,12 +590,20 @@ zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool r
zend_string *ret;
if (!(mdtype = php_openssl_get_evp_md_by_name(method))) {
- php_error_docref(NULL, E_WARNING, "Unknown digest algorithm");
+ if (stream != NULL) {
+ php_stream_warn(stream, Generic, "Unknown digest algorithm");
+ } else {
+ php_error_docref(NULL, E_WARNING, "Unknown digest algorithm");
+ }
return NULL;
} else if (!X509_digest(peer, mdtype, md, &n)) {
php_openssl_release_evp_md(mdtype);
php_openssl_store_errors();
- php_error_docref(NULL, E_ERROR, "Could not generate signature");
+ if (stream != NULL) {
+ php_stream_warn(stream, EncodingFailed, "Could not generate signature");
+ } else {
+ php_error_docref(NULL, E_WARNING, "Could not generate signature");
+ }
return NULL;
}
@@ -792,7 +800,7 @@ X509_STORE *php_openssl_setup_verify(zval *calist, uint32_t arg_num)
return NULL;
}
- if (!php_openssl_check_path_str_ex(str, file_path, arg_num, false, true, NULL)) {
+ if (!php_openssl_check_path_str_ex(str, file_path, arg_num, false, true, NULL, NULL)) {
zend_string_release(str);
continue;
}
diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h
index 20a04bbcd1a..b88a6c59e4e 100644
--- a/ext/openssl/php_openssl.h
+++ b/ext/openssl/php_openssl.h
@@ -102,34 +102,39 @@ void php_openssl_store_errors(void);
void php_openssl_errors_set_mark(void);
void php_openssl_errors_restore_mark(void);
-/* openssl file path extra */
+/* openssl file path extra
+ * When a non-NULL stream is passed and the path check fails for a stream context option
+ * (arg_num == 0), the warning is reported via the stream error API so it participates in
+ * any active stream error operation; otherwise it is emitted immediately. */
bool php_openssl_check_path_ex(
const char *file_path, size_t file_path_len, char *real_path, uint32_t arg_num,
- bool contains_file_protocol, bool is_from_array, const char *option_name);
+ bool contains_file_protocol, bool is_from_array, const char *option_name,
+ struct _php_stream *stream);
/* openssl file path check */
static inline bool php_openssl_check_path(
const char *file_path, size_t file_path_len, char *real_path, uint32_t arg_num)
{
return php_openssl_check_path_ex(
- file_path, file_path_len, real_path, arg_num, false, false, NULL);
+ file_path, file_path_len, real_path, arg_num, false, false, NULL, NULL);
}
/* openssl file path extra check with zend string */
static inline bool php_openssl_check_path_str_ex(
zend_string *file_path, char *real_path, uint32_t arg_num,
- bool contains_file_protocol, bool is_from_array, const char *option_name)
+ bool contains_file_protocol, bool is_from_array, const char *option_name,
+ struct _php_stream *stream)
{
return php_openssl_check_path_ex(
ZSTR_VAL(file_path), ZSTR_LEN(file_path), real_path, arg_num, contains_file_protocol,
- is_from_array, option_name);
+ is_from_array, option_name, stream);
}
/* openssl file path check with zend string */
static inline bool php_openssl_check_path_str(
zend_string *file_path, char *real_path, uint32_t arg_num)
{
- return php_openssl_check_path_str_ex(file_path, real_path, arg_num, true, false, NULL);
+ return php_openssl_check_path_str_ex(file_path, real_path, arg_num, true, false, NULL, NULL);
}
PHP_OPENSSL_API zend_long php_openssl_cipher_iv_length(const char *method);
diff --git a/ext/openssl/php_openssl_backend.h b/ext/openssl/php_openssl_backend.h
index 2d37e594ea5..bd12a5fe312 100644
--- a/ext/openssl/php_openssl_backend.h
+++ b/ext/openssl/php_openssl_backend.h
@@ -262,7 +262,8 @@ X509 *php_openssl_x509_from_param(
X509 *php_openssl_x509_from_zval(
zval *val, bool *free_cert, uint32_t arg_num, bool is_from_array, const char *option_name);
-zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw);
+zend_string* php_openssl_x509_fingerprint(
+ X509 *peer, const char *method, bool raw, struct _php_stream *stream);
int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension);
diff --git a/ext/openssl/tests/ServerClientTestCase.inc b/ext/openssl/tests/ServerClientTestCase.inc
index c5db41d4841..b7e866954fc 100644
--- a/ext/openssl/tests/ServerClientTestCase.inc
+++ b/ext/openssl/tests/ServerClientTestCase.inc
@@ -129,6 +129,10 @@ class ServerClientTestCase
private function cleanupWorkerProcess($worker)
{
fclose($this->workerStdIn[$worker]);
+ /* Drain stdout to EOF before closing it, so late worker writes (e.g.
+ * buffered error output) don't fail and abort the worker mid-output. */
+ stream_set_blocking($this->workerStdOut[$worker], true);
+ stream_get_contents($this->workerStdOut[$worker]);
fclose($this->workerStdOut[$worker]);
proc_close($this->workerHandle[$worker]);
}
diff --git a/ext/openssl/tests/bug68920.phpt b/ext/openssl/tests/bug68920.phpt
index 4abe12586b0..a2d669e5b7d 100644
--- a/ext/openssl/tests/bug68920.phpt
+++ b/ext/openssl/tests/bug68920.phpt
@@ -76,8 +76,6 @@
Warning: stream_socket_client(): Invalid peer_fingerprint array; [algo => fingerprint] form required in %s on line %d
-Warning: stream_socket_client(): peer_fingerprint match failure in %s on line %d
-
Warning: stream_socket_client(): Failed to enable crypto in %s on line %d
Warning: stream_socket_client(): Unable to connect to %s (Unknown error) in %s on line %d
@@ -85,8 +83,6 @@
Warning: stream_socket_client(): Invalid peer_fingerprint array; [algo => fingerprint] form required in %s on line %d
-Warning: stream_socket_client(): peer_fingerprint match failure in %s on line %d
-
Warning: stream_socket_client(): Failed to enable crypto in %s on line %d
Warning: stream_socket_client(): Unable to connect to %s (Unknown error) in %s on line %d
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index a154aa4572f..bc483df617b 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -145,7 +145,8 @@
#endif
extern php_stream* php_openssl_get_stream_from_ssl_handle(const SSL *ssl);
-extern zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw);
+extern zend_string* php_openssl_x509_fingerprint(
+ X509 *peer, const char *method, bool raw, php_stream *stream);
extern int php_openssl_get_ssl_stream_data_index(void);
static struct timeval php_openssl_subtract_timeval(struct timeval a, struct timeval b);
static int php_openssl_compare_timeval(struct timeval a, struct timeval b);
@@ -281,16 +282,14 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i
if (ERR_peek_error() == 0) {
if (nr_bytes == 0) {
if (!php_openssl_is_http_stream_talking_to_iis(stream) && ERR_get_error() != 0) {
- php_error_docref(NULL, E_WARNING, "SSL: fatal protocol error");
+ php_stream_warn(stream, ProtocolError, "SSL: fatal protocol error");
}
SSL_set_shutdown(sslsock->ssl_handle, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
stream->eof = 1;
retry = false;
} else {
char *estr = php_socket_strerror(php_socket_errno(), NULL, 0);
-
- php_error_docref(NULL, E_WARNING,
- "SSL: %s", estr);
+ php_stream_warn(stream, ProtocolError, "SSL: %s", estr);
efree(estr);
retry = false;
@@ -305,7 +304,7 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i
switch (ERR_GET_REASON(ecode)) {
case SSL_R_NO_SHARED_CIPHER:
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ProtocolError,
"SSL_R_NO_SHARED_CIPHER: no suitable shared cipher could be used. "
"This could be because the server is missing an SSL certificate "
"(local_cert context option)");
@@ -324,7 +323,7 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i
smart_str_0(&ebuf);
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ProtocolError,
"SSL operation failed with code %d. %s%s",
err,
ebuf.s ? "OpenSSL Error messages:\n" : "",
@@ -379,21 +378,19 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */
}
/* }}} */
-static int php_openssl_x509_fingerprint_cmp(X509 *peer, const char *method, const char *expected)
+static bool php_openssl_x509_fingerprint_is_equal(php_stream *stream, X509 *peer, const char *method, const zend_string *expected)
{
- zend_string *fingerprint;
- int result = -1;
-
- fingerprint = php_openssl_x509_fingerprint(peer, method, false);
+ bool is_equal = false;
+ zend_string *fingerprint = php_openssl_x509_fingerprint(peer, method, false, stream);
if (fingerprint) {
- result = strcasecmp(expected, ZSTR_VAL(fingerprint));
- zend_string_release_ex(fingerprint, 0);
+ is_equal = zend_string_equals_ci(fingerprint, expected);
+ zend_string_release_ex(fingerprint, false);
}
- return result;
+ return is_equal;
}
-static bool php_openssl_x509_fingerprint_match(X509 *peer, zval *val)
+static bool php_openssl_x509_fingerprint_match(php_stream *stream, X509 *peer, const zval *val)
{
if (Z_TYPE_P(val) == IS_STRING) {
const char *method = NULL;
@@ -408,29 +405,41 @@ static bool php_openssl_x509_fingerprint_match(X509 *peer, zval *val)
break;
}
- return method && php_openssl_x509_fingerprint_cmp(peer, method, Z_STRVAL_P(val)) == 0;
+ if (UNEXPECTED(method == NULL)) {
+ php_stream_warn(stream, AuthFailed, "peer_fingerprint length doesn't match a md5 or sha1 hash");
+ return false;
+ }
+ if (!php_openssl_x509_fingerprint_is_equal(stream, peer, method, Z_STR_P(val))) {
+ php_stream_warn(stream, AuthFailed, "peer_fingerprint match failure");
+ return false;
+ }
+ return true;
} else if (Z_TYPE_P(val) == IS_ARRAY) {
zval *current;
zend_string *key;
if (!zend_hash_num_elements(Z_ARRVAL_P(val))) {
- php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
+ // TODO: Should this be a ValueError (also must not be empty error)?
+ php_stream_warn(stream, Generic, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
return false;
}
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(val), key, current) {
if (key == NULL || Z_TYPE_P(current) != IS_STRING) {
- php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
+ // TODO: Should this be a ValueError?
+ php_stream_warn(stream, Generic, "Invalid peer_fingerprint array; [algo => fingerprint] form required");
return false;
}
- if (php_openssl_x509_fingerprint_cmp(peer, ZSTR_VAL(key), Z_STRVAL_P(current)) != 0) {
+ if (!php_openssl_x509_fingerprint_is_equal(stream, peer, ZSTR_VAL(key), Z_STR_P(current))) {
+ php_stream_warn(stream, AuthFailed, "peer_fingerprint match failure");
return false;
}
} ZEND_HASH_FOREACH_END();
return true;
} else {
- php_error_docref(NULL, E_WARNING,
+ // TODO: Should this be a TypeError?
+ php_stream_warn(stream, Generic,
"Invalid peer_fingerprint value; fingerprint string or array of the form [algo => fingerprint] required");
}
@@ -555,7 +564,7 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) /
}
/* }}} */
-static bool php_openssl_matches_common_name(X509 *peer, const char *subject_name) /* {{{ */
+static bool php_openssl_matches_common_name(php_stream *stream, const X509 *peer, const char *subject_name) /* {{{ */
{
char buf[1024];
X509_NAME *cert_name;
@@ -566,13 +575,13 @@ static bool php_openssl_matches_common_name(X509 *peer, const char *subject_name
cert_name_len = X509_NAME_get_text_by_NID(cert_name, NID_commonName, buf, sizeof(buf));
if (cert_name_len == -1) {
- php_error_docref(NULL, E_WARNING, "Unable to locate peer certificate CN");
+ php_stream_warn(stream, NetworkRecvFailed, "Unable to locate peer certificate CN");
} else if ((size_t)cert_name_len != strlen(buf)) {
- php_error_docref(NULL, E_WARNING, "Peer certificate CN=`%.*s' is malformed", cert_name_len, buf);
+ php_stream_warn(stream, AuthFailed, "Peer certificate CN=`%.*s' is malformed", cert_name_len, buf);
} else if (php_openssl_matches_wildcard_name(subject_name, buf)) {
is_match = true;
} else {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, AuthFailed,
"Peer certificate CN=`%.*s' did not match expected CN=`%s'",
cert_name_len, buf, subject_name);
}
@@ -605,7 +614,7 @@ static zend_result php_openssl_apply_peer_verification_policy(SSL *ssl, X509 *pe
peer_fingerprint = val;
if ((must_verify_peer || must_verify_peer_name || must_verify_fingerprint) && peer == NULL) {
- php_error_docref(NULL, E_WARNING, "Could not get peer certificate");
+ php_stream_warn(stream, NetworkRecvFailed, "Could not get peer certificate");
return FAILURE;
}
@@ -624,8 +633,7 @@ static zend_result php_openssl_apply_peer_verification_policy(SSL *ssl, X509 *pe
/* not allowed, so fall through */
ZEND_FALLTHROUGH;
default:
- php_error_docref(NULL, E_WARNING,
- "Could not verify peer: code:%d %s",
+ php_stream_warn(stream, AuthFailed, "Could not verify peer: code:%d %s",
err,
X509_verify_cert_error_string(err)
);
@@ -636,14 +644,11 @@ static zend_result php_openssl_apply_peer_verification_policy(SSL *ssl, X509 *pe
/* If a peer_fingerprint match is required this trumps peer and peer_name verification */
if (must_verify_fingerprint) {
if (Z_TYPE_P(peer_fingerprint) == IS_STRING || Z_TYPE_P(peer_fingerprint) == IS_ARRAY) {
- if (!php_openssl_x509_fingerprint_match(peer, peer_fingerprint)) {
- php_error_docref(NULL, E_WARNING,
- "peer_fingerprint match failure"
- );
+ if (!php_openssl_x509_fingerprint_match(stream, peer, peer_fingerprint)) {
return FAILURE;
}
} else {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, AuthFailed,
"Expected peer fingerprint must be a string or an array"
);
return FAILURE;
@@ -662,7 +667,7 @@ static zend_result php_openssl_apply_peer_verification_policy(SSL *ssl, X509 *pe
if (peer_name) {
if (php_openssl_matches_san_list(peer, peer_name)) {
return SUCCESS;
- } else if (php_openssl_matches_common_name(peer, peer_name)) {
+ } else if (php_openssl_matches_common_name(stream, peer, peer_name)) {
return SUCCESS;
} else {
return FAILURE;
@@ -725,7 +730,8 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx,
err_code = e;
}
- php_error_docref(NULL, E_WARNING, "Error encoding X509 certificate: %lu: %s", err_code, ERR_error_string(err_code, err_buf));
+ php_stream_warn(stream, EncodingFailed,
+ "Error encoding X509 certificate: %lu: %s", err_code, ERR_error_string(err_code, err_buf));
RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
}
@@ -734,7 +740,7 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx,
if (cert_ctx == NULL) {
char *err = php_win_err();
- php_error_docref(NULL, E_WARNING, "Error creating certificate context: %s", err);
+ php_stream_warn(stream, CreateFailed, "Error creating certificate context: %s", err);
php_win_err_free(err);
RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
}
@@ -758,7 +764,7 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx,
if (!CertGetCertificateChain(NULL, cert_ctx, NULL, NULL, &chain_params, chain_flags, NULL, &cert_chain_ctx)) {
char *err = php_win_err();
- php_error_docref(NULL, E_WARNING, "Error getting certificate chain: %s", err);
+ php_stream_warn(stream, NetworkRecvFailed, "Error getting certificate chain: %s", err);
php_win_err_free(err);
CertFreeCertificateContext(cert_ctx);
RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
@@ -801,7 +807,7 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx,
if (!verify_result) {
char *err = php_win_err();
- php_error_docref(NULL, E_WARNING, "Error verifying certificate chain policy: %s", err);
+ php_stream_warn(stream, AuthFailed, "Error verifying certificate chain policy: %s", err);
php_win_err_free(err);
RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED);
}
@@ -836,11 +842,12 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c
stream = php_stream_open_wrapper(cafile, "rb", 0, NULL);
if (stream == NULL) {
+ // TODO: no stream and no wrapper, cannot use php_stream_warn(stream, ReadFailed, ...) nor php_stream_wrapper_log_error()
php_error(E_WARNING, "failed loading cafile stream: `%s'", cafile);
return 0;
} else if (stream->wrapper->is_url) {
+ php_stream_warn(stream, PermissionDenied, "remote cafile streams are disabled for security purposes");
php_stream_close(stream);
- php_error(E_WARNING, "remote cafile streams are disabled for security purposes");
return 0;
}
@@ -898,7 +905,7 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c
}
if (certs_added == 0) {
- php_error(E_WARNING, "no valid certs found cafile stream: `%s'", cafile);
+ php_stream_warn(stream, DecodingFailed, "no valid certs found cafile stream: `%s'", cafile);
}
return certs_added;
@@ -924,7 +931,7 @@ static zend_result php_openssl_enable_peer_verification(SSL_CTX *ctx, php_stream
if (cert_names != NULL) {
SSL_CTX_set_client_CA_list(ctx, cert_names);
} else {
- php_error(E_WARNING, "SSL: failed loading CA names from cafile");
+ php_stream_warn(stream, InvalidFormat, "SSL: failed loading CA names from cafile");
return FAILURE;
}
}
@@ -946,7 +953,7 @@ static zend_result php_openssl_enable_peer_verification(SSL_CTX *ctx, php_stream
SSL_CTX_set_cert_verify_callback(ctx, php_openssl_win_cert_verify_callback, (void *)stream);
#else
if (sslsock->is_client && !SSL_CTX_set_default_verify_paths(ctx)) {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ProtocolError,
"Unable to set default verify locations and no CA settings specified");
return FAILURE;
}
@@ -980,13 +987,13 @@ static zend_result php_openssl_set_local_cert(SSL_CTX *ctx, php_stream *stream)
if (!php_openssl_check_path_ex(
certfile, certfile_len, resolved_path_buff, 0, false, false,
- "local_cert in ssl stream context")) {
- php_error_docref(NULL, E_WARNING, "Unable to get real path of certificate file `%s'", certfile);
+ "local_cert in ssl stream context", stream)) {
+ php_stream_warn(stream, NotFound, "Unable to get real path of certificate file `%s'", certfile);
return FAILURE;
}
/* a certificate to use for authentication */
if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff) != 1) {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, WriteFailed,
"Unable to set local cert chain file `%s'; Check that your cafile/capath "
"settings include details of your certificate and its issuer",
certfile);
@@ -996,16 +1003,16 @@ static zend_result php_openssl_set_local_cert(SSL_CTX *ctx, php_stream *stream)
GET_VER_OPT_STRINGL("local_pk", private_key, private_key_len);
if (private_key && !php_openssl_check_path_ex(
private_key, private_key_len, resolved_path_buff, 0, false, false,
- "local_pk in ssl stream context")) {
- php_error_docref(NULL, E_WARNING, "Unable to get real path of private key file `%s'", private_key);
+ "local_pk in ssl stream context", stream)) {
+ php_stream_warn(stream, NotFound, "Unable to get real path of private key file `%s'", private_key);
return FAILURE;
}
if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
- php_error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
+ php_stream_warn(stream, WriteFailed, "Unable to set private key file `%s'", resolved_path_buff);
return FAILURE;
}
if (!SSL_CTX_check_private_key(ctx)) {
- php_error_docref(NULL, E_WARNING, "Private key does not match certificate!");
+ php_stream_warn(stream, PermissionDenied, "Private key does not match certificate!");
}
}
@@ -1140,7 +1147,7 @@ static void php_openssl_limit_handshake_reneg(const SSL *ssl) /* {{{ */
/* Closing the stream inside this callback would segfault! */
stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE;
if (FAILURE == call_user_function(NULL, NULL, val, &retval, 1, ¶m)) {
- php_error(E_WARNING, "SSL: failed invoking reneg limit notification callback");
+ php_stream_warn(stream, UserspaceCallFailed, "SSL: failed invoking reneg limit notification callback");
}
stream->flags ^= PHP_STREAM_FLAG_NO_FCLOSE;
@@ -1151,7 +1158,7 @@ static void php_openssl_limit_handshake_reneg(const SSL *ssl) /* {{{ */
zval_ptr_dtor(&retval);
} else {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ProtocolError,
"SSL: client-initiated handshake rate limit exceeded by peer");
}
}
@@ -1224,7 +1231,7 @@ static zend_result php_openssl_set_server_dh_param(php_stream * stream, SSL_CTX
BIO *bio = BIO_new_file(Z_STRVAL_P(zdhpath), PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY));
if (bio == NULL) {
- php_error_docref(NULL, E_WARNING, "Invalid dh_param");
+ php_stream_warn(stream, NotFound, "Invalid dh_param");
return FAILURE;
}
@@ -1233,12 +1240,12 @@ static zend_result php_openssl_set_server_dh_param(php_stream * stream, SSL_CTX
BIO_free(bio);
if (pkey == NULL) {
- php_error_docref(NULL, E_WARNING, "Failed reading DH params");
+ php_stream_warn(stream, ReadFailed, "Failed reading DH params");
return FAILURE;
}
if (SSL_CTX_set0_tmp_dh_pkey(ctx, pkey) == 0) {
- php_error_docref(NULL, E_WARNING, "Failed assigning DH params");
+ php_stream_warn(stream, WriteFailed, "Failed assigning DH params");
EVP_PKEY_free(pkey);
return FAILURE;
}
@@ -1247,12 +1254,12 @@ static zend_result php_openssl_set_server_dh_param(php_stream * stream, SSL_CTX
BIO_free(bio);
if (dh == NULL) {
- php_error_docref(NULL, E_WARNING, "Failed reading DH params");
+ php_stream_warn(stream, ReadFailed, "Failed reading DH params");
return FAILURE;
}
if (SSL_CTX_set_tmp_dh(ctx, dh) == 0) {
- php_error_docref(NULL, E_WARNING, "Failed assigning DH params");
+ php_stream_warn(stream, WriteFailed, "Failed assigning DH params");
DH_free(dh);
return FAILURE;
}
@@ -1271,7 +1278,8 @@ static zend_result php_openssl_set_server_specific_opts(php_stream *stream, SSL_
/* We now use php_openssl_tmp_rsa_cb to generate a key of appropriate size whenever necessary */
if (php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "rsa_key_size") != NULL) {
- php_error_docref(NULL, E_WARNING, "rsa_key_size context option has been removed");
+ // TODO: Should this be E_DEPRECATED instead?
+ php_stream_warn(stream, Generic, "rsa_key_size context option has been removed");
}
if (php_openssl_set_server_dh_param(stream, ctx) == FAILURE) {
@@ -1326,18 +1334,18 @@ static int php_openssl_server_sni_callback(SSL *ssl_handle, int *al, void *arg)
}
/* }}} */
-static SSL_CTX *php_openssl_create_sni_server_ctx(char *cert_path, char *key_path) /* {{{ */
+static SSL_CTX *php_openssl_create_sni_server_ctx(php_stream *stream, char *cert_path, char *key_path) /* {{{ */
{
/* The hello method is not inherited by SSL structs when assigning a new context
* inside the SNI callback, so the just use SSLv23 */
SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
if (!ctx) {
- php_error_docref(NULL, E_WARNING, "Failed to create the SSL context");
+ php_stream_warn(stream, CreateFailed, "Failed to create the SSL context");
return NULL;
}
if (SSL_CTX_use_certificate_chain_file(ctx, cert_path) != 1) {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ReadFailed,
"Failed setting local cert chain file `%s'; " \
"check that your cafile/capath settings include " \
"details of your certificate and its issuer",
@@ -1346,7 +1354,7 @@ static SSL_CTX *php_openssl_create_sni_server_ctx(char *cert_path, char *key_pat
SSL_CTX_free(ctx);
return NULL;
} else if (SSL_CTX_use_PrivateKey_file(ctx, key_path, SSL_FILETYPE_PEM) != 1) {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ReadFailed,
"Failed setting private key from file `%s'",
key_path
);
@@ -1380,7 +1388,8 @@ static zend_result php_openssl_enable_server_sni(
}
if (Z_TYPE_P(val) != IS_ARRAY) {
- php_error_docref(NULL, E_WARNING,
+ // TODO: should this be a TypeError?
+ php_stream_warn(stream, Generic,
"SNI_server_certs requires an array mapping host names to cert paths"
);
return FAILURE;
@@ -1388,7 +1397,8 @@ static zend_result php_openssl_enable_server_sni(
sslsock->sni_cert_count = zend_hash_num_elements(Z_ARRVAL_P(val));
if (sslsock->sni_cert_count == 0) {
- php_error_docref(NULL, E_WARNING,
+ // TODO: should this be a ValueError?
+ php_stream_warn(stream, Generic,
"SNI_server_certs host cert array must not be empty"
);
return FAILURE;
@@ -1403,7 +1413,8 @@ static zend_result php_openssl_enable_server_sni(
(void) key_index;
if (!key) {
- php_error_docref(NULL, E_WARNING,
+ // TODO: should this be a ValueError?
+ php_stream_warn(stream, Generic,
"SNI_server_certs array requires string host name keys"
);
return FAILURE;
@@ -1418,7 +1429,8 @@ static zend_result php_openssl_enable_server_sni(
local_cert = zend_hash_str_find(Z_ARRVAL_P(current), "local_cert", sizeof("local_cert")-1);
if (local_cert == NULL) {
- php_error_docref(NULL, E_WARNING,
+ // TODO: should this be a ValueError?
+ php_stream_warn(stream, Generic,
"local_cert not present in the array"
);
return FAILURE;
@@ -1430,8 +1442,8 @@ static zend_result php_openssl_enable_server_sni(
}
if (!php_openssl_check_path_str_ex(
local_cert_str, resolved_cert_path_buff, 0, false, false,
- "SNI_server_certs local_cert in ssl stream context")) {
- php_error_docref(NULL, E_WARNING,
+ "SNI_server_certs local_cert in ssl stream context", stream)) {
+ php_stream_warn(stream, OpenFailed,
"Failed setting local cert chain file `%s'; could not open file",
ZSTR_VAL(local_cert_str)
);
@@ -1442,7 +1454,8 @@ static zend_result php_openssl_enable_server_sni(
local_pk = zend_hash_str_find(Z_ARRVAL_P(current), "local_pk", sizeof("local_pk")-1);
if (local_pk == NULL) {
- php_error_docref(NULL, E_WARNING,
+ // TODO: should this be a ValueError?
+ php_stream_warn(stream, Generic,
"local_pk not present in the array"
);
return FAILURE;
@@ -1454,8 +1467,8 @@ static zend_result php_openssl_enable_server_sni(
}
if (!php_openssl_check_path_str_ex(
local_pk_str, resolved_pk_path_buff, 0, false, false,
- "SNI_server_certs local_pk in ssl stream context")) {
- php_error_docref(NULL, E_WARNING,
+ "SNI_server_certs local_pk in ssl stream context", stream)) {
+ php_stream_warn(stream, OpenFailed,
"Failed setting local private key file `%s'; could not open file",
ZSTR_VAL(local_pk_str)
);
@@ -1464,18 +1477,19 @@ static zend_result php_openssl_enable_server_sni(
}
zend_string_release(local_pk_str);
- ctx = php_openssl_create_sni_server_ctx(resolved_cert_path_buff, resolved_pk_path_buff);
+ ctx = php_openssl_create_sni_server_ctx(stream, resolved_cert_path_buff, resolved_pk_path_buff);
} else if (Z_TYPE_P(current) == IS_STRING) {
- if (php_openssl_check_path_str_ex(Z_STR_P(current), resolved_path_buff, 0, false, false, "SNI_server_certs in ssl stream context")) {
- ctx = php_openssl_create_sni_server_ctx(resolved_path_buff, resolved_path_buff);
+ if (php_openssl_check_path_str_ex(Z_STR_P(current), resolved_path_buff, 0, false, false, "SNI_server_certs in ssl stream context", stream)) {
+ ctx = php_openssl_create_sni_server_ctx(stream, resolved_path_buff, resolved_path_buff);
} else {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, NotFound,
"Failed setting local cert chain file `%s'; file not found",
Z_STRVAL_P(current)
);
}
} else {
- php_error_docref(NULL, E_WARNING, "SNI_server_certs options values must be of type array|string");
+ // TODO: should this be a TypeError?
+ php_stream_warn(stream, Generic, "SNI_server_certs options values must be of type array|string");
}
if (ctx == NULL) {
@@ -1902,12 +1916,13 @@ static int php_openssl_psk_find_session_cb(SSL *ssl, const unsigned char *identi
/* PSK setup */
static zend_result php_openssl_validate_and_allocate_psk_callback(
+ php_stream *stream,
php_openssl_netstream_data_t *sslsock, const zval *callable,
bool is_client, bool is_persistent)
{
const char *callback_name = is_client ? "psk_client_cb" : "psk_server_cb";
if (is_persistent) {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, PersistentNotSupported,
"%s is not supported for persistent streams", callback_name);
return FAILURE;
}
@@ -1950,7 +1965,7 @@ static zend_result php_openssl_setup_client_psk(php_stream *stream,
}
if (FAILURE == php_openssl_validate_and_allocate_psk_callback(
- sslsock, val, true, php_stream_is_persistent(stream))) {
+ stream, sslsock, val, true, php_stream_is_persistent(stream))) {
return FAILURE;
}
@@ -1972,7 +1987,7 @@ static zend_result php_openssl_setup_server_psk(php_stream *stream,
}
if (FAILURE == php_openssl_validate_and_allocate_psk_callback(
- sslsock, val, false, php_stream_is_persistent(stream))) {
+ stream, sslsock, val, false, php_stream_is_persistent(stream))) {
return FAILURE;
}
@@ -2103,6 +2118,7 @@ enum php_openssl_session_callback_type {
* Validate callable and allocate callback structure if needed.
*/
static zend_result php_openssl_validate_and_allocate_session_callback(
+ php_stream *stream,
php_openssl_netstream_data_t *sslsock, const zval *callable,
enum php_openssl_session_callback_type cb_type, bool is_persistent)
{
@@ -2123,7 +2139,7 @@ static zend_result php_openssl_validate_and_allocate_session_callback(
/* Callbacks not supported for persistent streams */
if (is_persistent) {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, PersistentNotSupported,
"%s is not supported for persistent streams", callback_name);
return FAILURE;
}
@@ -2184,7 +2200,7 @@ static zend_result php_openssl_setup_client_session(php_stream *stream,
if (GET_VER_OPT("session_new_cb")) {
if (FAILURE == php_openssl_validate_and_allocate_session_callback(
- sslsock, val, PHP_OPENSSL_NEW_CB, is_persistent)) {
+ stream, sslsock, val, PHP_OPENSSL_NEW_CB, is_persistent)) {
return FAILURE;
}
@@ -2231,7 +2247,7 @@ static zend_result php_openssl_setup_server_session(php_stream *stream,
/* Check for session_get_cb first (determines cache mode) */
if (GET_VER_OPT("session_get_cb")) {
if (FAILURE == php_openssl_validate_and_allocate_session_callback(
- sslsock, val, PHP_OPENSSL_GET_CB, is_persistent)) {
+ stream, sslsock, val, PHP_OPENSSL_GET_CB, is_persistent)) {
return FAILURE;
}
has_get_cb = true;
@@ -2250,7 +2266,7 @@ static zend_result php_openssl_setup_server_session(php_stream *stream,
/* Check for session_new_cb */
if (GET_VER_OPT("session_new_cb")) {
if (FAILURE == php_openssl_validate_and_allocate_session_callback(
- sslsock, val, PHP_OPENSSL_NEW_CB, is_persistent)) {
+ stream, sslsock, val, PHP_OPENSSL_NEW_CB, is_persistent)) {
return FAILURE;
}
has_new_cb = true;
@@ -2271,7 +2287,7 @@ static zend_result php_openssl_setup_server_session(php_stream *stream,
/* Check for session_remove_cb (optional) */
if (GET_VER_OPT("session_remove_cb")) {
if (FAILURE == php_openssl_validate_and_allocate_session_callback(
- sslsock, val, PHP_OPENSSL_REMOVE_CB, is_persistent)) {
+ stream, sslsock, val, PHP_OPENSSL_REMOVE_CB, is_persistent)) {
return FAILURE;
}
@@ -2356,7 +2372,8 @@ static zend_result php_openssl_apply_client_session_data(php_stream *stream,
if (php_openssl_is_session_ce(val)) {
session = php_openssl_session_from_zval(val);
if (!session) {
- php_error_docref(NULL, E_WARNING,
+ // TODO: Should this be a TypeError?
+ php_stream_warn(stream, Generic,
"Invalid OpenSSLSession object, falling back to full handshake");
return FAILURE;
}
@@ -2369,7 +2386,7 @@ static zend_result php_openssl_apply_client_session_data(php_stream *stream,
if (session) {
if (SSL_set_session(sslsock->ssl_handle, session) != 1) {
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ResumptionFailed,
"Failed to set session for resumption, falling back to full handshake");
if (needs_free) {
SSL_SESSION_free(session);
@@ -2396,7 +2413,7 @@ static zend_result php_openssl_create_server_ctx(php_stream *stream,
sslsock->ctx = SSL_CTX_new(method);
if (sslsock->ctx == NULL) {
- php_error_docref(NULL, E_WARNING, "SSL context creation failure");
+ php_stream_warn(stream, CreateFailed, "SSL context creation failure");
return FAILURE;
}
@@ -2462,7 +2479,8 @@ static zend_result php_openssl_create_server_ctx(php_stream *stream,
if (GET_VER_OPT("security_level")) {
zend_long lval = zval_get_long(val);
if (lval < 0 || lval > 5) {
- php_error_docref(NULL, E_WARNING, "Security level must be between 0 and 5");
+ // TODO: Should this be a ValueError?
+ php_stream_warn(stream, Generic, "Security level must be between 0 and 5");
}
#ifdef HAVE_SEC_LEVEL
SSL_CTX_set_security_level(sslsock->ctx, lval);
@@ -2478,7 +2496,7 @@ static zend_result php_openssl_create_server_ctx(php_stream *stream,
unsigned char *alpn = php_openssl_alpn_protos_parse(&alpn_len, alpn_protocols);
if (alpn == NULL) {
- php_error_docref(NULL, E_WARNING, "Failed parsing comma-separated TLS ALPN protocol string");
+ php_stream_warn(stream, DecodingFailed, "Failed parsing comma-separated TLS ALPN protocol string");
SSL_CTX_free(sslsock->ctx);
sslsock->ctx = NULL;
return FAILURE;
@@ -2494,7 +2512,7 @@ static zend_result php_openssl_create_server_ctx(php_stream *stream,
efree(alpn);
}
#else
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ProtocolUnsupported,
"alpn_protocols support is not compiled into the OpenSSL library against which PHP is linked");
#endif
}
@@ -2544,7 +2562,7 @@ static zend_result php_openssl_setup_crypto(php_stream *stream,
{
if (sslsock->ssl_handle) {
if (sslsock->s.is_blocked) {
- php_error_docref(NULL, E_WARNING, "SSL/TLS already set-up for this stream");
+ php_stream_warn(stream, Generic, "SSL/TLS already set-up for this stream");
return FAILURE;
} else {
return SUCCESS;
@@ -2563,11 +2581,11 @@ static zend_result php_openssl_setup_crypto(php_stream *stream,
php_openssl_netstream_data_t *parent_sslsock;
if (cparam->inputs.session->ops != &php_openssl_socket_ops) {
- php_error_docref(NULL, E_WARNING, "Supplied session stream must be an SSL enabled stream");
+ php_stream_warn(stream, SslNotSupported, "Supplied session stream must be an SSL enabled stream");
} else if ((parent_sslsock = cparam->inputs.session->abstract)->ctx == NULL) {
- php_error_docref(NULL, E_WARNING, "Supplied SSL session stream is not set up");
+ php_stream_warn(stream, SslNotSupported, "Supplied SSL session stream is not set up");
} else if (sslsock->is_client && parent_sslsock->ssl_handle == NULL) {
- php_error_docref(NULL, E_WARNING, "Supplied SSL session stream is not initialized");
+ php_stream_warn(stream, SslNotSupported, "Supplied SSL session stream is not initialized");
} else {
SSL_CTX_up_ref(parent_sslsock->ctx);
sslsock->ctx = parent_sslsock->ctx;
@@ -2582,7 +2600,7 @@ static zend_result php_openssl_setup_crypto(php_stream *stream,
sslsock->ssl_handle = SSL_new(sslsock->ctx);
if (!sslsock->ssl_handle) {
- php_error_docref(NULL, E_WARNING, "SSL handle creation failure");
+ php_stream_warn(stream, CreateFailed, "SSL handle creation failure");
SSL_CTX_free(sslsock->ctx);
sslsock->ctx = NULL;
return FAILURE;
@@ -2598,7 +2616,7 @@ static zend_result php_openssl_setup_crypto(php_stream *stream,
if (SSL_copy_session_id(sslsock->ssl_handle, parent_sslsock->ssl_handle)) {
SSL_CTX_set_session_cache_mode(sslsock->ctx, SSL_SESS_CACHE_CLIENT);
} else {
- php_error_docref(NULL, E_WARNING, "SSL session copying failed creation failure");
+ php_stream_warn(stream, CreateFailed, "SSL session copying failed creation failure");
}
}
@@ -2614,7 +2632,7 @@ static zend_result php_openssl_setup_crypto(php_stream *stream,
if (sslsock->ssl_handle == NULL
|| !SSL_set_ex_data(sslsock->ssl_handle, php_openssl_get_ssl_stream_data_index(), stream)) {
- php_error_docref(NULL, E_WARNING, "SSL handle creation failure");
+ php_stream_warn(stream, CreateFailed, "SSL handle creation failure");
SSL_CTX_free(sslsock->ctx);
sslsock->ctx = NULL;
#ifdef HAVE_TLS_ALPN
@@ -2764,7 +2782,7 @@ static int php_openssl_enable_crypto(php_stream *stream,
elapsed_time = php_openssl_subtract_timeval(cur_time, start_time);
if (php_openssl_compare_timeval( elapsed_time, *timeout) > 0) {
- php_error_docref(NULL, E_WARNING, "SSL: Handshake timed out");
+ php_stream_warn(stream, TimeOut, "SSL: Handshake timed out");
return -1;
}
}
@@ -3220,7 +3238,7 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_
if (php_stream_xport_crypto_setup(xparam->outputs.client, clisockdata->method,
sock->ctx ? stream : NULL) < 0 || php_stream_xport_crypto_enable(
xparam->outputs.client, 1) < 0) {
- php_error_docref(NULL, E_WARNING, "Failed to enable crypto");
+ php_stream_warn(stream, ProtocolError, "Failed to enable crypto");
php_stream_close(xparam->outputs.client);
xparam->outputs.client = NULL;
@@ -3490,7 +3508,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
if (php_stream_xport_crypto_setup(stream, sslsock->method, session_stream) < 0 ||
php_stream_xport_crypto_enable(stream, 1) < 0) {
- php_error_docref(NULL, E_WARNING, "Failed to enable crypto");
+ php_stream_warn(stream, ProtocolError, "Failed to enable crypto");
xparam->outputs.returncode = -1;
}
}
@@ -3686,7 +3704,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
sslsock->enable_on_connect = 1;
sslsock->method = php_openssl_get_crypto_method(context, STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT);
} else if (strncmp(proto, "sslv2", protolen) == 0) {
- php_error_docref(NULL, E_WARNING, "SSLv2 unavailable in this PHP version");
+ php_stream_warn(stream, ProtocolUnsupported, "SSLv2 unavailable in this PHP version");
php_stream_close(stream);
return NULL;
} else if (strncmp(proto, "sslv3", protolen) == 0) {
@@ -3694,7 +3712,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_SSLv3_CLIENT;
#else
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ProtocolUnsupported,
"SSLv3 support is not compiled into the OpenSSL library against which PHP is linked");
php_stream_close(stream);
return NULL;
@@ -3710,7 +3728,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
#else
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ProtocolUnsupported,
"TLSv1.1 support is not compiled into the OpenSSL library against which PHP is linked");
php_stream_close(stream);
return NULL;
@@ -3720,7 +3738,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
#else
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ProtocolUnsupported,
"TLSv1.2 support is not compiled into the OpenSSL library against which PHP is linked");
php_stream_close(stream);
return NULL;
@@ -3730,7 +3748,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT;
#else
- php_error_docref(NULL, E_WARNING,
+ php_stream_warn(stream, ProtocolUnsupported,
"TLSv1.3 support is not compiled into the OpenSSL library against which PHP is linked");
php_stream_close(stream);
return NULL;
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c
index bad645f8668..7962f0f85de 100644
--- a/ext/standard/streamsfuncs.c
+++ b/ext/standard/streamsfuncs.c
@@ -325,7 +325,7 @@ PHP_FUNCTION(stream_socket_accept)
if (peername) {
zend_string_release(peername);
}
- php_error_docref(NULL, E_WARNING, "Accept failed: %s", errstr ? ZSTR_VAL(errstr) : "Unknown error");
+ php_stream_warn(stream, AcceptFailed, "Accept failed: %s", errstr ? ZSTR_VAL(errstr) : "Unknown error");
RETVAL_FALSE;
}
diff --git a/ext/standard/tests/streams/stream_errors_exception_mode_terminal.phpt b/ext/standard/tests/streams/stream_errors_exception_mode_terminal.phpt
index 37f5d39bfa7..6f470c61d1a 100644
--- a/ext/standard/tests/streams/stream_errors_exception_mode_terminal.phpt
+++ b/ext/standard/tests/streams/stream_errors_exception_mode_terminal.phpt
@@ -26,6 +26,6 @@
?>
--EXPECTF--
Caught: Failed to open stream: operation failed
-Code: 20
+Code: 21
Wrapper: PHP
Error code name: OpenFailed
diff --git a/main/streams/stream_errors.stub.php b/main/streams/stream_errors.stub.php
index 2c56932c485..255c92beb89 100644
--- a/main/streams/stream_errors.stub.php
+++ b/main/streams/stream_errors.stub.php
@@ -22,6 +22,7 @@ enum StreamErrorCode
case ConnectFailed;
case BindFailed;
case ListenFailed;
+ case AcceptFailed;
case NotWritable;
case NotReadable;
@@ -86,6 +87,7 @@ enum StreamErrorCode
case InvalidParam;
case RedirectLimit;
case AuthFailed;
+ case TimeOut;
/* Encoding/decoding/archiving operations */
case ArchivingFailed;
diff --git a/main/streams/stream_errors_arginfo.h b/main/streams/stream_errors_arginfo.h
index 3a10e9bc5a4..89df622beb0 100644
Binary files a/main/streams/stream_errors_arginfo.h and b/main/streams/stream_errors_arginfo.h differ
diff --git a/main/streams/stream_errors_decl.h b/main/streams/stream_errors_decl.h
index 4748768195f..69fe96252b4 100644
Binary files a/main/streams/stream_errors_decl.h and b/main/streams/stream_errors_decl.h differ