/**
* Wrapper for wp_remote_request(). Turns off SSL verification for certain SSL errors.
* This is lame, but many, many, many hosts have misconfigured SSL.
*
* When Jetpack is registered, the jetpack_fallback_no_verify_ssl_certs option is set to the current time if:
* 1. a certificate error is found AND
* 2. not verifying the certificate works around the problem.
*
* The option is checked on each request.
*
* @internal
* @see Jetpack::fix_url_for_bad_hosts()
*
* @return array|WP_Error WP HTTP response on success
*/
public static function _wp_remote_request($url, $args, $set_fallback = false)
{
/**
* SSL verification (`sslverify`) for the JetpackClient remote request
* defaults to off, use this filter to force it on.
*
* Return `true` to ENABLE SSL verification, return `false`
* to DISABLE SSL verification.
*
* @since 3.6.0
*
* @param bool Whether to force `sslverify` or not.
*/
if (apply_filters('jetpack_client_verify_ssl_certs', false)) {
return wp_remote_request($url, $args);
}
$fallback = Jetpack_Options::get_option('fallback_no_verify_ssl_certs');
if (false === $fallback) {
Jetpack_Options::update_option('fallback_no_verify_ssl_certs', 0);
}
if ((int) $fallback) {
// We're flagged to fallback
$args['sslverify'] = false;
}
$response = wp_remote_request($url, $args);
if (!$set_fallback || isset($args['sslverify']) && !$args['sslverify'] || !is_wp_error($response)) {
Jetpack_Client::set_time_diff($response, $set_fallback);
return $response;
}
// At this point, we're not flagged to fallback and we are allowed to set the flag on this request.
$message = $response->get_error_message();
// Is it an SSL Certificate verification error?
if (false === strpos($message, '14090086') && false === strpos($message, '1407E086') && false === strpos($message, 'error setting certificate verify locations') && false === strpos($message, 'Peer certificate cannot be authenticated with') && false === strpos($message, 'Problem with the SSL CA cert')) {
// No, it is not.
return $response;
}
// Redo the request without SSL certificate verification.
$args['sslverify'] = false;
$response = wp_remote_request($url, $args);
if (!is_wp_error($response)) {
// The request went through this time, flag for future fallbacks
Jetpack_Options::update_option('fallback_no_verify_ssl_certs', time());
Jetpack_Client::set_time_diff($response, $set_fallback);
}
return $response;
}