heartbleed affect the 3rd party php server receipt verify of itunes? - php

I have a working 3rd party php codes verify the receipt sent from ipad.
but it seems https://sandbox.itunes.apple.com/verifyReceipt no long response to my php code.
there's not even an error stat like {"status":21000} if I visite the url directly.
I've tried different ways on server side, like curl_exec($ch); or file_get_contents
even the simple test get nothing returned at all.
$result = file_get_contents('https://sandbox.itunes.apple.com/verifyReceipt');
echo $result;
I wonder if this is caused by heartbleed and what can I do?
my original working php code:
if ($isSandbox) {
$endpoint = 'https://sandbox.itunes.apple.com/verifyReceipt';
}
else {
$endpoint = 'https://buy.itunes.apple.com/verifyReceipt';
}
// Connect to Apple server and validate.
$postData = json_encode(array("receipt-data" => $receipt));
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded",
'method' => 'POST',
'content' => $postData
),
);
$context = stream_context_create($options);
$result = file_get_contents($endpoint, false, $context);

Well, after hours searching and checking, I finally figure this out, here's what happened:
I upload the test file to another server, turns out it's working so
not a php source problem.
I added
error_reporting(E_ALL);
ini_set('display_errors', '1');
to the php file got the error code is file-get-contents Couldn't
resolve host name
so I remember I yum update all the server software yesterday to
deal with heartbleed. and seems some update modified the
resolv.conf.
I changed the resolv.conf added google nameserver
8.8.8.8 but still not working
restart the nginx and php-fpm, problem solved

Related

API token authentication issues in php

First of all I want to say that I'm not a native english (french) so that's why this could bring some mistakes sometimes.
So my problem is that I'm trying to use the API of a website, which documentation can be found at documentation
The problem is for requests which need authentication, every thing is fine for public requests.
So I tried the first request which is according to the website 'retrieve account balances' which is a signed get method (using a hmac256 payload).
Thing are getting harder since the documentation is saying that the payload has to be either recvWindow=5000×tamp=1540203005798 (with the weird cross before tamp) even if I think this is more a display problem or has we can find in the documentation at another line : recvWindow=5000&timestamp=my timestamp.
So this is the first problem because I don't know the which one to use in the payload. (but I've tried with both and it didn't work so ...).
Then I wrote a quick php script to retrieve my informations :
<?php
include('pwd.php');
$time = time()*1000;
$sign = hash_hmac('sha256', 'recvWindow=5000&timestamp='.$time, $private);
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=> array("Authorization" => $public,
"Signature" => $sign
)
));
$context = stream_context_create($opts);
$fp = file_get_contents('https://trade.coss.io/c/api/v1/account/balances?
recvWindow=5000&timestamp='.$time, false, $context);
echo $fp;
?>
The first include juste includes my public key and my private key.
I run out of idea to find what is the problem with this script, because I tried with every payload with the cross without the cross with my timestamp with fixed timestamp but nothing work, I just get 500 error.
Any kind of help would be great.
I found the answer to my problem it came from the header which had a syntax mistake, instead of what I wrote the proper way is :
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=> array("Authorization: ".$public,
"Signature: ".$sign
)
));

cURL request in PHP script works via browser but not CRON

I know there's questions about this but so far none has helped me solve my problem.
I have a PHP script whose job is to send scheduled e-mails. It does this by calling a web service, which I control, via cURL.
Run in the browser, it works fine. Run via CRON, the cURL response is empty. It never reaches the web service; I know this because I had the WS write a text file when it's contacted. It does if you access via browser, not via CRON.
I know CRON runs in a different environment and I'm not relying on any environmental vars e.g. $_SERVER. The path to require() isn't the problem, either, as it's successfully getting data out of that file to connect to the DB.
This question suggested adding the following cURL opts, which I've done, but no dice:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
Here's my PHP script:
//prep
define('WS_URL', 'http://mywebservicedomain.com/index.php/web_service');
require '../application/config/database.php';
$db = new mysqli($db['default']['hostname'], $db['default']['username'], $db['default']['password'], $db['default']['database']) or die('failed to connect to DB');
//get scheduled e-mails
$res = $db->query('SELECT * FROM _cron_emails WHERE send_when < NOW()');
//process each...
while ($email_arr = $res->fetch_assoc()) {
//...get API connection info
$api_accnt = $db->query($sql = 'SELECT id, secret FROM _api_accounts WHERE project = "'.$email_arr['project'].'"');
$api_accnt = $api_accnt->fetch_assoc();
//...recreate $_POST env
$tmp = json_decode($email_arr['post_vars'], 1);
$_POST = array();
foreach($tmp as $key => $val) $_POST[$key] = !is_array($val) ? $val : implode(',', $val);
//...call API to send e-mail
$ch = curl_init($url = WS_URL.'/send_scheduled_email/'.$email_arr['email_id'].'/'.$email_arr['store_id'].'/'.$email_arr['item_id']);
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_SAFE_UPLOAD => true,
CURLOPT_SSL_VERIFYHOST => 1, //<-- tried adding this
CURLOPT_SSL_VERIFYPEER => 1, //<-- ditto
CURLOPT_POSTFIELDS => array_merge($_POST, array(
'api_key' => $api_accnt['id'],
'api_secret' => $api_accnt['secret'],
))
));
$resp = curl_exec($ch); //<-- empty when CRON
//if e-mail was sent OK, or decider script said it was ineligible, delete it from the queue
if (($resp == 'ok' || $resp == 'ineligible'))
$db->query('DELETE FROM _cron_emails WHERE id = '.$email_arr['id'].' LIMIT 1');
}
Does anyone have any idea why it fails to connect to my web service via cURL only when run in CRON?
Here's the CRON job:
/usr/bin/php /home/desyn/public_html/cron/send_scheduled_emails.php
In the end this turned out to be a very particular, and I imagine uncommon, problem. I doubt it'll prove too much help to others, but I leave it here in case.
Essentially, my server didn't like cURL'ing itself, via a domain.
The server being called by cURL in the CRON script was the same server that the CRON task was running on (but a different account and website.)
This has not proved to be a problem via a browser; only via CRON.
Changing the cURL request to use the server's local IP, rather than using the domain, solved this.

