iOS MDM push notification using Php, not working
Asked Answered
M

1

1

i know it's duplicate of this, but this one is not working for me.

My Php code to send notification is

// Put your device token here (without spaces):
$deviceToken = '6hPQc2HvdA20XGlQkznJxlappCrzm3kJccljjOsgF2k=\n'; #base64 encoded
// Put your private key's passphrase here:
$passphrase = 'Temp1234';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', './Certificates_push_dev_new.pem');
stream_context_set_option($ctx, 'ssl', 'cafile', './entrust_2048_ca.cer');

stream_context_set_option($ctx, 'ssl', 'verify_peer', true);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body

$payload = json_encode(array(
                             'mdm' => '3742A63A-5BB3-4D61-9D4B-E7968DADAF84',
                             'topic' => 'com.apple.mgmt.External.e5814e69-1c24-437f-bae9-562049fd3cd5'
                             ));

echo $payload . PHP_EOL;
// Build the binary notification
#$msg = chr(0).pack('n', 32).$deviceToken . pack('n', strlen($payload)).$payload;

// Build the binary notification
#$msg = chr(0) . pack('n', 32) . pack('J', $deviceToken) . pack('n', strlen($payload)) . $payload;

#$msg = chr(0).chr(0).chr(32).bin2hex(base64_decode($deviceToken)).chr(0).chr(strlen($payload)).$payload;
$msg = chr(0).chr(0).chr(32).bin2hex(base64_decode($deviceToken)).chr(0).chr(strlen($payload)).$payload;

// Send it to the server
# $result = fwrite($fp, $msg, strlen($msg));
$result = fwrite($fp, $msg);

if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);

Device Token with base64 Encoded

$deviceToken = '6hPQc2HvdA20XGlQkznJxlappCrzm3kJccljjOsgF2k=\n'; #base64 encoded

I have tried device token without base64 encoded as well in that case my token was

$deviceToken = '\xEA\u0013\xD0sa\xEFt\r\xB4\\iP\x939\xC9\xC6V\xA9\xA4*\xF3\x9By\tq\xC9c\x8C\xEB \u0017i';

To Check certificate validation, below command is working fine.

openssl s_client -connect gateway.push.apple.com:2195 -cert apns-dev.pem -key key.pem -CAfile entrust_2048_ca.cer

i don't receive any error while executing above php code. But device never contact our MDM server to pull configuration changes.

when my TestMDM installed profile, have "SIGNING CERTIFICATE" SECTION My MDM installed profile missing "SIGNING CERTIFICATE" SECTION

could "SIGNING CERTIFICATE" section cause be of issue, device not receiving notification ?, one screenshot is of TestMDM vendor and second is of my i.e MobiLock

Metacarpus answered 3/7, 2017 at 13:22 Comment(2)
Sorry. I barely remember by no how push notifications work. The last time I implemented it was almost 3 years ago. Tomas is right. Start with code which works. You want to check that you have correct topic. Signing certificate and PKCS12 doesn't play any role in this process. So you can ignore it.Shaeshaef
thanks @VictorRoninMetacarpus
F
2

I've had a go at pushing notifications myself, using PHP on Windows. One of the things I've noticed that might be wrong is your inclusion of the topic in the push payload. This isn't required.

