function seamless_donations_get_security_status() { $status = array(); $status['file_get_contents_enabled'] = false; // determines if file_get_contents can be used to check the SSL page $status['curl_enabled'] = false; // determines if the cURL library was found and enabled $status['ssl_version_ok'] = false; // determines if the current SSL version is high enough $status['curl_version_ok'] = false; // determine if the current cURL version is high enough $status['https_ipn_works'] = false; // determines if the SSL IPN is functional $status['http_ipn_works'] = false; // determines if the basic IPN is functional $status['curl_version'] = 'N/A'; $status['ssl_version'] = 'N/A'; $required_curl_version = '7.34.0'; $required_ssl_version = '1.0.1'; $http_ipn_url = plugins_url('/dgx-donate-paypalstd-ipn.php', dirname(__FILE__)); $https_ipn_url = plugins_url('/pay/paypalstd/ipn.php', dirname(__FILE__)); $https_ipn_url = str_ireplace('http://', 'https://', $https_ipn_url); // force https check // determine availability and version compatibility // all these calls are stfu'd because we have no idea what they'll do across the interwebs if (@function_exists('curl_init')) { $status['curl_enabled'] = true; $ch = @curl_init(); if ($ch != false) { $version = @curl_version(); $curl_compare = @seamless_donations_version_compare($version['version'], $required_curl_version); $ssl_compare = @seamless_donations_version_compare($version['ssl_version'], $required_ssl_version); $status['curl_version'] = $version['version']; $status['ssl_version'] = $version['ssl_version']; if ($curl_compare != '<') { $status['curl_version_ok'] = true; } if ($ssl_compare != '<') { $status['ssl_version_ok'] = true; } @curl_close($ch); } } if (@ini_get('allow_url_fopen')) { $status['file_get_contents_enabled'] = true; $test_result = @file_get_contents($http_ipn_url); if ($test_result !== false) { $status['http_ipn_works'] = true; } $test_result = @file_get_contents($https_ipn_url); if ($test_result !== false) { $status['https_ipn_works'] = true; } } return $status; }
function reply_to_paypal() { $request_data = $this->post_data; $request_data['cmd'] = '_notify-validate'; $request = http_build_query($request_data); $header = "POST /cgi-bin/webscr HTTP/1.0\r\n"; $header .= $this->host_header; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($request) . "\r\n\r\n"; $required_curl_version = '7.34.0'; $response = ''; dgx_donate_debug_log("IPN chatback attempt via TLS..."); $fp = fsockopen($this->chat_back_url, 443, $errno, $errstr, 30); if (!$fp) { dgx_donate_debug_log("IPN chatback attempt via SSL..."); $this->configure_for_production_or_test('ssl'); $fp = stream_socket_client($this->chat_back_url, $errno, $errstr, 30); } if ($fp) { dgx_donate_debug_log("IPN chatback attempt completed. Checking response..."); fputs($fp, $header . $request); $done = false; do { if (feof($fp)) { $done = true; } else { $response = fgets($fp, 1024); $done = in_array($response, array("VERIFIED", "INVALID")); } } while (!$done); } else { // let's try cURL as a final fallback // based on sample PayPal code at https://github.com/paypal/ipn-code-samples/blob/master/paypal_ipn.php dgx_donate_debug_log("IPN chatback attempt via SSL failed, attempting cURL..."); $this->configure_for_production_or_test('curl'); if (function_exists('curl_init')) { $ch = curl_init($this->chat_back_url); $version = curl_version(); $curl_compare = seamless_donations_version_compare($version['version'], $required_curl_version); if ($curl_compare == '<') { curl_close($ch); $ch = false; // kill the curl call } if ($ch != false) { curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $request); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); curl_setopt($ch, CURLOPT_SSLVERSION, 6); //Integer NOT string TLS v1.2 // set TCP timeout to 30 seconds curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close')); // CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" // and set the directory path of the certificate as shown below. // Ensure the file is readable by the webserver. // This is mandatory for some environments. // $cert = __DIR__ . "/ssl/cacert.pem"; // dgx_donate_debug_log( "Loading certificate from $cert" ); // curl_setopt( $ch, CURLOPT_CAINFO, $cert ); $response = curl_exec($ch); if (curl_errno($ch) != 0) { // cURL error dgx_donate_debug_log("IPN failed: unable to establish network chatback connection to PayPal via cURL"); dgx_donate_debug_log("IPN cURL error: " . curl_error($ch)); $version = curl_version(); dgx_donate_debug_log("cURL version: " . $version['version'] . " OpenSSL version: " . $version['ssl_version']); // https://curl.haxx.se/docs/manpage.html#--tlsv12 // https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations dgx_donate_debug_log("PayPal requires TLSv1.2, which requires cURL 7.34.0 and OpenSSL 1.0.1."); dgx_donate_debug_log("See https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations"); dgx_donate_debug_log("for minimum versions for other implementations."); } else { // Split response headers and payload, a better way for strcmp dgx_donate_debug_log("IPN chatback attempt via cURL completed. Checking response..."); $tokens = explode("\r\n\r\n", trim($response)); $response = trim(end($tokens)); } curl_close($ch); } } else { dgx_donate_debug_log("Unable to complete chatback attempt. SSL incompatible. Consider enabling cURL library."); dgx_donate_debug_log("See https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations"); dgx_donate_debug_log("for minimum versions for other implementations."); } } fclose($fp); //dgx_donate_debug_log ( "url = {$this->chat_back_url}, errno = $errno, errstr = $errstr" ); return $response; }