cURL connection refused

I'm trying to simply read the Philips Hue lights information from my home with the following code:
$fp = fopen(dirname(__FILE__).'/errorlog.txt', 'a');
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://119.119.20.20:2827/api/Js82jH2lao-pAiws89S9A-k9hHsukw72/lights',
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => $fp
));
$resp = curl_exec($ch);
curl_close($ch);
print_r($resp);
It returns nothing. Looking at errorlog.txt it says:
* About to connect() to 119.119.20.20 port 2827 (#0)
* Trying 119.119.20.20... * Connection refused
* couldn't connect to host
* Closing connection #0
I'm able to read the data and change light settings through a site like hurl.it which tells me I've setup my router correctly. allow_url_fopen on my server is on. I'm using curl because I want to do a PUT request as well. I don't want to use a library for simply turning on and off an light.
How can I make this work?
Edit to clarify: I'm using an external server to host the php, which communicates to my Philips Hue bridge at home. You can assume I forwarded my port correctly. No VPN.
My guess is it's a users/permissions issue.
Does www-data/http user have permission to use curl on your server? All php scripts will be executed as that user so without correct permissions curl will fail giving this error.
Which user created the php script? Have you changed file permissions to allow other users correct privileges?
Having said all that, you stated that you don't want to use a library for something so simple, why even bother with curl? file_get_contents can PUT, POST etc out of the box.
Get status from bridge as associative array:
$result = json_decode(file_get_contents('http://119.119.20.20:2827/api/Js82jH2lao-pAiws89S9A-k9hHsukw72/lights'), true);
Turn off all lights with a PUT request:
$data = '{"on":false}';
$result = file_get_contents('http://119.119.20.20:2827/api/Js82jH2lao-pAiws89S9A-k9hHsukw72/groups/0/action', null, stream_context_create(array(
'http' => array(
'method' => 'PUT',
'header' => 'Content-Type: application/json' . "\r\n"
. 'Content-Length: ' . strlen($data) . "\r\n",
'content' => $data
),
)));
Just tried it on my Hue setup. Works for me.

SOAP-ERROR: Parsing WSDL (PHP Version 5.6.17)

Really hoping someone can help with this as I just can't seem to resolve this issue.
I am having great difficulty with getting the code below to work on my website.
The purpose of the script is to return car lengths based on a provided registration number.
The problem is when I move this over to my live environment the script simply won't work. Please can anyone suggest a possible resolution? I don't understand why It works absolutely fine in the development environment but when I attempt to run it on my main site I get the following error:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://website.com/CarLengthChecker.asmx?WSDL' : failed to load external entity "https://website.com/CarLengthChecker.asmx?WSDL"
<?php
$carReg = "0000000";
try{
$opts = array(
'http'=>array(
'user_agent' => 'PHPSoapClient'
)
);
$context = stream_context_create($opts);
$client = new SoapClient ('https://wesite.com/CarLengthChecker.asmx?WSDL',
array('stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE));
$result = $client->GetVehicleDetails(array(
'VRM' => $carReg,
));
print_r($result);
}
catch(Exception $e){
echo $e->getMessage();
}
?>
I can access the WSDL address from a browser on the live server just not from the script.
I have checked the PHP settings on live and can confirm that both OpenSSL & SOAP
are enabled.
The resolution I found for this was to use the nusoap library (www.sourceforge.net/projects/nusoap). This problem may have been specific to our to live server environment but I would recommend attempting it if you are experiencing similar issues.

Windows Azure Authentication for Bing Search in PHP

I am trying to perform a Bing Search by using the Windows Azure Marketplace API, I have downloaded their guide and sample code. The code prepares a HTTPS request with basic authentication, however I am constantly getting the following error:
Warning: file_get_contents(https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/Web?Query=%27washburn%27&Adult=%27Off%27&$top=50&$format=Atom): failed to open stream: Connection refused
The php code (from Microsoft's document):
$context = stream_context_create(array(
'http' => array(
'proxy' => 'tcp://127.0.0.1:8888',
'request_fulluri' => true,
'header' => "Authorization: Basic " . base64_encode($accountKey.":".$accountKey)
)
));
Does anyone know what is causing the error please? I have correctly set the $accountKey and I tested it in a browser. What puzzles me a little is 127.0.0.1:8888 and also base64_encode($accountKey.":".$accountKey) , how come you need the $accountKey both before and after the : while when using a browser you are supposed to leave the username blank and just input the account key into the password field?
I have solved it and here is what I have found for future people that would be doing the same thing:
I commented out the line where it says:
'proxy' => 'tcp://127.0.0.1:8888',
'request_fulluri' => true,
and also set base64_encode("ignored:".$accountKey) instead
Base on what I read on MSDN, the username part is said to be ignored, so it shouldn't matter what value it is. I was thinking perhaps the length or the special characters in the key screwed things up so I replaces it with ignored (or anything really).
That did the trick and I can parse the returned JSON data. Good luck!

Categories