Here is some PHP code I've written to test using a device I registered in TestMDM. I'm not a PHP developer, but using this (http://codular.com/sending-ios-push-notifications-with-php) as a baseline and taking the pushMagic and deviceToken strings from my TestMDM database, I got it to successfully send a push.

As I'm on Windows, I also use a PFX certificate for push.

$deviceToken = '<YOUR DEVICE TOKEN AS BASE64 STRING>'; #base64 encoded
$token = bin2hex(base64_decode($deviceToken));

// Put your private key's passphrase here:
$passphrase = '<YOUR PASSWORD>';

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', './Push.pfx');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

$fp = stream_socket_client('gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp) {
    exit("Failed to connect: $err $errstr" . PHP_EOL);
}

echo 'Connected to APNS' . PHP_EOL . "<br />";

$payload = '{ \'mdm\' = \'<YOUR PUSH MAGIC FOR THIS DEVICE>\' }';

$inner = chr(1) . pack('n', 32) . pack('H*', $token)
        . chr(2) . pack('n', strlen($payload)). $payload
        . chr(3) . pack('n', 4) . pack('N', 1)
        . chr(4) . pack('n', 4)
        . pack('N', time() + 86400)
        . chr(5) . pack('n', 1) . chr(10);

$notification = chr(2) . pack('N', strlen($inner)) . $inner;

echo $payload . PHP_EOL;

$result = fwrite($fp, $notification, strlen($notification));

echo $result;

Once I run the script, I can see this in the logs of my device, which indicates it is working:

Jul 11 10:16:10 Toms-iPod mdmd[11218] <Notice>: (Note ) MDM: mdmd starting...
Jul 11 10:16:10 Toms-iPod mdmd[11218] <Notice>: (Note ) MDM: Network reachability has changed.
Jul 11 10:16:10 Toms-iPod mdmd[11218] <Notice>: (Note ) MDM: Network reachability has changed.
Jul 11 10:16:10 Toms-iPod mdmd[11218] <Notice>: (Note ) MDM: Push token received.
Jul 11 10:16:10 Toms-iPod mdmd[11218] <Notice>: (Note ) MDM: Received push notification.
Jul 11 10:16:10 Toms-iPod mdmd[11218] <Notice>: (Note ) MDM: Polling MDM server https://testmdm.azurewebsites.net/<redacted> for next command.

Hopefully this will help.

T

Foil answered 11/7, 2017 at 9:26 Comment(16)
replaced payload placeholder like $payload = '{ \'mdm\' = \'B07F7F6A-48C0-4CC6-AAAD-14B1BCF29E2E\' }';Metacarpus
so is this format correct for device token and push magic string ? , besides could it be issue related to device don't have appropriate certificate, Note - MDM is installed on device, having two certificate 1) Mobile Device management certificate , 2) SSL certificate of our server i.e generated using Let's Encrypt AuthorityMetacarpus
i can't see any logs using your provided code, you are great hope for me and last hope as well :) , so please follow this thread.Metacarpus
since you have mentioned, it's working for you, now i suspect issue may be related to certificate installed on device. We are using PKCS12, not SCEP.Metacarpus
i have use this device token $deviceToken = '6hPQc2HvdA20XGlQkznJxlappCrzm3kJccljjOsgF2k='; #base64 encoded , do i need to add '\n' at the end of device token ?Metacarpus
with your MDM i.e TestMDM there is one more certificate i.e SIGNING CERTIFICATE, it's missing in our case, so could it be reason for not receiving notification ?Metacarpus
You only need one certificate to perform the push. This is the one you created via Apple's MDM portal. With regards to the deviceToken, you certainly don't need a \n. PFX Certs are PKCS12, but the Windows version. If the certificates in your MDM profile are wrong, you'll see errors once the push notification is received.Foil
no luck, you have checked log using "apple configurator 2" , right ? , i can't see any log using same. i was not asking for push notification certificate, but for MDM profile certificate, "signing certificate is not visible for my mdm profile when installed on device", could this be reason ?Metacarpus
I have two certificates as I'm using self signed certificates. One is a CA cert and the other is the actual SSL certificate. The certificates in your MDM profiles don't come into play until your device tries to contact the MDM. As you have registered your device with the MDM, this proves your Lets Encrypt certificate is sufficient.Foil
your device token format was something like "by5DPaM1wJKGWSzyFFRPhvW/DOpO9k5JJjgwVNp4kho=" , just need to clarify ?Metacarpus
It looked like this (I've removed some characters in the middle $deviceToken = 'f7pip...CT6T0=';Foil
could it be issue, i am running my php code on localhost, while my mdm is on public host, means different server could it be issue ?, you were running php code on same server or different one ?Metacarpus
I ran my script on a my laptop. TestMDM runs in Azure. Try to think of the push notifications as independent of the MDM server. The push notification tells iOS that it should contact the MDM server using the URL in the profile that you installed.Foil
yes you are right. since mine is not working i suspect issue with everything :)Metacarpus
I would try and generate the push certificate again. This part caused me the most issue. When you generate the certificate request, how are you doing it?Foil
Hey tomas, can i have your skype id, mine is sheshnathz , will discuss theirMetacarpus

© 2022 - 2024 — McMap. All rights reserved.